From d7c49fa0208963139bb14e62cc8245bc6f6fbc19 Mon Sep 17 00:00:00 2001 From: Lily Vulcano Date: Fri, 8 May 2020 13:18:09 -0700 Subject: [PATCH] Merge pull request #2782 from millenomi/catalina-merge The Catalina Merge --- .../CFNotificationCenter.h | 4 +- .../AppServices.subproj/CFUserNotification.c | 13 +- .../AppServices.subproj/CFUserNotification.h | 82 +- CoreFoundation/Base.subproj/CFAvailability.h | 29 +- CoreFoundation/Base.subproj/CFBase.c | 40 +- CoreFoundation/Base.subproj/CFBase.h | 14 +- CoreFoundation/Base.subproj/CFByteOrder.h | 6 +- CoreFoundation/Base.subproj/CFFileUtilities.c | 6 +- CoreFoundation/Base.subproj/CFInternal.h | 131 +- CoreFoundation/Base.subproj/CFLogUtilities.h | 4 +- CoreFoundation/Base.subproj/CFOverflow.h | 18 +- CoreFoundation/Base.subproj/CFPlatform.c | 104 +- CoreFoundation/Base.subproj/CFPriv.h | 46 +- CoreFoundation/Base.subproj/CFRuntime.c | 144 +- CoreFoundation/Base.subproj/CFRuntime.h | 10 +- .../Base.subproj/CFRuntime_Internal.h | 16 +- CoreFoundation/Base.subproj/CFSortFunctions.c | 71 +- .../Base.subproj/CFSystemDirectories.c | 7 +- CoreFoundation/Base.subproj/CFUUID.c | 35 +- CoreFoundation/Base.subproj/CFUUID.h | 4 +- CoreFoundation/Base.subproj/CFUtilities.c | 139 +- CoreFoundation/Base.subproj/CFUtilities.h | 4 +- .../Base.subproj/CFWindowsUtilities.c | 5 +- CoreFoundation/Base.subproj/CoreFoundation.h | 12 +- .../Base.subproj/CoreFoundation_Prefix.h | 19 +- .../Base.subproj/ForFoundationOnly.h | 177 +- .../Base.subproj/ForSwiftFoundationOnly.h | 4 + CoreFoundation/CMakeLists.txt | 12 +- .../CFCharacterSetBitmaps.bitmap | Bin 434391 -> 434391 bytes .../CFUniCharPropertyDatabase.data | Bin 39972 -> 44324 bytes .../CharacterSets/CFUnicodeData-B.mapping | Bin 95264 -> 97040 bytes .../CharacterSets/CFUnicodeData-L.mapping | Bin 95264 -> 97040 bytes CoreFoundation/Collections.subproj/CFArray.c | 141 +- CoreFoundation/Collections.subproj/CFArray.h | 2 +- CoreFoundation/Collections.subproj/CFBag.c | 467 +-- CoreFoundation/Collections.subproj/CFBag.h | 4 +- .../Collections.subproj/CFBasicHash.c | 116 +- .../Collections.subproj/CFBasicHash.h | 4 +- .../CFBasicHashFindBucket.m | 6 +- .../Collections.subproj/CFBinaryHeap.c | 20 +- .../Collections.subproj/CFBinaryHeap.h | 4 +- .../Collections.subproj/CFBitVector.c | 6 +- .../Collections.subproj/CFBitVector.h | 4 +- .../CFCollections_Internal.h | 4 +- CoreFoundation/Collections.subproj/CFData.c | 170 +- CoreFoundation/Collections.subproj/CFData.h | 4 +- .../Collections.subproj/CFDictionary.c | 453 +-- .../Collections.subproj/CFDictionary.h | 4 +- CoreFoundation/Collections.subproj/CFSet.c | 482 +-- CoreFoundation/Collections.subproj/CFSet.h | 4 +- .../Collections.subproj/CFStorage.c | 55 +- .../Collections.subproj/CFStorage.h | 6 +- CoreFoundation/Collections.subproj/CFTree.c | 10 +- CoreFoundation/Collections.subproj/CFTree.h | 4 +- CoreFoundation/Error.subproj/CFError.c | 48 +- CoreFoundation/Error.subproj/CFError.h | 4 +- .../Error.subproj/CFError_Private.h | 4 +- CoreFoundation/Locale.subproj/CFCalendar.c | 211 +- CoreFoundation/Locale.subproj/CFCalendar.h | 4 +- .../Locale.subproj/CFDateComponents.c | 2 +- .../Locale.subproj/CFDateFormatter.c | 93 +- .../Locale.subproj/CFDateFormatter.h | 4 +- .../Locale.subproj/CFDateFormatter_Private.h | 4 +- CoreFoundation/Locale.subproj/CFICULogging.h | 14 +- CoreFoundation/Locale.subproj/CFLocale.c | 250 +- CoreFoundation/Locale.subproj/CFLocale.h | 4 +- .../Locale.subproj/CFLocaleIdentifier.c | 10 +- .../Locale.subproj/CFLocaleInternal.h | 4 +- CoreFoundation/Locale.subproj/CFLocaleKeys.c | 5 +- .../Locale.subproj/CFLocale_Private.h | 4 +- .../Locale.subproj/CFNumberFormatter.c | 83 +- .../Locale.subproj/CFNumberFormatter.h | 4 +- .../NumberDate.subproj/CFBigNumber.c | 16 +- .../NumberDate.subproj/CFBigNumber.h | 4 +- CoreFoundation/NumberDate.subproj/CFDate.c | 24 +- CoreFoundation/NumberDate.subproj/CFDate.h | 38 +- CoreFoundation/NumberDate.subproj/CFNumber.c | 31 +- CoreFoundation/NumberDate.subproj/CFNumber.h | 4 +- .../NumberDate.subproj/CFNumber_Private.h | 30 + .../NumberDate.subproj/CFTimeZone.c | 24 +- .../NumberDate.subproj/CFTimeZone.h | 4 +- .../Parsing.subproj/CFBinaryPList.c | 501 +-- .../Parsing.subproj/CFOldStylePList.c | 66 +- .../Parsing.subproj/CFPropertyList.c | 64 +- .../Parsing.subproj/CFPropertyList.h | 4 +- .../Parsing.subproj/CFXMLInputStream.c | 715 ----- .../Parsing.subproj/CFXMLInputStream.h | 91 - CoreFoundation/Parsing.subproj/CFXMLNode.c | 348 --- CoreFoundation/Parsing.subproj/CFXMLNode.h | 196 -- CoreFoundation/Parsing.subproj/CFXMLParser.c | 2028 ------------ CoreFoundation/Parsing.subproj/CFXMLParser.h | 274 -- CoreFoundation/Parsing.subproj/CFXMLTree.c | 244 -- CoreFoundation/PlugIn.subproj/CFBundle.c | 119 +- CoreFoundation/PlugIn.subproj/CFBundle.h | 8 +- CoreFoundation/PlugIn.subproj/CFBundlePriv.h | 10 +- .../PlugIn.subproj/CFBundle_Binary.c | 20 +- .../PlugIn.subproj/CFBundle_BinaryTypes.h | 4 +- CoreFoundation/PlugIn.subproj/CFBundle_Grok.c | 4 +- .../PlugIn.subproj/CFBundle_InfoPlist.c | 307 +- .../PlugIn.subproj/CFBundle_Internal.h | 24 +- .../PlugIn.subproj/CFBundle_Locale.c | 45 +- CoreFoundation/PlugIn.subproj/CFBundle_Main.c | 4 +- .../PlugIn.subproj/CFBundle_Resources.c | 136 +- .../PlugIn.subproj/CFBundle_SplitFileName.c | 137 + .../PlugIn.subproj/CFBundle_SplitFileName.h | 20 + .../PlugIn.subproj/CFBundle_Strings.c | 4 +- CoreFoundation/PlugIn.subproj/CFPlugIn.c | 801 ++++- CoreFoundation/PlugIn.subproj/CFPlugIn.h | 4 +- CoreFoundation/PlugIn.subproj/CFPlugInCOM.h | 4 +- .../PlugIn.subproj/CFPlugIn_Factory.c | 353 --- .../PlugIn.subproj/CFPlugIn_Factory.h | 26 +- .../PlugIn.subproj/CFPlugIn_Instance.c | 104 - .../PlugIn.subproj/CFPlugIn_PlugIn.c | 215 -- .../CFApplicationPreferences.c | 4 +- .../Preferences.subproj/CFPreferences.c | 6 +- .../Preferences.subproj/CFPreferences.h | 4 +- .../CFXMLPreferencesDomain.c | 4 +- CoreFoundation/RunLoop.subproj/CFMachPort.c | 126 +- CoreFoundation/RunLoop.subproj/CFMachPort.h | 4 +- .../RunLoop.subproj/CFMachPort_Internal.h | 4 +- .../RunLoop.subproj/CFMachPort_Lifetime.c | 17 +- .../RunLoop.subproj/CFMachPort_Lifetime.h | 2 +- .../RunLoop.subproj/CFMessagePort.c | 136 +- .../RunLoop.subproj/CFMessagePort.h | 4 +- CoreFoundation/RunLoop.subproj/CFRunLoop.c | 357 +-- CoreFoundation/RunLoop.subproj/CFRunLoop.h | 8 +- CoreFoundation/RunLoop.subproj/CFSocket.c | 1009 +----- CoreFoundation/RunLoop.subproj/CFSocket.h | 4 +- .../Stream.subproj/CFConcreteStreams.c | 4 +- .../Stream.subproj/CFSocketStream.c | 6 +- CoreFoundation/Stream.subproj/CFStream.c | 104 +- CoreFoundation/Stream.subproj/CFStream.h | 4 +- .../Stream.subproj/CFStreamAbstract.h | 4 +- .../Stream.subproj/CFStreamInternal.h | 26 +- CoreFoundation/Stream.subproj/CFStreamPriv.h | 6 +- .../String.subproj/CFAttributedString.c | 9 +- .../String.subproj/CFAttributedString.h | 2 +- .../String.subproj/CFAttributedStringPriv.h | 2 +- CoreFoundation/String.subproj/CFBurstTrie.c | 26 +- CoreFoundation/String.subproj/CFBurstTrie.h | 4 +- .../String.subproj/CFCharacterSet.c | 323 +- .../String.subproj/CFCharacterSet.h | 4 +- .../String.subproj/CFCharacterSetPriv.h | 9 +- CoreFoundation/String.subproj/CFRunArray.c | 2 +- CoreFoundation/String.subproj/CFRunArray.h | 2 +- CoreFoundation/String.subproj/CFString.c | 1339 ++++---- CoreFoundation/String.subproj/CFString.h | 6 +- .../String.subproj/CFStringDefaultEncoding.h | 6 +- .../String.subproj/CFStringEncodingExt.h | 4 +- .../String.subproj/CFStringEncodings.c | 29 +- .../String.subproj/CFStringScanner.c | 4 +- .../String.subproj/CFStringUtilities.c | 34 +- .../String.subproj/CFString_Internal.h | 7 +- .../CFBuiltinConverters.c | 4 +- .../StringEncodings.subproj/CFICUConverters.c | 4 +- .../StringEncodings.subproj/CFICUConverters.h | 4 +- .../CFPlatformConverters.c | 4 +- .../CFStringEncodingConverter.c | 5 +- .../CFStringEncodingConverter.h | 4 +- .../CFStringEncodingConverterExt.h | 4 +- .../CFStringEncodingConverterPriv.h | 4 +- .../CFStringEncodingDatabase.c | 4 +- .../CFStringEncodingDatabase.h | 4 +- .../StringEncodings.subproj/CFUniChar.c | 40 +- .../StringEncodings.subproj/CFUniChar.h | 4 +- .../StringEncodings.subproj/CFUniCharPriv.h | 4 +- .../CFUnicodeDecomposition.c | 12 +- .../CFUnicodeDecomposition.h | 4 +- .../CFUnicodePrecomposition.c | 4 +- .../CFUnicodePrecomposition.h | 4 +- CoreFoundation/URL.subproj/CFURL.c | 130 +- CoreFoundation/URL.subproj/CFURL.h | 24 +- CoreFoundation/URL.subproj/CFURL.inc.h | 82 +- CoreFoundation/URL.subproj/CFURLAccess.c | 26 +- CoreFoundation/URL.subproj/CFURLAccess.h | 4 +- CoreFoundation/URL.subproj/CFURLComponents.c | 159 +- CoreFoundation/URL.subproj/CFURLComponents.h | 129 +- .../URL.subproj/CFURLComponents_Internal.h | 9 +- .../URL.subproj/CFURLComponents_URIParser.c | 785 +++-- CoreFoundation/URL.subproj/CFURLPriv.h | 58 +- Foundation.xcodeproj/project.pbxproj | 94 +- Sources/Foundation/NSURL.swift | 1 + .../Foundation/Resources/NSURLTestData.plist | 209 +- Tests/Foundation/Tests/TestBridging.swift | 17 + Tests/Foundation/Tests/TestURL.swift | 10 +- .../usr/local/include/unicode/alphaindex.h | 18 +- .../usr/local/include/unicode/appendable.h | 52 +- .../usr/local/include/unicode/basictz.h | 4 + .../usr/local/include/unicode/brkiter.h | 82 +- .../usr/local/include/unicode/bytestream.h | 39 +- .../usr/local/include/unicode/bytestrie.h | 9 +- .../local/include/unicode/bytestriebuilder.h | 19 +- .../usr/local/include/unicode/calendar.h | 185 +- .../usr/local/include/unicode/caniter.h | 12 +- .../usr/local/include/unicode/casemap.h | 494 +++ .../usr/local/include/unicode/char16ptr.h | 310 ++ .../usr/local/include/unicode/chariter.h | 42 +- .../usr/local/include/unicode/choicfmt.h | 4 + .../usr/local/include/unicode/coleitr.h | 5 + .../usr/local/include/unicode/coll.h | 89 +- .../include/unicode/compactdecimalformat.h | 211 +- .../usr/local/include/unicode/curramt.h | 12 +- .../usr/local/include/unicode/currpinf.h | 20 +- .../usr/local/include/unicode/currunit.h | 49 +- .../usr/local/include/unicode/datefmt.h | 73 +- .../usr/local/include/unicode/dbbi.h | 4 + .../usr/local/include/unicode/dcfmtsym.h | 159 +- .../usr/local/include/unicode/decimfmt.h | 1195 +++---- .../usr/local/include/unicode/docmain.h | 35 +- .../usr/local/include/unicode/dtfmtsym.h | 138 +- .../usr/local/include/unicode/dtintrv.h | 12 +- .../usr/local/include/unicode/dtitvfmt.h | 269 +- .../usr/local/include/unicode/dtitvinf.h | 132 +- .../usr/local/include/unicode/dtptngen.h | 205 +- .../usr/local/include/unicode/dtrule.h | 4 + .../usr/local/include/unicode/edits.h | 528 ++++ .../usr/local/include/unicode/enumset.h | 5 + .../usr/local/include/unicode/errorcode.h | 6 +- .../usr/local/include/unicode/fieldpos.h | 9 +- .../usr/local/include/unicode/filteredbrk.h | 68 +- .../usr/local/include/unicode/fmtable.h | 43 +- .../usr/local/include/unicode/format.h | 4 + .../local/include/unicode/formattedvalue.h | 319 ++ .../usr/local/include/unicode/fpositer.h | 10 +- .../usr/local/include/unicode/gender.h | 11 +- .../usr/local/include/unicode/gregocal.h | 4 + .../usr/local/include/unicode/icudataver.h | 2 + .../usr/local/include/unicode/icuplug.h | 25 +- .../usr/local/include/unicode/idna.h | 14 +- .../usr/local/include/unicode/listformatter.h | 150 +- .../usr/local/include/unicode/localebuilder.h | 294 ++ .../usr/local/include/unicode/localpointer.h | 311 +- .../usr/local/include/unicode/locdspnm.h | 11 +- .../usr/local/include/unicode/locid.h | 393 ++- .../usr/local/include/unicode/measfmt.h | 154 +- .../usr/local/include/unicode/measunit.h | 2758 ++++++++++++++--- .../usr/local/include/unicode/measure.h | 4 + .../local/include/unicode/messagepattern.h | 10 +- .../include/unicode/module.private.modulemap | 90 + .../usr/local/include/unicode/msgfmt.h | 44 +- .../usr/local/include/unicode/normalizer2.h | 148 +- .../usr/local/include/unicode/normlzr.h | 110 +- .../usr/local/include/unicode/nounit.h | 111 + .../local/include/unicode/numberformatter.h | 2667 ++++++++++++++++ .../include/unicode/numberrangeformatter.h | 909 ++++++ .../usr/local/include/unicode/numfmt.h | 264 +- .../usr/local/include/unicode/numsys.h | 34 +- .../usr/local/include/unicode/parseerr.h | 6 +- .../usr/local/include/unicode/parsepos.h | 18 +- .../usr/local/include/unicode/platform.h | 190 +- .../usr/local/include/unicode/plurfmt.h | 16 +- .../usr/local/include/unicode/plurrule.h | 56 +- .../usr/local/include/unicode/ptypes.h | 4 + .../usr/local/include/unicode/putil.h | 8 +- .../usr/local/include/unicode/rbbi.h | 367 +-- .../usr/local/include/unicode/rbnf.h | 124 +- .../usr/local/include/unicode/rbtz.h | 4 + .../usr/local/include/unicode/regex.h | 273 +- .../usr/local/include/unicode/region.h | 24 +- .../usr/local/include/unicode/reldatefmt.h | 357 ++- .../usr/local/include/unicode/rep.h | 10 +- .../usr/local/include/unicode/resbund.h | 9 +- .../usr/local/include/unicode/schriter.h | 9 +- .../unicode/scientificnumberformatter.h | 29 +- .../usr/local/include/unicode/search.h | 4 + .../usr/local/include/unicode/selfmt.h | 4 + .../local/include/unicode/simpleformatter.h | 338 ++ .../usr/local/include/unicode/simpletz.h | 10 +- .../usr/local/include/unicode/smpdtfmt.h | 154 +- .../usr/local/include/unicode/sortkey.h | 4 + .../usr/local/include/unicode/std_string.h | 14 +- .../usr/local/include/unicode/strenum.h | 12 +- .../usr/local/include/unicode/stringoptions.h | 190 ++ .../usr/local/include/unicode/stringpiece.h | 12 +- .../local/include/unicode/stringtriebuilder.h | 63 +- .../usr/local/include/unicode/stsearch.h | 4 + .../usr/local/include/unicode/symtable.h | 4 + .../usr/local/include/unicode/tblcoll.h | 93 +- .../usr/local/include/unicode/timezone.h | 61 +- .../usr/local/include/unicode/tmunit.h | 36 +- .../usr/local/include/unicode/tmutamt.h | 4 + .../usr/local/include/unicode/tmutfmt.h | 7 + .../usr/local/include/unicode/translit.h | 301 +- .../usr/local/include/unicode/tzfmt.h | 25 +- .../usr/local/include/unicode/tznames.h | 22 +- .../usr/local/include/unicode/tzrule.h | 4 + .../usr/local/include/unicode/tztrans.h | 4 + .../usr/local/include/unicode/ualoc.h | 5 +- .../local/include/unicode/uameasureformat.h | 295 +- .../local/include/unicode/uatimeunitformat.h | 16 +- .../usr/local/include/unicode/ubidi.h | 212 +- .../local/include/unicode/ubiditransform.h | 323 ++ .../usr/local/include/unicode/ubrk.h | 135 +- .../usr/local/include/unicode/ucal.h | 43 +- .../usr/local/include/unicode/ucasemap.h | 56 +- .../usr/local/include/unicode/ucat.h | 2 + .../usr/local/include/unicode/uchar.h | 722 ++++- .../usr/local/include/unicode/ucharstrie.h | 98 +- .../local/include/unicode/ucharstriebuilder.h | 28 +- .../usr/local/include/unicode/uchriter.h | 65 +- .../usr/local/include/unicode/uclean.h | 28 +- .../usr/local/include/unicode/ucnv.h | 44 +- .../usr/local/include/unicode/ucnv_cb.h | 2 + .../usr/local/include/unicode/ucnv_err.h | 14 +- .../usr/local/include/unicode/ucnvsel.h | 4 +- .../usr/local/include/unicode/ucol.h | 46 +- .../usr/local/include/unicode/ucoleitr.h | 6 +- .../usr/local/include/unicode/uconfig.h | 55 +- .../usr/local/include/unicode/ucpmap.h | 162 + .../usr/local/include/unicode/ucptrie.h | 646 ++++ .../usr/local/include/unicode/ucsdet.h | 17 +- .../usr/local/include/unicode/ucurr.h | 87 +- .../usr/local/include/unicode/udat.h | 245 +- .../usr/local/include/unicode/udata.h | 13 +- .../include/unicode/udateintervalformat.h | 146 +- .../usr/local/include/unicode/udatpg.h | 80 +- .../local/include/unicode/udisplaycontext.h | 50 +- .../usr/local/include/unicode/uenum.h | 16 +- .../usr/local/include/unicode/ufieldpositer.h | 30 +- .../usr/local/include/unicode/uformattable.h | 12 +- .../local/include/unicode/uformattedvalue.h | 440 +++ .../usr/local/include/unicode/ugender.h | 6 +- .../usr/local/include/unicode/uidna.h | 6 +- .../usr/local/include/unicode/uiter.h | 8 +- .../usr/local/include/unicode/uldnames.h | 10 +- .../local/include/unicode/ulistformatter.h | 151 +- .../usr/local/include/unicode/uloc.h | 93 +- .../usr/local/include/unicode/ulocdata.h | 26 +- .../usr/local/include/unicode/umachine.h | 119 +- .../usr/local/include/unicode/umisc.h | 4 +- .../usr/local/include/unicode/umsg.h | 6 +- .../local/include/unicode/umutablecptrie.h | 241 ++ .../usr/local/include/unicode/unifilt.h | 6 +- .../usr/local/include/unicode/unifunct.h | 4 + .../usr/local/include/unicode/unimatch.h | 4 + .../usr/local/include/unicode/unirepl.h | 4 + .../usr/local/include/unicode/uniset.h | 119 +- .../usr/local/include/unicode/unistr.h | 1467 +++++---- .../usr/local/include/unicode/unorm.h | 191 +- .../usr/local/include/unicode/unorm2.h | 81 +- .../usr/local/include/unicode/unum.h | 230 +- .../local/include/unicode/unumberformatter.h | 713 +++++ .../usr/local/include/unicode/unumsys.h | 5 +- .../usr/local/include/unicode/uobject.h | 32 +- .../usr/local/include/unicode/upluralrules.h | 101 +- .../usr/local/include/unicode/urbtok.h | 150 +- .../usr/local/include/unicode/uregex.h | 24 +- .../usr/local/include/unicode/uregion.h | 8 +- .../usr/local/include/unicode/ureldatefmt.h | 517 +++ .../usr/local/include/unicode/urename.h | 159 +- .../usr/local/include/unicode/urep.h | 2 + .../usr/local/include/unicode/ures.h | 337 +- .../usr/local/include/unicode/uscript.h | 107 +- .../usr/local/include/unicode/usearch.h | 23 +- .../usr/local/include/unicode/uset.h | 20 +- .../usr/local/include/unicode/usetiter.h | 4 + .../usr/local/include/unicode/ushape.h | 6 +- .../usr/local/include/unicode/uspoof.h | 1268 +++++--- .../usr/local/include/unicode/usprep.h | 16 +- .../usr/local/include/unicode/ustdio.h | 12 +- .../usr/local/include/unicode/ustream.h | 13 +- .../usr/local/include/unicode/ustring.h | 85 +- .../usr/local/include/unicode/ustringtrie.h | 4 +- .../usr/local/include/unicode/utext.h | 53 +- .../usr/local/include/unicode/utf.h | 38 +- .../usr/local/include/unicode/utf16.h | 124 +- .../usr/local/include/unicode/utf32.h | 4 +- .../usr/local/include/unicode/utf8.h | 300 +- .../usr/local/include/unicode/utf_old.h | 47 +- .../usr/local/include/unicode/utmscale.h | 9 + .../usr/local/include/unicode/utrace.h | 26 +- .../usr/local/include/unicode/utrans.h | 8 +- .../usr/local/include/unicode/utypes.h | 217 +- .../usr/local/include/unicode/uvernum.h | 74 +- .../usr/local/include/unicode/uversion.h | 14 +- .../usr/local/include/unicode/vtzone.h | 4 + 376 files changed, 28130 insertions(+), 16017 deletions(-) create mode 100644 CoreFoundation/NumberDate.subproj/CFNumber_Private.h delete mode 100644 CoreFoundation/Parsing.subproj/CFXMLInputStream.c delete mode 100644 CoreFoundation/Parsing.subproj/CFXMLInputStream.h delete mode 100644 CoreFoundation/Parsing.subproj/CFXMLNode.c delete mode 100644 CoreFoundation/Parsing.subproj/CFXMLNode.h delete mode 100644 CoreFoundation/Parsing.subproj/CFXMLParser.c delete mode 100644 CoreFoundation/Parsing.subproj/CFXMLParser.h delete mode 100644 CoreFoundation/Parsing.subproj/CFXMLTree.c create mode 100644 CoreFoundation/PlugIn.subproj/CFBundle_SplitFileName.c create mode 100644 CoreFoundation/PlugIn.subproj/CFBundle_SplitFileName.h delete mode 100644 CoreFoundation/PlugIn.subproj/CFPlugIn_Factory.c delete mode 100644 CoreFoundation/PlugIn.subproj/CFPlugIn_Instance.c delete mode 100644 CoreFoundation/PlugIn.subproj/CFPlugIn_PlugIn.c create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/casemap.h create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/char16ptr.h create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/edits.h create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/formattedvalue.h create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/localebuilder.h create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/module.private.modulemap create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/nounit.h create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/numberformatter.h create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/numberrangeformatter.h create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/simpleformatter.h create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/stringoptions.h create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ubiditransform.h create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucpmap.h create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucptrie.h create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uformattedvalue.h create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/umutablecptrie.h create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unumberformatter.h create mode 100644 bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ureldatefmt.h diff --git a/CoreFoundation/AppServices.subproj/CFNotificationCenter.h b/CoreFoundation/AppServices.subproj/CFNotificationCenter.h index 1a96573ac6..f26544dc5c 100644 --- a/CoreFoundation/AppServices.subproj/CFNotificationCenter.h +++ b/CoreFoundation/AppServices.subproj/CFNotificationCenter.h @@ -1,7 +1,7 @@ /* CFNotificationCenter.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/AppServices.subproj/CFUserNotification.c b/CoreFoundation/AppServices.subproj/CFUserNotification.c index 0c69de3192..95c6ffee37 100644 --- a/CoreFoundation/AppServices.subproj/CFUserNotification.c +++ b/CoreFoundation/AppServices.subproj/CFUserNotification.c @@ -1,7 +1,7 @@ /* CFUserNotification.c - Copyright (c) 2000-2018, Apple Inc. All rights reserved. + Copyright (c) 2000-2019, Apple Inc. All rights reserved. - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -131,7 +131,7 @@ static void _CFUserNotificationAddToDictionary(const void *key, const void *valu if (CFGetTypeID(key) == CFStringGetTypeID()) CFDictionarySetValue((CFMutableDictionaryRef)context, key, value); } -static CFDictionaryRef _CFUserNotificationModifiedDictionary(CFAllocatorRef allocator, CFDictionaryRef dictionary, SInt32 token, SInt32 timeout, CFStringRef source) { +static CFDictionaryRef _CFUserNotificationCreateModifiedDictionary(CFAllocatorRef allocator, CFDictionaryRef dictionary, SInt32 token, SInt32 timeout, CFStringRef source) { CFMutableDictionaryRef md = CFDictionaryCreateMutable(allocator, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFNumberRef tokenNumber = CFNumberCreate(allocator, kCFNumberSInt32Type, &token); CFNumberRef timeoutNumber = CFNumberCreate(allocator, kCFNumberSInt32Type, &timeout); @@ -207,7 +207,7 @@ static SInt32 _CFUserNotificationSendRequest(CFAllocatorRef allocator, CFStringR retval = task_get_bootstrap_port(mach_task_self(), &bootstrapPort); if (ERR_SUCCESS == retval && MACH_PORT_NULL != serverPort) { - modifiedDictionary = _CFUserNotificationModifiedDictionary(allocator, dictionary, token, itimeout, _CFProcessNameString()); + modifiedDictionary = _CFUserNotificationCreateModifiedDictionary(allocator, dictionary, token, itimeout, _CFProcessNameString()); if (modifiedDictionary) { data = CFPropertyListCreateData(allocator, modifiedDictionary, kCFPropertyListXMLFormat_v1_0, 0, NULL); if (data) { @@ -265,11 +265,6 @@ CFUserNotificationRef CFUserNotificationCreate(CFAllocatorRef allocator, CFTimeI userNotification->_token = token; userNotification->_timeout = timeout; userNotification->_requestFlags = flags; - userNotification->_responseFlags = 0; - userNotification->_sessionID = NULL; - userNotification->_responseDictionary = NULL; - userNotification->_machPort = NULL; - userNotification->_callout = NULL; if (sessionID) userNotification->_sessionID = CFStringCreateCopy(allocator, sessionID); } else { retval = unix_err(ENOMEM); diff --git a/CoreFoundation/AppServices.subproj/CFUserNotification.h b/CoreFoundation/AppServices.subproj/CFUserNotification.h index 1fff5dd024..a9ab6538a7 100644 --- a/CoreFoundation/AppServices.subproj/CFUserNotification.h +++ b/CoreFoundation/AppServices.subproj/CFUserNotification.h @@ -1,7 +1,7 @@ /* CFUserNotification.h - Copyright (c) 2000-2018, Apple Inc. and the Swift project authors + Copyright (c) 2000-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -69,116 +69,114 @@ of the textfields. */ typedef void (*CFUserNotificationCallBack)(CFUserNotificationRef userNotification, CFOptionFlags responseFlags); CF_EXPORT -CFTypeID CFUserNotificationGetTypeID(void); +CFTypeID CFUserNotificationGetTypeID(void) API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -CFUserNotificationRef CFUserNotificationCreate(CFAllocatorRef allocator, CFTimeInterval timeout, CFOptionFlags flags, SInt32 *error, CFDictionaryRef dictionary); +CFUserNotificationRef CFUserNotificationCreate(CFAllocatorRef allocator, CFTimeInterval timeout, CFOptionFlags flags, SInt32 *error, CFDictionaryRef dictionary) API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -SInt32 CFUserNotificationReceiveResponse(CFUserNotificationRef userNotification, CFTimeInterval timeout, CFOptionFlags *responseFlags); +SInt32 CFUserNotificationReceiveResponse(CFUserNotificationRef userNotification, CFTimeInterval timeout, CFOptionFlags *responseFlags) API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -CFStringRef CFUserNotificationGetResponseValue(CFUserNotificationRef userNotification, CFStringRef key, CFIndex idx); +CFStringRef CFUserNotificationGetResponseValue(CFUserNotificationRef userNotification, CFStringRef key, CFIndex idx) API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -CFDictionaryRef CFUserNotificationGetResponseDictionary(CFUserNotificationRef userNotification); +CFDictionaryRef CFUserNotificationGetResponseDictionary(CFUserNotificationRef userNotification) API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -SInt32 CFUserNotificationUpdate(CFUserNotificationRef userNotification, CFTimeInterval timeout, CFOptionFlags flags, CFDictionaryRef dictionary); +SInt32 CFUserNotificationUpdate(CFUserNotificationRef userNotification, CFTimeInterval timeout, CFOptionFlags flags, CFDictionaryRef dictionary) API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -SInt32 CFUserNotificationCancel(CFUserNotificationRef userNotification); +SInt32 CFUserNotificationCancel(CFUserNotificationRef userNotification) API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -CFRunLoopSourceRef CFUserNotificationCreateRunLoopSource(CFAllocatorRef allocator, CFUserNotificationRef userNotification, CFUserNotificationCallBack callout, CFIndex order); +CFRunLoopSourceRef CFUserNotificationCreateRunLoopSource(CFAllocatorRef allocator, CFUserNotificationRef userNotification, CFUserNotificationCallBack callout, CFIndex order) API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); /* Convenience functions for handling the simplest and most common cases: a one-way notification, and a notification with up to three buttons. */ CF_EXPORT -SInt32 CFUserNotificationDisplayNotice(CFTimeInterval timeout, CFOptionFlags flags, CFURLRef iconURL, CFURLRef soundURL, CFURLRef localizationURL, CFStringRef alertHeader, CFStringRef alertMessage, CFStringRef defaultButtonTitle); +SInt32 CFUserNotificationDisplayNotice(CFTimeInterval timeout, CFOptionFlags flags, CFURLRef iconURL, CFURLRef soundURL, CFURLRef localizationURL, CFStringRef alertHeader, CFStringRef alertMessage, CFStringRef defaultButtonTitle) API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -SInt32 CFUserNotificationDisplayAlert(CFTimeInterval timeout, CFOptionFlags flags, CFURLRef iconURL, CFURLRef soundURL, CFURLRef localizationURL, CFStringRef alertHeader, CFStringRef alertMessage, CFStringRef defaultButtonTitle, CFStringRef alternateButtonTitle, CFStringRef otherButtonTitle, CFOptionFlags *responseFlags); +SInt32 CFUserNotificationDisplayAlert(CFTimeInterval timeout, CFOptionFlags flags, CFURLRef iconURL, CFURLRef soundURL, CFURLRef localizationURL, CFStringRef alertHeader, CFStringRef alertMessage, CFStringRef defaultButtonTitle, CFStringRef alternateButtonTitle, CFStringRef otherButtonTitle, CFOptionFlags *responseFlags) API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); /* Flags */ CF_ENUM(CFOptionFlags) { - kCFUserNotificationStopAlertLevel = 0, - kCFUserNotificationNoteAlertLevel = 1, - kCFUserNotificationCautionAlertLevel = 2, - kCFUserNotificationPlainAlertLevel = 3 + kCFUserNotificationStopAlertLevel API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos) = 0, + kCFUserNotificationNoteAlertLevel API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos) = 1, + kCFUserNotificationCautionAlertLevel API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos) = 2, + kCFUserNotificationPlainAlertLevel API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos) = 3 }; CF_ENUM(CFOptionFlags) { - kCFUserNotificationDefaultResponse = 0, - kCFUserNotificationAlternateResponse = 1, - kCFUserNotificationOtherResponse = 2, - kCFUserNotificationCancelResponse = 3 + kCFUserNotificationDefaultResponse API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos) = 0, + kCFUserNotificationAlternateResponse API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos) = 1, + kCFUserNotificationOtherResponse API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos) = 2, + kCFUserNotificationCancelResponse API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos) = 3 }; CF_ENUM(CFOptionFlags) { - kCFUserNotificationNoDefaultButtonFlag = (1UL << 5), - kCFUserNotificationUseRadioButtonsFlag = (1UL << 6) + kCFUserNotificationNoDefaultButtonFlag API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos) = (1UL << 5), + kCFUserNotificationUseRadioButtonsFlag API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos) = (1UL << 6) }; -CF_INLINE CFOptionFlags CFUserNotificationCheckBoxChecked(CFIndex i) {return ((CFOptionFlags)(1UL << (8 + i)));} -CF_INLINE CFOptionFlags CFUserNotificationSecureTextField(CFIndex i) {return ((CFOptionFlags)(1UL << (16 + i)));} -CF_INLINE CFOptionFlags CFUserNotificationPopUpSelection(CFIndex n) {return ((CFOptionFlags)(n << 24));} +CF_INLINE CFOptionFlags CFUserNotificationCheckBoxChecked(CFIndex i) API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos) {return ((CFOptionFlags)(1UL << (8 + i)));} +CF_INLINE CFOptionFlags CFUserNotificationSecureTextField(CFIndex i) API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos) {return ((CFOptionFlags)(1UL << (16 + i)));} +CF_INLINE CFOptionFlags CFUserNotificationPopUpSelection(CFIndex n) API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos) {return ((CFOptionFlags)(n << 24));} /* Keys */ CF_EXPORT -const CFStringRef kCFUserNotificationIconURLKey; +const CFStringRef kCFUserNotificationIconURLKey API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -const CFStringRef kCFUserNotificationSoundURLKey; +const CFStringRef kCFUserNotificationSoundURLKey API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -const CFStringRef kCFUserNotificationLocalizationURLKey; +const CFStringRef kCFUserNotificationLocalizationURLKey API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -const CFStringRef kCFUserNotificationAlertHeaderKey; +const CFStringRef kCFUserNotificationAlertHeaderKey API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -const CFStringRef kCFUserNotificationAlertMessageKey; +const CFStringRef kCFUserNotificationAlertMessageKey API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -const CFStringRef kCFUserNotificationDefaultButtonTitleKey; +const CFStringRef kCFUserNotificationDefaultButtonTitleKey API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -const CFStringRef kCFUserNotificationAlternateButtonTitleKey; +const CFStringRef kCFUserNotificationAlternateButtonTitleKey API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -const CFStringRef kCFUserNotificationOtherButtonTitleKey; +const CFStringRef kCFUserNotificationOtherButtonTitleKey API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -const CFStringRef kCFUserNotificationProgressIndicatorValueKey; +const CFStringRef kCFUserNotificationProgressIndicatorValueKey API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -const CFStringRef kCFUserNotificationPopUpTitlesKey; +const CFStringRef kCFUserNotificationPopUpTitlesKey API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -const CFStringRef kCFUserNotificationTextFieldTitlesKey; +const CFStringRef kCFUserNotificationTextFieldTitlesKey API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -const CFStringRef kCFUserNotificationCheckBoxTitlesKey; +const CFStringRef kCFUserNotificationCheckBoxTitlesKey API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -const CFStringRef kCFUserNotificationTextFieldValuesKey; +const CFStringRef kCFUserNotificationTextFieldValuesKey API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT const CFStringRef kCFUserNotificationPopUpSelectionKey API_AVAILABLE(macos(10.3)) API_UNAVAILABLE(ios, watchos, tvos); -#if (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) CF_EXPORT -const CFStringRef kCFUserNotificationAlertTopMostKey; +const CFStringRef kCFUserNotificationAlertTopMostKey API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -const CFStringRef kCFUserNotificationKeyboardTypesKey; -#endif +const CFStringRef kCFUserNotificationKeyboardTypesKey API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXTERN_C_END CF_IMPLICIT_BRIDGING_DISABLED diff --git a/CoreFoundation/Base.subproj/CFAvailability.h b/CoreFoundation/Base.subproj/CFAvailability.h index 83f1ee87e2..d790782ad3 100644 --- a/CoreFoundation/Base.subproj/CFAvailability.h +++ b/CoreFoundation/Base.subproj/CFAvailability.h @@ -1,7 +1,7 @@ /* CFAvailability.h - Copyright (c) 2013-2018, Apple Inc. and the Swift project authors + Copyright (c) 2013-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -10,7 +10,11 @@ #if !defined(__COREFOUNDATION_CFAVAILABILITY__) #define __COREFOUNDATION_CFAVAILABILITY__ 1 +#if __has_include() #include +#else +#include +#endif #if __has_include() && __has_include() && __has_include() #include @@ -36,7 +40,7 @@ // The arguments to these availability macros is a version number, e.g. 10_6, 3_0 or 'NA' // To use a deprecation message with the macro, add a string as the last argument. #if __has_feature(attribute_availability_with_version_underscores) || (__has_feature(attribute_availability_with_message) && __clang__ && __clang_major__ >= 7) -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX // This section is for compilers targeting OS X which support attribute_availability_with_message #define CF_AVAILABLE(_mac, _ios) __attribute__((availability(macosx,introduced=_mac))) @@ -46,7 +50,7 @@ #define CF_DEPRECATED_MAC(_macIntro, _macDep, ...) __attribute__((availability(macosx,introduced=_macIntro,deprecated=_macDep,message="" __VA_ARGS__))) #define CF_DEPRECATED_IOS(_iosIntro, _iosDep, ...) __attribute__((availability(macosx,unavailable))) -#elif (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) +#elif TARGET_OS_IPHONE // This section is for compilers targeting iOS which support attribute_availability_with_message #define CF_AVAILABLE(_mac, _ios) __attribute__((availability(ios,introduced=_ios))) @@ -58,7 +62,7 @@ #endif -#elif (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) +#elif TARGET_OS_OSX || TARGET_OS_IPHONE // This section is for OS X or iOS, and compilers without support for attribute_availability_with_message. We fall back to Availability.h. #ifndef __AVAILABILITY_INTERNAL__MAC_10_0_DEP__MAC_10_0 @@ -105,6 +109,17 @@ #define CF_ENUM_DEPRECATED_IOS(_iosIntro, _iosDep, ...) #endif +// "Soft" deprecation. +#ifndef API_TO_BE_DEPRECATED +/// This macro is used as a version number in API that will be deprecated in an upcoming release. We call this API "soft deprecated". Soft deprecation is an intermediate step before formal deprecation, used as a way to give you a heads-up about the API before you start getting a compiler warning. +/// You can find all places in your code that use soft deprecated API by redefining the value of this macro to your current minimum deployment target, for example: +/// (macOS) +/// clang -DAPI_TO_BE_DEPRECATED=10.12 other compiler flags +/// (iOS) +/// clang -DAPI_TO_BE_DEPRECATED=11.0 other compiler flags +#define API_TO_BE_DEPRECATED 100000 +#endif + // Enums and Options #if __has_attribute(enum_extensibility) #define __CF_ENUM_ATTRIBUTES __attribute__((enum_extensibility(open))) @@ -117,7 +132,9 @@ #endif #define __CF_ENUM_GET_MACRO(_1, _2, NAME, ...) NAME -#if (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && (__has_feature(objc_fixed_enum) || __has_extension(cxx_fixed_enum))) +#define __CF_ENUM_FIXED_IS_AVAILABLE (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && (__has_feature(objc_fixed_enum) || __has_extension(cxx_fixed_enum))) + +#if __CF_ENUM_FIXED_IS_AVAILABLE #define __CF_NAMED_ENUM(_type, _name) enum __CF_ENUM_ATTRIBUTES _name : _type _name; enum _name : _type #define __CF_ANON_ENUM(_type) enum __CF_ENUM_ATTRIBUTES : _type #define CF_CLOSED_ENUM(_type, _name) enum __CF_CLOSED_ENUM_ATTRIBUTES _name : _type _name; enum _name : _type diff --git a/CoreFoundation/Base.subproj/CFBase.c b/CoreFoundation/Base.subproj/CFBase.c index b21378653d..6d16c85750 100644 --- a/CoreFoundation/Base.subproj/CFBase.c +++ b/CoreFoundation/Base.subproj/CFBase.c @@ -1,11 +1,11 @@ /* CFBase.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Christopher Kane + Responsibility: Michael LeHew */ #include @@ -229,7 +229,13 @@ static const struct malloc_introspection_t __CFAllocatorNullZoneIntrospect = { static void *__CFAllocatorSystemAllocate(CFIndex size, CFOptionFlags hint, void *info) { malloc_zone_t * const zone = (info == &__MallocDefaultZoneInfoPlaceholder) ? malloc_default_zone() : (malloc_zone_t *)info; - return malloc_zone_malloc(zone, size); + void *result = NULL; + if (hint == _CFAllocatorHintZeroWhenAllocating) { + result = malloc_zone_calloc(zone, 1, size); + } else { + result = malloc_zone_malloc(zone, size); + } + return result; } static void *__CFAllocatorSystemReallocate(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info) { @@ -249,7 +255,11 @@ static void __CFAllocatorSystemDeallocate(void *ptr, void *info) { #else static void *__CFAllocatorSystemAllocate(CFIndex size, CFOptionFlags hint, void *info) { - return malloc(size); + if (hint == _CFAllocatorHintZeroWhenAllocating) { + return calloc(1, size); + } else { + return malloc(size); + } } static void *__CFAllocatorSystemReallocate(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info) { @@ -459,6 +469,8 @@ CFAllocatorRef CFAllocatorGetDefault(void) { } void CFAllocatorSetDefault(CFAllocatorRef allocator) { +#ifndef __clang_analyzer__ + // clang doesn't like complexity of staticly laid out instances like the black magic we do here and __CFGetDefaultAllocator CFAllocatorRef current = __CFGetDefaultAllocator(); #if defined(DEBUG) if (NULL != allocator) { @@ -478,6 +490,7 @@ void CFAllocatorSetDefault(CFAllocatorRef allocator) { CFRetain(allocator); _CFSetTSD(__CFTSDKeyAllocator, (void *)allocator, NULL); } +#endif } #if DEPLOYMENT_RUNTIME_SWIFT @@ -582,7 +595,7 @@ void *CFAllocatorAllocate(CFAllocatorRef allocator, CFIndex size, CFOptionFlags __CFGenericValidateType(allocator, _kCFRuntimeIDCFAllocator); #endif if (0 == size) return NULL; -#if TARGET_OS_OSX || TARGET_IOS_IPHONE +#if TARGET_OS_MAC if (allocator->_base._cfisa != __CFISAForCFAllocator()) { // malloc_zone_t * return malloc_zone_malloc((malloc_zone_t *)allocator, size); } @@ -743,16 +756,17 @@ void CFAllocatorGetContext(CFAllocatorRef allocator, CFAllocatorContext *context // -------- -------- -------- -------- -------- -------- -------- -------- - -static void __CFReallocationFailed(void *ptr, CFStringRef reason, void (^reallocationFailureHandler)(void *original, bool *outRecovered)) { +// Technically this function can return, but for analyzer purposes it's enough to claim it doesn't. +__attribute__((cold)) +static void __CFReallocationFailed(void *ptr, CFStringRef reason, void (^reallocationFailureHandler)(void *original, bool *outRecovered)) CLANG_ANALYZER_NORETURN { bool recovered = false; if (reallocationFailureHandler) { reallocationFailureHandler(ptr, &recovered); } if (!recovered) { - CRSetCrashLogMessage("Failed to grow buffer"); - HALT; + CRSetCrashLogMessage("Failed to grow buffer"); + HALT; } } @@ -772,10 +786,12 @@ void *__CFSafelyReallocateWithAllocator(CFAllocatorRef allocator, void *destinat if (__builtin_expect(reallocated == NULL, false) && !(destination == NULL && newCapacity == 0)) { __CFReallocationFailed(destination, CFSTR("realloc"), reallocationFailureHandler); } - return reallocated; + return _CLANG_ANALYZER_IGNORE_NONNULL(reallocated);; } - +Boolean __CFAllocatorRespectsHintZeroWhenAllocating(CFAllocatorRef allocator) { + return allocator == kCFAllocatorSystemDefault || allocator == kCFAllocatorMallocZone; +} CFRange __CFRangeMake(CFIndex loc, CFIndex len) { diff --git a/CoreFoundation/Base.subproj/CFBase.h b/CoreFoundation/Base.subproj/CFBase.h index 089d593424..8a0cbde819 100644 --- a/CoreFoundation/Base.subproj/CFBase.h +++ b/CoreFoundation/Base.subproj/CFBase.h @@ -1,7 +1,7 @@ /* CFBase.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -64,11 +64,11 @@ #include #endif -#if __BLOCKS__ && ((TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if __BLOCKS__ && (TARGET_OS_OSX || TARGET_OS_IPHONE) #include #endif - #if ((TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) && !DEPLOYMENT_RUNTIME_SWIFT + #if (TARGET_OS_OSX || TARGET_OS_IPHONE) && !DEPLOYMENT_RUNTIME_SWIFT #include #endif @@ -313,6 +313,12 @@ CF_EXTERN_C_BEGIN #define CF_NO_TAIL_CALL #endif +#if __has_attribute(warn_unused_result) +#define CF_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +#define CF_WARN_UNUSED_RESULT +#endif + #if !__has_feature(objc_generics_variance) #ifndef __covariant #define __covariant diff --git a/CoreFoundation/Base.subproj/CFByteOrder.h b/CoreFoundation/Base.subproj/CFByteOrder.h index 1bd0112595..bcf087fc07 100644 --- a/CoreFoundation/Base.subproj/CFByteOrder.h +++ b/CoreFoundation/Base.subproj/CFByteOrder.h @@ -1,7 +1,7 @@ /* CFByteOrder.h - Copyright (c) 1995-2018, Apple Inc. and the Swift project authors + Copyright (c) 1995-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -11,7 +11,7 @@ #define __COREFOUNDATION_CFBYTEORDER__ 1 #include -#if ((TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) && !defined(CF_USE_OSBYTEORDER_H) +#if (TARGET_OS_OSX || TARGET_OS_IPHONE) && !defined(CF_USE_OSBYTEORDER_H) #include #define CF_USE_OSBYTEORDER_H 1 #endif diff --git a/CoreFoundation/Base.subproj/CFFileUtilities.c b/CoreFoundation/Base.subproj/CFFileUtilities.c index 57e1d9e560..84e3f6253b 100644 --- a/CoreFoundation/Base.subproj/CFFileUtilities.c +++ b/CoreFoundation/Base.subproj/CFFileUtilities.c @@ -1,7 +1,7 @@ /* CFFileUtilities.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -598,7 +598,7 @@ CF_PRIVATE SInt32 _CFGetFileProperties(CFAllocatorRef alloc, CFURLRef pathURL, B } CF_PRIVATE bool _CFURLExists(CFURLRef url) { - Boolean exists; + Boolean exists = false; return url && (0 == _CFGetFileProperties(kCFAllocatorSystemDefault, url, &exists, NULL, NULL, NULL, NULL, NULL)) && exists; } diff --git a/CoreFoundation/Base.subproj/CFInternal.h b/CoreFoundation/Base.subproj/CFInternal.h index 5d60752911..4c7043b3d6 100644 --- a/CoreFoundation/Base.subproj/CFInternal.h +++ b/CoreFoundation/Base.subproj/CFInternal.h @@ -1,7 +1,7 @@ /* CFInternal.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -18,6 +18,12 @@ #if !defined(__COREFOUNDATION_CFINTERNAL__) #define __COREFOUNDATION_CFINTERNAL__ 1 +#if __has_include() +#include +#else +#include +#endif + #define __CF_COMPILE_YEAR__ (__DATE__[7] * 1000 + __DATE__[8] * 100 + __DATE__[9] * 10 + __DATE__[10] - 53328) #define __CF_COMPILE_MONTH__ ((__DATE__[1] + __DATE__[2] == 207) ? 1 : \ @@ -82,6 +88,9 @@ #define _CF_RELEASES_ARGUMENT_OBJ #endif +// For places where we need to return a +1 to satisfy the analyzer but the returned value is actually an un-deallocable singleton, use this macro. +#define _CF_RETURNS_SINGLETON CF_RETURNS_RETAINED + CF_EXTERN_C_BEGIN #include @@ -122,6 +131,7 @@ typedef struct os_log_s *os_log_t; #define os_log_debug(...) do { } while (0) #define os_log_error(...) do { } while (0) #define os_log_create(...) (NULL) +#define os_log_debug_enabled(...) (0) #endif // We want to eventually note that some objects are immortal to the Swift runtime, but this stopgap lets things work while we work to make an ABI for them. @@ -173,9 +183,29 @@ CF_EXPORT void _CFMachPortInstallNotifyPort(CFRunLoopRef rl, CFStringRef mode); CF_PRIVATE os_log_t _CFOSLog(void); +CF_PRIVATE os_log_t _CFMethodSignatureROMLog(void); + +// Messages logged with os_log_fault() to this log will show in the IDE as +// Runtime Issues warnings to framework clients, including external developers, +// and will be attributed to CoreFoundation. +// This log should only be used for warnings that the client can take action to +// address, such as API misuse, for APIs that are conceptually part of +// CoreFoundation from the client's perspective. +CF_PRIVATE os_log_t _CFRuntimeIssuesLog(void); + +// Messages logged with os_log_fault() to this log will show in the IDE as +// Runtime Issues warnings to framework clients, including external developers. +// The warnings will be attributed to Foundation not CoreFoundation. +// This log should only be used for warnings that the client can take action to +// address, such as API misuse, for APIs that are conceptually part of Foundation +// from the client's perspective. +CF_PRIVATE os_log_t _CFFoundationRuntimeIssuesLog(void); CF_PRIVATE CFIndex __CFActiveProcessorCount(void); +#define HALT __builtin_trap() +#define HALT_MSG(str) do { CRSetCrashLogMessage(str); HALT; } while (0) + #ifndef CLANG_ANALYZER_NORETURN #if __has_feature(attribute_analyzer_noreturn) #define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn)) @@ -184,13 +214,35 @@ CF_PRIVATE CFIndex __CFActiveProcessorCount(void); #endif #endif +// Use this in places where the result may be nil but the function is marked as nonnull (http://clang-analyzer.llvm.org/faq.html#nullability_intentional_violation) +// e.g. `return _CLANG_ANALYZER_IGNORE_NONNULL(nil);` or `id x = nil; return _CLANG_ANALYZER_IGNORE_NONNULL(x);` +#define _CLANG_ANALYZER_IGNORE_NONNULL(x) ((id _Nonnull)x) + +// For places where we need to return a +1 to satisfy the analyzer but the returned value is actually an un-deallocable singleton, use this macro. +#ifdef __clang_analyzer__ +#define _CLANG_ANALYZER_IGNORE_RETAIN(x) do { CFAutorelease(x); } while (0) +#else +#define _CLANG_ANALYZER_IGNORE_RETAIN(x) +#endif + +// For places where we want to assert something is true, but only for analyzer purposes. +#ifdef __clang_analyzer__ +#define _CLANG_ANALYZER_ASSERT(x) do { if (!(x)) HALT_MSG("Analyzer-only assert failed"); } while (0) +#else +#define _CLANG_ANALYZER_ASSERT(x) +#endif + +#ifdef __clang_analyzer__ +#define _CLANG_ANALYZER_IGNORE_UNINITIALIZED_BUFFER(buf, size) do { memset((buf), 0, (size)); } while (0) +#else +#define _CLANG_ANALYZER_IGNORE_UNINITIALIZED_BUFFER(buf, size) +#endif + + #if TARGET_OS_WIN32 #define __builtin_unreachable() do { } while (0) #endif -#define HALT __builtin_trap() -#define HALT_MSG(str) do { CRSetCrashLogMessage(str); HALT; } while (0) - #if defined(DEBUG) #define CFAssert(cond, prio, desc) do { if (!(cond)) { CFLog(prio, CFSTR(desc)); /* HALT; */ } } while (0) #define CFAssert1(cond, prio, desc, a1) do { if (!(cond)) { CFLog(prio, CFSTR(desc), a1); /* HALT; */ } } while (0) @@ -319,8 +371,7 @@ enum { __CFTSDKeyMachMessageHasVoucher = 13, __CFTSDKeyWeakReferenceHandler = 14, __CFTSDKeyIsInPreferences = 15, - __CFTSDKeyIsHoldingGlobalPreferencesLock = 16, // this can be removed if we run out of TSD keys, it's just for assertions - __CFTSDKeyPendingPreferencesKVONotifications = 17, + __CFTSDKeyPendingPreferencesKVONotifications = 16, // autorelease pool stuff must be higher than run loop constants __CFTSDKeyAutoreleaseData2 = 61, __CFTSDKeyAutoreleaseData1 = 62, @@ -501,12 +552,18 @@ extern void __CFTypeCollectionRelease(CFAllocatorRef allocator, const void *ptr) extern CFTypeRef CFMakeUncollectable(CFTypeRef cf); +__attribute__((cold)) CF_PRIVATE void _CFRaiseMemoryException(CFStringRef reason); CF_PRIVATE Boolean __CFProphylacticAutofsAccess; +#if __OBJC2__ +CF_EXPORT id const __NSDictionary0__; +CF_EXPORT id const __NSArray0__; +#else CF_EXPORT id __NSDictionary0__; CF_EXPORT id __NSArray0__; +#endif // __OBJC2__ #include @@ -516,15 +573,24 @@ CF_EXPORT id __NSArray0__; #define OS_UNFAIR_LOCK_INIT PTHREAD_MUTEX_INITIALIZER typedef pthread_mutex_t os_unfair_lock; typedef pthread_mutex_t * os_unfair_lock_t; -static void os_unfair_lock_lock(os_unfair_lock_t lock) { pthread_mutex_lock(lock); } -static void os_unfair_lock_unlock(os_unfair_lock_t lock) { pthread_mutex_unlock(lock); } +CF_INLINE void os_unfair_lock_lock(os_unfair_lock_t lock) { pthread_mutex_lock(lock); } +CF_INLINE void os_unfair_lock_unlock(os_unfair_lock_t lock) { pthread_mutex_unlock(lock); } #elif defined(_WIN32) #define OS_UNFAIR_LOCK_INIT CFLockInit #define os_unfair_lock CFLock_t +#define os_unfair_lock_t CFLock_t * #define os_unfair_lock_lock __CFLock #define os_unfair_lock_unlock __CFUnlock #endif // __has_include() +#if __has_include() +#include +#else +// Private: +#define OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION 0 +CF_INLINE void os_unfair_lock_lock_with_options(os_unfair_lock_t lock, uint32_t options) { os_unfair_lock_lock(lock); } +#endif + #if _POSIX_THREADS typedef pthread_mutex_t _CFMutex; #define _CF_MUTEX_STATIC_INITIALIZER PTHREAD_MUTEX_INITIALIZER @@ -612,12 +678,24 @@ CF_PRIVATE void _CF_dispatch_once(dispatch_once_t *, void (^)(void)); #endif #if TARGET_OS_MAC -CF_PRIVATE _Atomic(uint8_t) __CF120293; -CF_PRIVATE _Atomic(uint8_t) __CF120290; +#define __CF_FORK_STATE_FORKED_FLAG (1 << 0) +#define __CF_FORK_STATE_CF_USED_FLAG (1 << 1) +#define __CF_FORK_STATE_MULTITHREADED_FLAG (1 << 2) +CF_PRIVATE _Atomic(uint8_t) __CF_FORK_STATE; extern void __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__(void); -#define CHECK_FOR_FORK() do { __CF120290 = true; if (__CF120293) __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__(); } while (0) -#define CHECK_FOR_FORK_RET(...) do { CHECK_FOR_FORK(); if (__CF120293) return __VA_ARGS__; } while (0) -#define HAS_FORKED() (__CF120293) +extern void __CF_USED(void); +#define CHECK_FOR_FORK() do { \ + /* Write __CF_FORK_STATE_CF_USED_FLAG only once, avoiding a memory barrier for subsequent reads. */ \ + if (0 == (atomic_load_explicit(&__CF_FORK_STATE, memory_order_relaxed) & __CF_FORK_STATE_CF_USED_FLAG)) { \ + __CF_USED(); \ + } \ + if (atomic_load_explicit(&__CF_FORK_STATE, memory_order_relaxed) & __CF_FORK_STATE_FORKED_FLAG) { \ + __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__(); \ + } \ +} while (0) + +#define HAS_FORKED() ({ CHECK_FOR_FORK(); (atomic_load_explicit(&__CF_FORK_STATE, memory_order_relaxed) & __CF_FORK_STATE_FORKED_FLAG) != 0;}) +#define CHECK_FOR_FORK_RET(...) do { if (HAS_FORKED()) return __VA_ARGS__; } while (0) #endif #if !defined(CHECK_FOR_FORK) @@ -735,27 +813,16 @@ extern void _CFRuntimeSetInstanceTypeIDAndIsa(CFTypeRef cf, CFTypeID newTypeID); #define CF_SWIFT_CALLV(obj, fn, ...) (0) #endif -#ifndef __has_attribute -#define __has_attribute(...) 0 -#endif +CF_PRIVATE CFRuntimeClass const * __CFRuntimeClassTable[__CFRuntimeClassTableSize * 2]; -#if TARGET_OS_WIN32 -#define _CF_VISIBILITY_HIDDEN_ATTRIBUTE -#elif __has_attribute(visibility) -#define _CF_VISIBILITY_HIDDEN_ATTRIBUTE __attribute__((visibility("hidden"))) -#else -#define _CF_VISIBILITY_HIDDEN_ATTRIBUTE -#endif - -// an undeclared array length is only valid with extern, but CF_PRIVATE may or may not include extern as part of its expansion. Redefine the visibility attribute so we can explicitly make it an extern declaration. -extern _CF_VISIBILITY_HIDDEN_ATTRIBUTE uintptr_t __CFRuntimeObjCClassTable[]; +#define __CFRuntimeObjCClassTable (((uintptr_t *)__CFRuntimeClassTable) + __CFRuntimeClassTableSize) CF_INLINE uintptr_t __CFISAForTypeID(CFTypeID typeID) { return (typeID < __CFRuntimeClassTableSize) ? __CFRuntimeObjCClassTable[typeID] : 0; } - #define CF_OBJC_FUNCDISPATCHV(typeID, obj, ...) do { } while (0) +#define CF_OBJC_RETAINED_FUNCDISPATCHV(typeID, obj, ...) do { } while (0) #define CF_OBJC_CALLV(obj, ...) (0) #define CF_IS_OBJC(typeID, obj) (0) @@ -1002,6 +1069,7 @@ CF_INLINE dispatch_queue_t __CFDispatchQueueGetGenericBackground(void) { CF_PRIVATE CFStringRef _CFStringCopyBundleUnloadingProtectedString(CFStringRef str); CF_PRIVATE uint8_t *_CFDataGetBytePtrNonObjC(CFDataRef data); +CF_PRIVATE dispatch_data_t _CFDataCreateDispatchData(CFDataRef data); //avoids copying in most cases // Use this for functions that are intended to be breakpoint hooks. If you do not, the compiler may optimize them away. // Based on: BREAKPOINT_FUNCTION in objc-os.h @@ -1042,6 +1110,13 @@ CF_PRIVATE Boolean __CFInitialized; CF_PRIVATE _Atomic(bool) __CFMainThreadHasExited; CF_PRIVATE const CFStringRef __kCFLocaleCollatorID; +#if __OBJC__ +#import +@interface NSArray (CFBufferAdoption) +- (instancetype)_initByAdoptingBuffer:(id *)buffer count:(NSUInteger)count size:(size_t)size; +@end +#endif + CF_EXTERN_C_END diff --git a/CoreFoundation/Base.subproj/CFLogUtilities.h b/CoreFoundation/Base.subproj/CFLogUtilities.h index a6b37cfee1..cc90e215e2 100644 --- a/CoreFoundation/Base.subproj/CFLogUtilities.h +++ b/CoreFoundation/Base.subproj/CFLogUtilities.h @@ -1,7 +1,7 @@ /* CFLogUtilities.h - Copyright (c) 2004-2018, Apple Inc. and the Swift project authors + Copyright (c) 2004-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Base.subproj/CFOverflow.h b/CoreFoundation/Base.subproj/CFOverflow.h index e70e00ee6e..072a67adc5 100644 --- a/CoreFoundation/Base.subproj/CFOverflow.h +++ b/CoreFoundation/Base.subproj/CFOverflow.h @@ -1,7 +1,7 @@ /* CFOverflow.h - Copyright (c) 2017-2018, Apple Inc. and the Swift project authors + Copyright (c) 2017-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2017-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2017-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -75,4 +75,18 @@ CF_INLINE _CFOverflowResult _CFPointerSumWouldOverflow(void const *p, size_t n, return result; } +#if TARGET_OS_WIN32 +CF_INLINE bool _CFMultiplyBufferSizeWithoutOverflow(size_t a, size_t b, size_t *res) { + int32_t res32 = 0; + if (!os_mul_overflow((int32_t)a, (int32_t)b, &res32)) { + *res = res32; + return true; + } else { + return false; + } +} +#else +#define _CFMultiplyBufferSizeWithoutOverflow(a, b, res) (os_mul_overflow((a), (b), (res)) == 0) +#endif + #endif /* CFOverflow_h */ diff --git a/CoreFoundation/Base.subproj/CFPlatform.c b/CoreFoundation/Base.subproj/CFPlatform.c index 8dc9b944f0..794e61fc27 100644 --- a/CoreFoundation/Base.subproj/CFPlatform.c +++ b/CoreFoundation/Base.subproj/CFPlatform.c @@ -1,7 +1,7 @@ /* CFPlatform.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -22,6 +22,9 @@ #include #endif +#define _CFEmitInternalDiagnostics 0 + + #if TARGET_OS_WIN32 #include #include @@ -152,13 +155,17 @@ const char *_CFProcessPath(void) { } } #endif - uint32_t size = CFMaxPathSize; - char buffer[size]; - if (0 == _NSGetExecutablePath(buffer, &size)) { - __CFProcessPath = strdup(buffer); - __CFprogname = strrchr(__CFProcessPath, PATH_SEP); - __CFprogname = (__CFprogname ? __CFprogname + 1 : __CFProcessPath); + + { + uint32_t size = CFMaxPathSize; + char buffer[size]; + if (0 == _NSGetExecutablePath(buffer, &size)) { + __CFProcessPath = strdup(buffer); + __CFprogname = strrchr(__CFProcessPath, PATH_SEP); + __CFprogname = (__CFprogname ? __CFprogname + 1 : __CFProcessPath); + } } + if (!__CFProcessPath) { __CFProcessPath = ""; __CFprogname = __CFProcessPath; @@ -220,27 +227,85 @@ CF_PRIVATE CFStringRef _CFProcessNameString(void) { // Set the fallBackToHome parameter to true if we should fall back to the HOME environment variable if all else fails. Otherwise return NULL. static CFURLRef _CFCopyHomeDirURLForUser(const char *username, bool fallBackToHome) { const char *fixedHomePath = issetugid() ? NULL : __CFgetenv("CFFIXED_USER_HOME"); - const char *homePath = NULL; + + __block CFMutableStringRef errorMessage = NULL; + void (^prepareErrorMessage)(void) = ^{ + if (!errorMessage) { + errorMessage = CFStringCreateMutable(NULL, 0); + } else { + CFStringAppend(errorMessage, CFSTR("\n")); + } + }; // Calculate the home directory we will use // First try CFFIXED_USER_HOME (only if not setugid), then fall back to the upwd, then fall back to HOME environment variable CFURLRef home = NULL; - if (!issetugid() && fixedHomePath) home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)fixedHomePath, strlen(fixedHomePath), true); + if (!issetugid() && fixedHomePath) { + home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)fixedHomePath, strlen(fixedHomePath), true); + if (!home) { + prepareErrorMessage(); + if (_CFEmitInternalDiagnostics) { + CFStringAppendFormat(errorMessage, NULL, CFSTR("CFURLCreateFromFileSystemRepresentation failed to create URL for CFFIXED_USER_HOME value: %s"), fixedHomePath); + } else { + CFStringAppend(errorMessage, CFSTR("CFURLCreateFromFileSystemRepresentation failed to create URL for CFFIXED_USER_HOME value")); + } + } + } if (!home) { struct passwd *upwd = NULL; if (username) { + errno = 0; upwd = getpwnam(username); } else { uid_t euid; __CFGetUGIDs(&euid, NULL); + + errno = 0; upwd = getpwuid(euid ?: getuid()); } - if (upwd && upwd->pw_dir) { - home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)upwd->pw_dir, strlen(upwd->pw_dir), true); + if (upwd) { + if (upwd->pw_dir) { + home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)upwd->pw_dir, strlen(upwd->pw_dir), true); + } + if (!home && !username) { + prepareErrorMessage(); + if (!upwd->pw_dir) { + CFStringAppend(errorMessage, CFSTR("upwd->pw_dir is NULL")); + } else if (_CFEmitInternalDiagnostics) { + CFStringAppendFormat(errorMessage, NULL, CFSTR("CFURLCreateFromFileSystemRepresentation failed to create URL for upwd->pw_dir value: %s"), upwd->pw_dir); + } else { + CFStringAppend(errorMessage, CFSTR("CFURLCreateFromFileSystemRepresentation failed to create URL for upwd->pw_dir value")); + } + } + } else if (!username) { + int const savederrno = errno; + prepareErrorMessage(); + CFStringAppendFormat(errorMessage, NULL, CFSTR("getpwuid failed with code: %d"), savederrno); + } + } + if (fallBackToHome && !home) { + const char *homePath = __CFgetenv("HOME"); + if (homePath) { + home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)homePath, strlen(homePath), true); + if (!home) { + prepareErrorMessage(); + if (_CFEmitInternalDiagnostics) { + CFStringAppendFormat(errorMessage, NULL, CFSTR("CFURLCreateFromFileSystemRepresentation failed to create URL for HOME value: %s"), homePath); + } else { + CFStringAppend(errorMessage, CFSTR("CFURLCreateFromFileSystemRepresentation failed to create URL for HOME value")); + } + } } } - if (fallBackToHome && !home) homePath = __CFgetenv("HOME"); - if (fallBackToHome && !home && homePath) home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)homePath, strlen(homePath), true); + + if (errorMessage) { + if (!home) { + os_log_error(_CFOSLog(), "_CFCopyHomeDirURLForUser failed to create a proper home directory. Falling back to /var/empty. Error(s):\n%{public}@", errorMessage); + const char *_var_empty = "/var/empty"; + home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (const UInt8 *)_var_empty, strlen(_var_empty), true); + } + CFRelease(errorMessage); + } return home; } @@ -262,7 +327,7 @@ CF_PRIVATE CFStringRef _CFStringCreateHostName(void) { /* These are sanitized versions of the above functions. We might want to eliminate the above ones someday. These can return NULL. */ -CF_EXPORT CFStringRef CFGetUserName(void) { +CF_EXPORT CFStringRef CFGetUserName(void) CF_RETURNS_RETAINED { return CFCopyUserName(); } @@ -640,7 +705,8 @@ static void *__CFTSDGetSpecific() { _Atomic(bool) __CFMainThreadHasExited = false; static void __CFTSDFinalize(void *arg) { - if (pthread_main_np()) { + if (pthread_main_np() == 1) { + // Important: we need to be sure that the only time we set this flag to true is when we actually can guarentee we ARE the main thread. __CFMainThreadHasExited = true; } @@ -707,7 +773,7 @@ static __CFTSDTable *__CFTSDGetTable(const Boolean create) { // For the use of CF and Foundation only -CF_EXPORT void *_CFGetTSDCreateIfNeeded(const uint32_t slot, const Boolean create) { +CF_EXPORT void *_CFGetTSDCreateIfNeeded(const uint32_t slot, const Boolean create) CF_RETURNS_NOT_RETAINED { if (slot >= CF_TSD_MAX_SLOTS) { _CFLogSimple(kCFLogLevelError, "Error: TSD slot %d out of range (get)", slot); HALT; @@ -1213,6 +1279,10 @@ int32_t OSAtomicAdd32Barrier( int32_t theAmount, volatile int32_t *theValue ) { return __sync_fetch_and_add(theValue, theAmount) + theAmount; } +int64_t OSAtomicAdd64( int64_t theAmount, volatile int64_t *theValue ) { + return __sync_fetch_and_add(theValue, theAmount) + theAmount; +} + bool OSAtomicCompareAndSwap32Barrier(int32_t oldValue, int32_t newValue, volatile int32_t *theValue) { return __sync_bool_compare_and_swap(theValue, oldValue, newValue); } diff --git a/CoreFoundation/Base.subproj/CFPriv.h b/CoreFoundation/Base.subproj/CFPriv.h index 4f10f8655b..4c70bcaf9b 100644 --- a/CoreFoundation/Base.subproj/CFPriv.h +++ b/CoreFoundation/Base.subproj/CFPriv.h @@ -1,7 +1,7 @@ /* CFPriv.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -41,7 +41,7 @@ -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_LINUX)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) +#if (TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_LINUX)) || TARGET_OS_IPHONE #include #include #endif @@ -66,11 +66,12 @@ CF_EXPORT uid_t _CFGetEUID(void); CF_EXPORT uid_t _CFGetEGID(void); #endif -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_LINUX)) +#if (TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_LINUX)) CF_EXPORT void _CFRunLoopSetCurrent(CFRunLoopRef rl); #endif -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_LINUX)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) + +#if (TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_LINUX)) || TARGET_OS_IPHONE CF_EXPORT CFRunLoopRef CFRunLoopGetMain(void); CF_EXPORT SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterval seconds, Boolean returnAfterSourceHandled); @@ -244,6 +245,7 @@ CF_EXPORT const CFStringRef kCFHTTPURLStatusLine; CF_EXPORT CFStringRef CFCopySystemVersionString(void); // Human-readable string containing both marketing and build version CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void); CF_EXPORT CFDictionaryRef _CFCopyServerVersionDictionary(void); +CF_EXPORT CFStringRef _CFCopySystemVersionDictionaryValue(CFStringRef key) API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); CF_EXPORT const CFStringRef _kCFSystemVersionProductNameKey; CF_EXPORT const CFStringRef _kCFSystemVersionProductCopyrightKey; CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionKey; @@ -390,6 +392,15 @@ CF_INLINE void CFStringInitAppendBuffer(CFAllocatorRef alloc, CFStringAppendBuff buf->theString = CFStringCreateMutable(alloc, 0); } +// Releases an initialized CFStringAppendBuffer +CF_INLINE void CFStringReleaseAppendBuffer(CFStringAppendBuffer *buf) +{ + if ( buf->theString ) { + CFRelease(buf->theString); + buf->theString = NULL; + } +} + // Appends the characters of a string to the CFStringAppendBuffer. CF_INLINE void CFStringAppendStringToAppendBuffer(CFStringAppendBuffer *buf, CFStringRef appendedString) { @@ -494,8 +505,8 @@ void CFCharacterSetInitInlineBuffer(CFCharacterSetRef cset, CFCharacterSetInline @result true, if the value is in the character set, otherwise false. */ #if defined(CF_INLINE) -CF_INLINE Boolean CFCharacterSetInlineBufferIsLongCharacterMember(const CFCharacterSetInlineBuffer *buffer, UTF32Char character) { - Boolean isInverted = ((0 == (buffer->flags & kCFCharacterSetIsInverted)) ? FALSE : TRUE); +CF_INLINE bool CFCharacterSetInlineBufferIsLongCharacterMember(const CFCharacterSetInlineBuffer *buffer, UTF32Char character) { + bool isInverted = ((0 == (buffer->flags & kCFCharacterSetIsInverted)) ? false : true); if ((character >= buffer->rangeStart) && (character < buffer->rangeLimit)) { if ((character > 0xFFFF) || (0 != (buffer->flags & kCFCharacterSetNoBitmapAvailable))) return (CFCharacterSetIsLongCharacterMember(buffer->cset, character) != 0); @@ -532,6 +543,12 @@ CF_EXPORT CFTypeRef _CFTryRetain(CFTypeRef cf); CF_EXPORT Boolean _CFIsDeallocating(CFTypeRef cf); #endif +// The following functions can be used when you know for certain that the types involved are not objc types. Should only be used in the macro in NSPrivateDecls.h. You cannot generally guess which "CF" objects might secretly be ObjC ones. +CF_EXPORT Boolean _CFNonObjCEqual(CFTypeRef cf1, CFTypeRef cf2); +CF_EXPORT CFTypeRef _CFNonObjCRetain(CFTypeRef cf); +CF_EXPORT void _CFNonObjCRelease(CFTypeRef cf); +CF_EXPORT CFHashCode _CFNonObjCHash(CFTypeRef cf); + /* CFLocaleGetLanguageRegionEncodingForLocaleIdentifier gets the appropriate language and region codes, and the default legacy script code and encoding, for the specified locale (or language) string. @@ -547,12 +564,14 @@ CF_EXPORT Boolean CFLocaleGetLanguageRegionEncodingForLocaleIdentifier(CFStringRef localeIdentifier, LangCode *langCode, RegionCode *regCode, ScriptCode *scriptCode, CFStringEncoding *stringEncoding); CF_EXPORT void _CFLocaleResetCurrent(void); +CF_EXPORT void _CFCalendarResetCurrent(void); #if TARGET_OS_WIN32 CF_EXPORT CFMutableStringRef _CFCreateApplicationRepositoryPath(CFAllocatorRef alloc, int nFolder); #endif -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_LINUX)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) + +#if (TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_LINUX)) || TARGET_OS_IPHONE #include CF_EXPORT CFMessagePortRef CFMessagePortCreatePerProcessLocal(CFAllocatorRef allocator, CFStringRef name, CFMessagePortCallBack callout, CFMessagePortContext *context, Boolean *shouldFreeInfo); @@ -595,14 +614,17 @@ CF_INLINE struct timespec _CFFileTimeSpecFromAbsoluteTime(CFAbsoluteTime at) { } // The 'filtered' function below is preferred to this older one -CF_EXPORT Boolean _CFPropertyListCreateSingleValue(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFStringRef keyPath, CFPropertyListRef *value, CFErrorRef *error); +CF_EXPORT bool _CFPropertyListCreateSingleValue(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFStringRef keyPath, CFPropertyListRef *value, CFErrorRef *error); // Returns a subset of the property list, only including the keyPaths in the CFSet. If the top level object is not a dictionary, you will get back an empty dictionary as the result. -CF_EXPORT Boolean _CFPropertyListCreateFiltered(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFSetRef keyPaths, CFPropertyListRef *value, CFErrorRef *error) API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0)); +CF_EXPORT bool _CFPropertyListCreateFiltered(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFSetRef keyPaths, CFPropertyListRef *value, CFErrorRef *error) API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0)); // Returns a set of the keys of the top-level dictionary of a plist. Optimized for bplist (though it works with XML too). Only supports string keys. CF_EXPORT CFSetRef _CFPropertyListCopyTopLevelKeys(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFErrorRef *outError) API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)); +// Returns 'true' if the given 'data' can be determined to be a valid property list. If possible (right now, this means binary plist only) it does this without maintaining the entire object graph for lower overall memory usage. +CF_EXPORT bool _CFPropertyListValidateData(CFDataRef data, CFTypeID *outTopLevelTypeID) API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); + // Returns a subset of a bundle's Info.plist. The keyPaths follow the same rules as above CFPropertyList function. This function takes platform and product keys into account. typedef CF_OPTIONS(CFOptionFlags, _CFBundleFilteredPlistOptions) { _CFBundleFilteredPlistMemoryMapped = 1 @@ -616,6 +638,7 @@ CF_EXPORT CFPropertyListRef _CFBundleCreateFilteredLocalizedInfoPlist(CFBundleRe CF_EXPORT CFStringRef _CFGetWindowsAppleAppDataDirectory(void); CF_EXPORT CFArrayRef _CFGetWindowsBinaryDirectories(void); +CF_EXPORT CFStringRef _CFGetWindowsAppleSystemLibraryDirectory(void); // If your Windows application does not use a CFRunLoop on the main thread (perhaps because it is reserved for handling UI events via Windows API), then call this function to make distributed notifications arrive using a different run loop. CF_EXPORT void _CFNotificationCenterSetRunLoop(CFNotificationCenterRef nc, CFRunLoopRef rl); @@ -636,7 +659,7 @@ CF_EXPORT void _CFRunLoopSetWindowsMessageQueueHandler(CFRunLoopRef rl, CFString CF_EXPORT CFArrayRef CFDateFormatterCreateDateFormatsFromTemplates(CFAllocatorRef allocator, CFArrayRef tmplates, CFOptionFlags options, CFLocaleRef locale); -#if (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) +#if TARGET_OS_IPHONE // Available for internal use on embedded CF_EXPORT CFNotificationCenterRef CFNotificationCenterGetDistributedCenter(void); #endif @@ -678,6 +701,7 @@ CF_EXPORT CFStringRef _CFXDGCreateRuntimeDirectoryPath(void) CF_RETURNS_RETAINED #endif // !DEPLOYMENT_RUNTIME_OBJC + CF_EXTERN_C_END #endif /* ! __COREFOUNDATION_CFPRIV__ */ diff --git a/CoreFoundation/Base.subproj/CFRuntime.c b/CoreFoundation/Base.subproj/CFRuntime.c index e5169d635b..5c6a110be7 100644 --- a/CoreFoundation/Base.subproj/CFRuntime.c +++ b/CoreFoundation/Base.subproj/CFRuntime.c @@ -1,11 +1,11 @@ /* CFRuntime.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Christopher Kane + Responsibility: Michael LeHew */ #define ENABLE_ZOMBIES 1 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -188,8 +189,8 @@ CF_PRIVATE void objc_terminate(void) { #endif // the lock does not protect most reading of these; we just leak the old table to allow read-only accesses to continue to work -static CFLock_t __CFBigRuntimeFunnel = CFLockInit; -static CFRuntimeClass const * __CFRuntimeClassTable[__CFRuntimeClassTableSize] __attribute__((aligned)) = { +static os_unfair_lock __CFBigRuntimeFunnel = OS_UNFAIR_LOCK_INIT; +CFRuntimeClass const * __CFRuntimeClassTable[__CFRuntimeClassTableSize * 2] __attribute__((aligned)) = { [_kCFRuntimeIDNotAType] = &__CFNotATypeClass, [_kCFRuntimeIDCFType] = &__CFTypeClass, [_kCFRuntimeIDCFAllocator] = &__CFAllocatorClass, @@ -218,7 +219,7 @@ static CFRuntimeClass const * __CFRuntimeClassTable[__CFRuntimeClassTableSize] _ [_kCFRuntimeIDCFTimeZone] = &__CFTimeZoneClass, [_kCFRuntimeIDCFKeyedArchiverUID] = &__CFKeyedArchiverUIDClass, -#if TARGET_OS_OSX +#if TARGET_OS_OSX && DEPLOYMENT_RUNTIME_OBJC [_kCFRuntimeIDCFXMLParser] = &__CFXMLParserClass, [_kCFRuntimeIDCFXMLNode] = &__CFXMLNodeClass, #endif // TARGET_OS_OSX @@ -231,10 +232,10 @@ static CFRuntimeClass const * __CFRuntimeClassTable[__CFRuntimeClassTableSize] _ #if TARGET_OS_MAC [_kCFRuntimeIDCFMachPort] = &__CFMachPortClass, - [_kCFRuntimeIDCFMessagePort] = &__CFMessagePortClass, #endif + [_kCFRuntimeIDCFRunLoopMode] = &__CFRunLoopModeClass, [_kCFRuntimeIDCFRunLoop] = &__CFRunLoopClass, [_kCFRuntimeIDCFRunLoopSource] = &__CFRunLoopSourceClass, @@ -252,13 +253,12 @@ static CFRuntimeClass const * __CFRuntimeClassTable[__CFRuntimeClassTableSize] _ [_kCFRuntimeIDCFURLComponents] = &__CFURLComponentsClass, - + [_kCFRuntimeIDCFDateComponents] = &__CFDateComponentsClass, + }; static int32_t __CFRuntimeClassTableCount = _kCFRuntimeStartingClassID; -uintptr_t __CFRuntimeObjCClassTable[__CFRuntimeClassTableSize] __attribute__((aligned)) = {0}; - #if (TARGET_OS_MAC && !TARGET_OS_IPHONE && !__x86_64h__) // Match parity with private header bool (*__CFObjCIsCollectable)(void *) = NULL; #else @@ -297,27 +297,27 @@ CFTypeID _CFRuntimeRegisterClass(const CFRuntimeClass * const cls) { CFLog(kCFLogLevelWarning, CFSTR("*** _CFRuntimeRegisterClass() given inconsistent class '%s'. Program will crash soon."), cls->className); return _kCFRuntimeNotATypeID; } - __CFLock(&__CFBigRuntimeFunnel); + os_unfair_lock_lock_with_options(&__CFBigRuntimeFunnel, OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION); if (__CFMaxRuntimeTypes <= __CFRuntimeClassTableCount) { CFLog(kCFLogLevelWarning, CFSTR("*** CoreFoundation class table full; registration failing for class '%s'. Program will crash soon."), cls->className); - __CFUnlock(&__CFBigRuntimeFunnel); + os_unfair_lock_unlock(&__CFBigRuntimeFunnel); return _kCFRuntimeNotATypeID; } if (__CFRuntimeClassTableSize <= __CFRuntimeClassTableCount) { CFLog(kCFLogLevelWarning, CFSTR("*** CoreFoundation class table full; registration failing for class '%s'. Program will crash soon."), cls->className); - __CFUnlock(&__CFBigRuntimeFunnel); + os_unfair_lock_unlock(&__CFBigRuntimeFunnel); return _kCFRuntimeNotATypeID; } __CFRuntimeClassTable[__CFRuntimeClassTableCount++] = (CFRuntimeClass *)cls; CFTypeID typeID = __CFRuntimeClassTableCount - 1; - __CFUnlock(&__CFBigRuntimeFunnel); + os_unfair_lock_unlock(&__CFBigRuntimeFunnel); return typeID; } void _CFRuntimeBridgeTypeToClass(CFTypeID cf_typeID, const void *cls_ref) { - __CFLock(&__CFBigRuntimeFunnel); + os_unfair_lock_lock(&__CFBigRuntimeFunnel); __CFRuntimeObjCClassTable[cf_typeID] = (uintptr_t)cls_ref; - __CFUnlock(&__CFBigRuntimeFunnel); + os_unfair_lock_unlock(&__CFBigRuntimeFunnel); } const CFRuntimeClass * _CFRuntimeGetClassWithTypeID(CFTypeID typeID) { @@ -325,9 +325,9 @@ const CFRuntimeClass * _CFRuntimeGetClassWithTypeID(CFTypeID typeID) { } void _CFRuntimeUnregisterClassWithTypeID(CFTypeID typeID) { - __CFLock(&__CFBigRuntimeFunnel); + os_unfair_lock_lock_with_options(&__CFBigRuntimeFunnel, OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION); __CFRuntimeClassTable[typeID] = NULL; - __CFUnlock(&__CFBigRuntimeFunnel); + os_unfair_lock_unlock(&__CFBigRuntimeFunnel); } @@ -401,7 +401,7 @@ CF_INLINE uint32_t __CFHighRCFromInfo(__CFInfoType info) { } #endif -CF_INLINE CFRuntimeBase *_cf_aligned_malloc(size_t align, CFIndex size, const char *className) { +CF_INLINE CFRuntimeBase *_cf_aligned_calloc(size_t align, CFIndex size, const char *className) { CFRuntimeBase *memory; #if TARGET_OS_MAC @@ -420,7 +420,7 @@ CF_INLINE CFRuntimeBase *_cf_aligned_malloc(size_t align, CFIndex size, const ch CFLog(kCFLogLevelWarning, CFSTR("*** _CFRuntimeCreateInstance() tried to allocate an instance of '%s', which requires %zu-byte alignment, but memory could not be so allocated: %s"), className, align, errorStringPointer); #elif TARGET_OS_WIN32 CFLog(kCFLogLevelWarning, CFSTR("*** _CFRuntimeCreateInstance() tried to allocate an instance of '%s', which requires %zu-byte alignment, but aligned memory is not supported on this platform"), className, align); - memory = (CFRuntimeBase *)malloc(size); + memory = (CFRuntimeBase *)calloc(1, size); #else CFLog(kCFLogLevelWarning, CFSTR("*** _CFRuntimeCreateInstance() tried to allocate an instance of '%s', which requires %zu-byte alignment, but aligned memory is not supported on this platform"), className, align); memory = NULL; @@ -476,16 +476,23 @@ CFTypeRef _CFRuntimeCreateInstance(CFAllocatorRef allocator, CFTypeID typeID, CF size = (size + 0xF) & ~0xF; // CF objects are multiples of 16 in size // CFType version 0 objects are unscanned by default since they don't have write-barriers and hard retain their innards // CFType version 1 objects are scanned and use hand coded write-barriers to store collectable storage within + Boolean needsClear = false; CFRuntimeBase *memory = NULL; if (cls->version & _kCFRuntimeRequiresAlignment) { - memory = _cf_aligned_malloc(align, size, cls->className); + memory = _cf_aligned_calloc(align, size, cls->className); + } else if (__CFAllocatorRespectsHintZeroWhenAllocating(allocator)) { + memory = (CFRuntimeBase *)CFAllocatorAllocate(allocator, size, _CFAllocatorHintZeroWhenAllocating); } else { memory = (CFRuntimeBase *)CFAllocatorAllocate(allocator, size, 0); + needsClear = true; } + if (NULL == memory) { return NULL; - } + } else if (needsClear) { memset(memory, 0, size); + } + if (__CFOASafe && category) { __CFSetLastAllocationEventName(memory, (char *)category); } else if (__CFOASafe) { @@ -494,6 +501,7 @@ CFTypeRef _CFRuntimeCreateInstance(CFAllocatorRef allocator, CFTypeID typeID, CF if (!usesSystemDefaultAllocator) { // add space to hold allocator ref for non-standard allocators. // This means the allocator is 16 bytes before the result. See the line where we added 16 bytes above, when !usesSystemDefaultAllocator + // This retain is balanced in _CFRelease *(CFAllocatorRef *)((char *)memory) = (CFAllocatorRef)CFRetain(realAllocator); memory = (CFRuntimeBase *)((char *)memory + 16); } @@ -505,7 +513,7 @@ CFTypeRef _CFRuntimeCreateInstance(CFAllocatorRef allocator, CFTypeID typeID, CF if (customRC) { // The top 32 bits of the word are all FF // The rc bits in the lower 32 are 0xFF - memory->_cfinfoa = (uint64_t)((0xFFFFFFFFULL << 32) | ((uint32_t)(0xFF << 24) | RC_CUSTOM_RC_BIT | typeIDMasked | usesDefaultAllocatorMasked)); + memory->_cfinfoa = (uint64_t)((0xFFFFFFFFULL << 32) | ((uint32_t)(0xFFu << 24) | RC_CUSTOM_RC_BIT | typeIDMasked | usesDefaultAllocatorMasked)); } else { // The top 32 bits of the word start at 1 // The rc bits in the lower 32 are 0 @@ -514,7 +522,7 @@ CFTypeRef _CFRuntimeCreateInstance(CFAllocatorRef allocator, CFTypeID typeID, CF #else if (customRC) { // The rc bits in the lower 32 are 0xFF - memory->_cfinfoa = (uint32_t)((0xFF << 24) | RC_CUSTOM_RC_BIT | typeIDMasked | usesDefaultAllocatorMasked); + memory->_cfinfoa = (uint32_t)((0xFFu << 24) | RC_CUSTOM_RC_BIT | typeIDMasked | usesDefaultAllocatorMasked); } else { // The rc bits in the lower 32 are 1 memory->_cfinfoa = (uint32_t)((1 << 24) | typeIDMasked | usesDefaultAllocatorMasked); @@ -524,7 +532,12 @@ CFTypeRef _CFRuntimeCreateInstance(CFAllocatorRef allocator, CFTypeID typeID, CF if (NULL != cls->init) { (cls->init)(memory); } - return memory; + CFTypeRef cftype = (CFTypeRef)memory; +#ifdef __clang_analyzer__ + // The analyzer doesn't understand that we've manually set the retain count of this new CFTypeRef to 1. + CFRetain(cftype); +#endif + return cftype; #endif } @@ -601,13 +614,8 @@ enum { __kCFObjectReleasedEvent = 13 }; -#if TARGET_OS_OSX -#define NUM_EXTERN_TABLES 8 -#define EXTERN_TABLE_IDX(O) (((uintptr_t)(O) >> 8) & 0x7) -#else #define NUM_EXTERN_TABLES 1 #define EXTERN_TABLE_IDX(O) 0 -#endif // we disguise pointers so that programs like 'leaks' forget about these references #define DISGUISE(O) (~(uintptr_t)(O)) @@ -652,10 +660,7 @@ static uintptr_t __CFDoExternRefOperation(uintptr_t op, id obj) { CF_EXPORT CFTypeID CFNumberGetTypeID(void); -CF_INLINE CFTypeID __CFGenericTypeID_inline(const void *cf) { - - return __CFTypeIDFromInfo(atomic_load(&(((CFRuntimeBase *)cf)->_cfinfoa))); -} +CF_INLINE CFTypeID __CFGenericTypeID_inline(const void *cf); CFTypeID __CFGenericTypeID(const void *cf) { return __CFGenericTypeID_inline(cf); @@ -715,6 +720,11 @@ CFTypeID CFGetTypeID(CFTypeRef cf) { return __CFGenericTypeID_inline(cf); } +CF_INLINE CFTypeID __CFGenericTypeID_inline(const void *cf) { + return __CFTypeIDFromInfo(atomic_load(&(((CFRuntimeBase *)cf)->_cfinfoa))); +} + + CFStringRef CFCopyTypeIDDescription(CFTypeID type) { CFAssert2((NULL != __CFRuntimeClassTable[type]) && _kCFRuntimeIDNotAType != type && _kCFRuntimeIDCFType != type, __kCFLogAssertion, "%s(): type %lu is not a CF type ID", __PRETTY_FUNCTION__, type); return CFStringCreateWithCString(kCFAllocatorSystemDefault, __CFRuntimeClassTable[type]->className, kCFStringEncodingASCII); @@ -962,43 +972,50 @@ extern CFTypeID CFTreeGetTypeID(void); extern CFTypeID CFPlugInInstanceGetTypeID(void); extern CFTypeID CFStringTokenizerGetTypeID(void); extern CFTypeID CFStorageGetTypeID(void); -#if TARGET_OS_LINUX || (TARGET_OS_MAC && !DEPLOYMENT_RUNTIME_OBJC) +#if TARGET_OS_LINUX || (TARGET_OS_OSX && !DEPLOYMENT_RUNTIME_OBJC) CF_PRIVATE void __CFTSDInitialize(void); #endif #if TARGET_OS_WIN32 // From CFPlatform.c CF_PRIVATE void __CFTSDWindowsCleanup(void); -CF_PRIVATE void __CFFinalizeWindowsThreadData(); +CF_PRIVATE void __CFFinalizeWindowsThreadData(void); #endif #if TARGET_OS_MAC -_Atomic(uint8_t) __CF120290 = false; -static _Atomic(uint8_t) __CF120291 = false; -_Atomic(uint8_t) __CF120293 = false; +_Atomic(uint8_t) __CF_FORK_STATE = 0; char * __crashreporter_info__ = NULL; // Keep this symbol, since it was exported and other things may be linking against it, like GraphicsServices.framework on iOS __asm(".desc ___crashreporter_info__, 0x10"); -static void __01121__(void) { - __CF120291 = pthread_is_threaded_np() ? true : false; +static void __cf_atfork_prepare(void) { + if (pthread_is_threaded_np()) { + atomic_fetch_or(&__CF_FORK_STATE, __CF_FORK_STATE_MULTITHREADED_FLAG); + } else { + atomic_fetch_and(&__CF_FORK_STATE, ~__CF_FORK_STATE_MULTITHREADED_FLAG); + } } -static void __01123__(void) { +static void __cf_atfork_child(void) { // Ideally, child-side atfork handlers should be async-cancel-safe, as fork() // is async-cancel-safe and can be called from signal handlers. See also // http://standards.ieee.org/reading/ieee/interp/1003-1c-95_int/pasc-1003.1c-37.html // This is not a problem for CF. - if (__CF120290) { - __CF120293 = true; + uint8_t const state = atomic_load_explicit(&__CF_FORK_STATE, memory_order_relaxed); + if (state & __CF_FORK_STATE_CF_USED_FLAG) { + atomic_fetch_or(&__CF_FORK_STATE, __CF_FORK_STATE_FORKED_FLAG); #if TARGET_OS_OSX - if (__CF120291) { - CRSetCrashLogMessage2("*** multi-threaded process forked ***"); - } else { - CRSetCrashLogMessage2("*** single-threaded process forked ***"); - } + if (state & __CF_FORK_STATE_MULTITHREADED_FLAG) { + CRSetCrashLogMessage2("*** multi-threaded process forked ***"); + } else { + CRSetCrashLogMessage2("*** single-threaded process forked ***"); + } #endif } } +CF_PRIVATE void __CF_USED(void) { + atomic_fetch_or(&__CF_FORK_STATE, __CF_FORK_STATE_CF_USED_FLAG); +} + #define EXEC_WARNING_STRING_1 "The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec().\n" #define EXEC_WARNING_STRING_2 "Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() to debug.\n" @@ -1020,11 +1037,12 @@ static struct { const char *name; const char *value; } __CFEnv[] = { - {"PATH", NULL}, {"USER", NULL}, +#if TARGET_OS_WIN32 {"HOMEPATH", NULL}, {"HOMEDRIVE", NULL}, {"USERNAME", NULL}, +#endif {"TZFILE", NULL}, {"TZ", NULL}, {"NEXT_ROOT", NULL}, @@ -1032,18 +1050,12 @@ static struct { {"CFProcessPath", NULL}, {"CFNETWORK_LIBRARY_PATH", NULL}, {"CFUUIDVersionNumber", NULL}, - {"CFDebugNamedDataSharing", NULL}, - {"CFPropertyListAllowImmutableCollections", NULL}, - {"CFBundleUseDYLD", NULL}, {"CFBundleDisableStringsSharing", NULL}, {"CFCharacterSetCheckForExpandedSet", NULL}, - {"__CF_DEBUG_EXPANDED_SET", NULL}, - {"CFStringDisableROM", NULL}, {"CF_CHARSET_PATH", NULL}, {"__CF_USER_TEXT_ENCODING", NULL}, - {"CFNumberDisableCache", NULL}, - {"__CFPREFERENCES_AVOID_DAEMON", NULL}, {"APPLE_FRAMEWORKS_ROOT", NULL}, + {"IPHONE_SIMULATOR_ROOT", NULL}, #if !DEPLOYMENT_RUNTIME_OBJC {"HOME", NULL}, {"XDG_DATA_HOME", NULL}, @@ -1068,7 +1080,7 @@ CF_PRIVATE const char *__CFgetenvIfNotRestricted(const char *n) { return __CFgetenv(n); } -CF_PRIVATE Boolean __CFProcessIsRestricted() { +CF_PRIVATE Boolean __CFProcessIsRestricted(void) { return issetugid(); } @@ -1113,10 +1125,12 @@ static #if TARGET_OS_WIN32 CF_EXPORT #endif + void __CFInitialize(void) { if (!__CFInitialized && !__CFInitializing) { __CFInitializing = 1; + #if TARGET_OS_WIN32 if (!pthread_main_np()) HALT; // CoreFoundation must be initialized on the main thread @@ -1148,7 +1162,7 @@ void __CFInitialize(void) { #if TARGET_OS_MAC UInt32 s, r; __CFStringGetUserDefaultEncoding(&s, &r); // force the potential setenv to occur early - pthread_atfork(__01121__, NULL, __01123__); + pthread_atfork(__cf_atfork_prepare, NULL, __cf_atfork_child); #endif @@ -1629,11 +1643,16 @@ static void _CFRelease(CFTypeRef CF_RELEASES_ARGUMENT cf) { __CFAllocatorDeallocate((void *)cf); } else { CFAllocatorRef allocator = kCFAllocatorSystemDefault; + CFAllocatorRef allocatorToRelease = NULL; Boolean usesSystemDefaultAllocator = true; if (!__CFRuntimeGetFlag(cf, 7)) { allocator = CFGetAllocator(cf); usesSystemDefaultAllocator = _CFAllocatorIsSystemDefault(allocator); + + if (__kCFAllocatorTypeID_CONST != __CFGenericTypeID_inline(cf)) { + allocatorToRelease = (CFAllocatorRef _Nonnull)__CFGetAllocator(cf); + } } { @@ -1641,9 +1660,12 @@ static void _CFRelease(CFTypeRef CF_RELEASES_ARGUMENT cf) { CFAllocatorDeallocate(allocator, (uint8_t *)cf - (usesSystemDefaultAllocator ? 0 : 16)); } - if (kCFAllocatorSystemDefault != allocator) { - CFRelease(allocator); + // This release is balanced in _CFRuntimeCreateInstance, where we retain the allocator used. The analyzer doesn't understand this bit. +#ifndef __clang_analyzer__ + if (allocatorToRelease) { + CFRelease(allocatorToRelease); } +#endif } #endif } diff --git a/CoreFoundation/Base.subproj/CFRuntime.h b/CoreFoundation/Base.subproj/CFRuntime.h index b07f36a400..17e58b80af 100644 --- a/CoreFoundation/Base.subproj/CFRuntime.h +++ b/CoreFoundation/Base.subproj/CFRuntime.h @@ -1,7 +1,7 @@ /* CFRuntime.h - Copyright (c) 1999-2018, Apple Inc. All rights reserved. + Copyright (c) 1999-2019, Apple Inc. All rights reserved. - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -16,7 +16,7 @@ CF_EXTERN_C_BEGIN -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) && !__x86_64h__) +#if (TARGET_OS_MAC && !TARGET_OS_IPHONE && !__x86_64h__) // Although we no longer support GC, we leave exported symbols in place for now to avoid any lockstep dependency issues. CF_EXPORT bool kCFUseCollectableAllocator; @@ -228,8 +228,8 @@ CF_EXPORT CFTypeRef _CFRuntimeCreateInstance(CFAllocatorRef allocator, CFTypeID * number of bytes to allocate for the instance (BEYOND that * needed for the CFRuntimeBase). If the specified CFTypeID * is unknown to the CF runtime, this function returns NULL. - * No part of the new memory other than base header is - * initialized (the extra bytes are not zeroed, for example). + * The base header is initialized and the extra bytes if + * requested will be zeroed. * All instances created with this function must be destroyed * only through use of the CFRelease() function -- instances * must not be destroyed by using CFAllocatorDeallocate() diff --git a/CoreFoundation/Base.subproj/CFRuntime_Internal.h b/CoreFoundation/Base.subproj/CFRuntime_Internal.h index b36a0e0f24..edfe7b9fa8 100644 --- a/CoreFoundation/Base.subproj/CFRuntime_Internal.h +++ b/CoreFoundation/Base.subproj/CFRuntime_Internal.h @@ -1,7 +1,7 @@ /* CFRuntime_Internal.h - Copyright (c) 2018, Apple Inc. and the Swift project authors + Copyright (c) 2018-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -76,8 +76,10 @@ enum { _kCFRuntimeIDCFSocket = 61, _kCFRuntimeIDCFAttributedString = 62, _kCFRuntimeIDCFRunArray = 63, - _kCFRuntimeIDCFDateIntervalFormatter = 64, - // If you are adding a new value, it goes below this line. + _kCFRuntimeIDCFDateComponents = 66, + _kCFRuntimeIDCFDateIntervalFormatter = 69, + + // If you are adding a new value, it goes below this line.: // Stuff not in CF goes here. This value should be one more than the last one above. _kCFRuntimeStartingClassID @@ -125,9 +127,7 @@ CF_PRIVATE const CFRuntimeClass __CFPreferencesDomainClass; CF_PRIVATE const CFRuntimeClass __CFMachPortClass; -#if (TARGET_OS_MAC || TARGET_OS_WIN32 || DEPLOYMENT_RUNTIME_SWIFT) -CF_PRIVATE const CFRuntimeClass __CFMessagePortClass; -#endif + CF_PRIVATE const CFRuntimeClass __CFRunLoopModeClass; CF_PRIVATE const CFRuntimeClass __CFRunLoopClass; CF_PRIVATE const CFRuntimeClass __CFRunLoopSourceClass; @@ -143,6 +143,7 @@ CF_PRIVATE const CFRuntimeClass __CFWindowsNamedPipeClass; #endif CF_PRIVATE const CFRuntimeClass __CFTimeZoneClass; CF_PRIVATE const CFRuntimeClass __CFCalendarClass; +CF_PRIVATE const CFRuntimeClass __CFDateComponentsClass; CF_PRIVATE const CFRuntimeClass __CFDateIntervalFormatterClass; #pragma mark - Private initialiers to run at process start time @@ -158,4 +159,5 @@ CF_PRIVATE void __CFTSDWindowsInitialize(void); CF_PRIVATE void __CFXPreferencesInitialize(void); #endif + #endif /* CFRuntime_Internal_h */ diff --git a/CoreFoundation/Base.subproj/CFSortFunctions.c b/CoreFoundation/Base.subproj/CFSortFunctions.c index ee53cead0b..d394e85a4d 100644 --- a/CoreFoundation/Base.subproj/CFSortFunctions.c +++ b/CoreFoundation/Base.subproj/CFSortFunctions.c @@ -1,11 +1,11 @@ /* CFSortFunctions.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Christopher Kane + Responsibility: Michael LeHew */ #include @@ -20,6 +20,7 @@ #endif // __HAS_DISPATCH__ #include "CFLogUtilities.h" #include "CFInternal.h" +#include "CFOverflow.h" #if __has_include() #include @@ -234,7 +235,7 @@ static void __CFSortIndexesN(VALUE_TYPE listp[], INDEX_TYPE count, int32_t ncore } VALUE_TYPE **tmps = stack_tmps; - dispatch_apply(num_sect, DISPATCH_APPLY_CURRENT_ROOT_QUEUE, ^(size_t sect) { + dispatch_apply(num_sect, DISPATCH_APPLY_AUTO, ^(size_t sect) { INDEX_TYPE sect_len = (sect < num_sect - 1) ? sz : last_sect_len; __CFSimpleMergeSort(listp + sect * sz, sect_len, tmps[sect], cmp); // naturally stable }); @@ -242,7 +243,7 @@ static void __CFSortIndexesN(VALUE_TYPE listp[], INDEX_TYPE count, int32_t ncore INDEX_TYPE even_phase_cnt = ((num_sect / 2) * 2); INDEX_TYPE odd_phase_cnt = (((num_sect - 1) / 2) * 2); for (INDEX_TYPE idx = 0; idx < (num_sect + 1) / 2; idx++) { - dispatch_apply(even_phase_cnt, DISPATCH_APPLY_CURRENT_ROOT_QUEUE, ^(size_t sect) { // merge even + dispatch_apply(even_phase_cnt, DISPATCH_APPLY_AUTO, ^(size_t sect) { // merge even size_t right = sect & (size_t)0x1; VALUE_TYPE *left_base = listp + sect * sz - (right ? sz : 0); VALUE_TYPE *right_base = listp + sect * sz + (right ? 0 : sz); @@ -252,7 +253,7 @@ static void __CFSortIndexesN(VALUE_TYPE listp[], INDEX_TYPE count, int32_t ncore if (num_sect & 0x1) { memmove(tmps[num_sect - 1], listp + (num_sect - 1) * sz, last_sect_len * sizeof(VALUE_TYPE)); } - dispatch_apply(odd_phase_cnt, DISPATCH_APPLY_CURRENT_ROOT_QUEUE, ^(size_t sect) { // merge odd + dispatch_apply(odd_phase_cnt, DISPATCH_APPLY_AUTO, ^(size_t sect) { // merge odd size_t right = sect & (size_t)0x1; VALUE_TYPE *left_base = tmps[sect + (right ? 0 : 1)]; VALUE_TYPE *right_base = tmps[sect + (right ? 1 : 2)]; @@ -280,7 +281,10 @@ static void __CFSortIndexesN(VALUE_TYPE listp[], INDEX_TYPE count, int32_t ncore // fills an array of indexes (of length count) giving the indexes 0 - count-1, as sorted by the comparator block _CF_SORT_INDEXES_EXPORT void CFSortIndexes(CFIndex *indexBuffer, CFIndex count, CFOptionFlags opts, CFComparisonResult (^cmp)(CFIndex, CFIndex)) { if (count < 1) return; - if (INTPTR_MAX / sizeof(CFIndex) < count) return; + if (INTPTR_MAX / sizeof(CFIndex) < count) { + CRSetCrashLogMessage("Size of array to be sorted is too big"); + HALT; + } int32_t ncores = 0; if (opts & kCFSortConcurrent) { ncores = __CFActiveProcessorCount(); @@ -304,7 +308,7 @@ _CF_SORT_INDEXES_EXPORT void CFSortIndexes(CFIndex *indexBuffer, CFIndex count, /* Specifically hard-coded to 8; the count has to be very large before more chunks and/or cores is worthwhile. */ dispatch_queue_t q = dispatch_queue_create(__CF_QUEUE_NAME("NSSortIndexes"), DISPATCH_QUEUE_CONCURRENT); CFIndex sz = ((((size_t)count + 15) / 16) * 16) / 8; - dispatch_apply(8, DISPATCH_APPLY_CURRENT_ROOT_QUEUE, ^(size_t n) { + dispatch_apply(8, DISPATCH_APPLY_AUTO, ^(size_t n) { CFIndex idx = n * sz, lim = __CFMin(idx + sz, count); for (; idx < lim; idx++) indexBuffer[idx] = idx; }); @@ -325,55 +329,16 @@ _CF_SORT_INDEXES_EXPORT void CFSortIndexes(CFIndex *indexBuffer, CFIndex count, if (local != tmp) free(tmp); } -typedef CF_ENUM(uint8_t, _CFOverflowResult) { - _CFOverflowResultOK = 0, - _CFOverflowResultNegativeParameters, - _CFOverflowResultOverflows, -}; - -// Overflow utilities for positive integers -CF_INLINE _CFOverflowResult _CFIntegerProductWouldOverflow(CFIndex si_a, CFIndex si_b) { - _CFOverflowResult result = _CFOverflowResultOK; - if (si_a < 0 || si_b < 0) { - // we explicitly only implement a subset of the overflow checking, so report failure if out of domain - result = _CFOverflowResultNegativeParameters; - } else { - int32_t err = CHECKINT_NO_ERROR; -#if TARGET_RT_64_BIT - __checkint_int64_mul(si_a, si_b, &err); -#else - __checkint_int32_mul(si_a, si_b, &err); -#endif - if (err != CHECKINT_NO_ERROR) { - result = _CFOverflowResultOverflows; - } - } - return result; -} -CF_INLINE _CFOverflowResult _CFPointerSumWouldOverflow(void *p, size_t n) { - _CFOverflowResult result = _CFOverflowResultOK; - int32_t err = CHECKINT_NO_ERROR; -#if TARGET_RT_64_BIT - __checkint_uint64_add((uint64_t)p, (uint64_t)n, &err); -#else - __checkint_uint32_add((uint32_t)p, (uint32_t)n, &err); -#endif - if (err != CHECKINT_NO_ERROR) { - result = _CFOverflowResultOverflows; - } - return result; -} - /* Comparator is passed the address of the values. */ void CFQSortArray(void *list, CFIndex count, CFIndex elementSize, CFComparatorFunction comparator, void *context) { if (count < 2 || elementSize < 1) return; - _CFOverflowResult overflowResult = _CFIntegerProductWouldOverflow(count, elementSize); + _CFOverflowResult overflowResult = _CFPositiveIntegerProductWouldOverflow(count, elementSize, NULL); if (overflowResult != _CFOverflowResultOK) { CFLog(kCFLogLevelError, CFSTR("Unable to qsort array - count: %ld elementSize: %ld product overflows"), (long)count, (long)elementSize); CRSetCrashLogMessage("qsort - count/elementSize overflow"); HALT; } - overflowResult = _CFPointerSumWouldOverflow(list, count * elementSize); + overflowResult = _CFPointerSumWouldOverflow(list, count * elementSize, NULL); if (overflowResult != _CFOverflowResultOK) { CFLog(kCFLogLevelError, CFSTR("Unable to qsort array - list: %lu count: %ld elementSize: %ld - array access overflows"), (unsigned long)list, (long)count, (long)elementSize); CRSetCrashLogMessage("qsort - array access overflow"); @@ -389,7 +354,7 @@ void CFQSortArray(void *list, CFIndex count, CFIndex elementSize, CFComparatorFu CFSortIndexes(indexes, count, 0, ^(CFIndex a, CFIndex b) { return comparator((char *)list + a * elementSize, (char *)list + b * elementSize, context); }); STACK_BUFFER_DECL(uint8_t, locals, count <= (16 * 1024 / elementSize) ? count * elementSize : 1); void *store = (count <= (16 * 1024 / elementSize)) ? locals : malloc(count * elementSize); - overflowResult = _CFPointerSumWouldOverflow(store, count * elementSize); + overflowResult = _CFPointerSumWouldOverflow(store, count * elementSize, NULL); if (overflowResult != _CFOverflowResultOK) { CFLog(kCFLogLevelError, CFSTR("Unable to qsort array - list: %lu count: %ld elementSize: %ld array - store overflows"), (unsigned long)list, (long)count, (long)elementSize); CRSetCrashLogMessage("qsort - array storage overflow"); @@ -413,13 +378,13 @@ void CFQSortArray(void *list, CFIndex count, CFIndex elementSize, CFComparatorFu /* Comparator is passed the address of the values. */ void CFMergeSortArray(void *list, CFIndex count, CFIndex elementSize, CFComparatorFunction comparator, void *context) { if (count < 2 || elementSize < 1) return; - _CFOverflowResult overflowResult = _CFIntegerProductWouldOverflow(count, elementSize); + _CFOverflowResult overflowResult = _CFPositiveIntegerProductWouldOverflow(count, elementSize, NULL); if (overflowResult != _CFOverflowResultOK) { CFLog(kCFLogLevelError, CFSTR("Unable to mergesort array - count: %ld elementSize: %ld overflows"), (long)count, (long)elementSize); CRSetCrashLogMessage("merge sort - count/elementSize overflow"); HALT; } - overflowResult = _CFPointerSumWouldOverflow(list, count * elementSize); + overflowResult = _CFPointerSumWouldOverflow(list, count * elementSize, NULL); if (overflowResult != _CFOverflowResultOK) { CFLog(kCFLogLevelError, CFSTR("Unable to mergesort array - list: %lu count: %ld elementSize: %ld - array access overflows"), (unsigned long)list, (long)count, (long)elementSize); CRSetCrashLogMessage("merge sort - array access overflow"); @@ -435,7 +400,7 @@ void CFMergeSortArray(void *list, CFIndex count, CFIndex elementSize, CFComparat CFSortIndexes(indexes, count, kCFSortStable, ^(CFIndex a, CFIndex b) { return comparator((char *)list + a * elementSize, (char *)list + b * elementSize, context); }); STACK_BUFFER_DECL(uint8_t, locals, count <= (16 * 1024 / elementSize) ? count * elementSize : 1); void *store = (count <= (16 * 1024 / elementSize)) ? locals : malloc(count * elementSize); - overflowResult = _CFPointerSumWouldOverflow(store, count * elementSize); + overflowResult = _CFPointerSumWouldOverflow(store, count * elementSize, NULL); if (overflowResult != _CFOverflowResultOK) { CFLog(kCFLogLevelError, CFSTR("Unable to mergesort array - list: %lu count: %ld elementSize: %ld - array store overflows"), (unsigned long)list, (long)count, (long)elementSize); CRSetCrashLogMessage("merge sort - overflow array storage"); diff --git a/CoreFoundation/Base.subproj/CFSystemDirectories.c b/CoreFoundation/Base.subproj/CFSystemDirectories.c index fc4915a4a9..6df0d01070 100644 --- a/CoreFoundation/Base.subproj/CFSystemDirectories.c +++ b/CoreFoundation/Base.subproj/CFSystemDirectories.c @@ -1,7 +1,7 @@ /* CFSystemDirectories.c - Copyright (c) 1997-2018, Apple Inc. and the Swift project authors + Copyright (c) 1997-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -27,6 +27,9 @@ #include #include #include +#if __has_include() +#include +#endif // For now, CFSystemDirectories SPIs are exactly equivalent to (or at least a subset of) sysdir's. NSSearchPath* APIs in Foundation are not a subset of sysdir, so don't attempt to push that functionality down here without accommodating the differences. #define CFSearchPathToSysdir(dir) ((sysdir_search_path_directory_t)dir) diff --git a/CoreFoundation/Base.subproj/CFUUID.c b/CoreFoundation/Base.subproj/CFUUID.c index 9eb63c503e..9ebd27af7a 100644 --- a/CoreFoundation/Base.subproj/CFUUID.c +++ b/CoreFoundation/Base.subproj/CFUUID.c @@ -1,11 +1,11 @@ /* CFUUID.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: David Smith + Responsibility: Ben D. Jones */ #include @@ -44,13 +44,6 @@ struct __CFUUID { typedef struct __CFUUID __CFUUID_t; -static Boolean __CFisEqualUUIDBytes(const void *ptr1, const void *ptr2) { - CFUUIDBytes *p1 = (CFUUIDBytes *)ptr1; - CFUUIDBytes *p2 = (CFUUIDBytes *)ptr2; - - return (((p1->byte0 == p2->byte0) && (p1->byte1 == p2->byte1) && (p1->byte2 == p2->byte2) && (p1->byte3 == p2->byte3) && (p1->byte4 == p2->byte4) && (p1->byte5 == p2->byte5) && (p1->byte6 == p2->byte6) && (p1->byte7 == p2->byte7) && (p1->byte8 == p2->byte8) && (p1->byte9 == p2->byte9) && (p1->byte10 == p2->byte10) && (p1->byte11 == p2->byte11) && (p1->byte12 == p2->byte12) && (p1->byte13 == p2->byte13) && (p1->byte14 == p2->byte14) && (p1->byte15 == p2->byte15)) ? true : false); -} - static CFHashCode __CFhashUUIDBytes(const void *ptr) { return CFHashBytes((uint8_t *)ptr, 16); } @@ -125,6 +118,14 @@ static CFUUIDRef __CFUUIDCreateWithBytesPrimitive(CFAllocatorRef allocator, CFUU } else if (!isConst) { CFRetain(uuid); } + + if (isConst) { +#if !DEPLOYMENT_RUNTIME_SWIFT + __CFRuntimeSetRC(uuid, 0); // constant CFUUIDs should be immortal. This applies even to equivalent UUIDs created earlier that were *not* constant. +#else + CFRetain(uuid); // Swift doesn't support meddling with the retain count. Just ensure there is one retain here. +#endif + } }); return (CFUUIDRef)uuid; @@ -152,16 +153,15 @@ CFUUIDRef CFUUIDCreate(CFAllocatorRef alloc) { if (RPC_S_OK != rStatus && RPC_S_UUID_LOCAL_ONLY != rStatus) retval = 1; memmove(&bytes, &u, sizeof(bytes)); #elif TARGET_OS_MAC || TARGET_OS_LINUX - static Boolean useV1UUIDs = false, checked = false; + static int8_t useV1UUIDs = -1; uuid_t uuid; - if (!checked) { + if (useV1UUIDs == -1) { const char *value = __CFgetenv("CFUUIDVersionNumber"); if (value) { - if (1 == strtoul_l(value, NULL, 0, NULL)) useV1UUIDs = true; + useV1UUIDs = (1 == strtoul_l(value, NULL, 0, NULL)) ? 1 : 0; } - checked = true; } - if (useV1UUIDs) uuid_generate_time(uuid); else uuid_generate_random(uuid); + if (useV1UUIDs == 1) uuid_generate_time(uuid); else uuid_generate_random(uuid); memcpy((void *)&bytes, uuid, sizeof(uuid)); #else //This bzero works around . It isn't actually needed, since the function will simply return NULL on this deployment target, anyway. @@ -354,7 +354,12 @@ CFUUIDRef CFUUIDGetConstantUUIDWithBytes(CFAllocatorRef alloc, uint8_t byte0, ui bytes.byte14 = byte14; bytes.byte15 = byte15; + // The analyzer can't understand functions like __CFUUIDCreateWithBytesPrimitive which return retained objects based on a parameter. +#ifdef __clang_analyzer__ + return NULL; +#else return __CFUUIDCreateWithBytesPrimitive(alloc, bytes, true); +#endif } CFUUIDBytes CFUUIDGetUUIDBytes(CFUUIDRef uuid) { diff --git a/CoreFoundation/Base.subproj/CFUUID.h b/CoreFoundation/Base.subproj/CFUUID.h index 2ca4357028..2c41d4a13f 100644 --- a/CoreFoundation/Base.subproj/CFUUID.h +++ b/CoreFoundation/Base.subproj/CFUUID.h @@ -1,7 +1,7 @@ /* CFUUID.h - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Base.subproj/CFUtilities.c b/CoreFoundation/Base.subproj/CFUtilities.c index 06ac3dc684..aeb999e403 100644 --- a/CoreFoundation/Base.subproj/CFUtilities.c +++ b/CoreFoundation/Base.subproj/CFUtilities.c @@ -1,13 +1,19 @@ /* CFUtilities.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors Responsibility: Tony Parker */ +#if __has_include() +#import +#undef XPC_TRANSACTION_DEPRECATED +#define XPC_TRANSACTION_DEPRECATED +#endif + #include #include #include "CFInternal.h" @@ -93,6 +99,33 @@ CF_PRIVATE os_log_t _CFOSLog(void) { return logger; } +CF_PRIVATE os_log_t _CFMethodSignatureROMLog(void) { + static os_log_t logger; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + logger = os_log_create("com.apple.foundation", "MethodSignatureROM"); + }); + return logger; +} + +CF_PRIVATE os_log_t _CFRuntimeIssuesLog(void) { + static os_log_t logger; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + logger = os_log_create(OS_LOG_SUBSYSTEM_RUNTIME_ISSUES, "CoreFoundation"); + }); + return logger; +} + +CF_PRIVATE os_log_t _CFFoundationRuntimeIssuesLog(void) { + static os_log_t logger; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + logger = os_log_create(OS_LOG_SUBSYSTEM_RUNTIME_ISSUES, "Foundation"); + }); + return logger; +} + /* Comparator is passed the address of the values. */ /* Binary searches a sorted-increasing array of some type. Return value is either 1) the index of the element desired, @@ -246,6 +279,14 @@ static CFStringRef _CFCopyLocalizedVersionKey(CFBundleRef *bundlePtr, CFStringRe } #endif +#if TARGET_OS_WIN32 +static BOOL _CFGetWindowsSystemVersion(OSVERSIONINFOEX *osvi) { + ZeroMemory(osvi, sizeof(OSVERSIONINFOEX)); + osvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + return GetVersionEx((OSVERSIONINFO *)osvi); +} +#endif + static CFDictionaryRef _CFCopyVersionDictionary(CFStringRef path) { CFPropertyListRef plist = NULL; @@ -293,10 +334,7 @@ static CFDictionaryRef _CFCopyVersionDictionary(CFStringRef path) { } #elif TARGET_OS_WIN32 OSVERSIONINFOEX osvi; - ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - BOOL result = GetVersionEx((OSVERSIONINFO *)&osvi); - if (!result) return NULL; + if (!_CFGetWindowsSystemVersion(&osvi)) return NULL; plist = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 10, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); @@ -316,17 +354,21 @@ static CFDictionaryRef _CFCopyVersionDictionary(CFStringRef path) { return (CFDictionaryRef)plist; } -CFStringRef CFCopySystemVersionString(void) { +CFStringRef _CFCopySystemVersionDictionaryValue(CFStringRef key) { CFStringRef versionString; CFDictionaryRef dict = _CFCopyServerVersionDictionary(); if (!dict) dict = _CFCopySystemVersionDictionary(); if (!dict) return NULL; - versionString = (CFStringRef)CFDictionaryGetValue(dict, CFSTR("FullVersionString")); + versionString = (CFStringRef)CFDictionaryGetValue(dict, key); if (versionString) CFRetain(versionString); CFRelease(dict); return versionString; } +CFStringRef CFCopySystemVersionString(void) { + return _CFCopySystemVersionDictionaryValue(CFSTR("FullVersionString")); +} + CFDictionaryRef _CFCopySystemVersionDictionary(void) { static dispatch_once_t onceToken; static CFDictionaryRef result = NULL; @@ -360,6 +402,58 @@ CFDictionaryRef _CFCopyServerVersionDictionary(void) { } } +static CFOperatingSystemVersion _CFCalculateOSVersion(void) { + CFOperatingSystemVersion versionStruct = {-1, 0, 0}; +#if TARGET_OS_WIN32 + OSVERSIONINFOEX windowsVersion; + if (_CFGetWindowsSystemVersion(&windowsVersion)) { + versionStruct.majorVersion = windowsVersion.dwMajorVersion; + versionStruct.minorVersion = windowsVersion.dwMinorVersion; + versionStruct.patchVersion = windowsVersion.dwBuildNumber; + } +#else + CFStringRef productVersion = _CFCopySystemVersionDictionaryValue(_kCFSystemVersionProductVersionKey); + if (productVersion) { + CFArrayRef components = CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, productVersion, CFSTR(".")); + if (components) { + const CFIndex cnt = CFArrayGetCount(components); + if (0 < cnt) { + versionStruct.majorVersion = CFStringGetIntValue(CFArrayGetValueAtIndex(components, 0)); + if (1 < cnt) { + versionStruct.minorVersion = CFStringGetIntValue(CFArrayGetValueAtIndex(components, 1)); + if (2 < cnt) { + versionStruct.patchVersion = CFStringGetIntValue(CFArrayGetValueAtIndex(components, 2)); + } + } + } + CFRelease(components); + } + CFRelease(productVersion); + } +#endif + return versionStruct; +} + +CFOperatingSystemVersion _CFOperatingSystemVersionGetCurrent(void) { + static CFOperatingSystemVersion version; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + version = _CFCalculateOSVersion(); + }); + return version; +} + +Boolean _CFOperatingSystemVersionIsAtLeastVersion(CFOperatingSystemVersion version) { + const CFOperatingSystemVersion ourVersion = _CFOperatingSystemVersionGetCurrent(); + if (ourVersion.majorVersion < version.majorVersion) return false; + if (ourVersion.majorVersion > version.majorVersion) return true; + if (ourVersion.minorVersion < version.minorVersion) return false; + if (ourVersion.minorVersion > version.minorVersion) return true; + if (ourVersion.patchVersion < version.patchVersion) return false; + if (ourVersion.patchVersion > version.patchVersion) return true; + return true; +} + CONST_STRING_DECL(_kCFSystemVersionProductNameKey, "ProductName") CONST_STRING_DECL(_kCFSystemVersionProductCopyrightKey, "ProductCopyright") CONST_STRING_DECL(_kCFSystemVersionProductVersionKey, "ProductVersion") @@ -424,7 +518,9 @@ CF_PRIVATE void *__CFLookupCFNetworkFunction(const char *name) { } #endif -CF_PRIVATE CFIndex __CFActiveProcessorCount() { +// TSAN does not know about the commpage: [39153032] +__attribute__((no_sanitize_thread)) +CF_PRIVATE CFIndex __CFActiveProcessorCount(void) { #if CF_HAVE_HW_CONFIG_COMMPAGE static const uintptr_t p = _COMM_PAGE_ACTIVE_CPUS; return (CFIndex)(*(uint8_t*)p); @@ -546,7 +642,11 @@ typedef struct _ugids { uid_t _euid; uid_t _egid; } ugids; - + +// work around 33477678 by making these file-level globals +static ugids __CFGetUGIDs_cachedUGIDs = { -1, -1 }; +static dispatch_once_t __CFGetUGIDs_onceToken; + CF_PRIVATE void __CFGetUGIDs(uid_t *euid, gid_t *egid) { ugids(^lookup)(void) = ^{ ugids ids; @@ -565,12 +665,10 @@ CF_PRIVATE void __CFGetUGIDs(uid_t *euid, gid_t *egid) { if (_CFCanChangeEUIDs()) { ids = lookup(); } else { - static ugids cachedUGIDs = { -1, -1 }; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - cachedUGIDs = lookup(); + dispatch_once(&__CFGetUGIDs_onceToken, ^{ + __CFGetUGIDs_cachedUGIDs = lookup(); }); - ids = cachedUGIDs; + ids = __CFGetUGIDs_cachedUGIDs; } if (euid) *euid = ids._euid; @@ -764,6 +862,9 @@ static bool also_do_stderr(const _cf_logging_style style) { if (!(S_IFIFO == m || S_IFCHR == m)) return false; // disallow any whacky stuff result = true; } +#else + // just log to stderr, other logging facilities are out + result = true; #endif return result; } @@ -781,7 +882,7 @@ static struct tm *localtime_r(time_t *tv, struct tm *result) { static void _populateBanner(char **banner, char **time, char **thread, int *bannerLen) { double dummy; CFAbsoluteTime at = CFAbsoluteTimeGetCurrent(); - time_t tv = floor(at + kCFAbsoluteTimeIntervalSince1970); + time_t tv = (time_t)floor(at + kCFAbsoluteTimeIntervalSince1970); struct tm mine; localtime_r(&tv, &mine); int32_t year = mine.tm_year + 1900; @@ -816,10 +917,10 @@ static void _logToStderr(char *banner, const char *message, size_t length) { v[2].iov_base = "\n"; v[2].iov_len = (message[length - 1] != '\n') ? 1 : 0; int nv = (v[0].iov_base ? 1 : 0) + 1 + (v[2].iov_len ? 1 : 0); - static CFLock_t lock = CFLockInit; - __CFLock(&lock); + static os_unfair_lock lock = OS_UNFAIR_LOCK_INIT; + os_unfair_lock_lock(&lock); writev(STDERR_FILENO, v[0].iov_base ? v : v + 1, nv); - __CFUnlock(&lock); + os_unfair_lock_unlock(&lock); #elif TARGET_OS_WIN32 size_t bannerLen = strlen(banner); size_t bufLen = bannerLen + length + 1; diff --git a/CoreFoundation/Base.subproj/CFUtilities.h b/CoreFoundation/Base.subproj/CFUtilities.h index dfc866b60a..b70f14bacc 100644 --- a/CoreFoundation/Base.subproj/CFUtilities.h +++ b/CoreFoundation/Base.subproj/CFUtilities.h @@ -1,7 +1,7 @@ /* CFUtilities.h - Copyright (c) 2005-2018, Apple Inc. and the Swift project authors + Copyright (c) 2005-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Base.subproj/CFWindowsUtilities.c b/CoreFoundation/Base.subproj/CFWindowsUtilities.c index 11608aedc2..ef4e25cca0 100644 --- a/CoreFoundation/Base.subproj/CFWindowsUtilities.c +++ b/CoreFoundation/Base.subproj/CFWindowsUtilities.c @@ -1,8 +1,8 @@ /* CFWindowsUtilities.c - Copyright (c) 2008-2018, Apple Inc. and the Swift project authors + Copyright (c) 2008-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -115,6 +115,5 @@ void _CFGetFrameworkPath(wchar_t *path, int maxLength) { } } - #endif diff --git a/CoreFoundation/Base.subproj/CoreFoundation.h b/CoreFoundation/Base.subproj/CoreFoundation.h index 9d34c4ab80..c1cee4581e 100644 --- a/CoreFoundation/Base.subproj/CoreFoundation.h +++ b/CoreFoundation/Base.subproj/CoreFoundation.h @@ -1,7 +1,7 @@ /* CoreFoundation.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -69,7 +69,7 @@ #include #include -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) || TARGET_OS_WIN32 +#if TARGET_OS_OSX || TARGET_OS_IPHONE || TARGET_OS_WIN32 #include #include #include @@ -82,15 +82,15 @@ #endif -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) +#if TARGET_OS_OSX || TARGET_OS_IPHONE #endif -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) #include + +#if !DEPLOYMENT_RUNTIME_SWIFT #include #include #endif - #endif /* ! __COREFOUNDATION_COREFOUNDATION__ */ diff --git a/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h b/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h index 190574b3fa..a124e27eda 100644 --- a/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h +++ b/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h @@ -1,7 +1,7 @@ /* CoreFoundation_Prefix.h - Copyright (c) 2005-2018, Apple Inc. and the Swift project authors + Copyright (c) 2005-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -10,6 +10,12 @@ #ifndef __COREFOUNDATION_PREFIX_H__ #define __COREFOUNDATION_PREFIX_H__ 1 +#if __has_include() +#include +#else +#include +#endif + #define _DARWIN_UNLIMITED_SELECT 1 #include @@ -27,7 +33,7 @@ extern "C" { #endif -#if DEPLOYMENT_TARGET_IPHONESIMULATOR // work around +#if TARGET_OS_IPHONE && TARGET_OS_SIMULATOR // work around #include #include #define qos_class_self() (QOS_CLASS_UTILITY) @@ -266,6 +272,13 @@ typedef unsigned long fd_mask; #undef interface #endif +#if TARGET_OS_CYGWIN +#define HAVE_STRUCT_TIMESPEC 1 +#define strncasecmp_l(a, b, c, d) strncasecmp(a, b, c) +#define _NO_BOOL_TYPEDEF +#undef interface +#endif + #include CF_INLINE size_t malloc_size(void *memblock) { return malloc_usable_size(memblock); diff --git a/CoreFoundation/Base.subproj/ForFoundationOnly.h b/CoreFoundation/Base.subproj/ForFoundationOnly.h index 0b7c7f8090..77b0cb126e 100644 --- a/CoreFoundation/Base.subproj/ForFoundationOnly.h +++ b/CoreFoundation/Base.subproj/ForFoundationOnly.h @@ -1,7 +1,7 @@ /* ForFoundationOnly.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -44,7 +45,7 @@ CF_IMPLICIT_BRIDGING_DISABLED // NOTE: miscellaneous declarations are at the end -// ---- CFRuntime material ---------------------------------------- +#pragma mark - CFRuntime #if TARGET_OS_LINUX #include @@ -68,7 +69,8 @@ CF_IMPLICIT_BRIDGING_DISABLED CF_EXPORT void *_Nonnull __CFSafelyReallocate(void * _Nullable destination, size_t newCapacity, void (^_Nullable reallocationFailureHandler)(void *_Nonnull original, bool *_Nonnull outRecovered)); CF_EXPORT void *_Nonnull __CFSafelyReallocateWithAllocator(CFAllocatorRef _Nullable, void * _Nullable destination, size_t newCapacity, CFOptionFlags options, void (^_Nullable reallocationFailureHandler)(void *_Nonnull original, bool *_Nonnull outRecovered)); -// ---- CFBundle material ---------------------------------------- + +#pragma mark - CFBundle #include @@ -83,15 +85,34 @@ CF_EXPORT const CFStringRef _kCFBundleAllowMixedLocalizationsKey; CF_EXPORT const CFStringRef _kCFBundlePrincipalClassKey; #if __BLOCKS__ -CF_EXPORT CFTypeRef _CFBundleCopyFindResources(CFBundleRef _Nullable bundle, CFURLRef _Nullable bundleURL, CFArrayRef _Nullable _unused_pass_null_, CFStringRef _Nullable resourceName, CFStringRef _Nullable resourceType, CFStringRef _Nullable subPath, CFStringRef _Nullable lproj, Boolean returnArray, Boolean localized, Boolean (^_Nullable predicate)(CFStringRef filename, Boolean *_Nullable stop)); +CF_EXPORT CFTypeRef _Nullable _CFBundleCopyFindResources(CFBundleRef _Nullable bundle, CFURLRef _Nullable bundleURL, CFArrayRef _Nullable _unused_pass_null_, CFStringRef _Nullable resourceName, CFStringRef _Nullable resourceType, CFStringRef _Nullable subPath, CFStringRef _Nullable lproj, Boolean returnArray, Boolean localized, Boolean (^_Nullable predicate)(CFStringRef filename, Boolean *_Nullable stop)); #endif -CF_EXPORT Boolean _CFBundleLoadExecutableAndReturnError(CFBundleRef bundle, Boolean forceGlobal, CFErrorRef *error); +CF_EXPORT Boolean _CFBundleLoadExecutableAndReturnError(CFBundleRef bundle, Boolean forceGlobal, CFErrorRef _Nullable *_Nullable error); CF_EXPORT CFErrorRef _CFBundleCreateError(CFAllocatorRef _Nullable allocator, CFBundleRef bundle, CFIndex code); _CF_EXPORT_SCOPE_END -// ---- CFPreferences material ---------------------------------------- +#pragma mark - CFUUID + +_CF_EXPORT_SCOPE_BEGIN + +/// Compares UUID bytes using a secure constant-time comparison rdar://47657832. +/// Ensure that `lhs` and `rhs` are 128-bytes (`CFUUIDBytes` or `uuid_t`) for the comparision to be valid. +CF_INLINE Boolean __CFisEqualUUIDBytes(const void * const lhs, const void * const rhs) { + uint64_t lhsBytes[2]; + memcpy(lhsBytes, lhs, sizeof(lhsBytes)); + + uint64_t rhsBytes[2]; + memcpy(rhsBytes, rhs, sizeof(rhsBytes)); + + uint64_t const equal = (lhsBytes[0] ^ rhsBytes[0]) | (lhsBytes[1] ^ rhsBytes[1]); + return equal == 0; +} + +_CF_EXPORT_SCOPE_END + +#pragma mark - CFPreferences #define DEBUG_PREFERENCES_MEMORY 0 @@ -121,44 +142,53 @@ typedef struct { CFStringRef _appName; } _CFApplicationPreferences; +CF_EXPORT Boolean _CFPreferencesGetBooleanValueWithValue(CFPropertyListRef _Nullable value, Boolean * _Nullable keyExistsAndHasValidFormat); + _CF_EXPORT_SCOPE_END -// ---- CFString material ---------------------------------------- +#pragma mark - CFString #include -#define NSSTRING_BOUNDSERROR \ - [NSException raise:NSRangeException format:@"%@: Range or index out of bounds", __CFExceptionProem((id)self, _cmd)] +#define NSSTRING_BOUNDSERROR do {\ + _CFThrowFormattedException((CFStringRef)NSInvalidArgumentException, CFSTR("%@: Range or index out of bounds"), __CFExceptionProem(self, _cmd));\ +} while (0) -#define NSSTRING_RANGEERROR(range, len) \ - [NSException raise:NSRangeException format:@"%@: Range {%lu, %lu} out of bounds; string length %lu%s", __CFExceptionProem((id)self, _cmd), (unsigned long)range.location, (unsigned long)range.length, (unsigned long)len, ((range.length == __kCFStringInlineBufferLength) ? " (Note that the indicated range may be smaller than the original range passed to the API)" : "")] +#define NSSTRING_RANGEERROR(range, len) do { \ + _CFThrowFormattedException((CFStringRef)NSInvalidArgumentException, CFSTR("%@: Range {%lu, %lu} out of bounds; string length %lu%s"), __CFExceptionProem((id)self, _cmd), (unsigned long)range.location, (unsigned long)range.length, (unsigned long)len, ((range.length == __kCFStringInlineBufferLength) ? " (Note that the indicated range may be smaller than the original range passed to the API)" : ""));\ +} while (0) -#define NSSTRING_INDEXERROR(index, len) \ - [NSException raise:NSRangeException format:@"%@: Index %lu out of bounds; string length %lu", __CFExceptionProem((id)self, _cmd), (unsigned long)index, (unsigned long)len] +#define NSSTRING_INDEXERROR(index, len) do { \ + _CFThrowFormattedException((CFStringRef)NSInvalidArgumentException, CFSTR("%@: Index %lu out of bounds; string length %lu"), __CFExceptionProem((id)self, _cmd), (unsigned long)index, (unsigned long)len);\ +} while(0) // This can be made into an exception for post-10.10 apps #define NSSTRING_POSSIBLE_RANGEERROR(range, len) \ - if (__CFStringNoteErrors()) { \ + do { \ static bool warnonce = false; \ if (!warnonce) { \ warnonce = true; \ CFLog(kCFLogLevelWarning, CFSTR("*** %@: Range {%lu, %lu} out of bounds; string length %lu. This will become an exception for apps linked after 10.10 and iOS 8. Warning shown once per app execution."), __CFExceptionProem((id)self, _cmd), (unsigned long)range.location, (unsigned long)range.length, (unsigned long)len); \ } \ -} +} while(0) -#define NSSTRING_ILLEGALREQUESTERROR \ - [NSException raise:NSInvalidArgumentException format:@"Can't call %s in %@", sel_getName(_cmd), object_getClass((id)self)] +#define NSSTRING_ILLEGALREQUESTERROR do {\ + _CFThrowFormattedException((CFStringRef)NSInvalidArgumentException, CFSTR("Can't call %s in %@"), sel_getName(_cmd), object_getClass((id)self));\ +} while(0) -#define NSSTRING_INVALIDMUTATIONERROR \ - [NSException raise:NSInvalidArgumentException format:@"Attempt to mutate immutable object with %s", sel_getName(_cmd)] +#define NSSTRING_INVALIDMUTATIONERROR do {\ + _CFThrowFormattedException((CFStringRef)NSInvalidArgumentException, CFSTR("Attempt to mutate immutable object with %s"), sel_getName(_cmd));\ +} while(0) -#define NSSTRING_NULLCSTRINGERROR \ - [NSException raise:NSInvalidArgumentException format:@"%@: NULL cString", __CFExceptionProem((id)self, _cmd)] +#define NSSTRING_NULLCSTRINGERROR do {\ + _CFThrowFormattedException((CFStringRef)NSInvalidArgumentException, CFSTR("%@: NULL cString"), __CFExceptionProem((id)self, _cmd));\ +} while(0) -#define NSSTRING_NILSTRINGERROR \ - [NSException raise:NSInvalidArgumentException format:@"%@: nil argument", __CFExceptionProem((id)self, _cmd)] +#define NSSTRING_NILSTRINGERROR do {\ + _CFThrowFormattedException((CFStringRef)NSInvalidArgumentException, CFSTR("%@: nil argument"), __CFExceptionProem(self, _cmd));\ +} while(0) _CF_EXPORT_SCOPE_BEGIN @@ -235,14 +265,14 @@ enum { typedef struct { /* A simple struct to maintain ASCII/Unicode versions of the same buffer. */ union { - UInt8 *ascii; - UniChar *unicode; + UInt8 * _Nullable ascii; + UniChar * _Nullable unicode; } chars; Boolean isASCII; /* This really does mean 7-bit ASCII, not _NSDefaultCStringEncoding() */ Boolean shouldFreeChars; /* If the number of bytes exceeds __kCFVarWidthLocalBufferSize, bytes are allocated */ Boolean _unused1; Boolean _unused2; - CFAllocatorRef allocator; /* Use this allocator to allocate, reallocate, and deallocate the bytes */ + CFAllocatorRef _Nullable allocator; /* Use this allocator to allocate, reallocate, and deallocate the bytes */ CFIndex numChars; /* This is in terms of ascii or unicode; that is, if isASCII, it is number of 7-bit chars; otherwise it is number of UniChars; note that the actual allocated space might be larger */ UInt8 localBuffer[__kCFVarWidthLocalBufferSize]; /* private; 168 ISO2022JP chars, 504 Unicode chars, 1008 ASCII chars */ } CFVarWidthCharBuffer; @@ -295,6 +325,14 @@ CF_INLINE UniChar __CFStringGetCharacterFromInlineBufferQuick(CFStringInlineBuff return buf->buffer[idx - buf->bufferedRangeStart]; } +/* + This behaves exactly like CFStringGetCStringPtr except in three ways: + 1) It allows specifying that the resulting C string is not required to be terminated + 2) It's faster + 3) It *only* works on real CFStrings (e.g. _NSCFString, _NSCFConstantString), not NSString subclasses or tagged pointer strings + Generally this means it can only be safely used if preceded by a CF_IS_OBJC check (which CFStringGetCStringPtr normally does itself) or from inside _NSCF{Constant}String + */ +const char * _CFNonObjCStringGetCStringPtr(CFStringRef str, CFStringEncoding encoding, Boolean requiresNullTermination); /* These two allow specifying an alternate description function (instead of CFCopyDescription); used by NSString */ @@ -303,13 +341,13 @@ CF_EXPORT CFStringRef _CFStringCreateWithFormatAndArgumentsAux(CFAllocatorRef _ CF_EXPORT void _CFStringAppendFormatAndArgumentsAux2(CFMutableStringRef outputString, CFStringRef _Nonnull (*_Nullable copyDescFunc)(void *, const void *loc), CFStringRef _Nonnull (*_Nullable contextDescFunc)(void *, const void *, const void *, bool, bool *), CFDictionaryRef _Nullable formatOptions, CFStringRef formatString, va_list args); CF_EXPORT CFStringRef _Nullable _CFStringCreateWithFormatAndArgumentsAux2(CFAllocatorRef _Nullable alloc, CFStringRef _Nonnull (*_Nullable copyDescFunc)(void *, const void *loc), CFStringRef _Nonnull (*_Nullable contextDescFunc)(void *, const void *, const void *, bool, bool *), CFDictionaryRef _Nullable formatOptions, CFStringRef format, va_list arguments); -CF_EXPORT CFStringRef _Nullable CFStringCreateStringWithValidatedFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef validFormatSpecifiers, CFStringRef format, va_list arguments, CFErrorRef *errorPtr) API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)); +CF_EXPORT CFStringRef _Nullable CFStringCreateStringWithValidatedFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef validFormatSpecifiers, CFStringRef format, va_list arguments, CFErrorRef _Nullable *_Nullable errorPtr) API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)); /* For NSString (and NSAttributedString) usage, mutate with isMutable check */ enum {_CFStringErrNone = 0, _CFStringErrNotMutable = 1, _CFStringErrNilArg = 2, _CFStringErrBounds = 3}; CF_EXPORT int __CFStringCheckAndReplace(CFMutableStringRef str, CFRange range, CFStringRef replacement); -CF_EXPORT Boolean __CFStringNoteErrors(void); // Should string errors raise? +CF_EXPORT Boolean __CFStringNoteErrors(void); // Always returns `true`. /* For NSString usage, guarantees that the contents can be extracted as 8-bit bytes in the __CFStringGetEightBitStringEncoding(). */ @@ -331,7 +369,8 @@ CF_EXPORT CFHashCode CFHashBytes(uint8_t *_Nullable bytes, CFIndex length); _CF_EXPORT_SCOPE_END -// ---- Binary plist material ---------------------------------------- +#pragma mark - Binary plist + _CF_EXPORT_SCOPE_BEGIN typedef const struct CF_BRIDGED_TYPE(_NSKeyedArchiverUID) __CFKeyedArchiverUID * CFKeyedArchiverUIDRef; CF_EXPORT CFTypeID _CFKeyedArchiverUIDGetTypeID(void); @@ -373,21 +412,21 @@ typedef struct { CF_EXPORT bool __CFBinaryPlistGetTopLevelInfo(const uint8_t *databytes, uint64_t datalen, uint8_t *marker, uint64_t *offset, CFBinaryPlistTrailer *trailer); -CF_EXPORT bool __CFBinaryPlistGetOffsetForValueFromArray2(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFIndex idx, uint64_t *offset, CFMutableDictionaryRef objects); -CF_EXPORT bool __CFBinaryPlistGetOffsetForValueFromDictionary3(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFTypeRef key, uint64_t *_Nullable koffset, uint64_t *_Nullable voffset, Boolean unused, CFMutableDictionaryRef objects); +CF_EXPORT bool __CFBinaryPlistGetOffsetForValueFromArray2(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFIndex idx, uint64_t *offset, CFMutableDictionaryRef _Nullable unused); +CF_EXPORT bool __CFBinaryPlistGetOffsetForValueFromDictionary3(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFTypeRef key, uint64_t *_Nullable koffset, uint64_t *_Nullable voffset, Boolean unused, CFMutableDictionaryRef _Nullable unused2); CF_EXPORT bool __CFBinaryPlistCreateObject(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef _Nullable allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFPropertyListRef _Nullable * _Nonnull plist); CF_EXPORT CFIndex __CFBinaryPlistWriteToStream(CFPropertyListRef plist, CFTypeRef stream); CF_EXPORT CFIndex __CFBinaryPlistWriteToStreamWithEstimate(CFPropertyListRef plist, CFTypeRef stream, uint64_t estimate); // will be removed soon CF_EXPORT CFIndex __CFBinaryPlistWriteToStreamWithOptions(CFPropertyListRef plist, CFTypeRef stream, uint64_t estimate, CFOptionFlags options); // will be removed soon -CF_EXPORT CFIndex __CFBinaryPlistWrite(CFPropertyListRef plist, CFTypeRef stream, uint64_t estimate, CFOptionFlags options, CFErrorRef *error); +CF_EXPORT CFIndex __CFBinaryPlistWrite(CFPropertyListRef plist, CFTypeRef stream, uint64_t estimate, CFOptionFlags options, CFErrorRef _Nullable *_Nullable error); -// ---- Used by property list parsing in Foundation +#pragma mark - Property list parsing in Foundation -CF_EXPORT CFTypeRef _CFPropertyListCreateFromXMLData(CFAllocatorRef _Nullable allocator, CFDataRef xmlData, CFOptionFlags option, CFStringRef _Nullable * _Nullable errorString, Boolean allowNewTypes, CFPropertyListFormat *_Nullable format); +CF_EXPORT CFTypeRef _Nullable _CFPropertyListCreateFromXMLData(CFAllocatorRef _Nullable allocator, CFDataRef xmlData, CFOptionFlags option, CFStringRef _Nullable * _Nullable errorString, Boolean allowNewTypes, CFPropertyListFormat *_Nullable format); CF_EXPORT CFTypeRef _CFPropertyListCreateFromXMLString(CFAllocatorRef _Nullable allocator, CFStringRef xmlString, CFOptionFlags option, CFStringRef _Nullable * _Nullable errorString, Boolean allowNewTypes, CFPropertyListFormat *_Nullable format); -// ---- Sudden Termination material ---------------------------------------- +#pragma mark - Sudden Termination CF_EXPORT void _CFSuddenTerminationDisable(void); CF_EXPORT void _CFSuddenTerminationEnable(void); @@ -396,16 +435,16 @@ CF_EXPORT void _CFSuddenTerminationExitIfTerminationEnabled(int exitStatus); CF_EXPORT void _CFSuddenTerminationExitWhenTerminationEnabled(int exitStatus); CF_EXPORT size_t _CFSuddenTerminationDisablingCount(void); -// ---- Thread-specific data -------------------------------------------- +#pragma mark - Thread-specific data // Get some thread specific data from a pre-assigned slot. -CF_EXPORT void *_Nullable _CFGetTSDCreateIfNeeded(uint32_t slot, Boolean create); +CF_EXPORT void *_Nullable _CFGetTSDCreateIfNeeded(uint32_t slot, Boolean create) CF_RETURNS_NOT_RETAINED; CF_EXPORT void *_Nullable _CFGetTSD(uint32_t slot); // Set some thread specific data in a pre-assigned slot. Don't pick a random value. Make sure you're using a slot that is unique. Pass in a destructor to free this data, or NULL if none is needed. Unlike pthread TSD, the destructor is per-thread. CF_EXPORT void *_Nullable _CFSetTSD(uint32_t slot, void * _Nullable newVal, void (*_Nullable destructor)(void * _Nullable)); -// ---- CFError userInfoProvider --------------------------------------------- +#pragma mark - CFError userInfoProvider /* This callback block is consulted if a key is not present in the userInfo dictionary. Note that setting a callback for the same domain again simply replaces the previous callback. The block should return autoreleased results. Note that this functionality is now available as API on NSError; that should be used instead. */ @@ -458,9 +497,6 @@ CF_EXPORT void _CFBagSetCapacity(CFMutableBagRef bag, CFIndex cap); CF_EXPORT void _CFDictionarySetCapacity(CFMutableDictionaryRef dict, CFIndex cap); CF_EXPORT void _CFSetSetCapacity(CFMutableSetRef set, CFIndex cap); -CF_EXPORT void CFCharacterSetCompact(CFMutableCharacterSetRef theSet); -CF_EXPORT void CFCharacterSetFast(CFMutableCharacterSetRef theSet); - CF_EXPORT const void *_CFArrayCheckAndGetValueAtIndex(CFArrayRef array, CFIndex idx, Boolean *outOfBounds); CF_EXPORT void _CFArrayReplaceValues(CFMutableArrayRef array, CFRange range, const void *_Nullable * _Nullable newValues, CFIndex newCount); @@ -495,7 +531,7 @@ CF_INLINE CFHashCode _CFHashInt(long i) { CF_INLINE CFHashCode _CFHashDouble(const double d) { const double positive = (d < 0) ? -d : d; const double positiveInt = floor(positive + 0.5); - const double fractional = (positive - positiveInt) * ULONG_MAX; + const double fractional = (positive - positiveInt) * (double)ULONG_MAX; CFHashCode result = HASHFACTOR * (CFHashCode)fmod(positiveInt, (double)ULONG_MAX); if (fractional < 0) { // UBSan: Certain negative floating-point numbers are unrepresentable as 'unsigned long' which enters into undefined behavior territory in C. Thus we ensure it is positive, cast and then subtract as an integer where numbers behave correctly. @@ -522,6 +558,8 @@ CF_CROSS_PLATFORM_EXPORT void _CFNumberInitUInt64(CFNumberRef result, uint64_t v CF_CROSS_PLATFORM_EXPORT void _CFNumberInitFloat(CFNumberRef result, float value); CF_CROSS_PLATFORM_EXPORT void _CFNumberInitDouble(CFNumberRef result, double value); +CF_EXPORT CFNumberType _CFNumberGetType2(CFNumberRef number); + /* These four functions are used by NSError in formatting error descriptions. They take NS or CFError as arguments and return a retained CFString or NULL. */ CF_EXPORT CFStringRef _CFErrorCreateLocalizedDescription(CFErrorRef err); @@ -543,6 +581,10 @@ CF_EXPORT CFTypeRef _CFRunLoopGet2(CFRunLoopRef rl); CF_EXPORT Boolean _CFRunLoopIsCurrent(CFRunLoopRef rl); CF_EXPORT CFIndex _CFStreamInstanceSize(void); +CF_EXPORT void _CFReadStreamInitialize(CFReadStreamRef readStream); +CF_EXPORT void _CFWriteStreamInitialize(CFWriteStreamRef writeStream); +CF_EXPORT void _CFReadStreamDeallocate(CFReadStreamRef readStream); +CF_EXPORT void _CFWriteStreamDeallocate(CFWriteStreamRef writeStream); CF_EXPORT CFReadStreamRef CFReadStreamCreateWithData(_Nullable CFAllocatorRef alloc, CFDataRef data); #if TARGET_OS_MAC @@ -606,14 +648,27 @@ CF_EXPORT CFTimeInterval CFGetSystemUptime(void); CF_EXPORT CFStringRef CFCopySystemVersionString(void); CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void); +typedef struct { + CFIndex majorVersion; + CFIndex minorVersion; + CFIndex patchVersion; +} CFOperatingSystemVersion; + +CF_EXPORT CFOperatingSystemVersion _CFOperatingSystemVersionGetCurrent(void); + +CF_EXPORT Boolean _CFOperatingSystemVersionIsAtLeastVersion(CFOperatingSystemVersion version); + CF_CROSS_PLATFORM_EXPORT Boolean _CFCalendarInitWithIdentifier(CFCalendarRef calendar, CFStringRef identifier); -CF_CROSS_PLATFORM_EXPORT Boolean _CFCalendarComposeAbsoluteTimeV(CFCalendarRef calendar, /* out */ CFAbsoluteTime *atp, const char *componentDesc, int32_t *vector, int32_t count); -CF_CROSS_PLATFORM_EXPORT Boolean _CFCalendarDecomposeAbsoluteTimeV(CFCalendarRef calendar, CFAbsoluteTime at, const char *componentDesc, int32_t *_Nonnull * _Nonnull vector, int32_t count); -CF_CROSS_PLATFORM_EXPORT Boolean _CFCalendarAddComponentsV(CFCalendarRef calendar, /* inout */ CFAbsoluteTime *atp, CFOptionFlags options, const char *componentDesc, int32_t *vector, int32_t count); -CF_CROSS_PLATFORM_EXPORT Boolean _CFCalendarGetComponentDifferenceV(CFCalendarRef calendar, CFAbsoluteTime startingAT, CFAbsoluteTime resultAT, CFOptionFlags options, const char *componentDesc, int32_t *_Nonnull * _Nonnull vector, int32_t count); +CF_EXPORT Boolean _CFCalendarComposeAbsoluteTimeV(CFCalendarRef calendar, /* out */ CFAbsoluteTime *atp, const char *componentDesc, int32_t *vector, int32_t count); +CF_EXPORT Boolean _CFCalendarDecomposeAbsoluteTimeV(CFCalendarRef calendar, CFAbsoluteTime at, const char *componentDesc, int32_t *_Nonnull * _Nonnull vector, int32_t count); +CF_EXPORT Boolean _CFCalendarAddComponentsV(CFCalendarRef calendar, /* inout */ CFAbsoluteTime *atp, CFOptionFlags options, const char *componentDesc, int32_t *vector, int32_t count); +CF_EXPORT Boolean _CFCalendarGetComponentDifferenceV(CFCalendarRef calendar, CFAbsoluteTime startingAT, CFAbsoluteTime resultAT, CFOptionFlags options, const char *componentDesc, int32_t *_Nonnull * _Nonnull vector, int32_t count); CF_CROSS_PLATFORM_EXPORT Boolean _CFLocaleInit(CFLocaleRef locale, CFStringRef identifier); +/// Returns a result similar to `CFLocaleCopyPreferredLanguages` but by specifically reading the preferences for `kCFPreferencesCurrentUser` as opposed to walking up the preferences chain. This is needed by specific callers (e.g. `+[NSLocale setPreferredLanguages:]`) to check whether the defaults being set have changed from what’s already set. +CF_EXPORT CFArrayRef _CFLocaleCopyPreferredLanguagesForCurrentUser(void); + CF_CROSS_PLATFORM_EXPORT Boolean _CFTimeZoneInit(CFTimeZoneRef timeZone, CFStringRef name, _Nullable CFDataRef data); CF_CROSS_PLATFORM_EXPORT Boolean _CFCharacterSetInitWithCharactersInRange(CFMutableCharacterSetRef cset, CFRange theRange); @@ -621,35 +676,31 @@ CF_CROSS_PLATFORM_EXPORT Boolean _CFCharacterSetInitWithCharactersInString(CFMut CF_CROSS_PLATFORM_EXPORT Boolean _CFCharacterSetInitMutable(CFMutableCharacterSetRef cset); CF_CROSS_PLATFORM_EXPORT Boolean _CFCharacterSetInitWithBitmapRepresentation(CFMutableCharacterSetRef cset, CFDataRef theData); -// The following functions can be used when you know for certain that the types involved are not objc types. For Foundation Only! -CF_EXPORT Boolean _CFNonObjCEqual(CFTypeRef cf1, CFTypeRef cf2); -CF_EXPORT CFTypeRef _CFNonObjCRetain(CFTypeRef cf); -CF_EXPORT void _CFNonObjCRelease(CFTypeRef cf); -CF_EXPORT CFHashCode _CFNonObjCHash(CFTypeRef cf); - -CF_EXPORT void *__CFTSANTagMutableArray; -CF_EXPORT void *__CFTSANTagMutableDictionary; -CF_EXPORT void *__CFTSANTagMutableSet; -CF_EXPORT void *__CFTSANTagMutableOrderedSet; +CF_EXPORT void * _Nullable __CFTSANTagMutableArray; +CF_EXPORT void * _Nullable __CFTSANTagMutableDictionary; +CF_EXPORT void * _Nullable __CFTSANTagMutableSet; +CF_EXPORT void * _Nullable __CFTSANTagMutableOrderedSet; +CF_EXPORT void * _Nullable __CFTSANTagMutableData; -CF_EXPORT void *_CFRegisterThreadSanitizerTag(char *name); +CF_EXPORT void * _Nullable _CFRegisterThreadSanitizerTag(char *name); CF_EXPORT void _CFAssignThreadSanitizerTag(void *const _Nonnull ptr, void *const tag); -CF_EXPORT void (*__cf_tsanReadFunction)(void *, void *, void *); +CF_EXPORT void (* _Nullable __cf_tsanReadFunction)(void *, void *, void *); #define _CFRecordReadForDataOwnedBy(P, T) do {\ - if (__builtin_expect(__cf_tsanReadFunction != NULL, false) && (P) && (T)) {\ + if (__builtin_expect(__cf_tsanReadFunction != NULL, false)) {\ __cf_tsanReadFunction((P), __builtin_return_address(0), (T));\ }\ } while(0) -CF_EXPORT void (*__cf_tsanWriteFunction)(void *, void *, void *); +CF_EXPORT void (* _Nullable __cf_tsanWriteFunction)(void *, void *, void *); #define _CFRecordWriteForDataOwnedBy(P, T) do {\ - if (__builtin_expect(__cf_tsanWriteFunction != NULL, false) && (P) && (T)) {\ + if (__builtin_expect(__cf_tsanWriteFunction != NULL, false)) {\ __cf_tsanWriteFunction((P), __builtin_return_address(0), (T));\ }\ } while (0) -CF_EXPORT void *_CFCreateArrayStorage(size_t numPointers, Boolean zeroed, size_t *actualNumPointers); +CF_EXPORT void *_CFCreateArrayStorage(size_t numPointers, Boolean zeroed, size_t *actualNumPointers) CF_RETURNS_NOT_RETAINED; + #if DEPLOYMENT_RUNTIME_SWIFT diff --git a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h index 908aa1a05e..3bffd193d5 100644 --- a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h +++ b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h @@ -84,6 +84,9 @@ _CF_EXPORT_SCOPE_BEGIN +CF_PRIVATE Boolean __CFAllocatorRespectsHintZeroWhenAllocating(CFAllocatorRef _Nullable allocator); +static CFOptionFlags _CFAllocatorHintZeroWhenAllocating = 1; + CF_CROSS_PLATFORM_EXPORT Boolean _CFCalendarGetNextWeekend(CFCalendarRef calendar, _CFCalendarWeekendRange *range); CF_CROSS_PLATFORM_EXPORT void _CFCalendarEnumerateDates(CFCalendarRef calendar, CFDateRef start, CFDateComponentsRef matchingComponents, CFOptionFlags opts, void (^block)(CFDateRef, Boolean, Boolean*)); CF_EXPORT void CFCalendarSetGregorianStartDate(CFCalendarRef calendar, CFDateRef _Nullable date); @@ -134,6 +137,7 @@ struct _NSDictionaryBridge { CFIndex (*countForObject)(CFTypeRef dictionary, CFTypeRef value); void (*getObjects)(CFTypeRef dictionary, CFTypeRef _Nullable *_Nullable valuebuf, CFTypeRef _Nullable *_Nullable keybuf); void (*__apply)(CFTypeRef dictionary, void (*applier)(CFTypeRef key, CFTypeRef value, void *context), void *context); + void (*enumerateKeysAndObjectsWithOptions)(CFTypeRef dictionary, CFIndex options, void (^block)(const void *key, const void *value, Boolean *stop)); _Nonnull CFTypeRef (*_Nonnull copy)(CFTypeRef obj); }; diff --git a/CoreFoundation/CMakeLists.txt b/CoreFoundation/CMakeLists.txt index a6bc8424f6..55dc84fb1d 100644 --- a/CoreFoundation/CMakeLists.txt +++ b/CoreFoundation/CMakeLists.txt @@ -146,9 +146,9 @@ add_framework(CoreFoundation Locale.subproj/CFLocale_Private.h # NumberDate NumberDate.subproj/CFBigNumber.h + NumberDate.subproj/CFNumber_Private.h # Parsing Parsing.subproj/CFPropertyList_Private.h - Parsing.subproj/CFXMLInputStream.h # PlugIn PlugIn.subproj/CFBundlePriv.h PlugIn.subproj/CFBundle_BinaryTypes.h @@ -241,8 +241,6 @@ add_framework(CoreFoundation NumberDate.subproj/CFTimeZone.h # Parsing Parsing.subproj/CFPropertyList.h - Parsing.subproj/CFXMLNode.h - Parsing.subproj/CFXMLParser.h # PlugIn PlugIn.subproj/CFBundle.h PlugIn.subproj/CFPlugIn.h @@ -310,10 +308,6 @@ add_framework(CoreFoundation Parsing.subproj/CFBinaryPList.c Parsing.subproj/CFOldStylePList.c Parsing.subproj/CFPropertyList.c - Parsing.subproj/CFXMLInputStream.c - Parsing.subproj/CFXMLNode.c - Parsing.subproj/CFXMLParser.c - Parsing.subproj/CFXMLTree.c # PlugIn PlugIn.subproj/CFBundle_Binary.c PlugIn.subproj/CFBundle.c @@ -325,12 +319,10 @@ add_framework(CoreFoundation PlugIn.subproj/CFBundle_Main.c PlugIn.subproj/CFBundle_ResourceFork.c PlugIn.subproj/CFBundle_Resources.c + PlugIn.subproj/CFBundle_SplitFileName.c PlugIn.subproj/CFBundle_Strings.c PlugIn.subproj/CFBundle_Tables.c PlugIn.subproj/CFPlugIn.c - PlugIn.subproj/CFPlugIn_Factory.c - PlugIn.subproj/CFPlugIn_Instance.c - PlugIn.subproj/CFPlugIn_PlugIn.c # Preferences Preferences.subproj/CFApplicationPreferences.c Preferences.subproj/CFPreferences.c diff --git a/CoreFoundation/CharacterSets/CFCharacterSetBitmaps.bitmap b/CoreFoundation/CharacterSets/CFCharacterSetBitmaps.bitmap index 13f56b787d027a69cab60527ed6cbc8f9a2a2266..fcb505139bc0affd72376108efaa9bd2d97e7b17 100644 GIT binary patch delta 3808 zcmcJSdvKK16~OnL@3EWLZUQ7EA!Ik3i@O-C%nc^7$1&}HQJQiNUL`P7(YW_Brs}uk{HOB zgQ77%jdp6NMs^pE0NG{4Gj$`B`K@qlMPkMdG@^lReYkv}Q@;1@wuyIx@q93t=aU`W zZ<9SPZnv2a=dGgWrtz1c4`vy+f&t*hgC#Q^C;!FyFU0IfxMU>7&OIL-C#Hk%mY z+-{r?xQ%ZFvy6BkEwZ_+6oE%t%TJ}zk~U1CKMuxKVkFggq@q?8(^ne5tQZVej58H8 z#Js_kAEtocfa-Zh$@#2sY`89_xI;Dy;~tB3VjCN4UNb!nEJIAQ+Kq*a@~ABYb|d?{X>=s0I*gMw*&cpJuIG0Kh`HvM*do;R z#d)FOtbNSBuR{#g-=QALuJ=%6zmC8u9QVtI)3u62X(R+D9!RK+u^p=n>!lm&o{C43)BEceiM2pKn0g@u-NlqYdN%sqfbVP z53J~uvZiT=!_rZu;5B?kv2$A_-t>4A zO=VMypg zYv4tUbJ|r0L0DU#MC0r9b&imU66b7Z9emA6@m0E$mVQqe zme~JoCVH-7q@~H>3CB{|=_Y8bx(kF90=zec^jAP1%qD$5=934}3!F+3yJ=*vAxa$S zxPtfM(b!z}0E?;EUqH#O=y(?@$I&a9SY)C}zs*F!CSAxx0Vf-sg&(G<{ss<|=EX|Q z^mqfZhR{YYnm(&(COcGAi2b0R_IvSeuu_K?yJ_VIXl5Z!cL7%{rxaq_xk~_>YhG;^ zu*r1!B4&LRVkgj}KJ+>g*aDrO0z(D2c_MzeDcXX|Mf_2Xk&DbYAfOwB#im;))4E~k zr2HTx-8Y<%B30BtItB9;i)tpQZnTip1kt=S935raN&i%FemGVx8`*Sr3TA*ys$NUW zf}r)|{L_5ve8k%d;le?iuwOW)k)XbcU7U(zN@-G+o-Xkl10lM8K^sj2-hvdiVGXJP z0cNbl+ekky*C(<+ynnut#easqg9kAzhM4 zmpXg=CLYFgQMvTcx!%?doJ^zNWLs}zA`zN-^m+%HdDIST!_lT*$cZ5fIa$`oL$RJt zf+}=N((;YnbzZqdqoZ4t0Z#7z;{0WRxw%F8x$d`#UOVmBs^qHT@?7-ZR;6&vr#&X} zm(0?m{gCLhXy`F0Z1KD7c6#=6tuP$>k;v!hVTU~m5770!=x6q7Wh2nX&Dy90uLC9W zea$kEIck+jNS}vb5G`7)9H76yi^(G5^=F+Sn50O>9qiSomEv4zqqvF-#2q=4SkVS$ zzf)p9K@vRyFdb-kl|GFQ|4Qk$)|1qw<^RLbCU&k#nXU_E3#78Moiy()Wq>p-g9$Z8 z4}&~*>zs1D1U{k<3e?<0Rdom{_ByKUm``mQsJgiAjtDe9`e})pr}%B1qLH~>h#O#C z^W|@=8KP*r=QYbR>bU8xiBe~Mt$Ke;9TqPHmrH7-nt@+j!g`c7)B~iyu4cn}<~gq( z?p?acDzQm(DPCKEt-hoNGVHJI*ny&$3rC-oexR}`H`FJyEupe%vo>L$4b-lfvdiwb z*z}>$L0Y-?h)g>{wy9j3|3qZr!6hoCHw)Sa`*5Jt;gfW_)+|u{&K_;?usom5)*_;u ziIuYpFYEUvT|2MIYA>@yA3_ga&~hMy=3LM!(H)?7O7wD>&1O)bRNu&sT+{~j$qC7Y zEkal*Q9fAZ-FxF$$_;JFe^r7ftM&fMV4H{H)w)|$fax{*NO9UW5ie?VkJz|M(O<+6 zr(@+X&Jj8`-#C?*IS* delta 3058 zcmb`Jdu$Zf6^G}Zd92s=K8&%mey`Vtn1YRgq+m9%4_k)BNlaAiJfPJ0L4*|SROuV& zu2Utnq(DX^`4Fh^h6JLbgpzLIR(-@?(^_#G%9IvRK*cXeA~iKjgD5W8(|cz(h7gN? z=t!RR+`0G6Ip==ockbC(?%7zbxS+D~U2&~P)i-EEVs3QMvy(*q*}JXU5mLzh9-!{^ zu*QZ*WRRlAymLuZ_X6QBqLGb4Spp-bZ@qnLP)|LkAQ@UowCl7yWc%y1?F(HCBQ2kGAuh~7rbj+yd?wMCnzIL^_oP37!N1<3`{%W-?b+*r);L}F6^=*|2 z17})XnjXotg~G}8Ck;c??5$5>n+$cTZbknw@nRd0)WkAG(dKm?yyFV0c*TE12mEj}R{ zkNn$;m45lhcz#GqrMt^?An7OMXWF|Yha0fatu>@6g9!9O19>T3)z@NAGbv-c$FCG2!PRwx0;66q< z{X~H~F<*o)XTbuAvyQ*b0tP#dWC5d{&d-K(X_8}`A)w6zjcRNj?()D)Rd@4brr@7F zFdg|g;elJ|8zR=1K%GM{L^I2r+fl>8=&#^bQt{F#WKWC#SMjk@@Mu!@LRI&eC7_kJ z+3-X_Vj#}~@BgV7oOnfonWit4RYcdVYQXc$AcJYb@G{bctPGmy=yIs6)}HToa#))% z?;uH|J6{BeU?nID-TfoD2Kbo-i|HR@r30BlFHAk)_RI7X6?$>@UE#Vo;cGF}22L zgxGKWovJwO&%$dla5#Nq+r|xJV$&)>fxJ)O$sGbb2Ec*LD0IRK0V}jLB9Q_IuVsk%~v)!^_S3fk65PsSZ zRTvLQ1<_TFOGUcnPp~5OHnqhkPeVd(vF9{H(1#zLHW6HOW(vWKkuM==b^C6z(76UC zE|I5+7-HgS&~RXU1ePacxWqn}1DKp?7}^!l)wPAlxRputop@r*3t!|jD?PcCiSwXE zbF?nP`ioFHJ)WyC!8mJu&-N>rIR;zqO|_A!wnCq|4g*ZOO(9HWN^^@^uH%o>?i;Z3 z%jjO2fL2vs$muP_1Cy}A8cHU>f!FtmZz~L`B7@+eZZTIX;sW=6w^)+nFeioBE7oq! zoSC)DdTDrLKkEhHrUP!#@MBez;-i*kaTn9*3Ve0H=v4IrUL2Wbm!~PM;u4TJ8o0ih z6l2>4@wiq~o55PFlTL=o648_rZF{?u7eZeue^l^+z2Zvx^KXlJrr2+?(gi!kK06cB zqXY+ziXJ{o#*_O*_r1q+j$Vj}b&5$Rb4%iGea((f9~AR=AQ_Z>aQ+;UPRB2Zr-I}r zeo!ps(w-aQ$AJ3lAkn{;N|6F>)rvBFEhyzP6Rx+Ii9GJ33om_LV*Lh_`@oy&DVcY{ z9j(&6cfnto>5{nOtYOL70lcBkL*;eJMSeov!_q*qTl4-OksYE(5NPK`$)6!_KXeEp zYU~BRXA)g@P5Oq5_vxn`^lE|piD{_jo@_YFh=Fpg{D`Ut=&QBznzh=ECI|n5Q3{mmoPG*!tk$SPdkqLkd8!|?+)>^vwI;7?nW`e~zjg$0DW55re@FyCWGH&9kGlAZtx Xo0b1^J-PiLgX|z9)AM2FX3_ruCl}C& diff --git a/CoreFoundation/CharacterSets/CFUniCharPropertyDatabase.data b/CoreFoundation/CharacterSets/CFUniCharPropertyDatabase.data index 17fa59f7044a0fbfac71b1e02ff849e39e5d0e66..561761d01b17bb3b9365a916486b31cc983a2567 100644 GIT binary patch delta 1041 zcmYjQ-)|IE6rMBPnc3Ohmf7w?yHMy4wo(^by4@COySrW51xjgjTcC}gW|o!I2n{Wv zN`J_YXrxNC3}2P@i7IH~i)p=@7zk#oF;QOBS6qpSrcu%d^$$?b42quQ=A84*cfWh? zId^V+D&M#(2ck{UMoE$kNlLjSY1oi!HZ2AIRB*RAgot{Z3gQf7^)t8}lR$nkwR?edTS!n$RC#l#dve5vs`Y0CY zlnzp@VdYST~xKn?YEK{)|F%oSe1`qPG)%$t9 zFFG2E2>VM8aiB9ZgUfS@&|~cim#B&Tu^|Q@x2v?wUh(tJCZd=qYxB5~dm)6j&f8ei zsejZ}L!=@kGgdm z5!G|pOAVlSFtWWdO4Jl1YUU3_Eju1_{LWUQw)QwBk{vwY)UM91w5U9#s5m_w_Ni?0 zKZf};mtc;)hgZ%luy16-I-E>-@%^r5&L>59{Ab3zND>*`JQ5~sS}k)Z;9oLIgL+l zd`QeEKlztbM5Lo{>`VMQ^D4<0x%@GoHHz7jY5Zu}#g}uOcn~Mw6k%(-%$n_3$h9zW z*_q|^>?mPo&I{MuAq*eZz;DkoTmL_Q%iPVWhG5n}e$H^V)m_yIH=jJlZ$-h<;5Ijr l^Seo$RN>}RVSY5n9*W$L8=5^lreO6@IWEo)Uk}e0{SENvU`qf1 delta 783 zcmYjOO-vI}5Z>ADwxyQZvLF=DE>NHd!j>PAABzexAceFLm7fq+A^do;pavrmD4>aw z7`H>b7@!IP!@b>P#3y2raUHjhi|ng02Q<~k0_HIRIJRMJNpet{Xf&DQ zEc>h+7th)DYe7G6cWA)?Bxu1zr<6#H|0n4$Jdn&{WfI_K{18TASl61G9q|e5UiK;# z$;29^f~1nY%bVnJ!<0`k94q)v>|Sj0{v?^8_z3B1tVW3gG9;1~l4Wuj02^)Rm|EQi z7Lr#D|yqQR#@__(=lQ!c(*oJbKfUjy@I5TU-wU8H=&U-LAR2mshz_l5HwGMp}9lVoIO-ny`$R%e0 zWI~o3W3_%`b`AjK>JU5#rxNq>4(9_D904e#06@{s4WM{+Pz)udWi;@k<;N;;J93)3 zOV!j87Q22$M0Hff>G3FYhu;F;osFkXa;d9g);eVc+-eZf^1h7&^=#A)x!8??lu61=ASY5 zqavPoRrs=Xgl0KTvy@3s=nc}6p8p#m!g4xZ4yTb%-Sx?R?Yr1Mm_<2OrmWD*9|jXN kRmS%hY#8fu?crF7ld{K_(KTQvA8q8%s%UkNMfa-VH{7NJssI20 diff --git a/CoreFoundation/CharacterSets/CFUnicodeData-B.mapping b/CoreFoundation/CharacterSets/CFUnicodeData-B.mapping index 35934e482e594aef4fabfddc91172d81c0f85e0f..5d775d94fb59c744a4f29559b993b1ec945903ce 100644 GIT binary patch delta 8550 zcmW;R37k!39|!PrXEXO|8B|Jy$krn6tF+rvNU|kKl5E+x>@KCWO379vNkfX5G)baR zZ>u(`BxzHjnz1)?dB4xw=hNr=oadZ-+~xQGKWEN)?)U5&hqLQ6XxQN5D2i(O-+$*% zh@$RIqUg@+qp1H~QS`xQQS{wX^FvqFdAfY6@{CxNXR7iO{G3nn3(n-1e2QOj7PoOW zzvdin=UjfndHj}7^E*Dn9h}eaxqv(QEPvoa?ut@T<>w53G_i=g`8rS3m${Fxa6eb@FRtX@DT7xH{^2SXaW#uszyo}Z2f2oa z_&N`>kVp6ik8&-K@lF2A^-S|^9_I$0h@x|%SaeQ|87$aZzWJ$F=Q~CI+9=BR()@LN zi|gs7`5X8yH*qtc;+9yHaWCJCMOCI3^7c|H5F75lR_?`9hg;0+wewj9J8IhgG@Bud2w-()bzC;263@+BfITO3Nh(Gap{>;Vvg)i_|F5z!{k$afW->G2p{@^nH$(Oj7 z%ejv)b3b3~_heU^# z9TFW{c1Uz+*&)%PWrswEmK_ouT6RcuXxSmrp=F0ehn5`@9a?rsbZFTj(V=CBME}2K zheYRT*&)$+T6RcuXxSmrp=F0ehn5`@9a?rsbZFTj(V=CBM2D6g5*=E0NOWk~A<>~_ zheU^#9TFW{c1Uz+*&)&YZ`mQyp=F0ehn5`@9a?rsbZFTj(V=CBM2D6g5*=E0NOWk~ zA<>~_heU^#9TFW{c1Uz+*&)%PWrswEmR)snEUNk-r?6n!En~*VCa?bL-Rh}^Co-bU zzEPBnvZBoXjByY%IE~9c60d$z1!VF>d}5CODmC`2^>4INOCNiV3(|Jbg^Mvgy^m)NeuOC5h98=J4s%h-^Y zvk|XgV_wNCc$M>A&8st`R8}*CYnrM+<^7fR06)f3}{I57qFz?N(gO8~6g-af$sM_@eDl z75VJKr9OG6ie>iS&X>&J!R745m)VD}FxB5+MRt@ukSlYd>|uP>3rBMm$8t5tvw#!% z8p9i3!zp~7_py-o^9@epT0X=#`3ToBRLxs_oa-~9RQ3}FZ=0CO4V=Y|oWpk*%IIC6 z=oxOZy^xz3%4Z8h^}J_)sGj$IqGkNA`Iq?tL)Co9SNRcF^J9kU`6MG1WrrUAsfjnZ zm7$D2W9aFh^KE|N#G#zNw7rR6aSOMZf1h9TLvAw@(?TWFhlhmVKp9Q z4IX1H{>!>7;RP(EsyQQ>HfU(#I77LdVB?t^)9tz{l9E_Plyem`s76XM?NuWsSyUq> z+0CLHHB#a;XZAbZCDyrMj++ zcmBm5{F^=b4|}nQy;;n@Jiz`u$N@aWK|IVMJVJFot4I^&Po$}oMoxZN>8FPD?ORY ztn?Hrv(i(k%u4grV~#p2EoWi@%X1;ax4MYoTV2fXtuA5sR`VIY)nz=B%Xt=GVI{8Q z*<8iSEMOI`;W;d1Rjy?<^_a8Hpt_0mJeM0-gYU2=H}O1fVJ*JT+WdenfpR`#U4FuP z+{*L$IWM4kEWME1coDa=KELI~>M>`BK?Ck&L+)adyZImf%tri`mv9d+)@L_1;B8E@I~(!#%&5$z?7_>e$E9}|TxFsso6sdtnda=pmb}XgTd_CWun*g^ zFWa#n+p|AA@@{tK0CwR(cI6;;<6w5@5cWtJ3^nM?9CDE%aQEQQ5?W~IEbS; zgkw02V>yE3IEv#rniDvd6FHufIFYhfCKcX*OQ14SIEDA|Uf$39IE_>J5bx(Be1MN} z8XxC_e1Z>gCLiW3KEgSCl=Ju)pW$>a;N$AQ%tC`1CKmAtF6NV5!kNtHQ(VSbT+Z2i zg>$%)bGeH1Siq;bhR?8&^SPD_xQ@?qJr}C~G8+t@Gw}`=aTA~C7B1%de1RWu2|wbC z{Dk@3%BB3A%lIW<;x;blcD~GS`3iS%1$S~~_ziX$yvp5N#hv9{< z=hwWD+gYFAumQhilHairckohv&&#-zSMUd373zPN!8Im+WK-^DbN<9@`7^KMFKoqM z*@nNdE%&e;e`kCC!H)csow=7?xQ|`ApWXNuyQd8PHt4~B*po%s z`v>zdhw=!A^C(C181Lb~9K#ZhV<{&v%}G4Y)MSGb2KPo$I^tBu_y9BbAT#+e zv-l{pIh{G2!7_Z3xqOOo&SrvhS(Z=pB+lo_e3qxE|J>&cPBrm7^Y{YG@kN&BQdZzg zJdLii)2DL<&!Fqoe3O;=7OT)@cKRIkpS#hZs)=`5jhk7W z@9|vzmo?~mJ6)3>^E`gaTKtT)`339nE7s-LtVh@1>GSy=FW~pQkS@Q|7o`k-G^o#? zcrkxr1OCQ_{GCa<4p0Aw``Czo@e=;SOIgguJjlyoTX-hBQeCHSSBe3YRo9%CV=GgQOlOj!ogPa1?O zn8{6iiXr{8_yK1#q<#*!axO#K=W!dKW=Q!n+`;(_>0ZFye3l{93%Q5SF@$-M`*HF8 z2G5%aDPGJ2e1RdoOL&YgGNd-2C%7~-(p#eRGG_B7=5jg9(jAAyDRjpnQI0Ek8dtI+ zUu7k(az8F%6-uu*QH=$x!Pi)eYgm`B^8yyKKHp$Nu4N;>$;MpAEBF?#=6W{e+ibxN zw3ehdvNhikf`mmR{Vs3fCR#kwn|U+0(4vukkGJuC_MktP6L->|%L!{lx;QIJ^y2}B zupZ=49^yzIW(esKPT)~aW|d=35YqW?`6v<6S&|ziLg-2zu&A&}xmd-F{z7(qn7C+6=EwhFMG$f z#VsL=$1QG&Ews2L-lxSaA(O`~Zi$a*aZ7wci(6uA;nIq+IrUPXN3kMnSmH}s!xGzQ z4NGjNH7xNhtzn5Bw1y>i(i)c7MQd1MH?3ibpDAaFUzz87+QV}EljXUe75EQN;{l#7 z(}}|dXP7v~iY(=sJi)UvBkN(Ts1mbzHgj2-Wm$!%@En$7Ri4IbtjOxD#B*7NHCT-` zS%c?gwu#EtGN@&uE^G4w)?t0tWkc3uBc30NBG2QBE}+L_Mb@UWjd>9-pYvez*!Heh z+H7O(EsR#AsJ^GC#{{ttT~q3Hks delta 6745 zcmW;Q37k#!`v>rI=gxL75|S-s%a+hY30X=)NF`gsPmv@cWWAOoNeGQ4AxW|~X_63< zN>ZsLNt-rhUt;F!|2}`Om)H9_&pGG1_j*3_J@cJ$E^YB2Y1Qi1sZ%Eig3A8-Q|;3r z==5U{bbB%g{x>@acIfTLE^if*Qvo%UaQfe;Fd9`NmjGV$* zO)_U~Y4l7^yT)CL%v#&7M^63r>oRkG>pU(sCFP@84|gA&)4Io`QIW@UKL2ieg+x}6 z8btdBK~{wQnZkjLMuX@OraB(RG{+;E&N0kL3!>wg>HH+d^rtY+=U9N#S>`h$Z=l7ldQ_q ztj4pf?z;1=!HcZvb(6d{8l5X*b9j@!iR^HHqY^~piZ5)R)b*J+K*p`FX&izB# zKAH$pO?TE^8l%|31!H-)8z=A{{ik@Z{$zI4pUV6E1Jl^a`Ea;8>(5~qX0t2ju^Sig zelBEpF5&}R!X635QbkXOL)VMT`9Cil4qtDs;)4u_?;*a)KHR{*e1{Kn6Z>%sAK^Ck z=LdY0;ZP3XCwz>1m>8%Cr}J@!(>aLYbPo1L4sZw$@(KNLNQXN9k;51c>u~ zg|k_Wb6gir{fn%{Y}V#n*5y2g(?6f}xPUkEC599L_g6f;k+;w>X9y7{2khIi9(k$agr28#$Tpatb#wOwD_o#?740E%Ki> zQ?XTJ7T@O_Zetju?LJW$qaBXJ_9;8#U1=we<#1;N8GQ!o8Njv zdw4+q3x22n6%R5@)%X0Chxi?TNVxEO#bF-ik4}WK`iWtzer6b}U-$=qU@1#4GDBp65}9>H3>V{u2#^NB)l~qKe}T<8*@I;&74$d5VR3nnihr z#d($`d5&Rv&a)isgjLEXNHj&s<(Dis>5_6*M-nA~&-Vx3V&~u?lza8t!CO z?xLrl^p9DcyIF&KSd)8sEk!cF7WeTwe$Cq4&pMXk^aF~zJjm;Lh*><$8~79J@fX(T z5#Gq(c@zI+10Lng{D%#BoQ-&rjd_~4@GP6~JQGb77ZlBy$L37(R{qD^Qi6;KTQJJo znZ}mP;2n&y6$`L63$YCg^G+6FTNYzG7H4~wuoUOtr6{G*fn|6%%kmzU=e?}Jj;zG{ zScRQfm7Q6gU09P{S&Q9RoA$wsj^PN7$N}RLGGekP%%Se5odAFpVED zgF6}Hhb+KdEX0pkm>;tUKVdQMW^sPX65PX5{ETJ7{O?ti)%cv{`2{QROIG4OR^eBy z%CA|S->@e4vlhQ)Z607{>C=^oo)FC+w)I$;9tClN7<2ovlIVe7an7`gyOiOJ5R6&PqG(11!eZ8r=ZL} z^c0lYk7u2Kl;`*u&+~Eq%fY!!5Pft3yg6#<9v|?IF|)EpN04mFO&bwmlcII7V~nx!XkW?MfnsXR+vJ~H9X?oI5mf<_Ritn;4J!vP)$$#b+MR|?)c{R7Q z0zY6ye#lDn$eparPgsSY@)~}|s{EYQ_$90JE7qV#@MKMX%WL@^Yta*U^16iL2SsiE z$U6L)b@?l==WooSNActh{EPMYH|z5lZ{!Ky#8Yg*GrXDS*pUCS5ihba^O>*-k$Fkc zAsWQwK6y7&X%iwQ@5y@^XGh9;@;+Wpn-DSiPIl&%>_WLtcI8#FurcH>Lm?mvP#G2A3L`*!BHX&lS z(opIhqqVhLbp!&oIHM;RWLq&vQIyasp>_ zBD47v=W`Ml@@a-?nariM2@wlZGKDMnELU+V*YY`rshGwMe4b$%rZZs~OunE9Q!tC$ zIGf@0&*3h<$Z+bjxrcKZPWwFW<9vowzJLe#62s|U$isY@;ZQH)5iVvp%uAv{B6d{q zibgoaOL>y7GMwIJJkQq{PVI6g`Fb=klRv}hzhWLNH@wIb;^=6Fx~jX7?ONS;a!;(d6U;jo_J zV?4{jJjZZI&vPXI#|DB~lWG?9w2=J1*m3 zF6R?8Y?p>{C5Ll0pQNF?G=l3nk~thj!*^*kb2)|^IhJPdk{^We%^Vl`|6k=Vjb}y2 z6Cy$Gn$nSZ(FR)`S@Pm0^pYhnzJr#$_)c2#;wJTyB`^LlEqU?XwB*J28D_i_)TG`_JX=RHapp`9tkXE+%AzInuhiPSt|3oWW{1;yC+dIM{ z{DVb#l*M?ASMVf@oAme@#g!W8S%Mc?l1Y||1_c6^W|U=^&Z`(>Sr%kD7G`-C<<%_C z3M|QrEW=7H$I7h0D$$xjfy#<&G^(;HYp@z?u{!Ip2D7r8wvLpD)pvMZN>JdY?4GS7 z`#aq1u#Lk;ypy-EEt|5PyPC7T;}(2`E!m%~ID>71$SF@41=`a8LxJ|WGulK3Mw)eS x+|2#=vN=2PR(9oW?9LYK$=lhRE!l^6uwQP|wvjc3a?f>*%q*WhePm?({{glh=HUPU diff --git a/CoreFoundation/CharacterSets/CFUnicodeData-L.mapping b/CoreFoundation/CharacterSets/CFUnicodeData-L.mapping index b7194c68786f7b4f29a72ca54e5db54c02311f6f..681809fd757eef1b09891466e1ef1e28b4cd7022 100644 GIT binary patch delta 8548 zcmXBZ37k!3AHebF%w|y8lbwVl39lk;wj@cmgd`+n-$It_DoLV*BqWt2A&r_SOW9s+ zDk-IsQbhJW+xtE9_W7L8_kW&q?lm)h=b2l*x;Op#lj#+!*QkE|RpI~tjI0vE?Hxn7 zvr7mM_YC3d%^|$?QwaU5EUWl(!Nl_=E#(i<6n?`O_${Y$E2r^0PUkkh$nQCWKky}P z=S=>{m-!QCaR+DfXU^d-e1*SqE_db+iRe|sZx-fp7hmJ=e4T&r4esWA{>eA_7Z-33 z-{M{_-$Q@qm+BE%Q|{>ms}ZsIAOzrtd`f;&rGO0 zs60}4P8pz=uFLFJLUgUTay2bD+a4l0k-9aJ8vJE%NTcTjnx?x6BW-9hD%x`WCi zbqAG4>JBQ8)E!iwh}0ca9;rL1JW_X1d8F>3@<`o5<&nCB$|H3Ll}G9hDv#71R3522 zs60}4P8pz=uFLFJLUgUTay2bD*MxU{6g)g4qGsXM4VQg={!r0$^dNZmo@k-CG* zBXtLrN9qnLkJKGh9;rL1JW_X1d8F>3@<`o5<&nCB%A?bTJW++*&m&Xk)gF;Cxl{-n z7i1N$)4o8ufW!K!1McctLGnTRk>rE)BgqHpN0JZHk0c*H&HCo9tjvV6gTj-_4hl~y zJ19JX>Fcv9Ix;Yno&g(sCA z6rNOeP~$3Z)C zf{wTBIA}*s(D9ZX2kpoSI^MG5pdC3u$6IzBbi8H9LC0Hm9JC`R=y=PHgLeEs=y=PH zgO0cCIOurGj)RW3>^SIn%Z`JNx9m9Rc*~B1j<@VM=y=PHgO0cCIOurGj)RW3>^SIn z%Z`JNx9m9Rc*~B1&e^i#pdC3ui#jLhc*~B1cH{&dZ`pCsj+~(5Ejtd{krQ;hWye7~ za)OSx>^NvgPSEj|9S7}*#*_)+=`tZoazfU)`-hH*#$=t}x~^Q}VvP{Gr-qbJGlZV0 zAuVDbrf>jLIV3ftrg50_bdGeM!31-0Y-&i)>K^-K8@FXQY~ zZ;{V1*A4mknlGdP-*8@#3*1J6G( zc%1ig6kBkN8(Q*7FKor9theR_>uos6`h9%PAJCT5T)&?)theJ#w&yH%;2b`{x$MY! ze6VK1Z!kkA3-kF97qBxIvI`e^9#SVTUwTM; zhJ~z8WD!2gqMXEH=^>Fa*-*m5b1cQ@S%yUcBtC*N#SZ$cfHJr}1oWV~xlb>>y?`R$8 zI$zIu+`!klk@H>O#D%`0|MDH{o4JIa@m+q-_xJ^u^UL`8|G@B-g%7!fEBQ4)<~Ll; zZ@JbRZ{<4Y-*E%Cag+7$`5AxUm)5s)i!bO$Zngdszqh`F+xatp;xF;@|Fhv&3%|N? zCwK8T?zX;*fAM$jVea8k?&Wd*&6D15AJ1?<&+#8#V9c z2kb8!MQIgzAZ|Hn2$4=|D4BRmZ5-!IV{MzEW~*%%-30j^LaTJuqYSu3NB(X zE@p8qWeF~0NoKJW-)CuNvkX_T>^YCaM}~41R`E)%VR?SStGJF8xPcY9iIupSSMzgL z=9j#NTUdqP@LFzVRc_;T{DIZ@Bd<>wb{MMj7uMiT*5oe!hkvjZ|Ktta!yEZGYjZ#A z@BnY(A=c#)-ppgXg(r9`Pw_UMVd8efSwlUZXMJ8|14g+*N<*fy5z~1GbFndV^G@bv z6JE-@n2$|afOoSHo3RM*VNo_`v0Q!~-fJjfp#@8^CCjiC%ds`fvkfcoK2~B|R_6Vz z!gj36_N>MZtj-5mlO0)$5Aw!bA+-~4%H`wmLxx){bmr~s!UpWhJNPi0cwsj-#*k!^PjD>9@d=LSlbpbDoXDp*iR1Yk zpXL-!;8Z@t>72+Je3mmgiL*GFbNF2R{LeK!Z($y%@O8ex`JBoHoW_Nm&P9BYi#dZ! z`4X3LCbRf5-{&l5b2e9S4nN{6T*bNZ^S{RMs)bKDkL&mvH}G|C;v3w|`TU%3@=Gq@ z7QV%AxR6`lxS56c8H@097UdT##xGfdU$IoC=YNZ#jD@dRj^D66zhwn(WhH*c%G|~({GL_$ z1FLa6tMf+~%Y{1{yh<~s#ce4rqWK;gd zX57Q(+{+gHo2|HyZMdIp`48Li06Xv?J0=W=44rtGoq2>^d6eBUeFS0;9%nC}U|-iy zvOiC8AWw5J&+sw+%V9jr$9aw;d7h(rfr&AOi-xfb=l$C!BR<6xKFw40QUSoc~!2*1f1^E^W@og67J1oK_ zyqxc{DBt51T+U+rfW`SCOK>Gi@?)0bYL-6l`Cn@&W8qVl<$9LmMqbJPvOGWIRs4b# z_!TSiYgXd7yqe#!GQa0F+|DZeiP!RHR^_j}E@Al1P>sLydhTX*{>2*H%bMKB|L`By z;z8cP!@QA4S)0dMhbMUxPqQxn<;^_DTX=zqdkrCXNNvGXwqyodF*jTD61HJJ-p7J$ z%Obp=SFjyRusut&1IzINUd4{A#0Pl|JF#kR|2ga-!}S(AvnIRn26kl~KFpihjkoa; z)@OG%Vh`TQo@~lTc@KNB1$(nK`>-whvOW8;V{X6y`x_pzFo0b-kdJT>dvY*)a|rwK zF%INV4&g8k<8Y4P;~dQqOmZZjpx+D0r4L^MuTEoR@t| zfv9Lo&-rwm#j^alg%~ecrP4=on z(bCj9pEy71d>v1515a}k&u}yU<>x%hFL{nzvga3#W?Yl_#(8uk3R{`NZA|44OyiGC z=MHA@7v|zlW^xyE^AG0XpUlraeoh6rj|F*vg?N~Sd5lGlM2T?HaJhvuEXs4df)`ng zDS1O`ai+5bGg*>(S&EmjGz+i{3$rYXvK))^N|s`ImgQ9}&k9GHMxmmiqJ_$=#A|sq ztFba`@EX=)6*lnU?^?EGRo2eycN1@#F|I-ML%W-uHg$R{@8<1n#`?U64ZTfsHg^6f zo3Iy~vNxOYc{XP_>VL;EVyo=M4WoWhy*6H7&-wkV&kk(B2icIF*@zGG4t8f_KFT}U kC%fYv(b7vZcHiRzO6%-At)mypq&M@6t>uiFgQD^O0~3X!6#xJL delta 6742 zcmXBYd7O>a;|K8P&Yc-EmSh=g$i5{sAt75rLP)lRh>&dAmun3ndlQl^NysuZ_9a9~ zNRi~Lgvh?{`n~7%n}6P)^Eu}{^W2$xUiX=qd@E+&*_a|_%akcoDER-cABzRSpUr}x zf2$yv{+4b>5d3y12(}elRb*D?9|;nJpi?-A z4zVkv*qvea4hP|A_BD>-K;u{rVHyq#2QhIRZ9bmk^l3SP={Sk$In{gye$2->OP`T* z!a*ebxG*mqL}lUv6PdZl!Yo|EtXytBfh&B&Y+Mr#VzYCDaSm>^FDJh>&c)r#%^&T5 zf(Oj!;UVVbVdmq}a3qL+QaElyex9_U0MA%Zkmp#47g(5=-AEB$Wl>&dG2Ucx-nOm; z@3ABwy6#hqiVni17!w^tKh5~)Af_}Qi_&gI?iRD?D6=C zY{$iXi%VR%J(sZqSMY7FW=F1NC$8f=+{n({!Y@LgdRM^ zo;=K6JnBYz^BCXfaeW{DY2245*^j5#pJ&Vu;5iQD1^pmi;$U9k5MJX@-e4s425$M$ z4&yz=a6aG&KH^9QF+tQQMsYNw`2k}&hH)Irv@t<=95ciO(H}CCemt{q0uwlq+4&K3 z#srb5NkVSLWai-%=5wK`EWl|j%;_w~87yht$1KGpmgXlc%b85%ESBSJR^X?s$T_UU z&sZfU5=6}vs=Dwz*5G{BvS0yg8!zO`{G9c3e&iaGq{~e{FXDlq8*%Lypwaei}U#%7nokY!`#Co+^heM z``pk`9@PKNU-ZX#n1Ap$9_R1;U+Ve)!@?7a6a14WP5i}EJjpZsn`e27|ME01@C+~U zA70^EUgJ65aJ_$do9B6t7x<7D8N>$ROR2{%EL>(RuP~lhnV#2}k=L1-H<-Yi%)wjC z&D+e&JIv3!EW~>(%KI$A2Q0;hEW-?sghb&#mQR`y9ctL3Vr&oY5=8JWb#A2pyS(#T^h1dB4Z?Yze2w|plm+=Z3$q!EvN?;h1xvCeOR*J8^9`0|YbNqdmP-?a+wi$Gks#bwsHAAe z7x)&dvprvA2iCUnZPsN+)?+8u=R0i3&TPakY{IT=%6Hj}-PnTfu@$?sbwubPv|&%S zV=uO6Z@$g<*@=DFnSI%n{n(BD*_{K}lLOhCgV=|I*^fgwfI~TmsqekW5Mfwq;BXG- z2#(}Pj^-$i;b@NI2OQ5aoXD}9#BrR$4>^tFIfE0J#EG2Ak2sr?QqTV!VX|T_r*J-} zav`U25vOx8XK)EW=29kcIX~eF&g3f2VlroQEk9)n=Wsng<3`R+J^!19d5W!^&+S~m z9bCv={G7YFh~M)I?&V_c)gnj+{D}5%)8ve`;2TA9tzv|AGb3U=P8I` z?qCdeG7Wbzp5HMYcQXU`FeATbCjP)I+{*<1$n4z5ocxKo+%fi@gLUbSvKT3HsZf*!t-p(3v9-VY{5%x6%j5At$BrQc$MvVjqT$+ z1+gP}NTP8Q&I zEXX}9#2;9gKe7maVo@GoG5*Zr{DmcWm?ilepW^Q<#XtCTMEIXjnt!qkPqHje@fn_B zBG2+!{>yT_!1BDr3cSMSc#Rc#gU|C8EAb91^B$}40VA&pkG!cGF%%z!8#9_sn1-)0 zEt@g}U+3d&#w={kY;3`tY{@6siuw2k3$Qf{^Gz0G8#_@9VOKWfyKKyEY|8i8oZZLj^RR%YJdR@GTo~2ODuGU*j$|<9BSy z-E7S(Y|E=`&ui?MHi*8?F1*3_c$2+&i+y>U19^u-ndh!B!UgVeblM>EeI}(1;vR5r zNr|$c@$$WF6R4O!oFO}eq7G}T)_cc#eq!bAg<+Lrf>+?b0{}5!p$7U z{INl3I16yZqabBzuF%YI#jR#ckm8(@h*4s9>3>(?&SmSOBs?klvE8PN8O?7YVue8`*((gopM3^O-l`2^#chv}J@8JUln`6LsVpE+27xml2TS%~>r_-e^e zP)I1ED9WNN!D1}M;w-}wOiZfsawvOz`E)*@44+GC{c`9?qvs9l8CK>ie1Y{@jSX1C z?uM*o+=aE-m329p^%z_W1@#$X!<32jLfu2v8`)Rg_%+sGGuC8FzR1?B#kPEj?OB^0 aS%;lds?-my$dGcQWoUA~qzMB @@ -13,6 +13,7 @@ #include "CFInternal.h" #include "CFRuntime_Internal.h" #include +#include #define CF_ARRAY_ALWAYS_BRIDGE 0 @@ -294,7 +295,7 @@ CFTypeID CFArrayGetTypeID(void) { return _kCFRuntimeIDCFArray; } -static CFArrayRef __CFArrayInit(CFAllocatorRef allocator, UInt32 flags, CFIndex capacity, const CFArrayCallBacks *callBacks) { +static CFArrayRef __CFArrayCreateInit(CFAllocatorRef allocator, UInt32 flags, CFIndex capacity, const CFArrayCallBacks *callBacks) { struct __CFArray *memory; UInt32 size; __CFBitfieldSetValue(flags, 31, 2, 0); @@ -313,7 +314,7 @@ static CFArrayRef __CFArrayInit(CFAllocatorRef allocator, UInt32 flags, CFIndex case __kCFArrayDeque: break; } - memory = (struct __CFArray*)_CFRuntimeCreateInstance(allocator, CFArrayGetTypeID(), size, NULL); + memory = (struct __CFArray*)_CFRuntimeCreateInstance(allocator, _kCFRuntimeIDCFArray, size, NULL); if (NULL == memory) { return NULL; } @@ -348,7 +349,7 @@ CF_PRIVATE CFArrayRef __CFArrayCreateTransfer(CFAllocatorRef allocator, const vo __CFBitfieldSetValue(flags, 3, 2, __kCFArrayHasCFTypeCallBacks); UInt32 size = __CFArrayGetSizeOfType(flags) - sizeof(CFRuntimeBase); size += numValues * sizeof(struct __CFArrayBucket); - struct __CFArray *memory = (struct __CFArray*)_CFRuntimeCreateInstance(allocator, CFArrayGetTypeID(), size, NULL); + struct __CFArray *memory = (struct __CFArray*)_CFRuntimeCreateInstance(allocator, _kCFRuntimeIDCFArray, size, NULL); if (NULL == memory) { return NULL; } @@ -365,7 +366,7 @@ CF_PRIVATE CFArrayRef __CFArrayCreate0(CFAllocatorRef allocator, const void **va struct __CFArrayBucket *buckets; CFIndex idx; CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues); - result = __CFArrayInit(allocator, __kCFArrayImmutable, numValues, callBacks); + result = __CFArrayCreateInit(allocator, __kCFArrayImmutable, numValues, callBacks); cb = __CFArrayGetCallBacks(result); buckets = __CFArrayGetBucketsPtr(result); if (NULL != cb->retain) { @@ -389,7 +390,7 @@ CF_PRIVATE CFArrayRef __CFArrayCreate0(CFAllocatorRef allocator, const void **va CF_PRIVATE CFMutableArrayRef __CFArrayCreateMutable0(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks) { CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__, capacity); CFAssert2(capacity <= LONG_MAX / sizeof(void *), __kCFLogAssertion, "%s(): capacity (%ld) is too large for this architecture", __PRETTY_FUNCTION__, capacity); - return (CFMutableArrayRef)__CFArrayInit(allocator, __kCFArrayDeque, capacity, callBacks); + return (CFMutableArrayRef)__CFArrayCreateInit(allocator, __kCFArrayDeque, capacity, callBacks); } CF_PRIVATE CFArrayRef __CFArrayCreateCopy0(CFAllocatorRef allocator, CFArrayRef array) { @@ -398,12 +399,12 @@ CF_PRIVATE CFArrayRef __CFArrayCreateCopy0(CFAllocatorRef allocator, CFArrayRef struct __CFArrayBucket *buckets; CFIndex numValues = CFArrayGetCount(array); CFIndex idx; - if (CF_IS_OBJC(CFArrayGetTypeID(), array) || CF_IS_SWIFT(CFArrayGetTypeID(), array)) { + if (CF_IS_OBJC(_kCFRuntimeIDCFArray, array) || CF_IS_SWIFT(_kCFRuntimeIDCFArray, array)) { cb = &kCFTypeArrayCallBacks; } else { cb = __CFArrayGetCallBacks(array); } - result = __CFArrayInit(allocator, __kCFArrayImmutable, numValues, cb); + result = __CFArrayCreateInit(allocator, __kCFArrayImmutable, numValues, cb); cb = __CFArrayGetCallBacks(result); buckets = __CFArrayGetBucketsPtr(result); for (idx = 0; idx < numValues; idx++) { @@ -423,14 +424,14 @@ CF_PRIVATE CFMutableArrayRef __CFArrayCreateMutableCopy0(CFAllocatorRef allocato const CFArrayCallBacks *cb; CFIndex idx, numValues = CFArrayGetCount(array); UInt32 flags; - if (CF_IS_OBJC(CFArrayGetTypeID(), array) || CF_IS_SWIFT(CFArrayGetTypeID(), array)) { + if (CF_IS_OBJC(_kCFRuntimeIDCFArray, array) || CF_IS_SWIFT(_kCFRuntimeIDCFArray, array)) { cb = &kCFTypeArrayCallBacks; } else { cb = __CFArrayGetCallBacks(array); } flags = __kCFArrayDeque; - result = (CFMutableArrayRef)__CFArrayInit(allocator, flags, capacity, cb); + result = (CFMutableArrayRef)__CFArrayCreateInit(allocator, flags, capacity, cb); if (0 == capacity) _CFArraySetCapacity(result, numValues); for (idx = 0; idx < numValues; idx++) { const void *value = CFArrayGetValueAtIndex(array, idx); @@ -469,7 +470,7 @@ CF_PRIVATE CFIndex _CFNonObjCArrayGetCount(CFArrayRef array) { CFIndex CFArrayGetCount(CFArrayRef array) { CF_SWIFT_FUNCDISPATCHV(CFArrayGetTypeID(), CFIndex, (CFSwiftRef)array, NSArray.count); - CF_OBJC_FUNCDISPATCHV(CFArrayGetTypeID(), CFIndex, (NSArray *)array, count); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFArray, CFIndex, (NSArray *)array, count); __CFGenericValidateType(array, CFArrayGetTypeID()); CHECK_FOR_MUTATION(array); return __CFArrayGetCount(array); @@ -480,7 +481,7 @@ CFIndex CFArrayGetCountOfValue(CFArrayRef array, CFRange range, const void *valu __CFGenericValidateType(array, CFArrayGetTypeID()); __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__); CHECK_FOR_MUTATION(array); - const CFArrayCallBacks *cb = (CF_IS_OBJC(CFArrayGetTypeID(), array) || CF_IS_SWIFT(CFArrayGetTypeID(), array)) ? &kCFTypeArrayCallBacks : __CFArrayGetCallBacks(array); + const CFArrayCallBacks *cb = (CF_IS_OBJC(_kCFRuntimeIDCFArray, array) || CF_IS_SWIFT(_kCFRuntimeIDCFArray, array)) ? &kCFTypeArrayCallBacks : __CFArrayGetCallBacks(array); for (idx = 0; idx < range.length; idx++) { const void *item = CFArrayGetValueAtIndex(array, range.location + idx); if (value == item || (cb->equal && INVOKE_CALLBACK2(cb->equal, value, item))) { @@ -495,7 +496,7 @@ Boolean CFArrayContainsValue(CFArrayRef array, CFRange range, const void *value) __CFGenericValidateType(array, CFArrayGetTypeID()); __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__); CHECK_FOR_MUTATION(array); - const CFArrayCallBacks *cb = (CF_IS_OBJC(CFArrayGetTypeID(), array) || CF_IS_SWIFT(CFArrayGetTypeID(), array)) ? &kCFTypeArrayCallBacks : __CFArrayGetCallBacks(array); + const CFArrayCallBacks *cb = (CF_IS_OBJC(_kCFRuntimeIDCFArray, array) || CF_IS_SWIFT(_kCFRuntimeIDCFArray, array)) ? &kCFTypeArrayCallBacks : __CFArrayGetCallBacks(array); for (idx = 0; idx < range.length; idx++) { const void *item = CFArrayGetValueAtIndex(array, range.location + idx); if (value == item || (cb->equal && INVOKE_CALLBACK2(cb->equal, value, item))) { @@ -530,18 +531,16 @@ const void *_CFArrayCheckAndGetValueAtIndex(CFArrayRef array, CFIndex idx, Boole void CFArrayGetValues(CFArrayRef array, CFRange range, const void **values) { CF_SWIFT_FUNCDISPATCHV(CFArrayGetTypeID(), void, (CFSwiftRef)array, NSArray.getObjects, range, values); - CF_OBJC_FUNCDISPATCHV(CFArrayGetTypeID(), void, (NSArray *)array, getObjects:(id *)values range:NSMakeRange(range.location, range.length)); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFArray, void, (NSArray *)array, getObjects:(id *)values range:NSMakeRange(range.location, range.length)); __CFGenericValidateType(array, CFArrayGetTypeID()); __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__); CFAssert1(NULL != values, __kCFLogAssertion, "%s(): pointer to values may not be NULL", __PRETTY_FUNCTION__); CHECK_FOR_MUTATION(array); if (0 < range.length) { - switch (__CFArrayGetType(array)) { - case __kCFArrayImmutable: - case __kCFArrayDeque: - memmove(values, __CFArrayGetBucketsPtr(array) + range.location, range.length * sizeof(struct __CFArrayBucket)); - break; - } + struct __CFArrayBucket *const srcBuf = __CFArrayGetBucketsPtr(array); + if (srcBuf) { + memmove(values, srcBuf + range.location, range.length * sizeof(struct __CFArrayBucket)); + } } } @@ -590,7 +589,7 @@ CFIndex CFArrayGetFirstIndexOfValue(CFArrayRef array, CFRange range, const void __CFGenericValidateType(array, CFArrayGetTypeID()); __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__); CHECK_FOR_MUTATION(array); - const CFArrayCallBacks *cb = (CF_IS_OBJC(CFArrayGetTypeID(), array) || CF_IS_SWIFT(CFArrayGetTypeID(), array)) ? &kCFTypeArrayCallBacks : __CFArrayGetCallBacks(array); + const CFArrayCallBacks *cb = (CF_IS_OBJC(_kCFRuntimeIDCFArray, array) || CF_IS_SWIFT(_kCFRuntimeIDCFArray, array)) ? &kCFTypeArrayCallBacks : __CFArrayGetCallBacks(array); for (idx = 0; idx < range.length; idx++) { const void *item = CFArrayGetValueAtIndex(array, range.location + idx); if (value == item || (cb->equal && INVOKE_CALLBACK2(cb->equal, value, item))) @@ -604,7 +603,7 @@ CFIndex CFArrayGetLastIndexOfValue(CFArrayRef array, CFRange range, const void * __CFGenericValidateType(array, CFArrayGetTypeID()); __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__); CHECK_FOR_MUTATION(array); - const CFArrayCallBacks *cb = (CF_IS_OBJC(CFArrayGetTypeID(), array) || CF_IS_SWIFT(CFArrayGetTypeID(), array)) ? &kCFTypeArrayCallBacks : __CFArrayGetCallBacks(array); + const CFArrayCallBacks *cb = (CF_IS_OBJC(_kCFRuntimeIDCFArray, array) || CF_IS_SWIFT(_kCFRuntimeIDCFArray, array)) ? &kCFTypeArrayCallBacks : __CFArrayGetCallBacks(array); for (idx = range.length; idx--;) { const void *item = CFArrayGetValueAtIndex(array, range.location + idx); if (value == item || (cb->equal && INVOKE_CALLBACK2(cb->equal, value, item))) @@ -615,7 +614,7 @@ CFIndex CFArrayGetLastIndexOfValue(CFArrayRef array, CFRange range, const void * void CFArrayAppendValue(CFMutableArrayRef array, const void *value) { CF_SWIFT_FUNCDISPATCHV(CFArrayGetTypeID(), void, (CFSwiftRef)array, NSMutableArray.addObject, value); - CF_OBJC_FUNCDISPATCHV(CFArrayGetTypeID(), void, (NSMutableArray *)array, addObject:(id)value); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFArray, void, (NSMutableArray *)array, addObject:(id)value); __CFGenericValidateType(array, CFArrayGetTypeID()); CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__); @@ -625,7 +624,7 @@ void CFArrayAppendValue(CFMutableArrayRef array, const void *value) { void CFArraySetValueAtIndex(CFMutableArrayRef array, CFIndex idx, const void *value) { CF_SWIFT_FUNCDISPATCHV(CFArrayGetTypeID(), void, (CFSwiftRef)array, NSMutableArray.setObject, value, idx); - CF_OBJC_FUNCDISPATCHV(CFArrayGetTypeID(), void, (NSMutableArray *)array, setObject:(id)value atIndex:(NSUInteger)idx); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFArray, void, (NSMutableArray *)array, setObject:(id)value atIndex:(NSUInteger)idx); __CFGenericValidateType(array, CFArrayGetTypeID()); CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__); CFAssert2(0 <= idx && idx <= __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index (%ld) out of bounds", __PRETTY_FUNCTION__, idx); @@ -653,7 +652,7 @@ void CFArraySetValueAtIndex(CFMutableArrayRef array, CFIndex idx, const void *va void CFArrayInsertValueAtIndex(CFMutableArrayRef array, CFIndex idx, const void *value) { CF_SWIFT_FUNCDISPATCHV(CFArrayGetTypeID(), void, (CFSwiftRef)array, NSMutableArray.insertObject, idx, value); - CF_OBJC_FUNCDISPATCHV(CFArrayGetTypeID(), void, (NSMutableArray *)array, insertObject:(id)value atIndex:(NSUInteger)idx); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFArray, void, (NSMutableArray *)array, insertObject:(id)value atIndex:(NSUInteger)idx); __CFGenericValidateType(array, CFArrayGetTypeID()); CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__); CFAssert2(0 <= idx && idx <= __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index (%ld) out of bounds", __PRETTY_FUNCTION__, idx); @@ -667,7 +666,7 @@ void CFArrayExchangeValuesAtIndices(CFMutableArrayRef array, CFIndex idx1, CFInd const void *tmp; struct __CFArrayBucket *bucket1, *bucket2; CF_SWIFT_FUNCDISPATCHV(CFArrayGetTypeID(), void, (CFSwiftRef)array, NSMutableArray.exchangeObjectAtIndex, idx1, idx2); - CF_OBJC_FUNCDISPATCHV(CFArrayGetTypeID(), void, (NSMutableArray *)array, exchangeObjectAtIndex:(NSUInteger)idx1 withObjectAtIndex:(NSUInteger)idx2); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFArray, void, (NSMutableArray *)array, exchangeObjectAtIndex:(NSUInteger)idx1 withObjectAtIndex:(NSUInteger)idx2); __CFGenericValidateType(array, CFArrayGetTypeID()); CFAssert2(0 <= idx1 && idx1 < __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index #1 (%ld) out of bounds", __PRETTY_FUNCTION__, idx1); CFAssert2(0 <= idx2 && idx2 < __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index #2 (%ld) out of bounds", __PRETTY_FUNCTION__, idx2); @@ -685,7 +684,7 @@ void CFArrayExchangeValuesAtIndices(CFMutableArrayRef array, CFIndex idx1, CFInd void CFArrayRemoveValueAtIndex(CFMutableArrayRef array, CFIndex idx) { CF_SWIFT_FUNCDISPATCHV(CFArrayGetTypeID(), void, (CFSwiftRef)array, NSMutableArray.removeObjectAtIndex, idx); - CF_OBJC_FUNCDISPATCHV(CFArrayGetTypeID(), void, (NSMutableArray *)array, removeObjectAtIndex:(NSUInteger)idx); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFArray, void, (NSMutableArray *)array, removeObjectAtIndex:(NSUInteger)idx); __CFGenericValidateType(array, CFArrayGetTypeID()); CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__); CFAssert2(0 <= idx && idx < __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index (%ld) out of bounds", __PRETTY_FUNCTION__, idx); @@ -695,7 +694,7 @@ void CFArrayRemoveValueAtIndex(CFMutableArrayRef array, CFIndex idx) { void CFArrayRemoveAllValues(CFMutableArrayRef array) { CF_SWIFT_FUNCDISPATCHV(CFArrayGetTypeID(), void, (CFSwiftRef)array, NSMutableArray.removeAllObjects); - CF_OBJC_FUNCDISPATCHV(CFArrayGetTypeID(), void, (NSMutableArray *)array, removeAllObjects); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFArray, void, (NSMutableArray *)array, removeAllObjects); __CFGenericValidateType(array, CFArrayGetTypeID()); CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__); CHECK_FOR_MUTATION(array); @@ -787,18 +786,16 @@ static void __CFArrayRepositionDequeRegions(CFMutableArrayRef array, CFRange ran } } -static void __CFArrayHandleOutOfMemory(CFTypeRef obj, CFIndex numBytes) { +__attribute__((cold)) +static void __CFArrayHandleOutOfMemory(CFTypeRef obj, CFIndex numBytes) CLANG_ANALYZER_NORETURN { CFStringRef msg = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("Attempt to allocate %ld bytes for CFArray failed"), numBytes); - { - CFLog(kCFLogLevelCritical, CFSTR("%@"), msg); - HALT; - } - CFRelease(msg); + CFLog(kCFLogLevelCritical, CFSTR("%@"), msg); + HALT; } // This function is for Foundation's benefit; no one else should use it. void _CFArraySetCapacity(CFMutableArrayRef array, CFIndex cap) { - if (CF_IS_OBJC(CFArrayGetTypeID(), array) || CF_IS_SWIFT(CFArrayGetTypeID(), array)) return; + if (CF_IS_OBJC(_kCFRuntimeIDCFArray, array) || CF_IS_SWIFT(_kCFRuntimeIDCFArray, array)) return; __CFGenericValidateType(array, CFArrayGetTypeID()); CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__); CFAssert3(__CFArrayGetCount(array) <= cap, __kCFLogAssertion, "%s(): desired capacity (%ld) is less than count (%ld)", __PRETTY_FUNCTION__, cap, __CFArrayGetCount(array)); @@ -836,7 +833,7 @@ void _CFArraySetCapacity(CFMutableArrayRef array, CFIndex cap) { void CFArrayReplaceValues(CFMutableArrayRef array, CFRange range, const void **newValues, CFIndex newCount) { CF_SWIFT_FUNCDISPATCHV(CFArrayGetTypeID(), void, (CFSwiftRef)array, NSMutableArray.replaceObjectsInRange, range, newValues, newCount); - CF_OBJC_FUNCDISPATCHV(CFArrayGetTypeID(), void, (NSMutableArray *)array, replaceObjectsInRange:NSMakeRange(range.location, range.length) withObjects:(id *)newValues count:(NSUInteger)newCount); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFArray, void, (NSMutableArray *)array, replaceObjectsInRange:NSMakeRange(range.location, range.length) withObjects:(id *)newValues count:(NSUInteger)newCount); __CFGenericValidateType(array, CFArrayGetTypeID()); __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__); CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__); @@ -858,19 +855,19 @@ void _CFArrayReplaceValues(CFMutableArrayRef array, CFRange range, const void ** CFAssert1(newCount <= futureCnt, __kCFLogAssertion, "%s(): internal error 1", __PRETTY_FUNCTION__); cb = __CFArrayGetCallBacks(array); CFAllocatorRef allocator = __CFGetAllocator(array); - + /* Retain new values if needed, possibly allocating a temporary buffer for them */ if (NULL != cb->retain) { - newv = (newCount <= 256) ? (const void **)buffer : (const void **)CFAllocatorAllocate(kCFAllocatorSystemDefault, newCount * sizeof(void *), 0); - if (newv != buffer && __CFOASafe) __CFSetLastAllocationEventName(newv, "CFArray (temp)"); - for (idx = 0; idx < newCount; idx++) { - newv[idx] = (void *)INVOKE_CALLBACK2(cb->retain, allocator, (void *)newValues[idx]); - } + newv = (newCount <= 256) ? (const void **)buffer : (const void **)CFAllocatorAllocate(kCFAllocatorSystemDefault, newCount * sizeof(void *), 0); + if (newv != buffer && __CFOASafe) __CFSetLastAllocationEventName(newv, "CFArray (temp)"); + for (idx = 0; idx < newCount; idx++) { + newv[idx] = (void *)INVOKE_CALLBACK2(cb->retain, allocator, (void *)newValues[idx]); + } } else { - newv = newValues; + newv = newValues; } array->_mutations++; - + /* Now, there are three regions of interest, each of which may be empty: * A: the region from index 0 to one less than the range.location * B: the region of the range @@ -882,37 +879,37 @@ void _CFArrayReplaceValues(CFMutableArrayRef array, CFRange range, const void ** * the length of the range being replaced. */ if (0 < range.length) { - __CFArrayReleaseValues(array, range, false); + __CFArrayReleaseValues(array, range, false); } // region B elements are now "dead" - if (0) { - } else if (NULL == array->_store) { - if (0) { - } else if (0 <= futureCnt) { - struct __CFArrayDeque *deque; - CFIndex capacity = __CFArrayDequeRoundUpCapacity(futureCnt); - CFIndex size = sizeof(struct __CFArrayDeque) + capacity * sizeof(struct __CFArrayBucket); - deque = (struct __CFArrayDeque *)CFAllocatorAllocate((allocator), size, 0); - if (__CFOASafe) __CFSetLastAllocationEventName(deque, "CFArray (store-deque)"); - deque->_leftIdx = (capacity - newCount) / 2; - deque->_capacity = capacity; + if (NULL == array->_store) { + if (0 <= futureCnt) { + struct __CFArrayDeque *deque; + CFIndex capacity = __CFArrayDequeRoundUpCapacity(futureCnt); + CFIndex size = sizeof(struct __CFArrayDeque) + capacity * sizeof(struct __CFArrayBucket); + deque = (struct __CFArrayDeque *)CFAllocatorAllocate((allocator), size, 0); + if (__CFOASafe) __CFSetLastAllocationEventName(deque, "CFArray (store-deque)"); + deque->_leftIdx = (capacity - newCount) / 2; + deque->_capacity = capacity; array->_store = deque; - } + } } else { // Deque - // reposition regions A and C for new region B elements in gap - if (0) { - } else if (range.length != newCount) { - __CFArrayRepositionDequeRegions(array, range, newCount); - } + // reposition regions A and C for new region B elements in gap + if (range.length != newCount) { + __CFArrayRepositionDequeRegions(array, range, newCount); + } } // copy in new region B elements if (0 < newCount) { - if (0) { - } else { // Deque - struct __CFArrayDeque *deque = (struct __CFArrayDeque *)array->_store; - struct __CFArrayBucket *raw_buckets = (struct __CFArrayBucket *)((uint8_t *)deque + sizeof(struct __CFArrayDeque)); - memmove(raw_buckets + deque->_leftIdx + range.location, newv, newCount * sizeof(struct __CFArrayBucket)); - } + // Deque + struct __CFArrayDeque *deque = (struct __CFArrayDeque *)array->_store; + struct __CFArrayBucket *raw_buckets = (struct __CFArrayBucket *)((uint8_t *)deque + sizeof(struct __CFArrayDeque)); + + if (!deque) { + CRSetCrashLogMessage("CFArray expectation failed"); + HALT; + } + memmove(raw_buckets + deque->_leftIdx + range.location, newv, newCount * sizeof(struct __CFArrayBucket)); } __CFArraySetCount(array, futureCnt); if (newv != buffer && newv != newValues) CFAllocatorDeallocate(kCFAllocatorSystemDefault, newv); @@ -966,7 +963,7 @@ void CFArraySortValues(CFMutableArrayRef array, CFRange range, CFComparatorFunct __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__); CFAssert1(NULL != comparator, __kCFLogAssertion, "%s(): pointer to comparator function may not be NULL", __PRETTY_FUNCTION__); Boolean immutable = false; - if (CF_IS_OBJC(CFArrayGetTypeID(), array)) { + if (CF_IS_OBJC(_kCFRuntimeIDCFArray, array)) { BOOL result; result = CF_OBJC_CALLV((NSMutableArray *)array, isKindOfClass:[NSMutableArray class]); immutable = !result; @@ -979,7 +976,7 @@ void CFArraySortValues(CFMutableArrayRef array, CFRange range, CFComparatorFunct immutable = true; } const CFArrayCallBacks *cb = NULL; - if (CF_IS_OBJC(CFArrayGetTypeID(), array) || CF_IS_SWIFT(CFArrayGetTypeID(), array)) { + if (CF_IS_OBJC(_kCFRuntimeIDCFArray, array) || CF_IS_SWIFT(_kCFRuntimeIDCFArray, array)) { cb = &kCFTypeArrayCallBacks; } else { cb = __CFArrayGetCallBacks(array); diff --git a/CoreFoundation/Collections.subproj/CFArray.h b/CoreFoundation/Collections.subproj/CFArray.h index 0741982093..1ac10debfe 100644 --- a/CoreFoundation/Collections.subproj/CFArray.h +++ b/CoreFoundation/Collections.subproj/CFArray.h @@ -1,5 +1,5 @@ /* CFArray.h - Copyright (c) 1998-2018, Apple Inc. All rights reserved. + Copyright (c) 1998-2019, Apple Inc. All rights reserved. */ /*! diff --git a/CoreFoundation/Collections.subproj/CFBag.c b/CoreFoundation/Collections.subproj/CFBag.c index 9fa2c4518e..8aecb4cd67 100644 --- a/CoreFoundation/Collections.subproj/CFBag.c +++ b/CoreFoundation/Collections.subproj/CFBag.c @@ -1,17 +1,12 @@ /* CFBag.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors - Licensed under Apache License v2.0 with Runtime Library Exception - See http://swift.org/LICENSE.txt for license information - See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Michael LeHew - Machine generated from Notes/HashingCode.template -*/ - - - - + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors + Licensed under Apache License v2.0 with Runtime Library Exception + See http://swift.org/LICENSE.txt for license information + See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors + Responsibility: Michael LeHew + */ #include #include "CFInternal.h" @@ -20,60 +15,9 @@ #include -#define CFDictionary 0 -#define CFSet 0 -#define CFBag 0 -#undef CFBag -#define CFBag 1 - -#if CFDictionary - - -const CFBagKeyCallBacks kCFTypeBagKeyCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; -const CFBagKeyCallBacks kCFCopyStringBagKeyCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; -const CFBagValueCallBacks kCFTypeBagValueCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual}; - -#define CFHashRef CFDictionaryRef -#define CFMutableHashRef CFMutableDictionaryRef -#define CFHashKeyCallBacks CFBagKeyCallBacks -#define CFHashValueCallBacks CFBagValueCallBacks -#endif - -#if CFSet -const CFBagCallBacks kCFTypeBagCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; -const CFBagCallBacks kCFCopyStringBagCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; - -#define CFBagKeyCallBacks CFBagCallBacks -#define CFBagValueCallBacks CFBagCallBacks -#define kCFTypeBagKeyCallBacks kCFTypeBagCallBacks -#define kCFTypeBagValueCallBacks kCFTypeBagCallBacks - -#define CFHashRef CFSetRef -#define CFMutableHashRef CFMutableSetRef -#define CFHashKeyCallBacks CFBagCallBacks -#define CFHashValueCallBacks CFBagCallBacks -#endif - -#if CFBag const CFBagCallBacks kCFTypeBagCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; const CFBagCallBacks kCFCopyStringBagCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; -#define CFBagKeyCallBacks CFBagCallBacks -#define CFBagValueCallBacks CFBagCallBacks -#define kCFTypeBagKeyCallBacks kCFTypeBagCallBacks -#define kCFTypeBagValueCallBacks kCFTypeBagCallBacks - -#define CFHashRef CFBagRef -#define CFMutableHashRef CFMutableBagRef -#define CFHashKeyCallBacks CFBagCallBacks -#define CFHashValueCallBacks CFBagCallBacks -#endif - - -typedef uintptr_t any_t; -typedef const void * const_any_pointer_t; -typedef void * any_pointer_t; - static Boolean __CFBagEqual(CFTypeRef cf1, CFTypeRef cf2) { return __CFBasicHashEqual((CFBasicHashRef)cf1, (CFBasicHashRef)cf2); } @@ -106,52 +50,43 @@ CFTypeID CFBagGetTypeID(void) { return _kCFRuntimeIDCFBag; } - -static CFBasicHashRef __CFBagCreateGeneric(CFAllocatorRef allocator, const CFHashKeyCallBacks *keyCallBacks, const CFHashValueCallBacks *valueCallBacks, Boolean useValueCB) { - CFOptionFlags flags = kCFBasicHashLinearHashing; // kCFBasicHashExponentialHashing - flags |= (CFDictionary ? kCFBasicHashHasKeys : 0) | (CFBag ? kCFBasicHashHasCounts : 0); - - +static CFBasicHashRef __CFBagCreateGeneric(CFAllocatorRef allocator, CFBagCallBacks const *const inCallbacks) { + CFOptionFlags flags = kCFBasicHashLinearHashing | kCFBasicHashHasCounts; // kCFBasicHashExponentialHashing + CFBasicHashCallbacks callbacks; - callbacks.retainKey = keyCallBacks ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))keyCallBacks->retain : NULL; - callbacks.releaseKey = keyCallBacks ? (void (*)(CFAllocatorRef, uintptr_t))keyCallBacks->release : NULL; - callbacks.equateKeys = keyCallBacks ? (Boolean (*)(uintptr_t, uintptr_t))keyCallBacks->equal : NULL; - callbacks.hashKey = keyCallBacks ? (CFHashCode (*)(uintptr_t))keyCallBacks->hash : NULL; + callbacks.retainKey = inCallbacks ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))inCallbacks->retain : NULL; + callbacks.releaseKey = inCallbacks ? (void (*)(CFAllocatorRef, uintptr_t))inCallbacks->release : NULL; + callbacks.equateKeys = inCallbacks ? (Boolean (*)(uintptr_t, uintptr_t))inCallbacks->equal : NULL; + callbacks.hashKey = inCallbacks ? (CFHashCode (*)(uintptr_t))inCallbacks->hash : NULL; callbacks.getIndirectKey = NULL; - callbacks.copyKeyDescription = keyCallBacks ? (CFStringRef (*)(uintptr_t))keyCallBacks->copyDescription : NULL; - callbacks.retainValue = useValueCB ? (valueCallBacks ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))valueCallBacks->retain : NULL) : (callbacks.retainKey); - callbacks.releaseValue = useValueCB ? (valueCallBacks ? (void (*)(CFAllocatorRef, uintptr_t))valueCallBacks->release : NULL) : (callbacks.releaseKey); - callbacks.equateValues = useValueCB ? (valueCallBacks ? (Boolean (*)(uintptr_t, uintptr_t))valueCallBacks->equal : NULL) : (callbacks.equateKeys); - callbacks.copyValueDescription = useValueCB ? (valueCallBacks ? (CFStringRef (*)(uintptr_t))valueCallBacks->copyDescription : NULL) : (callbacks.copyKeyDescription); - + callbacks.copyKeyDescription = inCallbacks ? (CFStringRef (*)(uintptr_t))inCallbacks->copyDescription : NULL; + callbacks.retainValue = callbacks.retainKey; + callbacks.releaseValue = callbacks.releaseKey; + callbacks.equateValues = callbacks.equateKeys; + callbacks.copyValueDescription = callbacks.copyKeyDescription; + CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, &callbacks); return ht; } -#if CFDictionary -CF_PRIVATE CFHashRef __CFBagCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, const_any_pointer_t *vlist, CFIndex numValues) { -#endif -#if CFSet || CFBag -CF_PRIVATE CFHashRef __CFBagCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIndex numValues) { - const_any_pointer_t *vlist = klist; -#endif +CF_PRIVATE CFBagRef __CFBagCreateTransfer(CFAllocatorRef allocator, const void **klist, CFIndex numValues) { + const void **vlist = klist; CFTypeID typeID = CFBagGetTypeID(); CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues); - CFOptionFlags flags = kCFBasicHashLinearHashing; // kCFBasicHashExponentialHashing - flags |= (CFDictionary ? kCFBasicHashHasKeys : 0) | (CFBag ? kCFBasicHashHasCounts : 0); - + CFOptionFlags flags = kCFBasicHashLinearHashing | kCFBasicHashHasCounts; // kCFBasicHashExponentialHashing + CFBasicHashCallbacks callbacks; - callbacks.retainKey = (uintptr_t (*)(CFAllocatorRef, uintptr_t))kCFTypeBagKeyCallBacks.retain; - callbacks.releaseKey = (void (*)(CFAllocatorRef, uintptr_t))kCFTypeBagKeyCallBacks.release; - callbacks.equateKeys = (Boolean (*)(uintptr_t, uintptr_t))kCFTypeBagKeyCallBacks.equal; - callbacks.hashKey = (CFHashCode (*)(uintptr_t))kCFTypeBagKeyCallBacks.hash; + callbacks.retainKey = (uintptr_t (*)(CFAllocatorRef, uintptr_t))kCFTypeBagCallBacks.retain; + callbacks.releaseKey = (void (*)(CFAllocatorRef, uintptr_t))kCFTypeBagCallBacks.release; + callbacks.equateKeys = (Boolean (*)(uintptr_t, uintptr_t))kCFTypeBagCallBacks.equal; + callbacks.hashKey = (CFHashCode (*)(uintptr_t))kCFTypeBagCallBacks.hash; callbacks.getIndirectKey = NULL; - callbacks.copyKeyDescription = (CFStringRef (*)(uintptr_t))kCFTypeBagKeyCallBacks.copyDescription; - callbacks.retainValue = CFDictionary ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))kCFTypeBagValueCallBacks.retain : callbacks.retainKey; - callbacks.releaseValue = CFDictionary ? (void (*)(CFAllocatorRef, uintptr_t))kCFTypeBagValueCallBacks.release : callbacks.releaseKey; - callbacks.equateValues = CFDictionary ? (Boolean (*)(uintptr_t, uintptr_t))kCFTypeBagValueCallBacks.equal : callbacks.equateKeys; - callbacks.copyValueDescription = CFDictionary ? (CFStringRef (*)(uintptr_t))kCFTypeBagValueCallBacks.copyDescription : callbacks.copyKeyDescription; - + callbacks.copyKeyDescription = (CFStringRef (*)(uintptr_t))kCFTypeBagCallBacks.copyDescription; + callbacks.retainValue = callbacks.retainKey; + callbacks.releaseValue = callbacks.releaseKey; + callbacks.equateValues = callbacks.equateKeys; + callbacks.copyValueDescription = callbacks.copyKeyDescription; + CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, &callbacks); CFBasicHashSuppressRC(ht); if (0 < numValues) CFBasicHashSetCapacity(ht, numValues); @@ -162,20 +97,14 @@ CF_PRIVATE CFHashRef __CFBagCreateTransfer(CFAllocatorRef allocator, const_any_p CFBasicHashMakeImmutable(ht); _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFBag (immutable)"); - return (CFHashRef)ht; + return (CFBagRef)ht; } -#if CFDictionary -CFHashRef CFBagCreate(CFAllocatorRef allocator, const_any_pointer_t *klist, const_any_pointer_t *vlist, CFIndex numValues, const CFBagKeyCallBacks *keyCallBacks, const CFBagValueCallBacks *valueCallBacks) { -#endif -#if CFSet || CFBag -CFHashRef CFBagCreate(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIndex numValues, const CFBagKeyCallBacks *keyCallBacks) { - const_any_pointer_t *vlist = klist; - const CFBagValueCallBacks *valueCallBacks = 0; -#endif +CFBagRef CFBagCreate(CFAllocatorRef allocator, const void **klist, CFIndex numValues, const CFBagCallBacks *callbacks) { + const void **vlist = klist; CFTypeID typeID = CFBagGetTypeID(); CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues); - CFBasicHashRef ht = __CFBagCreateGeneric(allocator, keyCallBacks, valueCallBacks, CFDictionary); + CFBasicHashRef ht = __CFBagCreateGeneric(allocator, callbacks); if (!ht) return NULL; if (0 < numValues) CFBasicHashSetCapacity(ht, numValues); for (CFIndex idx = 0; idx < numValues; idx++) { @@ -184,52 +113,39 @@ CFHashRef CFBagCreate(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIn CFBasicHashMakeImmutable(ht); _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFBag (immutable)"); - return (CFHashRef)ht; + return (CFBagRef)ht; } -#if CFDictionary -CFMutableHashRef CFBagCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFBagKeyCallBacks *keyCallBacks, const CFBagValueCallBacks *valueCallBacks) { -#endif -#if CFSet || CFBag -CFMutableHashRef CFBagCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFBagKeyCallBacks *keyCallBacks) { - const CFBagValueCallBacks *valueCallBacks = 0; -#endif +CFMutableBagRef CFBagCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFBagCallBacks *callbacks) { CFTypeID typeID = CFBagGetTypeID(); CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__, capacity); - CFBasicHashRef ht = __CFBagCreateGeneric(allocator, keyCallBacks, valueCallBacks, CFDictionary); + CFBasicHashRef ht = __CFBagCreateGeneric(allocator, callbacks); if (!ht) return NULL; _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFBag (mutable)"); - return (CFMutableHashRef)ht; + return (CFMutableBagRef)ht; } -CFHashRef CFBagCreateCopy(CFAllocatorRef allocator, CFHashRef other) { +CFBagRef CFBagCreateCopy(CFAllocatorRef allocator, CFBagRef other) { CFTypeID typeID = CFBagGetTypeID(); CFAssert1(other, __kCFLogAssertion, "%s(): other CFBag cannot be NULL", __PRETTY_FUNCTION__); __CFGenericValidateType(other, typeID); Boolean markImmutable = false; CFBasicHashRef ht = NULL; if (CF_IS_OBJC(typeID, other)) { -#if CFDictionary || CFSet - ht = (CFBasicHashRef)CF_OBJC_CALLV((id)other, copyWithZone:NULL); -#elif CFBag CFIndex numValues = CFBagGetCount(other); - const_any_pointer_t vbuffer[256]; - const_any_pointer_t *vlist = (numValues <= 256) ? vbuffer : (const_any_pointer_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(const_any_pointer_t), 0); - const_any_pointer_t *klist = vlist; + const void *vbuffer[256]; + Boolean const useStack = numValues <= 256; + const void **vlist = (useStack) ? vbuffer : (const void **)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(const void *), 0); + const void **klist = vlist; CFBagGetValues(other, vlist); - ht = __CFBagCreateGeneric(allocator, & kCFTypeBagKeyCallBacks, CFDictionary ? & kCFTypeBagValueCallBacks : NULL, CFDictionary); + ht = __CFBagCreateGeneric(allocator, &kCFTypeBagCallBacks); if (ht && 0 < numValues) CFBasicHashSetCapacity(ht, numValues); for (CFIndex idx = 0; ht && idx < numValues; idx++) { CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]); } - if (vlist != vbuffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, vlist); + if (!useStack) CFAllocatorDeallocate(kCFAllocatorSystemDefault, vlist); markImmutable = true; -#endif // CFBag - } else if (CF_IS_SWIFT(typeID, other)) { -#if CFDictionary || CFSet - ht = (CFBasicHashRef)CF_SWIFT_CALLV(other, NSObject.copyWithZone, nil); -#endif } else { // non-objc types ht = CFBasicHashCreateCopy(allocator, (CFBasicHashRef)other); markImmutable = true; @@ -238,12 +154,12 @@ CFHashRef CFBagCreateCopy(CFAllocatorRef allocator, CFHashRef other) { CFBasicHashMakeImmutable(ht); _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFBag (immutable)"); - return (CFHashRef)ht; + return (CFBagRef)ht; } - return (CFHashRef)ht; + return (CFBagRef)ht; } -CFMutableHashRef CFBagCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFHashRef other) { +CFMutableBagRef CFBagCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFBagRef other) { CFTypeID typeID = CFBagGetTypeID(); CFAssert1(other, __kCFLogAssertion, "%s(): other CFBag cannot be NULL", __PRETTY_FUNCTION__); __CFGenericValidateType(other, typeID); @@ -251,194 +167,79 @@ CFMutableHashRef CFBagCreateMutableCopy(CFAllocatorRef allocator, CFIndex capaci CFBasicHashRef ht = NULL; if (CF_IS_OBJC(typeID, other) || CF_IS_SWIFT(typeID, other)) { CFIndex numValues = CFBagGetCount(other); - const_any_pointer_t vbuffer[256], kbuffer[256]; - const_any_pointer_t *vlist = (numValues <= 256) ? vbuffer : (const_any_pointer_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(const_any_pointer_t), 0); -#if CFSet || CFBag - const_any_pointer_t *klist = vlist; + const void *vbuffer[256], *kbuffer[256]; + Boolean const useStack = numValues <= 256; + const void **vlist = (useStack) ? vbuffer : (const void **)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(const void *), 0); + const void **klist = vlist; CFBagGetValues(other, vlist); -#endif -#if CFDictionary - const_any_pointer_t *klist = (numValues <= 256) ? kbuffer : (const_any_pointer_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(const_any_pointer_t), 0); - CFDictionaryGetKeysAndValues(other, klist, vlist); -#endif - ht = __CFBagCreateGeneric(allocator, & kCFTypeBagKeyCallBacks, CFDictionary ? & kCFTypeBagValueCallBacks : NULL, CFDictionary); + ht = __CFBagCreateGeneric(allocator, & kCFTypeBagCallBacks); if (ht && 0 < numValues) CFBasicHashSetCapacity(ht, numValues); for (CFIndex idx = 0; ht && idx < numValues; idx++) { CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]); } if (klist != kbuffer && klist != vlist) CFAllocatorDeallocate(kCFAllocatorSystemDefault, klist); - if (vlist != vbuffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, vlist); + if (!useStack) CFAllocatorDeallocate(kCFAllocatorSystemDefault, vlist); } else { ht = CFBasicHashCreateCopy(allocator, (CFBasicHashRef)other); } if (!ht) return NULL; _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFBag (mutable)"); - return (CFMutableHashRef)ht; + return (CFMutableBagRef)ht; } -CFIndex CFBagGetCount(CFHashRef hc) { -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), CFIndex, (CFSwiftRef)hc, NSDictionary.count); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), CFIndex, (NSDictionary *)hc, count); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), CFIndex, (CFSwiftRef)hc, NSSet.count); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), CFIndex, (NSSet *)hc, count); -#endif +CFIndex CFBagGetCount(CFBagRef hc) { __CFGenericValidateType(hc, CFBagGetTypeID()); return CFBasicHashGetCount((CFBasicHashRef)hc); } -#if CFDictionary -CFIndex CFBagGetCountOfKey(CFHashRef hc, const_any_pointer_t key) { -#endif -#if CFSet || CFBag -CFIndex CFBagGetCountOfValue(CFHashRef hc, const_any_pointer_t key) { -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), CFIndex, (CFSwiftRef)hc, NSDictionary.countForKey, key); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), CFIndex, (NSDictionary *)hc, countForKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), CFIndex, (CFSwiftRef)hc, NSSet.countForKey, key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), CFIndex, (NSSet *)hc, countForObject:(id)key); -#endif +CFIndex CFBagGetCountOfValue(CFBagRef hc, const void *key) { __CFGenericValidateType(hc, CFBagGetTypeID()); return CFBasicHashGetCountOfKey((CFBasicHashRef)hc, (uintptr_t)key); } -#if CFDictionary -Boolean CFBagContainsKey(CFHashRef hc, const_any_pointer_t key) { -#endif -#if CFSet || CFBag -Boolean CFBagContainsValue(CFHashRef hc, const_any_pointer_t key) { -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), char, (CFSwiftRef)hc, NSDictionary.containsKey, key); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), char, (NSDictionary *)hc, containsKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), char, (CFSwiftRef)hc, NSSet.containsObject, (CFSwiftRef)key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), char, (NSSet *)hc, containsObject:(id)key); -#endif +Boolean CFBagContainsValue(CFBagRef hc, const void *key) { __CFGenericValidateType(hc, CFBagGetTypeID()); return (0 < CFBasicHashGetCountOfKey((CFBasicHashRef)hc, (uintptr_t)key)); } -const_any_pointer_t CFBagGetValue(CFHashRef hc, const_any_pointer_t key) { -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), const_any_pointer_t, (CFSwiftRef)hc, NSDictionary.objectForKey, key); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), const_any_pointer_t, (NSDictionary *)hc, objectForKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), const_any_pointer_t, (CFSwiftRef)hc, NSSet.member, key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), const_any_pointer_t, (NSSet *)hc, member:(id)key); -#endif +const void *CFBagGetValue(CFBagRef hc, const void *key) { __CFGenericValidateType(hc, CFBagGetTypeID()); CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key); - return (0 < bkt.count ? (const_any_pointer_t)bkt.weak_value : 0); + return (0 < bkt.count ? (const void *)bkt.weak_value : 0); } -Boolean CFBagGetValueIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *value) { -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), Boolean, (CFSwiftRef)hc, NSDictionary.__getValue, value, key); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), Boolean, (NSDictionary *)hc, __getValue:(id *)value forKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), Boolean, (CFSwiftRef)hc, NSSet.__getValue, value, key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), Boolean, (NSSet *)hc, __getValue:(id *)value forObj:(id)key); -#endif +Boolean CFBagGetValueIfPresent(CFBagRef hc, const void *key, const void **value) { __CFGenericValidateType(hc, CFBagGetTypeID()); CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key); if (0 < bkt.count) { if (value) { - *value = (const_any_pointer_t)bkt.weak_value; - } - return true; - } - return false; -} - -#if CFDictionary -CFIndex CFDictionaryGetCountOfValue(CFHashRef hc, const_any_pointer_t value) { - CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), CFIndex, (CFSwiftRef)hc, NSDictionary.count); - CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), CFIndex, (NSDictionary *)hc, countForObject:(id)value); - __CFGenericValidateType(hc, CFBagGetTypeID()); - return CFBasicHashGetCountOfValue((CFBasicHashRef)hc, (uintptr_t)value); -} - -Boolean CFDictionaryContainsValue(CFHashRef hc, const_any_pointer_t value) { - CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), char, (CFSwiftRef)hc, NSDictionary.containsObject, value); - CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), char, (NSDictionary *)hc, containsObject:(id)value); - __CFGenericValidateType(hc, CFBagGetTypeID()); - return (0 < CFBasicHashGetCountOfValue((CFBasicHashRef)hc, (uintptr_t)value)); -} - -CF_EXPORT Boolean CFDictionaryGetKeyIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *actualkey) { - __CFGenericValidateType(hc, CFBagGetTypeID()); - CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key); - if (0 < bkt.count) { - if (actualkey) { - *actualkey = (const_any_pointer_t)bkt.weak_key; + *value = (const void *)bkt.weak_value; } return true; } return false; } -#endif -#if CFDictionary -void CFBagGetKeysAndValues(CFHashRef hc, const_any_pointer_t *keybuf, const_any_pointer_t *valuebuf) { -#endif -#if CFSet || CFBag -void CFBagGetValues(CFHashRef hc, const_any_pointer_t *keybuf) { - const_any_pointer_t *valuebuf = 0; -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), void, (CFSwiftRef)hc, NSDictionary.getObjects, valuebuf, keybuf); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated" - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSDictionary *)hc, getObjects:(id *)valuebuf andKeys:(id *)keybuf); -#pragma GCC diagnostic pop -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), void, (CFSwiftRef)hc, NSSet.getObjects, keybuf); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSSet *)hc, getObjects:(id *)keybuf); -#endif +void CFBagGetValues(CFBagRef hc, const void **keybuf) { + const void **valuebuf = 0; __CFGenericValidateType(hc, CFBagGetTypeID()); CFBasicHashGetElements((CFBasicHashRef)hc, CFBagGetCount(hc), (uintptr_t *)valuebuf, (uintptr_t *)keybuf); } -void CFBagApplyFunction(CFHashRef hc, CFBagApplierFunction applier, any_pointer_t context) { +void CFBagApplyFunction(CFBagRef hc, CFBagApplierFunction applier, void *context) { FAULT_CALLBACK((void **)&(applier)); -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), void, (CFSwiftRef)hc, NSDictionary.__apply, applier, context); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSDictionary *)hc, __apply:(void (*)(const void *, const void *, void *))applier context:(void *)context); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), void, (CFSwiftRef)hc, NSSet.__apply, applier, context); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSSet *)hc, __applyValues:(void (*)(const void *, void *))applier context:(void *)context); -#endif __CFGenericValidateType(hc, CFBagGetTypeID()); CFBasicHashApply((CFBasicHashRef)hc, ^(CFBasicHashBucket bkt) { -#if CFDictionary - INVOKE_CALLBACK3(applier, (const_any_pointer_t)bkt.weak_key, (const_any_pointer_t)bkt.weak_value, context); -#endif -#if CFSet - INVOKE_CALLBACK2(applier, (const_any_pointer_t)bkt.weak_value, context); -#endif -#if CFBag - for (CFIndex cnt = bkt.count; cnt--;) { - INVOKE_CALLBACK2(applier, (const_any_pointer_t)bkt.weak_value, context); - } -#endif - return (Boolean)true; - }); + for (CFIndex cnt = bkt.count; cnt--;) { + INVOKE_CALLBACK2(applier, (const void *)bkt.weak_value, context); + } + return (Boolean)true; + }); } // This function is for Foundation's benefit; no one else should use it. -CF_EXPORT unsigned long _CFBagFastEnumeration(CFHashRef hc, struct __objcFastEnumerationStateEquivalent *state, void *stackbuffer, unsigned long count) { +CF_EXPORT unsigned long _CFBagFastEnumeration(CFBagRef hc, struct __objcFastEnumerationStateEquivalent *state, void *stackbuffer, unsigned long count) { if (CF_IS_SWIFT(CFBagGetTypeID(), hc)) return 0; if (CF_IS_OBJC(CFBagGetTypeID(), hc)) return 0; __CFGenericValidateType(hc, CFBagGetTypeID()); @@ -446,7 +247,7 @@ CF_EXPORT unsigned long _CFBagFastEnumeration(CFHashRef hc, struct __objcFastEnu } // This function is for Foundation's benefit; no one else should use it. -CF_EXPORT Boolean _CFBagIsMutable(CFHashRef hc) { +CF_EXPORT Boolean _CFBagIsMutable(CFBagRef hc) { if (CF_IS_SWIFT(CFBagGetTypeID(), hc)) return false; if (CF_IS_OBJC(CFBagGetTypeID(), hc)) return false; __CFGenericValidateType(hc, CFBagGetTypeID()); @@ -454,7 +255,7 @@ CF_EXPORT Boolean _CFBagIsMutable(CFHashRef hc) { } // This function is for Foundation's benefit; no one else should use it. -CF_EXPORT void _CFBagSetCapacity(CFMutableHashRef hc, CFIndex cap) { +CF_EXPORT void _CFBagSetCapacity(CFMutableBagRef hc, CFIndex cap) { if (CF_IS_SWIFT(CFBagGetTypeID(), hc)) return; if (CF_IS_OBJC(CFBagGetTypeID(), hc)) return; __CFGenericValidateType(hc, CFBagGetTypeID()); @@ -463,148 +264,50 @@ CF_EXPORT void _CFBagSetCapacity(CFMutableHashRef hc, CFIndex cap) { CFBasicHashSetCapacity((CFBasicHashRef)hc, cap); } -CF_INLINE CFIndex __CFBagGetKVOBit(CFHashRef hc) { - return __CFRuntimeGetFlag(hc, 0); -} - -CF_INLINE void __CFBagSetKVOBit(CFHashRef hc, CFIndex bit) { - __CFRuntimeSetFlag(hc, 0, ((uintptr_t)bit & 0x1)); -} - -// This function is for Foundation's benefit; no one else should use it. -CF_EXPORT CFIndex _CFBagGetKVOBit(CFHashRef hc) { - return __CFBagGetKVOBit(hc); -} - -// This function is for Foundation's benefit; no one else should use it. -CF_EXPORT void _CFBagSetKVOBit(CFHashRef hc, CFIndex bit) { - __CFBagSetKVOBit(hc, bit); -} - - -#if !defined(CF_OBJC_KVO_WILLCHANGE) -#define CF_OBJC_KVO_WILLCHANGE(obj, key) -#define CF_OBJC_KVO_DIDCHANGE(obj, key) -#define CF_OBJC_KVO_WILLCHANGEALL(obj) -#define CF_OBJC_KVO_DIDCHANGEALL(obj) -#endif - -#if CFDictionary -void CFBagAddValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) { -#endif -#if CFSet || CFBag -void CFBagAddValue(CFMutableHashRef hc, const_any_pointer_t key) { - const_any_pointer_t value = key; -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.__addObject, key, value); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableDictionary *)hc, __addObject:(id)value forKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.addObject, (CFSwiftRef)key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableSet *)hc, addObject:(id)key); -#endif +void CFBagAddValue(CFMutableBagRef hc, const void *key) { + const void *value = key; __CFGenericValidateType(hc, CFBagGetTypeID()); CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc); if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) { CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__, hc); } - CF_OBJC_KVO_WILLCHANGE(hc, key); CFBasicHashAddValue((CFBasicHashRef)hc, (uintptr_t)key, (uintptr_t)value); - CF_OBJC_KVO_DIDCHANGE(hc, key); } -#if CFDictionary -void CFBagReplaceValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) { -#endif -#if CFSet || CFBag -void CFBagReplaceValue(CFMutableHashRef hc, const_any_pointer_t key) { - const_any_pointer_t value = key; -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.replaceObject, key, value); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableDictionary *)hc, replaceObject:(id)value forKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.replaceObject, (CFSwiftRef)key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableSet *)hc, replaceObject:(id)key); -#endif +void CFBagReplaceValue(CFMutableBagRef hc, const void *key) { + const void *value = key; __CFGenericValidateType(hc, CFBagGetTypeID()); CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc); if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) { CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__, hc); } - CF_OBJC_KVO_WILLCHANGE(hc, key); CFBasicHashReplaceValue((CFBasicHashRef)hc, (uintptr_t)key, (uintptr_t)value); - CF_OBJC_KVO_DIDCHANGE(hc, key); } -#if CFDictionary -void CFBagSetValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) { -#endif -#if CFSet || CFBag -void CFBagSetValue(CFMutableHashRef hc, const_any_pointer_t key) { - const_any_pointer_t value = key; -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.__setObject, key, value); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableDictionary *)hc, __setObject:(id)value forKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.setObject, (CFSwiftRef)key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableSet *)hc, setObject:(id)key); -#endif +void CFBagSetValue(CFMutableBagRef hc, const void *key) { + const void *value = key; __CFGenericValidateType(hc, CFBagGetTypeID()); CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc); if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) { CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__, hc); } - CF_OBJC_KVO_WILLCHANGE(hc, key); -//#warning this for a dictionary used to not replace the key CFBasicHashSetValue((CFBasicHashRef)hc, (uintptr_t)key, (uintptr_t)value); - CF_OBJC_KVO_DIDCHANGE(hc, key); } -void CFBagRemoveValue(CFMutableHashRef hc, const_any_pointer_t key) { -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.removeObjectForKey, key); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableDictionary *)hc, removeObjectForKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.removeObject, (CFSwiftRef)key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableSet *)hc, removeObject:(id)key); -#endif +void CFBagRemoveValue(CFMutableBagRef hc, const void *key) { __CFGenericValidateType(hc, CFBagGetTypeID()); CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc); if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) { CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__, hc); } - CF_OBJC_KVO_WILLCHANGE(hc, key); CFBasicHashRemoveValue((CFBasicHashRef)hc, (uintptr_t)key); - CF_OBJC_KVO_DIDCHANGE(hc, key); } -void CFBagRemoveAllValues(CFMutableHashRef hc) { -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.removeAllObjects); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableDictionary *)hc, removeAllObjects); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.removeAllObjects); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableSet *)hc, removeAllObjects); -#endif +void CFBagRemoveAllValues(CFMutableBagRef hc) { __CFGenericValidateType(hc, CFBagGetTypeID()); CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc); if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) { CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__, hc); } - CF_OBJC_KVO_WILLCHANGEALL(hc); CFBasicHashRemoveAllValues((CFBasicHashRef)hc); - CF_OBJC_KVO_DIDCHANGEALL(hc); } - -#undef CF_OBJC_KVO_WILLCHANGE -#undef CF_OBJC_KVO_DIDCHANGE -#undef CF_OBJC_KVO_WILLCHANGEALL -#undef CF_OBJC_KVO_DIDCHANGEALL - diff --git a/CoreFoundation/Collections.subproj/CFBag.h b/CoreFoundation/Collections.subproj/CFBag.h index f562e71e00..e5337439d6 100644 --- a/CoreFoundation/Collections.subproj/CFBag.h +++ b/CoreFoundation/Collections.subproj/CFBag.h @@ -1,7 +1,7 @@ /* CFBag.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Collections.subproj/CFBasicHash.c b/CoreFoundation/Collections.subproj/CFBasicHash.c index 806a4a786a..532be974b6 100644 --- a/CoreFoundation/Collections.subproj/CFBasicHash.c +++ b/CoreFoundation/Collections.subproj/CFBasicHash.c @@ -1,11 +1,11 @@ /* CFBasicHash.m - Copyright (c) 2008-2018, Apple Inc. and the Swift project authors + Copyright (c) 2008-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Christopher Kane + Responsibility: Michael LeHew */ #include "CFBasicHash.h" @@ -18,6 +18,7 @@ #if __HAS_DISPATCH__ #include #endif +#include "CFInternal.h" #include "CFOverflow.h" #if TARGET_OS_MAC @@ -272,6 +273,24 @@ CF_INLINE void *__CFBasicHashAllocateMemory2(CFAllocatorRef allocator, CFIndex c return CFAllocatorAllocate(allocator, memorySize, 0); } +CF_INLINE void *__CFBasicHashAllocateMemoryCleared(CFConstBasicHashRef ht, CFIndex count, CFIndex elem_size, Boolean strong, Boolean compactablem) { + CFIndex memorySize; + if (os_mul_overflow(count, elem_size, &memorySize)) { + HALT_MSG("overflow while growing CFBasicHash"); + } + CFAllocatorRef allocator = CFGetAllocator(ht); + void *new_mem = NULL; + if (__CFAllocatorRespectsHintZeroWhenAllocating(allocator)) { + new_mem = CFAllocatorAllocate(allocator, memorySize, _CFAllocatorHintZeroWhenAllocating); + if (!new_mem) { HALT; } + } else { + new_mem = CFAllocatorAllocate(allocator, memorySize, 0); + if (!new_mem) { HALT; } + memset(new_mem, 0, memorySize); + } + return new_mem; +} + #define __CFBasicHashSubABZero 0xa7baadb1 #define __CFBasicHashSubABOne 0xa5baadb9 @@ -856,8 +875,6 @@ CF_INLINE CFBasicHashBucket __CFBasicHashFindBucket(CFConstBasicHashRef ht, uint } } HALT; - CFBasicHashBucket result = {kCFNotFound, 0UL, 0UL, 0}; - return result; } CF_INLINE CFIndex __CFBasicHashFindBucket_NoCollision(CFConstBasicHashRef ht, uintptr_t stack_key, uintptr_t key_hash) { @@ -1125,27 +1142,19 @@ static void __CFBasicHashRehash(CFBasicHashRef ht, CFIndex newItemCount) { uintptr_t *new_hashes = NULL; if (0 < new_num_buckets) { - new_values = (CFBasicHashValue *)__CFBasicHashAllocateMemory(ht, new_num_buckets, sizeof(CFBasicHashValue), CFBasicHashHasStrongValues(ht), 0); - if (!new_values) HALT; + new_values = (CFBasicHashValue *)__CFBasicHashAllocateMemoryCleared(ht, new_num_buckets, sizeof(CFBasicHashValue), CFBasicHashHasStrongValues(ht), false); __SetLastAllocationEventName(new_values, "CFBasicHash (value-store)"); - memset(new_values, 0, new_num_buckets * sizeof(CFBasicHashValue)); if (ht->bits.keys_offset) { - new_keys = (CFBasicHashValue *)__CFBasicHashAllocateMemory(ht, new_num_buckets, sizeof(CFBasicHashValue), CFBasicHashHasStrongKeys(ht), 0); - if (!new_keys) HALT; + new_keys = (CFBasicHashValue *)__CFBasicHashAllocateMemoryCleared(ht, new_num_buckets, sizeof(CFBasicHashValue), CFBasicHashHasStrongKeys(ht), false); __SetLastAllocationEventName(new_keys, "CFBasicHash (key-store)"); - memset(new_keys, 0, new_num_buckets * sizeof(CFBasicHashValue)); } if (ht->bits.counts_offset) { - new_counts = (uintptr_t *)__CFBasicHashAllocateMemory(ht, new_num_buckets, (1 << ht->bits.counts_width), false, false); - if (!new_counts) HALT; + new_counts = (uintptr_t *)__CFBasicHashAllocateMemoryCleared(ht, new_num_buckets, (1 << ht->bits.counts_width), false, false); __SetLastAllocationEventName(new_counts, "CFBasicHash (count-store)"); - memset(new_counts, 0, new_num_buckets * (1 << ht->bits.counts_width)); } if (__CFBasicHashHasHashCache(ht)) { - new_hashes = (uintptr_t *)__CFBasicHashAllocateMemory(ht, new_num_buckets, sizeof(uintptr_t), false, false); - if (!new_hashes) HALT; + new_hashes = (uintptr_t *)__CFBasicHashAllocateMemoryCleared(ht, new_num_buckets, sizeof(uintptr_t), false, false); __SetLastAllocationEventName(new_hashes, "CFBasicHash (hash-store)"); - memset(new_hashes, 0, new_num_buckets * sizeof(uintptr_t)); } } @@ -1178,7 +1187,8 @@ static void __CFBasicHashRehash(CFBasicHashRef ht, CFIndex newItemCount) { if (__CFBasicHashSubABZero == stack_value) stack_value = 0UL; if (__CFBasicHashSubABOne == stack_value) stack_value = ~0UL; uintptr_t stack_key = stack_value; - if (ht->bits.keys_offset) { + // old keys will only be non-null if ht->bits.keys_offset is set (see above) + if (old_keys) { stack_key = old_keys[idx].neutral; if (__CFBasicHashSubABZero == stack_key) stack_key = 0UL; if (__CFBasicHashSubABOne == stack_key) stack_key = ~0UL; @@ -1442,7 +1452,6 @@ CF_PRIVATE size_t CFBasicHashGetSize(CFConstBasicHashRef ht, Boolean total) { if (ht->bits.keys_offset) size += sizeof(CFBasicHashValue *); if (ht->bits.counts_offset) size += sizeof(void *); if (__CFBasicHashHasHashCache(ht)) size += sizeof(uintptr_t *); -#if ENABLE_MEMORY_COUNTERS || ENABLE_DTRACE_PROBES if (total) { CFIndex num_buckets = __CFBasicHashTableSizes[ht->bits.num_buckets_idx]; if (0 < num_buckets) { @@ -1452,9 +1461,6 @@ CF_PRIVATE size_t CFBasicHashGetSize(CFConstBasicHashRef ht, Boolean total) { if (__CFBasicHashHasHashCache(ht)) size += malloc_size(__CFBasicHashGetHashes(ht)); } } -#else - (void)total; -#endif return size; } @@ -1561,20 +1567,32 @@ CF_PRIVATE CFBasicHashRef CFBasicHashCreate(CFAllocatorRef allocator, CFOptionFl CFBasicHashRef ht = (CFBasicHashRef)_CFRuntimeCreateInstance(allocator, CFBasicHashGetTypeID(), size, NULL); if (NULL == ht) return NULL; - ht->bits.finalized = 0; ht->bits.hash_style = (flags >> 13) & 0x3; - ht->bits.fast_grow = (flags & kCFBasicHashAggressiveGrowth) ? 1 : 0; - ht->bits.counts_width = 0; - ht->bits.strong_values = (flags & kCFBasicHashStrongValues) ? 1 : 0; - ht->bits.strong_keys = (flags & kCFBasicHashStrongKeys) ? 1 : 0; - ht->bits.weak_values = (flags & kCFBasicHashWeakValues) ? 1 : 0; - ht->bits.weak_keys = (flags & kCFBasicHashWeakKeys) ? 1 : 0; - ht->bits.int_values = (flags & kCFBasicHashIntegerValues) ? 1 : 0; - ht->bits.int_keys = (flags & kCFBasicHashIntegerKeys) ? 1 : 0; - ht->bits.indirect_keys = (flags & kCFBasicHashIndirectKeys) ? 1 : 0; - ht->bits.num_buckets_idx = 0; - ht->bits.used_buckets = 0; - ht->bits.deleted = 0; + + if (flags & kCFBasicHashAggressiveGrowth) { + ht->bits.fast_grow = 1; + } + if (flags & kCFBasicHashStrongValues) { + ht->bits.strong_values = 1; + } + if (flags & kCFBasicHashStrongKeys) { + ht->bits.strong_keys = 1; + } + if (flags & kCFBasicHashWeakValues) { + ht->bits.weak_values = 1; + } + if (flags & kCFBasicHashWeakKeys) { + ht->bits.weak_keys = 1; + } + if (flags & kCFBasicHashIntegerValues) { + ht->bits.int_values = 1; + } + if (flags & kCFBasicHashIntegerKeys) { + ht->bits.int_keys = 1; + } + if (flags & kCFBasicHashIndirectKeys) { + ht->bits.indirect_keys = 1; + } ht->bits.mutations = 1; if (ht->bits.strong_values && ht->bits.weak_values) HALT; @@ -1588,17 +1606,15 @@ CF_PRIVATE CFBasicHashRef CFBasicHashCreate(CFAllocatorRef allocator, CFOptionFl if (ht->bits.indirect_keys && ht->bits.int_keys) HALT; uint64_t offset = 1; - ht->bits.keys_offset = (flags & kCFBasicHashHasKeys) ? offset++ : 0; - ht->bits.counts_offset = (flags & kCFBasicHashHasCounts) ? offset++ : 0; - ht->bits.hashes_offset = (flags & kCFBasicHashHasHashCache) ? offset++ : 0; - -#if TARGET_OS_IPHONE - ht->bits.hashes_offset = 0; - ht->bits.strong_values = 0; - ht->bits.strong_keys = 0; - ht->bits.weak_values = 0; - ht->bits.weak_keys = 0; -#endif + if (flags & kCFBasicHashHasKeys) { + ht->bits.keys_offset = offset++; + } + if (flags & kCFBasicHashHasCounts) { + ht->bits.counts_offset = offset++; + } + if (flags & kCFBasicHashHasHashCache) { + ht->bits.hashes_offset = offset++; + } ht->bits.__kret = CFBasicHashGetPtrIndex((void *)cb->retainKey); ht->bits.__vret = CFBasicHashGetPtrIndex((void *)cb->retainValue); @@ -1611,10 +1627,6 @@ CF_PRIVATE CFBasicHashRef CFBasicHashCreate(CFAllocatorRef allocator, CFOptionFl ht->bits.__khas = CFBasicHashGetPtrIndex((void *)cb->hashKey); ht->bits.__kget = CFBasicHashGetPtrIndex((void *)cb->getIndirectKey); - for (CFIndex idx = 0; idx < offset; idx++) { - ht->pointers[idx] = NULL; - } - #if ENABLE_MEMORY_COUNTERS int64_t size_now = OSAtomicAdd64Barrier((int64_t) CFBasicHashGetSize(ht, true), & __CFBasicHashTotalSize); while (__CFBasicHashPeakSize < size_now && !OSAtomicCompareAndSwap64Barrier(__CFBasicHashPeakSize, size_now, & __CFBasicHashPeakSize)); @@ -1720,8 +1732,8 @@ CF_PRIVATE CFBasicHashRef CFBasicHashCreateCopy(CFAllocatorRef allocator, CFCons } } } - if (new_counts) memmove(new_counts, old_counts, new_num_buckets * (1 << ht->bits.counts_width)); - if (new_hashes) memmove(new_hashes, old_hashes, new_num_buckets * sizeof(uintptr_t)); + if (new_counts && old_counts) memmove(new_counts, old_counts, new_num_buckets * (1 << ht->bits.counts_width)); + if (new_hashes && old_hashes) memmove(new_hashes, old_hashes, new_num_buckets * sizeof(uintptr_t)); #if ENABLE_MEMORY_COUNTERS int64_t size_now = OSAtomicAdd64Barrier((int64_t) CFBasicHashGetSize(ht, true), & __CFBasicHashTotalSize); diff --git a/CoreFoundation/Collections.subproj/CFBasicHash.h b/CoreFoundation/Collections.subproj/CFBasicHash.h index e2648fb128..43083bcbf4 100644 --- a/CoreFoundation/Collections.subproj/CFBasicHash.h +++ b/CoreFoundation/Collections.subproj/CFBasicHash.h @@ -1,7 +1,7 @@ /* CFBasicHash.h - Copyright (c) 2008-2018, Apple Inc. and the Swift project authors + Copyright (c) 2008-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Collections.subproj/CFBasicHashFindBucket.m b/CoreFoundation/Collections.subproj/CFBasicHashFindBucket.m index b85f3bd727..a01de4a6e5 100644 --- a/CoreFoundation/Collections.subproj/CFBasicHashFindBucket.m +++ b/CoreFoundation/Collections.subproj/CFBasicHashFindBucket.m @@ -1,11 +1,11 @@ /* CFBasicHashFindBucket.m - Copyright (c) 2009-2018, Apple Inc. and the Swift project authors + Copyright (c) 2009-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Christopher Kane + Responsibility: Michael LeHew */ diff --git a/CoreFoundation/Collections.subproj/CFBinaryHeap.c b/CoreFoundation/Collections.subproj/CFBinaryHeap.c index 1ec0c325a4..3b498d82a1 100644 --- a/CoreFoundation/Collections.subproj/CFBinaryHeap.c +++ b/CoreFoundation/Collections.subproj/CFBinaryHeap.c @@ -1,11 +1,11 @@ /* CFBinaryHeap.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Christopher Kane + Responsibility: Michael LeHew */ #include @@ -133,6 +133,7 @@ static CFStringRef __CFBinaryHeapCopyDescription(CFTypeRef cf) { list = (cnt <= 128) ? (const void **)buffer : (const void **)CFAllocatorAllocate(kCFAllocatorSystemDefault, cnt * sizeof(void *), 0); if (__CFOASafe && list != buffer) __CFSetLastAllocationEventName(list, "CFBinaryHeap (temp)"); CFBinaryHeapGetValues(heap, list); + _CLANG_ANALYZER_IGNORE_UNINITIALIZED_BUFFER(list, cnt * sizeof(void *)); // The analyzer doesn't understand that the 'cnt' values in both this function and CFBinaryHeapGetValues are identical. for (idx = 0; idx < cnt; idx++) { CFStringRef desc = NULL; const void *item = list[idx]; @@ -178,7 +179,7 @@ CFTypeID CFBinaryHeapGetTypeID(void) { return _kCFRuntimeIDCFBinaryHeap; } -static CFBinaryHeapRef __CFBinaryHeapInit(CFAllocatorRef allocator, UInt32 flags, CFIndex capacity, const void **values, CFIndex numValues, const CFBinaryHeapCallBacks *callBacks, const CFBinaryHeapCompareContext *compareContext) { +static CFBinaryHeapRef __CFBinaryHeapCreateInit(CFAllocatorRef allocator, UInt32 flags, CFIndex capacity, const void **values, CFIndex numValues, const CFBinaryHeapCallBacks *callBacks, const CFBinaryHeapCompareContext *compareContext) { CFBinaryHeapRef memory; CFIndex idx; CFIndex size; @@ -200,18 +201,11 @@ static CFBinaryHeapRef __CFBinaryHeapInit(CFAllocatorRef allocator, UInt32 flags CFRelease(memory); return NULL; } - __CFBinaryHeapSetNumBucketsUsed(memory, 0); - __CFBinaryHeapSetCount(memory, 0); if (NULL != callBacks) { memory->_callbacks.retain = callBacks->retain; memory->_callbacks.release = callBacks->release; memory->_callbacks.copyDescription = callBacks->copyDescription; memory->_callbacks.compare = callBacks->compare; - } else { - memory->_callbacks.retain = 0; - memory->_callbacks.release = 0; - memory->_callbacks.copyDescription = 0; - memory->_callbacks.compare = 0; } if (compareContext) memcpy(&memory->_context, compareContext, sizeof(CFBinaryHeapCompareContext)); // CF: retain info for proper operation @@ -224,12 +218,12 @@ static CFBinaryHeapRef __CFBinaryHeapInit(CFAllocatorRef allocator, UInt32 flags } CFBinaryHeapRef CFBinaryHeapCreate(CFAllocatorRef allocator, CFIndex capacity, const CFBinaryHeapCallBacks *callBacks, const CFBinaryHeapCompareContext *compareContext) { - return __CFBinaryHeapInit(allocator, kCFBinaryHeapMutable, capacity, NULL, 0, callBacks, compareContext); + return __CFBinaryHeapCreateInit(allocator, kCFBinaryHeapMutable, capacity, NULL, 0, callBacks, compareContext); } CFBinaryHeapRef CFBinaryHeapCreateCopy(CFAllocatorRef allocator, CFIndex capacity, CFBinaryHeapRef heap) { __CFGenericValidateType(heap, CFBinaryHeapGetTypeID()); - return __CFBinaryHeapInit(allocator, kCFBinaryHeapMutable, capacity, (const void **)heap->_buckets, __CFBinaryHeapCount(heap), &(heap->_callbacks), &(heap->_context)); + return __CFBinaryHeapCreateInit(allocator, kCFBinaryHeapMutable, capacity, (const void **)heap->_buckets, __CFBinaryHeapCount(heap), &(heap->_callbacks), &(heap->_context)); } CFIndex CFBinaryHeapGetCount(CFBinaryHeapRef heap) { diff --git a/CoreFoundation/Collections.subproj/CFBinaryHeap.h b/CoreFoundation/Collections.subproj/CFBinaryHeap.h index 8583735079..23cf01a498 100644 --- a/CoreFoundation/Collections.subproj/CFBinaryHeap.h +++ b/CoreFoundation/Collections.subproj/CFBinaryHeap.h @@ -1,7 +1,7 @@ /* CFBinaryHeap.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Collections.subproj/CFBitVector.c b/CoreFoundation/Collections.subproj/CFBitVector.c index 6a82cccca5..3ec3ff1701 100644 --- a/CoreFoundation/Collections.subproj/CFBitVector.c +++ b/CoreFoundation/Collections.subproj/CFBitVector.c @@ -1,11 +1,11 @@ /* CFBitVector.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Christopher Kane + Responsibility: Michael LeHew */ #include diff --git a/CoreFoundation/Collections.subproj/CFBitVector.h b/CoreFoundation/Collections.subproj/CFBitVector.h index 5eb49915f6..86ec08b9a6 100644 --- a/CoreFoundation/Collections.subproj/CFBitVector.h +++ b/CoreFoundation/Collections.subproj/CFBitVector.h @@ -1,7 +1,7 @@ /* CFBitVector.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Collections.subproj/CFCollections_Internal.h b/CoreFoundation/Collections.subproj/CFCollections_Internal.h index 12780ace1d..0d85c44ee4 100644 --- a/CoreFoundation/Collections.subproj/CFCollections_Internal.h +++ b/CoreFoundation/Collections.subproj/CFCollections_Internal.h @@ -1,7 +1,7 @@ /* CFCollections_Internal.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Collections.subproj/CFData.c b/CoreFoundation/Collections.subproj/CFData.c index 2a8ab9095b..46f8a55756 100644 --- a/CoreFoundation/Collections.subproj/CFData.c +++ b/CoreFoundation/Collections.subproj/CFData.c @@ -1,7 +1,7 @@ /* CFData.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -152,7 +152,7 @@ CF_INLINE CFIndex __CFDataLength(CFDataRef data) { } CF_INLINE void __CFDataSetLength(CFMutableDataRef data, CFIndex v) { - /* for a CFData, _bytesUsed == _length */ + data->_length = v; } CF_INLINE CFIndex __CFDataCapacity(CFDataRef data) { @@ -160,18 +160,6 @@ CF_INLINE CFIndex __CFDataCapacity(CFDataRef data) { } CF_INLINE void __CFDataSetCapacity(CFMutableDataRef data, CFIndex v) { - /* for a CFData, _bytesNum == _capacity */ -} - -CF_INLINE void __CFDataSetNumBytesUsed(CFMutableDataRef data, CFIndex v) { - data->_length = v; -} - -CF_INLINE CFIndex __CFDataNumBytes(CFDataRef data) { - return data->_capacity; -} - -CF_INLINE void __CFDataSetNumBytes(CFMutableDataRef data, CFIndex v) { data->_capacity = v; } @@ -202,22 +190,16 @@ CF_INLINE CFIndex __CFDataRoundUpCapacity(CFIndex capacity) { } } -CF_INLINE CFIndex __CFDataNumBytesForCapacity(CFIndex capacity) { - return capacity; -} - -static void __CFDataHandleOutOfMemory(CFTypeRef obj, CFIndex numBytes) { +__attribute__((cold)) +static void __CFDataHandleOutOfMemory(CFTypeRef obj, CFIndex numBytes) CLANG_ANALYZER_NORETURN { CFStringRef msg; if(0 < numBytes && numBytes <= CFDATA_MAX_SIZE) { msg = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("Attempt to allocate %ld bytes for NS/CFData failed"), numBytes); } else { msg = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("Attempt to allocate %ld bytes for NS/CFData failed. Maximum size: %lld"), numBytes, CFDATA_MAX_SIZE); } - { - CFLog(kCFLogLevelCritical, CFSTR("%@"), msg); - HALT; - } - CFRelease(msg); + CFLog(kCFLogLevelCritical, CFSTR("%@"), msg); + HALT; } #if defined(DEBUG) @@ -346,29 +328,25 @@ void _CFDataInit(CFMutableDataRef memory, CFOptionFlags variety, CFIndex capacit Boolean isGrowable = ((variety & __kCFGrowableMask) != 0); Boolean isDontDeallocate = ((variety & __kCFDontDeallocate) != 0); - __CFDataSetNumBytesUsed(memory, 0); __CFDataSetLength(memory, 0); __CFDataSetDontDeallocate(memory, isDontDeallocate); if (isMutable && isGrowable) { __CFDataSetCapacity(memory, __CFDataRoundUpCapacity(1)); - __CFDataSetNumBytes(memory, __CFDataNumBytesForCapacity(__CFDataRoundUpCapacity(1))); __CFSetMutableVariety(memory, kCFMutable); } else { /* Don't round up capacity */ __CFDataSetCapacity(memory, capacity); - __CFDataSetNumBytes(memory, __CFDataNumBytesForCapacity(capacity)); __CFSetMutableVariety(memory, kCFFixedMutable); } if (noCopy) { memory->_bytes = (uint8_t *)bytes; - __CFDataSetNumBytesUsed(memory, length); __CFDataSetLength(memory, length); // Mutable no-copy datas are not allowed, so don't bother setting needsToZero flag. } else { Boolean cleared = (isMutable && !isGrowable && !_CFExecutableLinkedOnOrAfter(CFSystemVersionSnowLeopard)); // assume that allocators give 16-byte aligned memory back -- it is their responsibility - memory->_bytes = __CFDataAllocate(memory, __CFDataNumBytes(memory) * sizeof(uint8_t), cleared); + memory->_bytes = __CFDataAllocate(memory, __CFDataCapacity(memory) * sizeof(uint8_t), cleared); if (__CFOASafe) __CFSetLastAllocationEventName(memory->_bytes, "CFData (store)"); if (NULL == memory->_bytes) { return; @@ -403,7 +381,7 @@ static CFMutableDataRef __CFDataInit(CFAllocatorRef allocator, _CFDataMutableVar CFIndex size = sizeof(struct __CFData) - sizeof(CFRuntimeBase); if (allocateInline) { - size += sizeof(uint8_t) * __CFDataNumBytesForCapacity(capacity) + sizeof(uint8_t) * 15; // for 16-byte alignment fixup + size += sizeof(uint8_t) * capacity + sizeof(uint8_t) * 15; // for 16-byte alignment fixup } memory = (CFMutableDataRef)_CFRuntimeCreateInstance(allocator, CFDataGetTypeID(), size, NULL); if (NULL == memory) { @@ -412,32 +390,31 @@ static CFMutableDataRef __CFDataInit(CFAllocatorRef allocator, _CFDataMutableVar #if DEPLOYMENT_RUNTIME_SWIFT memory->_deallocHandler = NULL; #endif - __CFDataSetNumBytesUsed(memory, 0); __CFDataSetLength(memory, 0); __CFDataSetInline(memory, allocateInline); __CFDataSetUseAllocator(memory, useAllocator); - + if (isMutable && isGrowable) { __CFDataSetCapacity(memory, __CFDataRoundUpCapacity(1)); - __CFDataSetNumBytes(memory, __CFDataNumBytesForCapacity(__CFDataRoundUpCapacity(1))); - __CFSetMutableVariety(memory, kCFMutable); + __CFSetMutableVariety(memory, kCFMutable); } else { - /* Don't round up capacity */ + // Don't round up capacity __CFDataSetCapacity(memory, capacity); - __CFDataSetNumBytes(memory, __CFDataNumBytesForCapacity(capacity)); - __CFSetMutableVariety(memory, kCFFixedMutable); + + // Immutable datas are temporarily set to "fixed mutable" since we pass it to CFDataReplaceBytes() to copy in the initial bytes. + __CFSetMutableVariety(memory, kCFFixedMutable); } + if (noCopy) { - *((void **)&memory->_bytes) = (uint8_t *)bytes; + memory->_bytes = (uint8_t *)bytes; memory->_bytesDeallocator = (CFAllocatorRef)CFRetain(bytesDeallocator); - __CFDataSetNumBytesUsed(memory, length); __CFDataSetLength(memory, length); // Mutable no-copy datas are not allowed, so don't bother setting needsToZero flag. } else { Boolean cleared = (isMutable && !isGrowable && !_CFExecutableLinkedOnOrAfter(CFSystemVersionSnowLeopard)); if (!allocateInline) { // assume that allocators give 16-byte aligned memory back -- it is their responsibility - *((void **)&memory->_bytes) = __CFDataAllocate(memory, __CFDataNumBytes(memory) * sizeof(uint8_t), cleared); + memory->_bytes = __CFDataAllocate(memory, __CFDataCapacity(memory) * sizeof(uint8_t), cleared); if (__CFOASafe) __CFSetLastAllocationEventName(memory->_bytes, "CFData (store)"); if (NULL == memory->_bytes) { CFRelease(memory); @@ -456,7 +433,11 @@ static CFMutableDataRef __CFDataInit(CFAllocatorRef allocator, _CFDataMutableVar memory->_bytesDeallocator = NULL; CFDataReplaceBytes(memory, CFRangeMake(0, 0), bytes, length); } - __CFSetMutableVariety(memory, variety); + + // Ensure immutable datas get marked as such now. + if (!isMutable) { + __CFSetMutableVariety(memory, kCFImmutable); + } return memory; } @@ -474,7 +455,7 @@ CFDataRef CFDataCreateCopy(CFAllocatorRef allocator, CFDataRef data) { Boolean allowRetain = true; if (allowRetain) { CF_OBJC_FUNCDISPATCHV(CFDataGetTypeID(), CFDataRef, (NSData *)data, copy); - CF_SWIFT_NSDATA_FUNCDISPATCHV(CFDataGetTypeID(), CFDataRef, (CFSwiftRef)data, NSData.copy); + CF_SWIFT_NSDATA_FUNCDISPATCHV(CFDataGetTypeID(), CFDataRef, data, NSData.copy); // If the data isn't mutable... if (!__CFDataIsMutable(data)) { @@ -551,14 +532,13 @@ static void __CFDataGrow(CFMutableDataRef data, CFIndex numNewValues, Boolean cl CFIndex newLength = oldLength + numNewValues; if (newLength > CFDATA_MAX_SIZE || newLength < 0) __CFDataHandleOutOfMemory(data, newLength * sizeof(uint8_t)); CFIndex capacity = __CFDataRoundUpCapacity(newLength); - CFIndex numBytes = __CFDataNumBytesForCapacity(capacity); CFAllocatorRef allocator = CFGetAllocator(data); void *bytes = NULL; void *oldBytes = data->_bytes; - Boolean allocateCleared = clear && __CFDataShouldAllocateCleared(data, numBytes); + Boolean allocateCleared = clear && __CFDataShouldAllocateCleared(data, capacity); if (allocateCleared && !__CFDataUseAllocator(data) && (oldLength == 0 || (newLength / oldLength) > 4)) { // If the length that needs to be zeroed is significantly greater than the length of the data, then calloc/memmove is probably more efficient than realloc/memset. - bytes = __CFDataAllocate(data, numBytes * sizeof(uint8_t), true); + bytes = __CFDataAllocate(data, capacity * sizeof(uint8_t), true); if (NULL != bytes) { memmove(bytes, oldBytes, oldLength); __CFDataDeallocate(data); @@ -568,17 +548,18 @@ static void __CFDataGrow(CFMutableDataRef data, CFIndex numNewValues, Boolean cl // If the calloc/memmove approach either failed or was never attempted, then realloc. allocateCleared = false; if (__CFDataUseAllocator(data)) { - bytes = __CFSafelyReallocateWithAllocator(allocator, oldBytes, numBytes * sizeof(uint8_t), 0, NULL); + bytes = __CFSafelyReallocateWithAllocator(allocator, oldBytes, capacity * sizeof(uint8_t), 0, NULL); } else { - bytes = __CFSafelyReallocate(oldBytes, numBytes * sizeof(uint8_t), NULL); + bytes = __CFSafelyReallocate(oldBytes, capacity * sizeof(uint8_t), NULL); } } - if (NULL == bytes) __CFDataHandleOutOfMemory(data, numBytes * sizeof(uint8_t)); + if (NULL == bytes) __CFDataHandleOutOfMemory(data, capacity * sizeof(uint8_t)); + if (clear && !allocateCleared && oldLength < newLength) { + memset((uint8_t *)bytes + oldLength, 0, newLength - oldLength); + } __CFDataSetCapacity(data, capacity); - __CFDataSetNumBytes(data, numBytes); - if (clear && !allocateCleared && oldLength < newLength) memset((uint8_t *)bytes + oldLength, 0, newLength - oldLength); __CFDataSetNeedsToZero(data, !allocateCleared); - *((void **)&data->_bytes) = bytes; + data->_bytes = bytes; if (__CFOASafe) __CFSetLastAllocationEventName(data->_bytes, "CFData (store)"); } @@ -604,7 +585,7 @@ void CFDataSetLength(CFMutableDataRef data, CFIndex newLength) { } else { CFAssert1(newLength <= __CFDataCapacity(data), __kCFLogAssertion, "%s(): fixed-capacity data is full", __PRETTY_FUNCTION__); // Continuing after this could cause buffer overruns. - if (newLength > __CFDataCapacity(data)) HALT; + HALT_MSG("fixed-capacity CFMutableData is full"); } } else if (oldLength < newLength && __CFDataNeedsToZero(data)) { memset(_CFDataGetBytePtrNonObjC(data) + oldLength, 0, newLength - oldLength); @@ -613,7 +594,6 @@ void CFDataSetLength(CFMutableDataRef data, CFIndex newLength) { } } __CFDataSetLength(data, newLength); - __CFDataSetNumBytesUsed(data, newLength); } void CFDataIncreaseLength(CFMutableDataRef data, CFIndex extraLength) { @@ -638,47 +618,65 @@ void CFDataDeleteBytes(CFMutableDataRef data, CFRange range) { CFDataReplaceBytes(data, range, NULL, 0); } -void CFDataReplaceBytes(CFMutableDataRef data, CFRange range, const uint8_t *newBytes, CFIndex newLength) { - CF_OBJC_FUNCDISPATCHV(CFDataGetTypeID(), void, (NSMutableData *)data, replaceBytesInRange:NSMakeRange(range.location, range.length) withBytes:(const void *)newBytes length:(NSUInteger)newLength); - CF_SWIFT_NSDATA_FUNCDISPATCHV(_kCFRuntimeIDCFData, void, data, NSData.replaceBytes, range, newBytes, newLength); +void CFDataReplaceBytes(CFMutableDataRef data, CFRange range, const uint8_t *newBytes, CFIndex newBytesLength) { + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFData, void, (NSMutableData *)data, replaceBytesInRange:NSMakeRange(range.location, range.length) withBytes:(const void *)newBytes length:(NSUInteger)newBytesLength); + CF_SWIFT_NSDATA_FUNCDISPATCHV(_kCFRuntimeIDCFData, void, data, NSData.replaceBytes, range, newBytes, newBytesLength); __CFGenericValidateType(data, CFDataGetTypeID()); __CFDataValidateRange(data, range, __PRETTY_FUNCTION__); CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__); - CFAssert2(0 <= newLength, __kCFLogAssertion, "%s(): newLength (%ld) cannot be less than zero", __PRETTY_FUNCTION__, newLength); - - CFIndex len = __CFDataLength(data); - if (len < 0 || range.length < 0 || newLength < 0) HALT; - CFIndex newCount = len - range.length + newLength; - if (newCount < 0) HALT; - - uint8_t *bytePtr = _CFDataGetBytePtrNonObjC(data); - uint8_t *srcBuf = (uint8_t *)newBytes; + CFAssert2(0 <= newBytesLength, __kCFLogAssertion, "%s(): newLength (%ld) cannot be less than zero", __PRETTY_FUNCTION__, newBytesLength); + + CFIndex const originalCapacity = __CFDataCapacity(data); + CFIndex const originalLength = __CFDataLength(data); + if (range.length < 0) HALT_MSG("Negative range.length passed to CFDataReplaceBytes"); + if (newBytesLength < 0) HALT_MSG("Negative buffer length passed to CFDataReplaceBytes"); + CFIndex const newLength = originalLength - range.length + newBytesLength; + if (newLength < 0) HALT_MSG("Invalid range passed to CFDataReplaceBytes"); + if (newBytesLength > 0 && newBytes == NULL) HALT_MSG("Invalid length passed to CFDataReplaceBytes when newBytes == NULL"); + + uint8_t * dstBuf = _CFDataGetBytePtrNonObjC(data); + uint8_t * srcBuf = (uint8_t *)newBytes; switch (__CFMutableVariety(data)) { - case kCFMutable: - if (__CFDataNumBytes(data) < newCount) { - if (bytePtr && newBytes && newBytes < bytePtr + __CFDataCapacity(data) && bytePtr < newBytes + newLength) { - srcBuf = (uint8_t *)malloc(newLength * sizeof(uint8_t)); - memmove(srcBuf, newBytes, newLength * sizeof(uint8_t)); + case kCFMutable: + if (originalCapacity < newLength) { + + // We need to grow the CFData, but if the buffer we're inserting overlaps with the current buffer, we need to copy it out so it can survive a realloc, which may change the pointers, making newBytes invalid. + Boolean const buffersOverlap = dstBuf && srcBuf && (srcBuf < dstBuf + originalCapacity) && (srcBuf < newBytes + newBytesLength); + if (buffersOverlap) { + size_t const allocationSize = newBytesLength * sizeof(uint8_t); + srcBuf = (uint8_t *)malloc(allocationSize); + if (srcBuf == NULL) { + __CFDataHandleOutOfMemory(data, allocationSize); + } + memmove(srcBuf, newBytes, allocationSize); + } + + __CFDataGrow(data, newLength - originalLength, false); + dstBuf = _CFDataGetBytePtrNonObjC(data); } - __CFDataGrow(data, newLength - range.length, false); - bytePtr = _CFDataGetBytePtrNonObjC(data); - } - break; - case kCFFixedMutable: - CFAssert1(newCount <= __CFDataCapacity(data), __kCFLogAssertion, "%s(): fixed-capacity data is full", __PRETTY_FUNCTION__); - // Continuing after this could cause buffer overruns. - if (newCount > __CFDataCapacity(data)) HALT; - break; + break; + case kCFFixedMutable: + CFAssert1(newLength <= originalCapacity, __kCFLogAssertion, "%s(): fixed-capacity data is full", __PRETTY_FUNCTION__); + // Continuing after this could cause buffer overruns. + if (newLength > originalCapacity) HALT_MSG("fixed-capacity CFMutableData is full"); + break; } - if (newLength != range.length && range.location + range.length < len) { - memmove(bytePtr + range.location + newLength, bytePtr + range.location + range.length, (len - range.location - range.length) * sizeof(uint8_t)); + + Boolean const hasBytesToInsert = srcBuf != NULL && newBytesLength > 0; + CFIndex const distanceToShift = newBytesLength - range.length; + CFIndex const amountToShift = originalLength - (range.location + range.length); + Boolean const hasBytesToShift = distanceToShift != 0 && amountToShift > 0; + if (hasBytesToShift) { + uint8_t * const shiftSrc = dstBuf + range.location + range.length; + uint8_t * const shiftDst = shiftSrc + distanceToShift; + memmove(shiftDst, shiftSrc, amountToShift * sizeof(uint8_t)); } - if (0 < newLength) { - memmove(bytePtr + range.location, srcBuf, newLength * sizeof(uint8_t)); + + if (hasBytesToInsert) { + memmove(dstBuf + range.location, srcBuf, newBytesLength * sizeof(uint8_t)); } if (srcBuf != newBytes) free(srcBuf); - __CFDataSetNumBytesUsed(data, newCount); - __CFDataSetLength(data, newCount); + __CFDataSetLength(data, newLength); } #define REVERSE_BUFFER(type, buf, len) { \ diff --git a/CoreFoundation/Collections.subproj/CFData.h b/CoreFoundation/Collections.subproj/CFData.h index 2ae4012796..41eef4514d 100644 --- a/CoreFoundation/Collections.subproj/CFData.h +++ b/CoreFoundation/Collections.subproj/CFData.h @@ -1,7 +1,7 @@ /* CFData.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Collections.subproj/CFDictionary.c b/CoreFoundation/Collections.subproj/CFDictionary.c index a8ad71c927..11b49768ea 100644 --- a/CoreFoundation/Collections.subproj/CFDictionary.c +++ b/CoreFoundation/Collections.subproj/CFDictionary.c @@ -1,79 +1,25 @@ /* CFDictionary.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors - Licensed under Apache License v2.0 with Runtime Library Exception - See http://swift.org/LICENSE.txt for license information - See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Michael LeHew - Machine generated from Notes/HashingCode.template -*/ - - - - + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors + Licensed under Apache License v2.0 with Runtime Library Exception + See http://swift.org/LICENSE.txt for license information + See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors + Responsibility: Michael LeHew + */ #include #include "CFInternal.h" #include "CFBasicHash.h" +#include #include #include "CFRuntime_Internal.h" -#define CFDictionary 0 -#define CFSet 0 -#define CFBag 0 -#undef CFDictionary -#define CFDictionary 1 - -#if CFDictionary - - const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; const CFDictionaryKeyCallBacks kCFCopyStringDictionaryKeyCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual}; -#define CFHashRef CFDictionaryRef -#define CFMutableHashRef CFMutableDictionaryRef -#define CFHashKeyCallBacks CFDictionaryKeyCallBacks -#define CFHashValueCallBacks CFDictionaryValueCallBacks -#endif - -#if CFSet -const CFDictionaryCallBacks kCFTypeDictionaryCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; -const CFDictionaryCallBacks kCFCopyStringDictionaryCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; - -#define CFDictionaryKeyCallBacks CFDictionaryCallBacks -#define CFDictionaryValueCallBacks CFDictionaryCallBacks -#define kCFTypeDictionaryKeyCallBacks kCFTypeDictionaryCallBacks -#define kCFTypeDictionaryValueCallBacks kCFTypeDictionaryCallBacks - -#define CFHashRef CFSetRef -#define CFMutableHashRef CFMutableSetRef -#define CFHashKeyCallBacks CFDictionaryCallBacks -#define CFHashValueCallBacks CFDictionaryCallBacks -#endif - -#if CFBag -const CFDictionaryCallBacks kCFTypeDictionaryCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; -const CFDictionaryCallBacks kCFCopyStringDictionaryCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; - -#define CFDictionaryKeyCallBacks CFDictionaryCallBacks -#define CFDictionaryValueCallBacks CFDictionaryCallBacks -#define kCFTypeDictionaryKeyCallBacks kCFTypeDictionaryCallBacks -#define kCFTypeDictionaryValueCallBacks kCFTypeDictionaryCallBacks - -#define CFHashRef CFBagRef -#define CFMutableHashRef CFMutableBagRef -#define CFHashKeyCallBacks CFDictionaryCallBacks -#define CFHashValueCallBacks CFDictionaryCallBacks -#endif - - -typedef uintptr_t any_t; -typedef const void * const_any_pointer_t; -typedef void * any_pointer_t; - static Boolean __CFDictionaryEqual(CFTypeRef cf1, CFTypeRef cf2) { return __CFBasicHashEqual((CFBasicHashRef)cf1, (CFBasicHashRef)cf2); } @@ -106,12 +52,9 @@ CFTypeID CFDictionaryGetTypeID(void) { return _kCFRuntimeIDCFDictionary; } - -static CFBasicHashRef __CFDictionaryCreateGeneric(CFAllocatorRef allocator, const CFHashKeyCallBacks *keyCallBacks, const CFHashValueCallBacks *valueCallBacks, Boolean useValueCB) { - CFOptionFlags flags = kCFBasicHashLinearHashing; // kCFBasicHashExponentialHashing - flags |= (CFDictionary ? kCFBasicHashHasKeys : 0) | (CFBag ? kCFBasicHashHasCounts : 0); - - +static CFBasicHashRef __CFDictionaryCreateGeneric(CFAllocatorRef allocator, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks, Boolean useValueCB) { + CFOptionFlags flags = kCFBasicHashLinearHashing | kCFBasicHashHasKeys; // kCFBasicHashExponentialHashing + CFBasicHashCallbacks callbacks; callbacks.retainKey = keyCallBacks ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))keyCallBacks->retain : NULL; callbacks.releaseKey = keyCallBacks ? (void (*)(CFAllocatorRef, uintptr_t))keyCallBacks->release : NULL; @@ -123,23 +66,23 @@ static CFBasicHashRef __CFDictionaryCreateGeneric(CFAllocatorRef allocator, cons callbacks.releaseValue = useValueCB ? (valueCallBacks ? (void (*)(CFAllocatorRef, uintptr_t))valueCallBacks->release : NULL) : (callbacks.releaseKey); callbacks.equateValues = useValueCB ? (valueCallBacks ? (Boolean (*)(uintptr_t, uintptr_t))valueCallBacks->equal : NULL) : (callbacks.equateKeys); callbacks.copyValueDescription = useValueCB ? (valueCallBacks ? (CFStringRef (*)(uintptr_t))valueCallBacks->copyDescription : NULL) : (callbacks.copyKeyDescription); - + CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, &callbacks); return ht; } -#if CFDictionary -CF_PRIVATE CFHashRef __CFDictionaryCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, const_any_pointer_t *vlist, CFIndex numValues) { -#endif -#if CFSet || CFBag -CF_PRIVATE CFHashRef __CFDictionaryCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIndex numValues) { - const_any_pointer_t *vlist = klist; +CF_PRIVATE CFDictionaryRef __CFDictionaryCreateTransfer(CFAllocatorRef allocator, void const **klist, void const **vlist, CFIndex numValues) { +#if !DEPLOYMENT_RUNTIME_SWIFT + CF_PRIVATE CFDictionaryRef __NSCFDictionaryCreateTransfer(CFAllocatorRef allocator, const id *klist, const id *vlist, CFIndex numValues); + CFDictionaryRef nsResult = __NSCFDictionaryCreateTransfer(allocator, (const id *)klist, (const id *)vlist, numValues); + if (nsResult) { + return nsResult; + } #endif - CFTypeID typeID = CFDictionaryGetTypeID(); + CFTypeID typeID = _kCFRuntimeIDCFDictionary; CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues); - CFOptionFlags flags = kCFBasicHashLinearHashing; // kCFBasicHashExponentialHashing - flags |= (CFDictionary ? kCFBasicHashHasKeys : 0) | (CFBag ? kCFBasicHashHasCounts : 0); - + CFOptionFlags flags = kCFBasicHashLinearHashing | kCFBasicHashHasKeys; // kCFBasicHashExponentialHashing + CFBasicHashCallbacks callbacks; callbacks.retainKey = (uintptr_t (*)(CFAllocatorRef, uintptr_t))kCFTypeDictionaryKeyCallBacks.retain; callbacks.releaseKey = (void (*)(CFAllocatorRef, uintptr_t))kCFTypeDictionaryKeyCallBacks.release; @@ -147,11 +90,11 @@ CF_PRIVATE CFHashRef __CFDictionaryCreateTransfer(CFAllocatorRef allocator, cons callbacks.hashKey = (CFHashCode (*)(uintptr_t))kCFTypeDictionaryKeyCallBacks.hash; callbacks.getIndirectKey = NULL; callbacks.copyKeyDescription = (CFStringRef (*)(uintptr_t))kCFTypeDictionaryKeyCallBacks.copyDescription; - callbacks.retainValue = CFDictionary ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))kCFTypeDictionaryValueCallBacks.retain : callbacks.retainKey; - callbacks.releaseValue = CFDictionary ? (void (*)(CFAllocatorRef, uintptr_t))kCFTypeDictionaryValueCallBacks.release : callbacks.releaseKey; - callbacks.equateValues = CFDictionary ? (Boolean (*)(uintptr_t, uintptr_t))kCFTypeDictionaryValueCallBacks.equal : callbacks.equateKeys; - callbacks.copyValueDescription = CFDictionary ? (CFStringRef (*)(uintptr_t))kCFTypeDictionaryValueCallBacks.copyDescription : callbacks.copyKeyDescription; - + callbacks.retainValue = (uintptr_t (*)(CFAllocatorRef, uintptr_t))kCFTypeDictionaryValueCallBacks.retain; + callbacks.releaseValue = (void (*)(CFAllocatorRef, uintptr_t))kCFTypeDictionaryValueCallBacks.release; + callbacks.equateValues = (Boolean (*)(uintptr_t, uintptr_t))kCFTypeDictionaryValueCallBacks.equal; + callbacks.copyValueDescription = (CFStringRef (*)(uintptr_t))kCFTypeDictionaryValueCallBacks.copyDescription; + CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, &callbacks); CFBasicHashSuppressRC(ht); if (0 < numValues) CFBasicHashSetCapacity(ht, numValues); @@ -162,20 +105,20 @@ CF_PRIVATE CFHashRef __CFDictionaryCreateTransfer(CFAllocatorRef allocator, cons CFBasicHashMakeImmutable(ht); _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFDictionary (immutable)"); - return (CFHashRef)ht; + return (CFDictionaryRef)ht; } -#if CFDictionary -CFHashRef CFDictionaryCreate(CFAllocatorRef allocator, const_any_pointer_t *klist, const_any_pointer_t *vlist, CFIndex numValues, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks) { -#endif -#if CFSet || CFBag -CFHashRef CFDictionaryCreate(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIndex numValues, const CFDictionaryKeyCallBacks *keyCallBacks) { - const_any_pointer_t *vlist = klist; - const CFDictionaryValueCallBacks *valueCallBacks = 0; +CFDictionaryRef CFDictionaryCreate(CFAllocatorRef allocator, void const **klist, void const **vlist, CFIndex numValues, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks) { +#if !DEPLOYMENT_RUNTIME_SWIFT + CF_PRIVATE CFDictionaryRef __NSCFDictionaryCreate(CFAllocatorRef allocator, void const **klist, void const **vlist, CFIndex numValues, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks); + CFDictionaryRef nsResult = __NSCFDictionaryCreate(allocator, klist, vlist, numValues, keyCallBacks, valueCallBacks); + if (nsResult) { + return nsResult; + } #endif - CFTypeID typeID = CFDictionaryGetTypeID(); + CFTypeID typeID = _kCFRuntimeIDCFDictionary; CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues); - CFBasicHashRef ht = __CFDictionaryCreateGeneric(allocator, keyCallBacks, valueCallBacks, CFDictionary); + CFBasicHashRef ht = __CFDictionaryCreateGeneric(allocator, keyCallBacks, valueCallBacks, true); if (!ht) return NULL; if (0 < numValues) CFBasicHashSetCapacity(ht, numValues); for (CFIndex idx = 0; idx < numValues; idx++) { @@ -184,52 +127,40 @@ CFHashRef CFDictionaryCreate(CFAllocatorRef allocator, const_any_pointer_t *klis CFBasicHashMakeImmutable(ht); _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFDictionary (immutable)"); - return (CFHashRef)ht; + return (CFDictionaryRef)ht; } -#if CFDictionary -CFMutableHashRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks) { -#endif -#if CFSet || CFBag -CFMutableHashRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks) { - const CFDictionaryValueCallBacks *valueCallBacks = 0; +CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks) { +#if !DEPLOYMENT_RUNTIME_SWIFT + CF_PRIVATE CFMutableDictionaryRef __NSCFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks); + CFMutableDictionaryRef nsResult = __NSCFDictionaryCreateMutable(allocator, capacity, keyCallBacks, valueCallBacks); + if (nsResult) { + return nsResult; + } #endif - CFTypeID typeID = CFDictionaryGetTypeID(); + CFTypeID typeID = _kCFRuntimeIDCFDictionary; CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__, capacity); - CFBasicHashRef ht = __CFDictionaryCreateGeneric(allocator, keyCallBacks, valueCallBacks, CFDictionary); + CFBasicHashRef ht = __CFDictionaryCreateGeneric(allocator, keyCallBacks, valueCallBacks, true); if (!ht) return NULL; + if (capacity > 0) { + if (capacity > 1000) capacity = 1000; + CFBasicHashSetCapacity(ht, capacity); + } _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFDictionary (mutable)"); - return (CFMutableHashRef)ht; + return (CFMutableDictionaryRef)ht; } -CFHashRef CFDictionaryCreateCopy(CFAllocatorRef allocator, CFHashRef other) { - CFTypeID typeID = CFDictionaryGetTypeID(); +CFDictionaryRef CFDictionaryCreateCopy(CFAllocatorRef allocator, CFDictionaryRef other) { + CFTypeID typeID = _kCFRuntimeIDCFDictionary; CFAssert1(other, __kCFLogAssertion, "%s(): other CFDictionary cannot be NULL", __PRETTY_FUNCTION__); __CFGenericValidateType(other, typeID); Boolean markImmutable = false; CFBasicHashRef ht = NULL; if (CF_IS_OBJC(typeID, other)) { -#if CFDictionary || CFSet ht = (CFBasicHashRef)CF_OBJC_CALLV((id)other, copyWithZone:NULL); -#elif CFBag - CFIndex numValues = CFDictionaryGetCount(other); - const_any_pointer_t vbuffer[256]; - const_any_pointer_t *vlist = (numValues <= 256) ? vbuffer : (const_any_pointer_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(const_any_pointer_t), 0); - const_any_pointer_t *klist = vlist; - CFDictionaryGetValues(other, vlist); - ht = __CFDictionaryCreateGeneric(allocator, & kCFTypeDictionaryKeyCallBacks, CFDictionary ? & kCFTypeDictionaryValueCallBacks : NULL, CFDictionary); - if (ht && 0 < numValues) CFBasicHashSetCapacity(ht, numValues); - for (CFIndex idx = 0; ht && idx < numValues; idx++) { - CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]); - } - if (vlist != vbuffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, vlist); - markImmutable = true; -#endif // CFBag } else if (CF_IS_SWIFT(typeID, other)) { -#if CFDictionary || CFSet ht = (CFBasicHashRef)CF_SWIFT_CALLV(other, NSObject.copyWithZone, nil); -#endif } else { // non-objc types ht = CFBasicHashCreateCopy(allocator, (CFBasicHashRef)other); markImmutable = true; @@ -238,30 +169,28 @@ CFHashRef CFDictionaryCreateCopy(CFAllocatorRef allocator, CFHashRef other) { CFBasicHashMakeImmutable(ht); _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFDictionary (immutable)"); - return (CFHashRef)ht; + return (CFDictionaryRef)ht; } - return (CFHashRef)ht; + return (CFDictionaryRef)ht; } -CFMutableHashRef CFDictionaryCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFHashRef other) { - CFTypeID typeID = CFDictionaryGetTypeID(); +CFMutableDictionaryRef CFDictionaryCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFDictionaryRef other) { + CFTypeID typeID = _kCFRuntimeIDCFDictionary; CFAssert1(other, __kCFLogAssertion, "%s(): other CFDictionary cannot be NULL", __PRETTY_FUNCTION__); __CFGenericValidateType(other, typeID); CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__, capacity); CFBasicHashRef ht = NULL; - if (CF_IS_OBJC(typeID, other) || CF_IS_SWIFT(typeID, other)) { + Boolean const isObjC = CF_IS_OBJC(typeID, other); + if (isObjC && _CFAllocatorIsSystemDefault(allocator)) { + return (CFMutableDictionaryRef)CF_OBJC_CALLV((id)other, _cfMutableCopy); + } + if (isObjC || CF_IS_SWIFT(typeID, other)) { CFIndex numValues = CFDictionaryGetCount(other); - const_any_pointer_t vbuffer[256], kbuffer[256]; - const_any_pointer_t *vlist = (numValues <= 256) ? vbuffer : (const_any_pointer_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(const_any_pointer_t), 0); -#if CFSet || CFBag - const_any_pointer_t *klist = vlist; - CFDictionaryGetValues(other, vlist); -#endif -#if CFDictionary - const_any_pointer_t *klist = (numValues <= 256) ? kbuffer : (const_any_pointer_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(const_any_pointer_t), 0); + void const *vbuffer[256], *kbuffer[256]; + void const **vlist = (numValues <= 256) ? vbuffer : (void const **)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(void const *), 0); + void const **klist = (numValues <= 256) ? kbuffer : (void const **)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(void const *), 0); CFDictionaryGetKeysAndValues(other, klist, vlist); -#endif - ht = __CFDictionaryCreateGeneric(allocator, & kCFTypeDictionaryKeyCallBacks, CFDictionary ? & kCFTypeDictionaryValueCallBacks : NULL, CFDictionary); + ht = __CFDictionaryCreateGeneric(allocator, & kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks, true); if (ht && 0 < numValues) CFBasicHashSetCapacity(ht, numValues); for (CFIndex idx = 0; ht && idx < numValues; idx++) { CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]); @@ -274,220 +203,152 @@ CFMutableHashRef CFDictionaryCreateMutableCopy(CFAllocatorRef allocator, CFIndex if (!ht) return NULL; _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFDictionary (mutable)"); - return (CFMutableHashRef)ht; + return (CFMutableDictionaryRef)ht; } -CFIndex CFDictionaryGetCount(CFHashRef hc) { -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), CFIndex, (CFSwiftRef)hc, NSDictionary.count); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), CFIndex, (NSDictionary *)hc, count); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), CFIndex, (CFSwiftRef)hc, NSSet.count); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), CFIndex, (NSSet *)hc, count); -#endif +CFIndex CFDictionaryGetCount(CFDictionaryRef hc) { + CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), CFIndex, (CFSwiftRef)hc, NSDictionary.count); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDictionary, CFIndex, (NSDictionary *)hc, count); __CFGenericValidateType(hc, CFDictionaryGetTypeID()); return CFBasicHashGetCount((CFBasicHashRef)hc); } -#if CFDictionary -CFIndex CFDictionaryGetCountOfKey(CFHashRef hc, const_any_pointer_t key) { -#endif -#if CFSet || CFBag -CFIndex CFDictionaryGetCountOfValue(CFHashRef hc, const_any_pointer_t key) { -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), CFIndex, (CFSwiftRef)hc, NSDictionary.countForKey, key); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), CFIndex, (NSDictionary *)hc, countForKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), CFIndex, (CFSwiftRef)hc, NSSet.countForKey, key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), CFIndex, (NSSet *)hc, countForObject:(id)key); -#endif +CFIndex CFDictionaryGetCountOfKey(CFDictionaryRef hc, void const *key) { + CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), CFIndex, (CFSwiftRef)hc, NSDictionary.countForKey, key); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDictionary, CFIndex, (NSDictionary *)hc, countForKey:(id)key); __CFGenericValidateType(hc, CFDictionaryGetTypeID()); return CFBasicHashGetCountOfKey((CFBasicHashRef)hc, (uintptr_t)key); } -#if CFDictionary -Boolean CFDictionaryContainsKey(CFHashRef hc, const_any_pointer_t key) { -#endif -#if CFSet || CFBag -Boolean CFDictionaryContainsValue(CFHashRef hc, const_any_pointer_t key) { -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), char, (CFSwiftRef)hc, NSDictionary.containsKey, key); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), char, (NSDictionary *)hc, containsKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), char, (CFSwiftRef)hc, NSSet.containsObject, (CFSwiftRef)key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), char, (NSSet *)hc, containsObject:(id)key); -#endif +Boolean CFDictionaryContainsKey(CFDictionaryRef hc, void const *key) { + CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), char, (CFSwiftRef)hc, NSDictionary.containsKey, key); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDictionary, char, (NSDictionary *)hc, containsKey:(id)key); __CFGenericValidateType(hc, CFDictionaryGetTypeID()); return (0 < CFBasicHashGetCountOfKey((CFBasicHashRef)hc, (uintptr_t)key)); } -const_any_pointer_t CFDictionaryGetValue(CFHashRef hc, const_any_pointer_t key) { -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), const_any_pointer_t, (CFSwiftRef)hc, NSDictionary.objectForKey, key); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), const_any_pointer_t, (NSDictionary *)hc, objectForKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), const_any_pointer_t, (CFSwiftRef)hc, NSSet.member, key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), const_any_pointer_t, (NSSet *)hc, member:(id)key); -#endif +void const *CFDictionaryGetValue(CFDictionaryRef hc, void const *key) { + CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void const *, (CFSwiftRef)hc, NSDictionary.objectForKey, key); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDictionary, void const *, (NSDictionary *)hc, objectForKey:(id)key); __CFGenericValidateType(hc, CFDictionaryGetTypeID()); CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key); - return (0 < bkt.count ? (const_any_pointer_t)bkt.weak_value : 0); + return (0 < bkt.count ? (void const *)bkt.weak_value : 0); } -Boolean CFDictionaryGetValueIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *value) { -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), Boolean, (CFSwiftRef)hc, NSDictionary.__getValue, value, key); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), Boolean, (NSDictionary *)hc, __getValue:(id *)value forKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), Boolean, (CFSwiftRef)hc, NSSet.__getValue, value, key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), Boolean, (NSSet *)hc, __getValue:(id *)value forObj:(id)key); -#endif +Boolean CFDictionaryGetValueIfPresent(CFDictionaryRef hc, void const *key, void const **value) { + CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), Boolean, (CFSwiftRef)hc, NSDictionary.__getValue, value, key); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDictionary, Boolean, (NSDictionary *)hc, __getValue:(id *)value forKey:(id)key); __CFGenericValidateType(hc, CFDictionaryGetTypeID()); CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key); if (0 < bkt.count) { if (value) { - *value = (const_any_pointer_t)bkt.weak_value; + *value = (void const *)bkt.weak_value; } return true; } return false; } -#if CFDictionary -CFIndex CFDictionaryGetCountOfValue(CFHashRef hc, const_any_pointer_t value) { +CFIndex CFDictionaryGetCountOfValue(CFDictionaryRef hc, void const *value) { CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), CFIndex, (CFSwiftRef)hc, NSDictionary.count); - CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), CFIndex, (NSDictionary *)hc, countForObject:(id)value); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDictionary, CFIndex, (NSDictionary *)hc, countForObject:(id)value); __CFGenericValidateType(hc, CFDictionaryGetTypeID()); return CFBasicHashGetCountOfValue((CFBasicHashRef)hc, (uintptr_t)value); } -Boolean CFDictionaryContainsValue(CFHashRef hc, const_any_pointer_t value) { +Boolean CFDictionaryContainsValue(CFDictionaryRef hc, void const *value) { CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), char, (CFSwiftRef)hc, NSDictionary.containsObject, value); - CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), char, (NSDictionary *)hc, containsObject:(id)value); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDictionary, char, (NSDictionary *)hc, containsObject:(id)value); __CFGenericValidateType(hc, CFDictionaryGetTypeID()); return (0 < CFBasicHashGetCountOfValue((CFBasicHashRef)hc, (uintptr_t)value)); } -CF_EXPORT Boolean CFDictionaryGetKeyIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *actualkey) { +CF_EXPORT Boolean CFDictionaryGetKeyIfPresent(CFDictionaryRef hc, void const *key, void const **actualkey) { __CFGenericValidateType(hc, CFDictionaryGetTypeID()); CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key); if (0 < bkt.count) { if (actualkey) { - *actualkey = (const_any_pointer_t)bkt.weak_key; + *actualkey = (void const *)bkt.weak_key; } return true; } return false; } -#endif -#if CFDictionary -void CFDictionaryGetKeysAndValues(CFHashRef hc, const_any_pointer_t *keybuf, const_any_pointer_t *valuebuf) { -#endif -#if CFSet || CFBag -void CFDictionaryGetValues(CFHashRef hc, const_any_pointer_t *keybuf) { - const_any_pointer_t *valuebuf = 0; -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSDictionary.getObjects, valuebuf, keybuf); +void CFDictionaryGetKeysAndValues(CFDictionaryRef hc, void const **keybuf, void const **valuebuf) { + CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSDictionary.getObjects, valuebuf, keybuf); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated" - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSDictionary *)hc, getObjects:(id *)valuebuf andKeys:(id *)keybuf); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDictionary, void, (NSDictionary *)hc, getObjects:(id *)valuebuf andKeys:(id *)keybuf); #pragma GCC diagnostic pop -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSSet.getObjects, keybuf); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSSet *)hc, getObjects:(id *)keybuf); -#endif __CFGenericValidateType(hc, CFDictionaryGetTypeID()); CFBasicHashGetElements((CFBasicHashRef)hc, CFDictionaryGetCount(hc), (uintptr_t *)valuebuf, (uintptr_t *)keybuf); } -void CFDictionaryApplyFunction(CFHashRef hc, CFDictionaryApplierFunction applier, any_pointer_t context) { +void CFDictionaryApplyFunction(CFDictionaryRef hc, CFDictionaryApplierFunction applier, void *context) { FAULT_CALLBACK((void **)&(applier)); -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSDictionary.__apply, applier, context); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSDictionary *)hc, __apply:(void (*)(const void *, const void *, void *))applier context:(void *)context); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSSet.__apply, applier, context); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSSet *)hc, __applyValues:(void (*)(const void *, void *))applier context:(void *)context); -#endif + CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSDictionary.__apply, applier, context); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDictionary, void, (NSDictionary *)hc, __apply:(void (*)(const void *, const void *, void *))applier context:(void *)context); __CFGenericValidateType(hc, CFDictionaryGetTypeID()); CFBasicHashApply((CFBasicHashRef)hc, ^(CFBasicHashBucket bkt) { -#if CFDictionary - INVOKE_CALLBACK3(applier, (const_any_pointer_t)bkt.weak_key, (const_any_pointer_t)bkt.weak_value, context); -#endif -#if CFSet - INVOKE_CALLBACK2(applier, (const_any_pointer_t)bkt.weak_value, context); -#endif -#if CFBag - for (CFIndex cnt = bkt.count; cnt--;) { - INVOKE_CALLBACK2(applier, (const_any_pointer_t)bkt.weak_value, context); - } -#endif - return (Boolean)true; - }); + INVOKE_CALLBACK3(applier, (void const *)bkt.weak_key, (void const *)bkt.weak_value, context); + return (Boolean)true; + }); } -CF_PRIVATE void CFDictionaryApply(CFHashRef hc, void (^block)(const void *key, const void *value, Boolean *stop)) { +CF_PRIVATE void CFDictionaryApply(CFDictionaryRef hc, void (^block)(const void *key, const void *value, Boolean *stop)) { + CF_SWIFT_FUNCDISPATCHV(_kCFRuntimeIDCFDictionary, void, (CFSwiftRef)hc, NSDictionary.enumerateKeysAndObjectsWithOptions, 0, block); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDictionary, void, (NSDictionary *)hc, enumerateKeysAndObjectsWithOptions:0 usingBlock:(void (^ _Nonnull)(id _Nonnull, id _Nonnull, BOOL * _Nonnull))block); __CFGenericValidateType(hc, CFDictionaryGetTypeID()); CFBasicHashApply((CFBasicHashRef)hc, ^(CFBasicHashBucket bkt) { Boolean stop = false; - block((const_any_pointer_t)bkt.weak_key, (const_any_pointer_t)bkt.weak_value, &stop); + block((void const *)bkt.weak_key, (void const *)bkt.weak_value, &stop); if (stop) return (Boolean)false; return (Boolean)true; }); } // This function is for Foundation's benefit; no one else should use it. -CF_EXPORT unsigned long _CFDictionaryFastEnumeration(CFHashRef hc, struct __objcFastEnumerationStateEquivalent *state, void *stackbuffer, unsigned long count) { - if (CF_IS_SWIFT(CFDictionaryGetTypeID(), hc)) return 0; - if (CF_IS_OBJC(CFDictionaryGetTypeID(), hc)) return 0; +CF_EXPORT unsigned long _CFDictionaryFastEnumeration(CFDictionaryRef hc, struct __objcFastEnumerationStateEquivalent *state, void *stackbuffer, unsigned long count) { + if (CF_IS_SWIFT(_kCFRuntimeIDCFDictionary, hc)) return 0; + if (CF_IS_OBJC(_kCFRuntimeIDCFDictionary, hc)) return 0; __CFGenericValidateType(hc, CFDictionaryGetTypeID()); return __CFBasicHashFastEnumeration((CFBasicHashRef)hc, (struct __objcFastEnumerationStateEquivalent2 *)state, stackbuffer, count); } // This function is for Foundation's benefit; no one else should use it. -CF_EXPORT Boolean _CFDictionaryIsMutable(CFHashRef hc) { - if (CF_IS_SWIFT(CFDictionaryGetTypeID(), hc)) return false; - if (CF_IS_OBJC(CFDictionaryGetTypeID(), hc)) return false; +CF_EXPORT Boolean _CFDictionaryIsMutable(CFDictionaryRef hc) { + if (CF_IS_SWIFT(_kCFRuntimeIDCFDictionary, hc)) return false; + if (CF_IS_OBJC(_kCFRuntimeIDCFDictionary, hc)) return false; __CFGenericValidateType(hc, CFDictionaryGetTypeID()); return CFBasicHashIsMutable((CFBasicHashRef)hc); } // This function is for Foundation's benefit; no one else should use it. -CF_EXPORT void _CFDictionarySetCapacity(CFMutableHashRef hc, CFIndex cap) { - if (CF_IS_SWIFT(CFDictionaryGetTypeID(), hc)) return; - if (CF_IS_OBJC(CFDictionaryGetTypeID(), hc)) return; +CF_EXPORT void _CFDictionarySetCapacity(CFMutableDictionaryRef hc, CFIndex cap) { + if (CF_IS_SWIFT(_kCFRuntimeIDCFDictionary, hc)) return; + if (CF_IS_OBJC(_kCFRuntimeIDCFDictionary, hc)) return; __CFGenericValidateType(hc, CFDictionaryGetTypeID()); CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc); CFAssert3(CFDictionaryGetCount(hc) <= cap, __kCFLogAssertion, "%s(): desired capacity (%ld) is less than count (%ld)", __PRETTY_FUNCTION__, cap, CFDictionaryGetCount(hc)); CFBasicHashSetCapacity((CFBasicHashRef)hc, cap); } -CF_INLINE CFIndex __CFDictionaryGetKVOBit(CFHashRef hc) { +CF_INLINE CFIndex __CFDictionaryGetKVOBit(CFDictionaryRef hc) { return __CFRuntimeGetFlag(hc, 0); } -CF_INLINE void __CFDictionarySetKVOBit(CFHashRef hc, CFIndex bit) { +CF_INLINE void __CFDictionarySetKVOBit(CFDictionaryRef hc, CFIndex bit) { __CFRuntimeSetFlag(hc, 0, ((uintptr_t)bit & 0x1)); } // This function is for Foundation's benefit; no one else should use it. -CF_EXPORT CFIndex _CFDictionaryGetKVOBit(CFHashRef hc) { +CF_EXPORT CFIndex _CFDictionaryGetKVOBit(CFDictionaryRef hc) { return __CFDictionaryGetKVOBit(hc); } // This function is for Foundation's benefit; no one else should use it. -CF_EXPORT void _CFDictionarySetKVOBit(CFHashRef hc, CFIndex bit) { +CF_EXPORT void _CFDictionarySetKVOBit(CFDictionaryRef hc, CFIndex bit) { __CFDictionarySetKVOBit(hc, bit); } @@ -499,21 +360,9 @@ CF_EXPORT void _CFDictionarySetKVOBit(CFHashRef hc, CFIndex bit) { #define CF_OBJC_KVO_DIDCHANGEALL(obj) #endif -#if CFDictionary -void CFDictionaryAddValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) { -#endif -#if CFSet || CFBag -void CFDictionaryAddValue(CFMutableHashRef hc, const_any_pointer_t key) { - const_any_pointer_t value = key; -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.__addObject, key, value); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableDictionary *)hc, __addObject:(id)value forKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.addObject, (CFSwiftRef)key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableSet *)hc, addObject:(id)key); -#endif +void CFDictionaryAddValue(CFMutableDictionaryRef hc, void const *key, void const *value) { + CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.__addObject, key, value); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDictionary, void, (NSMutableDictionary *)hc, __addObject:(id)value forKey:(id)key); __CFGenericValidateType(hc, CFDictionaryGetTypeID()); CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc); if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) { @@ -524,21 +373,9 @@ void CFDictionaryAddValue(CFMutableHashRef hc, const_any_pointer_t key) { CF_OBJC_KVO_DIDCHANGE(hc, key); } -#if CFDictionary -void CFDictionaryReplaceValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) { -#endif -#if CFSet || CFBag -void CFDictionaryReplaceValue(CFMutableHashRef hc, const_any_pointer_t key) { - const_any_pointer_t value = key; -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.replaceObject, key, value); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableDictionary *)hc, replaceObject:(id)value forKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.replaceObject, (CFSwiftRef)key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableSet *)hc, replaceObject:(id)key); -#endif +void CFDictionaryReplaceValue(CFMutableDictionaryRef hc, void const *key, void const *value) { + CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.replaceObject, key, value); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDictionary, void, (NSMutableDictionary *)hc, replaceObject:(id)value forKey:(id)key); __CFGenericValidateType(hc, CFDictionaryGetTypeID()); CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc); if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) { @@ -549,41 +386,23 @@ void CFDictionaryReplaceValue(CFMutableHashRef hc, const_any_pointer_t key) { CF_OBJC_KVO_DIDCHANGE(hc, key); } -#if CFDictionary -void CFDictionarySetValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) { -#endif -#if CFSet || CFBag -void CFDictionarySetValue(CFMutableHashRef hc, const_any_pointer_t key) { - const_any_pointer_t value = key; -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.__setObject, key, value); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableDictionary *)hc, __setObject:(id)value forKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.setObject, (CFSwiftRef)key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableSet *)hc, setObject:(id)key); -#endif +void CFDictionarySetValue(CFMutableDictionaryRef hc, void const *key, void const *value) { + CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.__setObject, key, value); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDictionary, void, (NSMutableDictionary *)hc, __setObject:(id)value forKey:(id)key); __CFGenericValidateType(hc, CFDictionaryGetTypeID()); CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc); if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) { CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__, hc); } CF_OBJC_KVO_WILLCHANGE(hc, key); -//#warning this for a dictionary used to not replace the key + //#warning this for a dictionary used to not replace the key CFBasicHashSetValue((CFBasicHashRef)hc, (uintptr_t)key, (uintptr_t)value); CF_OBJC_KVO_DIDCHANGE(hc, key); } -void CFDictionaryRemoveValue(CFMutableHashRef hc, const_any_pointer_t key) { -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.removeObjectForKey, key); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableDictionary *)hc, removeObjectForKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.removeObject, (CFSwiftRef)key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableSet *)hc, removeObject:(id)key); -#endif +void CFDictionaryRemoveValue(CFMutableDictionaryRef hc, void const *key) { + CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.removeObjectForKey, key); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDictionary, void, (NSMutableDictionary *)hc, removeObjectForKey:(id)key); __CFGenericValidateType(hc, CFDictionaryGetTypeID()); CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc); if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) { @@ -594,15 +413,9 @@ void CFDictionaryRemoveValue(CFMutableHashRef hc, const_any_pointer_t key) { CF_OBJC_KVO_DIDCHANGE(hc, key); } -void CFDictionaryRemoveAllValues(CFMutableHashRef hc) { -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.removeAllObjects); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableDictionary *)hc, removeAllObjects); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.removeAllObjects); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableSet *)hc, removeAllObjects); -#endif +void CFDictionaryRemoveAllValues(CFMutableDictionaryRef hc) { + CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.removeAllObjects); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDictionary, void, (NSMutableDictionary *)hc, removeAllObjects); __CFGenericValidateType(hc, CFDictionaryGetTypeID()); CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc); if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) { diff --git a/CoreFoundation/Collections.subproj/CFDictionary.h b/CoreFoundation/Collections.subproj/CFDictionary.h index 575affb9d8..a52f5ce722 100644 --- a/CoreFoundation/Collections.subproj/CFDictionary.h +++ b/CoreFoundation/Collections.subproj/CFDictionary.h @@ -1,7 +1,7 @@ /* CFDictionary.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Collections.subproj/CFSet.c b/CoreFoundation/Collections.subproj/CFSet.c index afca65e1ae..e151a1be38 100644 --- a/CoreFoundation/Collections.subproj/CFSet.c +++ b/CoreFoundation/Collections.subproj/CFSet.c @@ -1,17 +1,12 @@ /* CFSet.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors - Licensed under Apache License v2.0 with Runtime Library Exception - See http://swift.org/LICENSE.txt for license information - See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Michael LeHew - Machine generated from Notes/HashingCode.template -*/ - - - - + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors + Licensed under Apache License v2.0 with Runtime Library Exception + See http://swift.org/LICENSE.txt for license information + See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors + Responsibility: Michael LeHew + */ #include #include "CFInternal.h" @@ -20,60 +15,9 @@ #include "CFRuntime_Internal.h" -#define CFDictionary 0 -#define CFSet 0 -#define CFBag 0 -#undef CFSet -#define CFSet 1 - -#if CFDictionary - - -const CFSetKeyCallBacks kCFTypeSetKeyCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; -const CFSetKeyCallBacks kCFCopyStringSetKeyCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; -const CFSetValueCallBacks kCFTypeSetValueCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual}; - -#define CFHashRef CFDictionaryRef -#define CFMutableHashRef CFMutableDictionaryRef -#define CFHashKeyCallBacks CFSetKeyCallBacks -#define CFHashValueCallBacks CFSetValueCallBacks -#endif - -#if CFSet -const CFSetCallBacks kCFTypeSetCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; -const CFSetCallBacks kCFCopyStringSetCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; - -#define CFSetKeyCallBacks CFSetCallBacks -#define CFSetValueCallBacks CFSetCallBacks -#define kCFTypeSetKeyCallBacks kCFTypeSetCallBacks -#define kCFTypeSetValueCallBacks kCFTypeSetCallBacks - -#define CFHashRef CFSetRef -#define CFMutableHashRef CFMutableSetRef -#define CFHashKeyCallBacks CFSetCallBacks -#define CFHashValueCallBacks CFSetCallBacks -#endif - -#if CFBag const CFSetCallBacks kCFTypeSetCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; const CFSetCallBacks kCFCopyStringSetCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; -#define CFSetKeyCallBacks CFSetCallBacks -#define CFSetValueCallBacks CFSetCallBacks -#define kCFTypeSetKeyCallBacks kCFTypeSetCallBacks -#define kCFTypeSetValueCallBacks kCFTypeSetCallBacks - -#define CFHashRef CFBagRef -#define CFMutableHashRef CFMutableBagRef -#define CFHashKeyCallBacks CFSetCallBacks -#define CFHashValueCallBacks CFSetCallBacks -#endif - - -typedef uintptr_t any_t; -typedef const void * const_any_pointer_t; -typedef void * any_pointer_t; - static Boolean __CFSetEqual(CFTypeRef cf1, CFTypeRef cf2) { return __CFBasicHashEqual((CFBasicHashRef)cf1, (CFBasicHashRef)cf2); } @@ -106,52 +50,44 @@ CFTypeID CFSetGetTypeID(void) { return _kCFRuntimeIDCFSet; } - -static CFBasicHashRef __CFSetCreateGeneric(CFAllocatorRef allocator, const CFHashKeyCallBacks *keyCallBacks, const CFHashValueCallBacks *valueCallBacks, Boolean useValueCB) { +static CFBasicHashRef __CFSetCreateGeneric(CFAllocatorRef allocator, const CFSetCallBacks *inCallbacks) { CFOptionFlags flags = kCFBasicHashLinearHashing; // kCFBasicHashExponentialHashing - flags |= (CFDictionary ? kCFBasicHashHasKeys : 0) | (CFBag ? kCFBasicHashHasCounts : 0); - - + CFBasicHashCallbacks callbacks; - callbacks.retainKey = keyCallBacks ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))keyCallBacks->retain : NULL; - callbacks.releaseKey = keyCallBacks ? (void (*)(CFAllocatorRef, uintptr_t))keyCallBacks->release : NULL; - callbacks.equateKeys = keyCallBacks ? (Boolean (*)(uintptr_t, uintptr_t))keyCallBacks->equal : NULL; - callbacks.hashKey = keyCallBacks ? (CFHashCode (*)(uintptr_t))keyCallBacks->hash : NULL; + callbacks.retainKey = inCallbacks ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))inCallbacks->retain : NULL; + callbacks.releaseKey = inCallbacks ? (void (*)(CFAllocatorRef, uintptr_t))inCallbacks->release : NULL; + callbacks.equateKeys = inCallbacks ? (Boolean (*)(uintptr_t, uintptr_t))inCallbacks->equal : NULL; + callbacks.hashKey = inCallbacks ? (CFHashCode (*)(uintptr_t))inCallbacks->hash : NULL; callbacks.getIndirectKey = NULL; - callbacks.copyKeyDescription = keyCallBacks ? (CFStringRef (*)(uintptr_t))keyCallBacks->copyDescription : NULL; - callbacks.retainValue = useValueCB ? (valueCallBacks ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))valueCallBacks->retain : NULL) : (callbacks.retainKey); - callbacks.releaseValue = useValueCB ? (valueCallBacks ? (void (*)(CFAllocatorRef, uintptr_t))valueCallBacks->release : NULL) : (callbacks.releaseKey); - callbacks.equateValues = useValueCB ? (valueCallBacks ? (Boolean (*)(uintptr_t, uintptr_t))valueCallBacks->equal : NULL) : (callbacks.equateKeys); - callbacks.copyValueDescription = useValueCB ? (valueCallBacks ? (CFStringRef (*)(uintptr_t))valueCallBacks->copyDescription : NULL) : (callbacks.copyKeyDescription); - + callbacks.copyKeyDescription = inCallbacks ? (CFStringRef (*)(uintptr_t))inCallbacks->copyDescription : NULL; + callbacks.retainValue = callbacks.retainKey; + callbacks.releaseValue = callbacks.releaseKey; + callbacks.equateValues = callbacks.equateKeys; + callbacks.copyValueDescription = callbacks.copyKeyDescription; + CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, &callbacks); return ht; } -#if CFDictionary -CF_PRIVATE CFHashRef __CFSetCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, const_any_pointer_t *vlist, CFIndex numValues) { -#endif -#if CFSet || CFBag -CF_PRIVATE CFHashRef __CFSetCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIndex numValues) { - const_any_pointer_t *vlist = klist; -#endif +CF_PRIVATE CFSetRef __CFSetCreateTransfer(CFAllocatorRef allocator, const void **klist, CFIndex numValues) { + const void **vlist = klist; + CFTypeID typeID = CFSetGetTypeID(); CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues); CFOptionFlags flags = kCFBasicHashLinearHashing; // kCFBasicHashExponentialHashing - flags |= (CFDictionary ? kCFBasicHashHasKeys : 0) | (CFBag ? kCFBasicHashHasCounts : 0); - + CFBasicHashCallbacks callbacks; - callbacks.retainKey = (uintptr_t (*)(CFAllocatorRef, uintptr_t))kCFTypeSetKeyCallBacks.retain; - callbacks.releaseKey = (void (*)(CFAllocatorRef, uintptr_t))kCFTypeSetKeyCallBacks.release; - callbacks.equateKeys = (Boolean (*)(uintptr_t, uintptr_t))kCFTypeSetKeyCallBacks.equal; - callbacks.hashKey = (CFHashCode (*)(uintptr_t))kCFTypeSetKeyCallBacks.hash; + callbacks.retainKey = (uintptr_t (*)(CFAllocatorRef, uintptr_t))kCFTypeSetCallBacks.retain; + callbacks.releaseKey = (void (*)(CFAllocatorRef, uintptr_t))kCFTypeSetCallBacks.release; + callbacks.equateKeys = (Boolean (*)(uintptr_t, uintptr_t))kCFTypeSetCallBacks.equal; + callbacks.hashKey = (CFHashCode (*)(uintptr_t))kCFTypeSetCallBacks.hash; callbacks.getIndirectKey = NULL; - callbacks.copyKeyDescription = (CFStringRef (*)(uintptr_t))kCFTypeSetKeyCallBacks.copyDescription; - callbacks.retainValue = CFDictionary ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))kCFTypeSetValueCallBacks.retain : callbacks.retainKey; - callbacks.releaseValue = CFDictionary ? (void (*)(CFAllocatorRef, uintptr_t))kCFTypeSetValueCallBacks.release : callbacks.releaseKey; - callbacks.equateValues = CFDictionary ? (Boolean (*)(uintptr_t, uintptr_t))kCFTypeSetValueCallBacks.equal : callbacks.equateKeys; - callbacks.copyValueDescription = CFDictionary ? (CFStringRef (*)(uintptr_t))kCFTypeSetValueCallBacks.copyDescription : callbacks.copyKeyDescription; - + callbacks.copyKeyDescription = (CFStringRef (*)(uintptr_t))kCFTypeSetCallBacks.copyDescription; + callbacks.retainValue = callbacks.retainKey; + callbacks.releaseValue = callbacks.releaseKey; + callbacks.equateValues = callbacks.equateKeys; + callbacks.copyValueDescription = callbacks.copyKeyDescription; + CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, &callbacks); CFBasicHashSuppressRC(ht); if (0 < numValues) CFBasicHashSetCapacity(ht, numValues); @@ -162,20 +98,15 @@ CF_PRIVATE CFHashRef __CFSetCreateTransfer(CFAllocatorRef allocator, const_any_p CFBasicHashMakeImmutable(ht); _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (immutable)"); - return (CFHashRef)ht; + return (CFSetRef)ht; } -#if CFDictionary -CFHashRef CFSetCreate(CFAllocatorRef allocator, const_any_pointer_t *klist, const_any_pointer_t *vlist, CFIndex numValues, const CFSetKeyCallBacks *keyCallBacks, const CFSetValueCallBacks *valueCallBacks) { -#endif -#if CFSet || CFBag -CFHashRef CFSetCreate(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIndex numValues, const CFSetKeyCallBacks *keyCallBacks) { - const_any_pointer_t *vlist = klist; - const CFSetValueCallBacks *valueCallBacks = 0; -#endif +CFSetRef CFSetCreate(CFAllocatorRef allocator, const void **klist, CFIndex numValues, const CFSetCallBacks *callbacks) { + const void **vlist = klist; + CFTypeID typeID = CFSetGetTypeID(); CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues); - CFBasicHashRef ht = __CFSetCreateGeneric(allocator, keyCallBacks, valueCallBacks, CFDictionary); + CFBasicHashRef ht = __CFSetCreateGeneric(allocator, callbacks); if (!ht) return NULL; if (0 < numValues) CFBasicHashSetCapacity(ht, numValues); for (CFIndex idx = 0; idx < numValues; idx++) { @@ -184,52 +115,29 @@ CFHashRef CFSetCreate(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIn CFBasicHashMakeImmutable(ht); _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (immutable)"); - return (CFHashRef)ht; + return (CFSetRef)ht; } -#if CFDictionary -CFMutableHashRef CFSetCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFSetKeyCallBacks *keyCallBacks, const CFSetValueCallBacks *valueCallBacks) { -#endif -#if CFSet || CFBag -CFMutableHashRef CFSetCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFSetKeyCallBacks *keyCallBacks) { - const CFSetValueCallBacks *valueCallBacks = 0; -#endif +CFMutableSetRef CFSetCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFSetCallBacks *callbacks) { CFTypeID typeID = CFSetGetTypeID(); CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__, capacity); - CFBasicHashRef ht = __CFSetCreateGeneric(allocator, keyCallBacks, valueCallBacks, CFDictionary); + CFBasicHashRef ht = __CFSetCreateGeneric(allocator, callbacks); if (!ht) return NULL; _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (mutable)"); - return (CFMutableHashRef)ht; + return (CFMutableSetRef)ht; } -CFHashRef CFSetCreateCopy(CFAllocatorRef allocator, CFHashRef other) { +CFSetRef CFSetCreateCopy(CFAllocatorRef allocator, CFSetRef other) { CFTypeID typeID = CFSetGetTypeID(); CFAssert1(other, __kCFLogAssertion, "%s(): other CFSet cannot be NULL", __PRETTY_FUNCTION__); __CFGenericValidateType(other, typeID); Boolean markImmutable = false; CFBasicHashRef ht = NULL; if (CF_IS_OBJC(typeID, other)) { -#if CFDictionary || CFSet ht = (CFBasicHashRef)CF_OBJC_CALLV((id)other, copyWithZone:NULL); -#elif CFBag - CFIndex numValues = CFSetGetCount(other); - const_any_pointer_t vbuffer[256]; - const_any_pointer_t *vlist = (numValues <= 256) ? vbuffer : (const_any_pointer_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(const_any_pointer_t), 0); - const_any_pointer_t *klist = vlist; - CFSetGetValues(other, vlist); - ht = __CFSetCreateGeneric(allocator, & kCFTypeSetKeyCallBacks, CFDictionary ? & kCFTypeSetValueCallBacks : NULL, CFDictionary); - if (ht && 0 < numValues) CFBasicHashSetCapacity(ht, numValues); - for (CFIndex idx = 0; ht && idx < numValues; idx++) { - CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]); - } - if (vlist != vbuffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, vlist); - markImmutable = true; -#endif // CFBag } else if (CF_IS_SWIFT(typeID, other)) { -#if CFDictionary || CFSet ht = (CFBasicHashRef)CF_SWIFT_CALLV(other, NSObject.copyWithZone, nil); -#endif } else { // non-objc types ht = CFBasicHashCreateCopy(allocator, (CFBasicHashRef)other); markImmutable = true; @@ -238,12 +146,12 @@ CFHashRef CFSetCreateCopy(CFAllocatorRef allocator, CFHashRef other) { CFBasicHashMakeImmutable(ht); _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (immutable)"); - return (CFHashRef)ht; + return (CFSetRef)ht; } - return (CFHashRef)ht; + return (CFSetRef)ht; } -CFMutableHashRef CFSetCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFHashRef other) { +CFMutableSetRef CFSetCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFSetRef other) { CFTypeID typeID = CFSetGetTypeID(); CFAssert1(other, __kCFLogAssertion, "%s(): other CFSet cannot be NULL", __PRETTY_FUNCTION__); __CFGenericValidateType(other, typeID); @@ -251,17 +159,11 @@ CFMutableHashRef CFSetCreateMutableCopy(CFAllocatorRef allocator, CFIndex capaci CFBasicHashRef ht = NULL; if (CF_IS_OBJC(typeID, other) || CF_IS_SWIFT(typeID, other)) { CFIndex numValues = CFSetGetCount(other); - const_any_pointer_t vbuffer[256], kbuffer[256]; - const_any_pointer_t *vlist = (numValues <= 256) ? vbuffer : (const_any_pointer_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(const_any_pointer_t), 0); -#if CFSet || CFBag - const_any_pointer_t *klist = vlist; + const void *vbuffer[256], *kbuffer[256]; + const void **vlist = (numValues <= 256) ? vbuffer : (const void **)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(const void *), 0); + const void **klist = vlist; CFSetGetValues(other, vlist); -#endif -#if CFDictionary - const_any_pointer_t *klist = (numValues <= 256) ? kbuffer : (const_any_pointer_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(const_any_pointer_t), 0); - CFDictionaryGetKeysAndValues(other, klist, vlist); -#endif - ht = __CFSetCreateGeneric(allocator, & kCFTypeSetKeyCallBacks, CFDictionary ? & kCFTypeSetValueCallBacks : NULL, CFDictionary); + ht = __CFSetCreateGeneric(allocator, & kCFTypeSetCallBacks); if (ht && 0 < numValues) CFBasicHashSetCapacity(ht, numValues); for (CFIndex idx = 0; ht && idx < numValues; idx++) { CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]); @@ -274,171 +176,73 @@ CFMutableHashRef CFSetCreateMutableCopy(CFAllocatorRef allocator, CFIndex capaci if (!ht) return NULL; _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (mutable)"); - return (CFMutableHashRef)ht; + return (CFMutableSetRef)ht; } -CFIndex CFSetGetCount(CFHashRef hc) { -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), CFIndex, (CFSwiftRef)hc, NSDictionary.count); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), CFIndex, (NSDictionary *)hc, count); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), CFIndex, (CFSwiftRef)hc, NSSet.count); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), CFIndex, (NSSet *)hc, count); -#endif +CFIndex CFSetGetCount(CFSetRef hc) { + CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), CFIndex, (CFSwiftRef)hc, NSSet.count); + CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), CFIndex, (NSSet *)hc, count); __CFGenericValidateType(hc, CFSetGetTypeID()); return CFBasicHashGetCount((CFBasicHashRef)hc); } -#if CFDictionary -CFIndex CFSetGetCountOfKey(CFHashRef hc, const_any_pointer_t key) { -#endif -#if CFSet || CFBag -CFIndex CFSetGetCountOfValue(CFHashRef hc, const_any_pointer_t key) { -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), CFIndex, (CFSwiftRef)hc, NSDictionary.countForKey, key); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), CFIndex, (NSDictionary *)hc, countForKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), CFIndex, (CFSwiftRef)hc, NSSet.countForKey, key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), CFIndex, (NSSet *)hc, countForObject:(id)key); -#endif +CFIndex CFSetGetCountOfValue(CFSetRef hc, const void *key) { + CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), CFIndex, (CFSwiftRef)hc, NSSet.countForKey, key); + CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), CFIndex, (NSSet *)hc, countForObject:(id)key); __CFGenericValidateType(hc, CFSetGetTypeID()); return CFBasicHashGetCountOfKey((CFBasicHashRef)hc, (uintptr_t)key); } -#if CFDictionary -Boolean CFSetContainsKey(CFHashRef hc, const_any_pointer_t key) { -#endif -#if CFSet || CFBag -Boolean CFSetContainsValue(CFHashRef hc, const_any_pointer_t key) { -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), char, (CFSwiftRef)hc, NSDictionary.containsKey, key); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), char, (NSDictionary *)hc, containsKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), char, (CFSwiftRef)hc, NSSet.containsObject, (CFSwiftRef)key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), char, (NSSet *)hc, containsObject:(id)key); -#endif +Boolean CFSetContainsValue(CFSetRef hc, const void *key) { + CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), char, (CFSwiftRef)hc, NSSet.containsObject, (CFSwiftRef)key); + CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), char, (NSSet *)hc, containsObject:(id)key); __CFGenericValidateType(hc, CFSetGetTypeID()); return (0 < CFBasicHashGetCountOfKey((CFBasicHashRef)hc, (uintptr_t)key)); } -const_any_pointer_t CFSetGetValue(CFHashRef hc, const_any_pointer_t key) { -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), const_any_pointer_t, (CFSwiftRef)hc, NSDictionary.objectForKey, key); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), const_any_pointer_t, (NSDictionary *)hc, objectForKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), const_any_pointer_t, (CFSwiftRef)hc, NSSet.member, key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), const_any_pointer_t, (NSSet *)hc, member:(id)key); -#endif +const void *CFSetGetValue(CFSetRef hc, const void *key) { + CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), const void *, (CFSwiftRef)hc, NSSet.member, key); + CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), const void *, (NSSet *)hc, member:(id)key); __CFGenericValidateType(hc, CFSetGetTypeID()); CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key); - return (0 < bkt.count ? (const_any_pointer_t)bkt.weak_value : 0); + return (0 < bkt.count ? (const void *)bkt.weak_value : 0); } -Boolean CFSetGetValueIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *value) { -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), Boolean, (CFSwiftRef)hc, NSDictionary.__getValue, value, key); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), Boolean, (NSDictionary *)hc, __getValue:(id *)value forKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), Boolean, (CFSwiftRef)hc, NSSet.__getValue, value, key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), Boolean, (NSSet *)hc, __getValue:(id *)value forObj:(id)key); -#endif +Boolean CFSetGetValueIfPresent(CFSetRef hc, const void *key, const void **value) { + CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), Boolean, (CFSwiftRef)hc, NSSet.__getValue, value, key); + CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), Boolean, (NSSet *)hc, __getValue:(id *)value forObj:(id)key); __CFGenericValidateType(hc, CFSetGetTypeID()); CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key); if (0 < bkt.count) { if (value) { - *value = (const_any_pointer_t)bkt.weak_value; - } - return true; - } - return false; -} - -#if CFDictionary -CFIndex CFDictionaryGetCountOfValue(CFHashRef hc, const_any_pointer_t value) { - CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), CFIndex, (CFSwiftRef)hc, NSDictionary.count); - CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), CFIndex, (NSDictionary *)hc, countForObject:(id)value); - __CFGenericValidateType(hc, CFSetGetTypeID()); - return CFBasicHashGetCountOfValue((CFBasicHashRef)hc, (uintptr_t)value); -} - -Boolean CFDictionaryContainsValue(CFHashRef hc, const_any_pointer_t value) { - CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), char, (CFSwiftRef)hc, NSDictionary.containsObject, value); - CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), char, (NSDictionary *)hc, containsObject:(id)value); - __CFGenericValidateType(hc, CFSetGetTypeID()); - return (0 < CFBasicHashGetCountOfValue((CFBasicHashRef)hc, (uintptr_t)value)); -} - -CF_EXPORT Boolean CFDictionaryGetKeyIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *actualkey) { - __CFGenericValidateType(hc, CFSetGetTypeID()); - CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key); - if (0 < bkt.count) { - if (actualkey) { - *actualkey = (const_any_pointer_t)bkt.weak_key; + *value = (const void *)bkt.weak_value; } return true; } return false; } -#endif -#if CFDictionary -void CFSetGetKeysAndValues(CFHashRef hc, const_any_pointer_t *keybuf, const_any_pointer_t *valuebuf) { -#endif -#if CFSet || CFBag -void CFSetGetValues(CFHashRef hc, const_any_pointer_t *keybuf) { - const_any_pointer_t *valuebuf = 0; -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSDictionary.getObjects, valuebuf, keybuf); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated" - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSDictionary *)hc, getObjects:(id *)valuebuf andKeys:(id *)keybuf); -#pragma GCC diagnostic pop -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSSet.getObjects, keybuf); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSSet *)hc, getObjects:(id *)keybuf); -#endif +void CFSetGetValues(CFSetRef hc, const void **keybuf) { + const void **valuebuf = 0; + CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSSet.getObjects, keybuf); + CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSSet *)hc, getObjects:(id *)keybuf); __CFGenericValidateType(hc, CFSetGetTypeID()); CFBasicHashGetElements((CFBasicHashRef)hc, CFSetGetCount(hc), (uintptr_t *)valuebuf, (uintptr_t *)keybuf); } -void CFSetApplyFunction(CFHashRef hc, CFSetApplierFunction applier, any_pointer_t context) { +void CFSetApplyFunction(CFSetRef hc, CFSetApplierFunction applier, void *context) { FAULT_CALLBACK((void **)&(applier)); -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSDictionary.__apply, applier, context); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSDictionary *)hc, __apply:(void (*)(const void *, const void *, void *))applier context:(void *)context); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSSet.__apply, applier, context); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSSet *)hc, __applyValues:(void (*)(const void *, void *))applier context:(void *)context); -#endif + CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSSet.__apply, applier, context); + CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSSet *)hc, __applyValues:(void (*)(const void *, void *))applier context:(void *)context); __CFGenericValidateType(hc, CFSetGetTypeID()); CFBasicHashApply((CFBasicHashRef)hc, ^(CFBasicHashBucket bkt) { -#if CFDictionary - INVOKE_CALLBACK3(applier, (const_any_pointer_t)bkt.weak_key, (const_any_pointer_t)bkt.weak_value, context); -#endif -#if CFSet - INVOKE_CALLBACK2(applier, (const_any_pointer_t)bkt.weak_value, context); -#endif -#if CFBag - for (CFIndex cnt = bkt.count; cnt--;) { - INVOKE_CALLBACK2(applier, (const_any_pointer_t)bkt.weak_value, context); - } -#endif - return (Boolean)true; - }); + INVOKE_CALLBACK2(applier, (const void *)bkt.weak_value, context); + return (Boolean)true; + }); } // This function is for Foundation's benefit; no one else should use it. -CF_EXPORT unsigned long _CFSetFastEnumeration(CFHashRef hc, struct __objcFastEnumerationStateEquivalent *state, void *stackbuffer, unsigned long count) { +CF_EXPORT unsigned long _CFSetFastEnumeration(CFSetRef hc, struct __objcFastEnumerationStateEquivalent *state, void *stackbuffer, unsigned long count) { if (CF_IS_SWIFT(CFSetGetTypeID(), hc)) return 0; if (CF_IS_OBJC(CFSetGetTypeID(), hc)) return 0; __CFGenericValidateType(hc, CFSetGetTypeID()); @@ -446,7 +250,7 @@ CF_EXPORT unsigned long _CFSetFastEnumeration(CFHashRef hc, struct __objcFastEnu } // This function is for Foundation's benefit; no one else should use it. -CF_EXPORT Boolean _CFSetIsMutable(CFHashRef hc) { +CF_EXPORT Boolean _CFSetIsMutable(CFSetRef hc) { if (CF_IS_SWIFT(CFSetGetTypeID(), hc)) return false; if (CF_IS_OBJC(CFSetGetTypeID(), hc)) return false; __CFGenericValidateType(hc, CFSetGetTypeID()); @@ -454,7 +258,7 @@ CF_EXPORT Boolean _CFSetIsMutable(CFHashRef hc) { } // This function is for Foundation's benefit; no one else should use it. -CF_EXPORT void _CFSetSetCapacity(CFMutableHashRef hc, CFIndex cap) { +CF_EXPORT void _CFSetSetCapacity(CFMutableSetRef hc, CFIndex cap) { if (CF_IS_SWIFT(CFSetGetTypeID(), hc)) return; if (CF_IS_OBJC(CFSetGetTypeID(), hc)) return; __CFGenericValidateType(hc, CFSetGetTypeID()); @@ -463,148 +267,60 @@ CF_EXPORT void _CFSetSetCapacity(CFMutableHashRef hc, CFIndex cap) { CFBasicHashSetCapacity((CFBasicHashRef)hc, cap); } -CF_INLINE CFIndex __CFSetGetKVOBit(CFHashRef hc) { - return __CFRuntimeGetFlag(hc, 0); -} - -CF_INLINE void __CFSetSetKVOBit(CFHashRef hc, CFIndex bit) { - __CFRuntimeSetFlag(hc, 0, ((uintptr_t)bit & 0x1)); -} - -// This function is for Foundation's benefit; no one else should use it. -CF_EXPORT CFIndex _CFSetGetKVOBit(CFHashRef hc) { - return __CFSetGetKVOBit(hc); -} - -// This function is for Foundation's benefit; no one else should use it. -CF_EXPORT void _CFSetSetKVOBit(CFHashRef hc, CFIndex bit) { - __CFSetSetKVOBit(hc, bit); -} - - -#if !defined(CF_OBJC_KVO_WILLCHANGE) -#define CF_OBJC_KVO_WILLCHANGE(obj, key) -#define CF_OBJC_KVO_DIDCHANGE(obj, key) -#define CF_OBJC_KVO_WILLCHANGEALL(obj) -#define CF_OBJC_KVO_DIDCHANGEALL(obj) -#endif - -#if CFDictionary -void CFSetAddValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) { -#endif -#if CFSet || CFBag -void CFSetAddValue(CFMutableHashRef hc, const_any_pointer_t key) { - const_any_pointer_t value = key; -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.__addObject, key, value); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSMutableDictionary *)hc, __addObject:(id)value forKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.addObject, (CFSwiftRef)key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSMutableSet *)hc, addObject:(id)key); -#endif +void CFSetAddValue(CFMutableSetRef hc, const void *key) { + const void *value = key; + CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.addObject, (CFSwiftRef)key); + CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSMutableSet *)hc, addObject:(id)key); __CFGenericValidateType(hc, CFSetGetTypeID()); CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc); if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) { CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__, hc); } - CF_OBJC_KVO_WILLCHANGE(hc, key); CFBasicHashAddValue((CFBasicHashRef)hc, (uintptr_t)key, (uintptr_t)value); - CF_OBJC_KVO_DIDCHANGE(hc, key); } -#if CFDictionary -void CFSetReplaceValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) { -#endif -#if CFSet || CFBag -void CFSetReplaceValue(CFMutableHashRef hc, const_any_pointer_t key) { - const_any_pointer_t value = key; -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.replaceObject, key, value); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSMutableDictionary *)hc, replaceObject:(id)value forKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.replaceObject, (CFSwiftRef)key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSMutableSet *)hc, replaceObject:(id)key); -#endif +void CFSetReplaceValue(CFMutableSetRef hc, const void *key) { + const void *value = key; + CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.replaceObject, (CFSwiftRef)key); + CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSMutableSet *)hc, replaceObject:(id)key); __CFGenericValidateType(hc, CFSetGetTypeID()); CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc); if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) { CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__, hc); } - CF_OBJC_KVO_WILLCHANGE(hc, key); CFBasicHashReplaceValue((CFBasicHashRef)hc, (uintptr_t)key, (uintptr_t)value); - CF_OBJC_KVO_DIDCHANGE(hc, key); } -#if CFDictionary -void CFSetSetValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) { -#endif -#if CFSet || CFBag -void CFSetSetValue(CFMutableHashRef hc, const_any_pointer_t key) { - const_any_pointer_t value = key; -#endif -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.__setObject, key, value); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSMutableDictionary *)hc, __setObject:(id)value forKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.setObject, (CFSwiftRef)key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSMutableSet *)hc, setObject:(id)key); -#endif +void CFSetSetValue(CFMutableSetRef hc, const void *key) { + const void *value = key; + CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.setObject, (CFSwiftRef)key); + CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSMutableSet *)hc, setObject:(id)key); __CFGenericValidateType(hc, CFSetGetTypeID()); CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc); if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) { CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__, hc); } - CF_OBJC_KVO_WILLCHANGE(hc, key); -//#warning this for a dictionary used to not replace the key CFBasicHashSetValue((CFBasicHashRef)hc, (uintptr_t)key, (uintptr_t)value); - CF_OBJC_KVO_DIDCHANGE(hc, key); } -void CFSetRemoveValue(CFMutableHashRef hc, const_any_pointer_t key) { -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.removeObjectForKey, key); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSMutableDictionary *)hc, removeObjectForKey:(id)key); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.removeObject, (CFSwiftRef)key); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSMutableSet *)hc, removeObject:(id)key); -#endif +void CFSetRemoveValue(CFMutableSetRef hc, const void *key) { + CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.removeObject, (CFSwiftRef)key); + CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSMutableSet *)hc, removeObject:(id)key); __CFGenericValidateType(hc, CFSetGetTypeID()); CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc); if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) { CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__, hc); } - CF_OBJC_KVO_WILLCHANGE(hc, key); CFBasicHashRemoveValue((CFBasicHashRef)hc, (uintptr_t)key); - CF_OBJC_KVO_DIDCHANGE(hc, key); } -void CFSetRemoveAllValues(CFMutableHashRef hc) { -#if CFDictionary - if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSMutableDictionary.removeAllObjects); - if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSMutableDictionary *)hc, removeAllObjects); -#endif -#if CFSet - if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.removeAllObjects); - if (CFSet) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSMutableSet *)hc, removeAllObjects); -#endif +void CFSetRemoveAllValues(CFMutableSetRef hc) { + CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSMutableSet.removeAllObjects); + CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSMutableSet *)hc, removeAllObjects); __CFGenericValidateType(hc, CFSetGetTypeID()); CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc); if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) { CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__, hc); } - CF_OBJC_KVO_WILLCHANGEALL(hc); CFBasicHashRemoveAllValues((CFBasicHashRef)hc); - CF_OBJC_KVO_DIDCHANGEALL(hc); } - -#undef CF_OBJC_KVO_WILLCHANGE -#undef CF_OBJC_KVO_DIDCHANGE -#undef CF_OBJC_KVO_WILLCHANGEALL -#undef CF_OBJC_KVO_DIDCHANGEALL - diff --git a/CoreFoundation/Collections.subproj/CFSet.h b/CoreFoundation/Collections.subproj/CFSet.h index a9c0c34766..65e248c209 100644 --- a/CoreFoundation/Collections.subproj/CFSet.h +++ b/CoreFoundation/Collections.subproj/CFSet.h @@ -1,7 +1,7 @@ /* CFSet.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Collections.subproj/CFStorage.c b/CoreFoundation/Collections.subproj/CFStorage.c index 6942c43832..de1fb64168 100644 --- a/CoreFoundation/Collections.subproj/CFStorage.c +++ b/CoreFoundation/Collections.subproj/CFStorage.c @@ -1,7 +1,7 @@ /* CFStorage.c - Copyright (c) 1999-2018, Apple Inc. All rights reserved. + Copyright (c) 1999-2019, Apple Inc. All rights reserved. - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -142,7 +142,8 @@ CF_INLINE void __CFStorageAllocLeafNodeMemory(CFAllocatorRef allocator, CFStorag } } -#if 0 + +#if 0 || defined (__clang_analyzer__) #define ASSERT(x) do { if (! (x)) { fprintf(stderr, "Assertion %s failed on line %d\n", #x, __LINE__); HALT; } } while (0) #else #define ASSERT(x) do { if (0 && ! (x)) { } } while(0) @@ -200,7 +201,7 @@ CF_INLINE CFStorageNode *__CFStorageRetainNodeThreadUnsafe(CFStorageNode *node) static void __CFStorageDeallocateNode(CFStorageRef storage, CFStorageNode *node); -CF_INLINE void __CFStorageReleaseNode(CFStorageRef storage, CFStorageNode *node) { +CF_INLINE void __CFStorageReleaseNode(CFStorageRef storage, CFStorageNode * _Nonnull node) { if (node->refCount > 0) { uint32_t newRefCount = OSAtomicDecrement32((int32_t *)&node->refCount); if (newRefCount == 0) { @@ -244,7 +245,7 @@ static inline void __CFStorageSetChild(CFStorageNode *parentNode, CFIndex childI *((void **)&parentNode->info.notLeaf.child[childIndex]) = newChild; } -static inline void __CFStorageGetChildren(const CFStorageNode *parent, CFStorageNode ** _CF_RESTRICT resultArray, bool shouldRetain, bool shouldFreeze) { +static inline void __CFStorageGetChildren(const CFStorageNode * _Nonnull parent, CFStorageNode ** _CF_RESTRICT resultArray, bool shouldRetain, bool shouldFreeze) { ASSERT(! parent->isLeaf); CFIndex i; for (i=0; i < 3; i++) { @@ -252,6 +253,10 @@ static inline void __CFStorageGetChildren(const CFStorageNode *parent, CFStorage if (node != NULL && shouldRetain) __CFStorageRetainNode(node); if (node != NULL && shouldFreeze) __CFStorageFreezeNode(node); resultArray[i] = node; +#ifdef __clang_analyzer__ + // There's an implicit invariant that all non-NULL child nodes are at the front of the array, with all NULLs after. This check will satisfy to the analyzer that that invariant holds. + if (node == NULL) break; +#endif } } @@ -307,7 +312,7 @@ CF_INLINE uint8_t *__CFStorageGetFromCache(CFStorageRef storage, CFIndex loc, CF relativeByteNum (not optional, for performance reasons) returns the relative byte number of the specified byte in the child. Don't call with leaf nodes! */ -CF_INLINE CFStorageNode *__CFStorageFindChild(const CFStorageNode * _CF_RESTRICT node, CFIndex byteNum, bool forInsertionOrDeletion, CFIndex * _CF_RESTRICT childNum, CFIndex * _CF_RESTRICT relativeByteNum) { +CF_INLINE CFStorageNode * _Nonnull __CFStorageFindChild(const CFStorageNode * _CF_RESTRICT node, CFIndex byteNum, bool forInsertionOrDeletion, CFIndex * _CF_RESTRICT childNum, CFIndex * _CF_RESTRICT relativeByteNum) { if (forInsertionOrDeletion) byteNum--; /* If for insertion, we do <= checks, not <, so this accomplishes the same thing */ CFStorageNode *result; result = node->info.notLeaf.child[0]; @@ -440,14 +445,14 @@ static void __CFStorageDeallocateNode(CFStorageRef storage, CFStorageNode *node) The Insertion functions return two nodes. As an awful performance hack, if the first node returned from __CFStorageInsert* is the same as the node passed in, that node is *not* retained, so should not be relased. If it is a different node, it is retained. */ -static CFStorageDoubleNodeReturn __CFStorageInsert(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode *node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum); -static CFStorageNode *__CFStorageDelete(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode *node, CFRange range, bool compact); +static CFStorageDoubleNodeReturn __CFStorageInsert(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode * _Nonnull node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum); +static CFStorageNode *__CFStorageDelete(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode * _Nonnull node, CFRange range, bool compact); -static CFStorageDoubleNodeReturn __CFStorageInsertFrozen(CFAllocatorRef allocator, CFStorageRef storage, const CFStorageNode *node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum); +static CFStorageDoubleNodeReturn __CFStorageInsertFrozen(CFAllocatorRef allocator, CFStorageRef storage, const CFStorageNode * _Nonnull node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum); static CFStorageNode *__CFStorageDeleteFrozen(CFAllocatorRef allocator, CFStorageRef storage, const CFStorageNode *node, CFRange range); -static CFStorageDoubleNodeReturn __CFStorageInsertUnfrozen(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode *node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum); -static CFStorageNode *__CFStorageDeleteUnfrozen(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode *node, CFRange range, bool compact, bool isRootNode); +static CFStorageDoubleNodeReturn __CFStorageInsertUnfrozen(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode * _Nonnull node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum); +static CFStorageNode *__CFStorageDeleteUnfrozen(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode * _Nonnull node, CFRange range, bool compact, bool isRootNode); #pragma mark Frozen Deletion @@ -591,8 +596,8 @@ static CFStorageNode *__CFStorageDeleteUnfrozen(CFAllocatorRef allocator, CFStor CFStorageNode *newChildren[3] = {NULL, NULL, NULL}; CFIndex newChildIndex = __CFStoragePopulateBranchChildrenAfterDeletion(allocator, storage, node, range, newChildren, false/*childrenAreDefinitelyFrozen*/, compact); node->numBytes -= range.length; - ASSERT(newChildIndex >= 1); //we expect to have at least one child; else we would have deleted everything up above - + ASSERT(newChildIndex >= 1 && node->info.notLeaf.child[0]); //we expect to have at least one child; else we would have deleted everything up above + /* Release all of our existing children. Either we are about to return a new child in place of us; or we are about to set our children to the new ones */ __CFStorageReleaseNode(storage, node->info.notLeaf.child[0]); __CFStorageReleaseNodeWithNullCheck(storage, node->info.notLeaf.child[1]); @@ -617,7 +622,7 @@ static CFStorageNode *__CFStorageDeleteUnfrozen(CFAllocatorRef allocator, CFStor #pragma mark Frozen Insertion /* Insertion into an frozen leaf. We return two nodes, either of which may be 'node', or possibly two new nodes. This always sets the cache. */ -static CFStorageDoubleNodeReturn __CFStorageInsertLeafFrozen(CFAllocatorRef allocator, CFStorageRef storage, const CFStorageNode *node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum) { +static CFStorageDoubleNodeReturn __CFStorageInsertLeafFrozen(CFAllocatorRef allocator, CFStorageRef storage, const CFStorageNode * _Nonnull node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum) { /* Inserting into a frozen leaf. If we can fit the new data along with our existing data into a single node, then do so (i.e. if we can return one node, do it). Otherwise, all of the data would have to fit into a second node (we are never called with more data than storage->maxLeafCapacity) so just make a new node with the data and return that. */ CFStorageNode *leftResult, *rightResult; CHECK_NODE_INTEGRITY(node); @@ -683,7 +688,7 @@ static CFStorageDoubleNodeReturn __CFStorageInsertLeafFrozen(CFAllocatorRef allo return CFStorageDoubleNodeReturnMake(leftResult, rightResult); } -static CFStorageDoubleNodeReturn __CFStorageInsertBranchFrozen(CFAllocatorRef allocator, CFStorageRef storage, const CFStorageNode *node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum) { +static CFStorageDoubleNodeReturn __CFStorageInsertBranchFrozen(CFAllocatorRef allocator, CFStorageRef storage, const CFStorageNode * _Nonnull node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum) { /* Inserting into a frozen branch. We definitely will need to make a new copy of us, so make that up front. We may or may not need to make a new sibling. Note that in some cases, we may be able to get away with not creating a new copy of us, e.g. inserting at the very end of the tree. In that case, we could preserve us and make a sibling containing exactly one node. However, we do not really want to have branches with exactly one child; because then why not just return the child? And then the whole tree can become unbalanced. So then instead, always distribute the children equally among our nodes. */ CHECK_NODE_INTEGRITY(node); CFStorageNode *copyOfMe = __CFStorageCreateNode(allocator, storage, false, 0); @@ -692,12 +697,14 @@ static CFStorageDoubleNodeReturn __CFStorageInsertBranchFrozen(CFAllocatorRef al CFIndex childNum; CFStorageNode *child = __CFStorageFindChild(node, byteNum, true, &childNum, &relativeByteNum); ASSERT(childNum >= 0 && childNum <= 2); + ASSERT(child); CFStorageDoubleNodeReturn childReturn = __CFStorageInsertFrozen(allocator, storage, child, relativeByteNum, size, absoluteByteNum); ASSERT(childReturn.child); //we always get at least one back /* Make a local array of all new children (retained). We'll then move them to the new nodes. */ CFStorageNode *newChildren[4] = {NULL}; __CFStorageGetChildren(node, newChildren, true/*retain*/, true/*freeze*/); + ASSERT(newChildren[childNum]); // node's children is unchanged since __CFStorageFindChild. if (newChildren[childNum] != childReturn.child) { __CFStorageReleaseNode(storage, newChildren[childNum]); newChildren[childNum] = childReturn.child; // Transfers the retain @@ -730,7 +737,7 @@ static CFStorageDoubleNodeReturn __CFStorageInsertBranchFrozen(CFAllocatorRef al return CFStorageDoubleNodeReturnMake(copyOfMe, siblingOfMe); } -static CFStorageDoubleNodeReturn __CFStorageInsertFrozen(CFAllocatorRef allocator, CFStorageRef storage, const CFStorageNode *node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum) { +static CFStorageDoubleNodeReturn __CFStorageInsertFrozen(CFAllocatorRef allocator, CFStorageRef storage, const CFStorageNode * _Nonnull node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum) { if (node->isLeaf) { return __CFStorageInsertLeafFrozen(allocator, storage, node, byteNum, size, absoluteByteNum); } @@ -743,7 +750,7 @@ static CFStorageDoubleNodeReturn __CFStorageInsertFrozen(CFAllocatorRef allocato #pragma mark Unfrozen Insertion /* Insertion into an unfrozen leaf. We return two nodes, one of which is 'node'. This always sets the cache. */ -static CFStorageDoubleNodeReturn __CFStorageInsertLeafUnfrozen(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode *node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum) { +static CFStorageDoubleNodeReturn __CFStorageInsertLeafUnfrozen(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode * _Nonnull node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum) { if (size + node->numBytes > storage->maxLeafCapacity) { // Need to create more child nodes CFStorageNode *newNode; if (byteNum == node->numBytes) { // Inserting at end; easy... @@ -796,13 +803,13 @@ static CFStorageDoubleNodeReturn __CFStorageInsertLeafUnfrozen(CFAllocatorRef al } } -static CFStorageDoubleNodeReturn __CFStorageInsertBranchUnfrozen(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode *node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum) { +static CFStorageDoubleNodeReturn __CFStorageInsertBranchUnfrozen(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode * _Nonnull node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum) { CFIndex relativeByteNum; CFIndex childNum; // we will insert after childNum, i.e. if childNum is 0, any new node becomes index 1. This can have value 0, 1, or 2. CFStorageNode *childNode = __CFStorageFindChild(node, byteNum, true, &childNum, &relativeByteNum); + ASSERT(childNode != NULL); CFStorageDoubleNodeReturn newNodes = __CFStorageInsert(allocator, storage, childNode, relativeByteNum, size, absoluteByteNum); CFStorageDoubleNodeReturn result = {node, NULL}; // the default return value meaning we did all of the work ourselves and our parent does not need to do anything - ASSERT(childNode != NULL); ASSERT(newNodes.child != NULL); if (newNodes.child != childNode) { @@ -851,7 +858,7 @@ static CFStorageDoubleNodeReturn __CFStorageInsertBranchUnfrozen(CFAllocatorRef /* Returns NULL or additional node to come after this node Assumption: size is never > storage->maxLeafCapacity */ -static CFStorageDoubleNodeReturn __CFStorageInsertUnfrozen(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode *node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum) { +static CFStorageDoubleNodeReturn __CFStorageInsertUnfrozen(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode * _Nonnull node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum) { ASSERT(! node->isFrozen); if (node->isLeaf) { return __CFStorageInsertLeafUnfrozen(allocator, storage, node, byteNum, size, absoluteByteNum); @@ -862,7 +869,7 @@ static CFStorageDoubleNodeReturn __CFStorageInsertUnfrozen(CFAllocatorRef alloca #pragma mark Frozen or Unfrozen Dispatch Functions -static CFStorageDoubleNodeReturn __CFStorageInsert(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode *node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum) { +static CFStorageDoubleNodeReturn __CFStorageInsert(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode * _Nonnull node, CFIndex byteNum, CFIndex size, CFIndex absoluteByteNum) { if (node->isFrozen && ! __CFStorageThawNodeDuringMutation(storage, node)) { return __CFStorageInsertFrozen(allocator, storage, node, byteNum, size, absoluteByteNum); } @@ -871,7 +878,7 @@ static CFStorageDoubleNodeReturn __CFStorageInsert(CFAllocatorRef allocator, CFS } } -static CFStorageNode *__CFStorageDelete(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode *node, CFRange range, bool compact) { +static CFStorageNode *__CFStorageDelete(CFAllocatorRef allocator, CFStorageRef storage, CFStorageNode * _Nonnull node, CFRange range, bool compact) { if (node->isFrozen && ! __CFStorageThawNodeDuringMutation(storage, node)) { return __CFStorageDeleteFrozen(allocator, storage, node, range); } @@ -985,7 +992,7 @@ static bool __CFStorageEnumerateNodesInByteRangeWithBlock(CFStorageRef storage, CFStorageNode ** childrenPtr = children; #if __HAS_DISPATCH__ __block bool blockStop = false; - dispatch_apply(numChildren, __CFDispatchQueueGetGenericMatchingCurrent(), ^(size_t ind) { + dispatch_apply(numChildren, DISPATCH_APPLY_AUTO, ^(size_t ind) { if (! blockStop && overlapsPtr[ind].length > 0) { if (__CFStorageEnumerateNodesInByteRangeWithBlock(storage, childrenPtr[ind], globalOffsetOfNode + offsetsPtr[ind], CFRangeMake(overlapsPtr[ind].location - offsetsPtr[ind], overlapsPtr[ind].length), concurrencyToken, applier)) { blockStop = true; @@ -1111,9 +1118,7 @@ CFStorageRef CFStorageCreate(CFAllocatorRef allocator, CFIndex valueSize) { if (valueSize && ((storage->maxLeafCapacity % valueSize) != 0)) { storage->maxLeafCapacity = (storage->maxLeafCapacity / valueSize) * valueSize; // Make it fit perfectly (3406853) } - memset(&(storage->rootNode), 0, sizeof(CFStorageNode)); storage->rootNode.isLeaf = true; - storage->rootNode.refCount = 0; if (__CFOASafe) __CFSetLastAllocationEventName(storage, "CFStorage"); return storage; } diff --git a/CoreFoundation/Collections.subproj/CFStorage.h b/CoreFoundation/Collections.subproj/CFStorage.h index ac267d85eb..a7361b84e4 100644 --- a/CoreFoundation/Collections.subproj/CFStorage.h +++ b/CoreFoundation/Collections.subproj/CFStorage.h @@ -1,7 +1,7 @@ /* CFStorage.h - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -50,7 +50,7 @@ typedef struct CF_BRIDGED_MUTABLE_TYPE(id) __CFStorage *CFStorageRef; @typedef CFStorageApplierFunction Type of the callback function used by the apply functions of CFStorage. - @param value The current value from the storage. + @param val The current value from the storage. @param context The user-defined context parameter given to the apply function. */ diff --git a/CoreFoundation/Collections.subproj/CFTree.c b/CoreFoundation/Collections.subproj/CFTree.c index 0f87429973..e929891396 100644 --- a/CoreFoundation/Collections.subproj/CFTree.c +++ b/CoreFoundation/Collections.subproj/CFTree.c @@ -1,11 +1,11 @@ /* CFTree.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Christopher Kane + Responsibility: Michael LeHew */ #include @@ -127,10 +127,6 @@ CFTreeRef CFTreeCreate(CFAllocatorRef allocator, const CFTreeContext *context) { if (NULL == memory) { return NULL; } - memory->_parent = NULL; - memory->_sibling = NULL; - memory->_child = NULL; - memory->_rightmostChild = NULL; /* Start the context off in a recognizable state */ __CFRuntimeSetValue(memory, 1, 0, __kCFTreeHasNullCallBacks); diff --git a/CoreFoundation/Collections.subproj/CFTree.h b/CoreFoundation/Collections.subproj/CFTree.h index ce5694dd31..9b0251653b 100644 --- a/CoreFoundation/Collections.subproj/CFTree.h +++ b/CoreFoundation/Collections.subproj/CFTree.h @@ -1,7 +1,7 @@ /* CFTree.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Error.subproj/CFError.c b/CoreFoundation/Error.subproj/CFError.c index 77dd9d2612..ab48eb42a4 100644 --- a/CoreFoundation/Error.subproj/CFError.c +++ b/CoreFoundation/Error.subproj/CFError.c @@ -1,7 +1,7 @@ /* CFError.c - Copyright (c) 2006-2018, Apple Inc. and the Swift project authors + Copyright (c) 2006-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -70,7 +70,7 @@ static CFDictionaryRef _CFErrorCreateEmptyDictionary(CFAllocatorRef allocator); /* This lock is used in the few places in CFError where we create and access shared static objects. Should only be around tiny snippets of code; no recursion */ -static CFLock_t _CFErrorSpinlock = CFLockInit; +static os_unfair_lock _CFErrorLock = OS_UNFAIR_LOCK_INIT; @@ -169,16 +169,13 @@ CFTypeID CFErrorGetTypeID(void) { */ static CFDictionaryRef _CFErrorCreateEmptyDictionary(CFAllocatorRef allocator) { if (allocator == NULL) allocator = __CFGetDefaultAllocator(); +#if DEPLOYMENT_TARGET_OBJC if (_CFAllocatorIsSystemDefault(allocator)) { - static CFDictionaryRef emptyErrorDictionary = NULL; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - emptyErrorDictionary = CFDictionaryCreate(allocator, NULL, NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - }); - return (CFDictionaryRef)CFRetain(emptyErrorDictionary); - } else { - return CFDictionaryCreate(allocator, NULL, NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + return (CFDictionaryRef)CFRetain(__NSDictionary0__); } +#endif + + return CFDictionaryCreate(allocator, NULL, NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } /* A non-retained accessor for the userInfo. Might return NULL in some cases, if the subclass of NSError returned nil for some reason. It works with a CF or NSError. @@ -249,13 +246,13 @@ CFStringRef _CFErrorCreateLocalizedDescription(CFErrorRef err) { CFStringRef reason = _CFErrorCopyUserInfoKey(err, kCFErrorLocalizedFailureReasonKey); // This can come from userInfo or callback if (reason) { CFStringRef const backstopComboString = CFSTR("%@ %@"); - CFStringRef comboString = backstopComboString; + CFStringRef comboString = NULL; #if TARGET_OS_MAC || TARGET_OS_WIN32 CFBundleRef cfBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.CoreFoundation")); if (cfBundle) comboString = CFCopyLocalizedStringFromTableInBundle(CFSTR("%@ %@"), CFSTR("Error"), cfBundle, "Used for presenting the 'what failed' and 'why it failed' sections of an error message, where each one is one or more complete sentences. The first %@ corresponds to the 'what failed' (For instance 'The file could not be saved.') and the second one 'why it failed' (For instance 'The volume is out of space.')"); #endif - CFStringRef result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, comboString, failure, reason); - if (comboString && comboString != backstopComboString) CFRelease(comboString); + CFStringRef result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, comboString ?: backstopComboString, failure, reason); + if (comboString) CFRelease(comboString); CFRelease(failure); CFRelease(reason); return result; @@ -339,7 +336,10 @@ static void _CFErrorFormatDebugDescriptionAux(CFErrorRef err, errorFormattingCon static void userInfoKeyValueShow(const void *key, const void *value, void *ctxt) { errorFormattingContext *context = ctxt; - if (CFEqual(key, kCFErrorUnderlyingErrorKey)) { + if (context == NULL) { + HALT_MSG("*** userInfoKeyValueShow() called with NULL context ***"); + } + if (CFEqual(key, kCFErrorUnderlyingErrorKey) && value != NULL && CFGetTypeID(value) == CFErrorGetTypeID()) { CFStringAppendFormat(context->result, NULL, CFSTR("%@=%p {"), key, value); _CFErrorFormatDebugDescriptionAux((CFErrorRef)value, context); CFStringAppend(context->result, CFSTR("}, ")); @@ -560,7 +560,7 @@ static void _CFErrorInitializeCallBackTable(void) { dictionaryValueCallBacks.release = blockReleaseValueCallBack; CFMutableDictionaryRef table = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, &dictionaryValueCallBacks); - __CFLock(&_CFErrorSpinlock); + os_unfair_lock_lock_with_options(&_CFErrorLock, OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION); if (!_CFErrorCallBackTable) { _CFErrorCallBackTable = table; // Register the known providers, going thru a special variant of the function that doesn't lock @@ -568,38 +568,38 @@ static void _CFErrorInitializeCallBackTable(void) { #if TARGET_OS_MAC __CFErrorSetCallBackForDomainNoLock(kCFErrorDomainMach, _CFErrorMachCallBack); #endif - __CFUnlock(&_CFErrorSpinlock); + os_unfair_lock_unlock(&_CFErrorLock); } else { - __CFUnlock(&_CFErrorSpinlock); + os_unfair_lock_unlock(&_CFErrorLock); CFRelease(table); } } void CFErrorSetCallBackBlockForDomain(CFStringRef domainName, CFErrorUserInfoKeyCallBackBlock block) { if (!_CFErrorCallBackTable) _CFErrorInitializeCallBackTable(); - __CFLock(&_CFErrorSpinlock); + os_unfair_lock_lock_with_options(&_CFErrorLock, OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION); if (block) { CFDictionarySetValue(_CFErrorCallBackTable, domainName, (void *)block); } else { CFDictionaryRemoveValue(_CFErrorCallBackTable, domainName); } - __CFUnlock(&_CFErrorSpinlock); + os_unfair_lock_unlock(&_CFErrorLock); } CFErrorUserInfoKeyCallBackBlock CFErrorGetCallBackBlockForDomain(CFStringRef domainName) { if (!_CFErrorCallBackTable) _CFErrorInitializeCallBackTable(); - __CFLock(&_CFErrorSpinlock); + os_unfair_lock_lock_with_options(&_CFErrorLock, OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION); CFErrorUserInfoKeyCallBackBlock callBack = _CFErrorCallBackTable ? (CFErrorUserInfoKeyCallBackBlock)CFDictionaryGetValue(_CFErrorCallBackTable, domainName) : NULL; - __CFUnlock(&_CFErrorSpinlock); + os_unfair_lock_unlock(&_CFErrorLock); return callBack; } CFErrorUserInfoKeyCallBackBlock CFErrorCopyCallBackBlockForDomain(CFStringRef domainName) { if (!_CFErrorCallBackTable) _CFErrorInitializeCallBackTable(); - __CFLock(&_CFErrorSpinlock); + os_unfair_lock_lock_with_options(&_CFErrorLock, OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION); CFErrorUserInfoKeyCallBackBlock callBack = _CFErrorCallBackTable ? (CFErrorUserInfoKeyCallBackBlock)CFDictionaryGetValue(_CFErrorCallBackTable, domainName) : NULL; if (callBack) CFRetain(callBack); - __CFUnlock(&_CFErrorSpinlock); + os_unfair_lock_unlock(&_CFErrorLock); return callBack; } diff --git a/CoreFoundation/Error.subproj/CFError.h b/CoreFoundation/Error.subproj/CFError.h index 7cd3ebb077..cfe74fb55d 100644 --- a/CoreFoundation/Error.subproj/CFError.h +++ b/CoreFoundation/Error.subproj/CFError.h @@ -1,7 +1,7 @@ /* CFError.h - Copyright (c) 2006-2018, Apple Inc. and the Swift project authors + Copyright (c) 2006-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Error.subproj/CFError_Private.h b/CoreFoundation/Error.subproj/CFError_Private.h index c7649d2150..f046650c72 100644 --- a/CoreFoundation/Error.subproj/CFError_Private.h +++ b/CoreFoundation/Error.subproj/CFError_Private.h @@ -1,7 +1,7 @@ /* CFError_Private.h - Copyright (c) 2006-2018, Apple Inc. and the Swift project authors + Copyright (c) 2006-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Locale.subproj/CFCalendar.c b/CoreFoundation/Locale.subproj/CFCalendar.c index 7fe113cafa..8169570c36 100644 --- a/CoreFoundation/Locale.subproj/CFCalendar.c +++ b/CoreFoundation/Locale.subproj/CFCalendar.c @@ -1,7 +1,7 @@ /* CFCalendar.c - Copyright (c) 2004-2018, Apple Inc. and the Swift project authors + Copyright (c) 2004-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -568,21 +568,51 @@ CF_PRIVATE void __CFCalendarZapCal(CFCalendarRef calendar) { ICU_LOG(" if (cal) ucal_close(cal);\n"); } -CFCalendarRef CFCalendarCopyCurrent(void) { - CFLocaleRef locale = CFLocaleCopyCurrent(); - CFStringRef calID = (CFStringRef)CFLocaleGetValue(locale, kCFLocaleCalendarIdentifierKey); - if (calID) { - CFCalendarRef calendar = CFCalendarCreateWithIdentifier(kCFAllocatorSystemDefault, calID); - if (calendar) CFCalendarSetLocale(calendar, locale); - CFRelease(locale); - return calendar; - } else if(locale) { - CFRelease(locale); +// Applies user-editable settings (first weekday, minimum days in first week) from the given locale onto the given calendar without applying the locale onto the calendar. +static void __CFCalendarApplyUserSettingsFromLocale(CFCalendarRef calendar, CFLocaleRef locale) { + CFDictionaryRef prefs = __CFLocaleGetPrefs(locale); + if (prefs && !calendar->_userSet_firstWeekday) { + CFPropertyListRef metapref = (CFPropertyListRef)CFDictionaryGetValue(prefs, CFSTR("AppleFirstWeekday")); + if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) { + metapref = (CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)metapref, calendar->_identifier); + } + if (NULL != metapref && CFGetTypeID(metapref) == CFNumberGetTypeID()) { + CFIndex wkdy; + if (CFNumberGetValue((CFNumberRef)metapref, kCFNumberCFIndexType, &wkdy)) { + calendar->_firstWeekday = wkdy; + if (calendar->_cal) { + __cficu_ucal_setAttribute(calendar->_cal, UCAL_FIRST_DAY_OF_WEEK, wkdy); + ICU_LOG(" ucal_setAttribute(cal, UCAL_FIRST_DAY_OF_WEEK, %ld);\n", wkdy); + } + } + } + } + + if (prefs && !calendar->_userSet_minDaysInFirstWeek) { + CFPropertyListRef metapref = (CFPropertyListRef)CFDictionaryGetValue(prefs, CFSTR("AppleMinDaysInFirstWeek")); + if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) { + metapref = (CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)metapref, calendar->_identifier); + } + if (NULL != metapref && CFGetTypeID(metapref) == CFNumberGetTypeID()) { + CFIndex mwd; + if (CFNumberGetValue((CFNumberRef)metapref, kCFNumberCFIndexType, &mwd)) { + calendar->_minDaysInFirstWeek = mwd; + if (calendar->_cal) { + __cficu_ucal_setAttribute(calendar->_cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK, mwd); + ICU_LOG(" ucal_setAttribute(cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK, %ld);\n", mwd); + } + } + } } - return NULL; } -static CFStringRef _CFCalendarGetCanonicalIdentifier(CFStringRef identifier) { + +static bool _CFCalendarInitialize(CFCalendarRef calendar, CFAllocatorRef allocator, CFStringRef identifier, CFTimeZoneRef tz, CFLocaleRef locale, CFIndex firstDayOfWeek, CFIndex minDaysInFirstWeek, CFDateRef gregorianStartDate) { + ICU_LOG(" // CFCalendarCreateWithIdentifier enter\n"); + if (allocator == NULL) allocator = __CFGetDefaultAllocator(); + __CFGenericValidateType(allocator, CFAllocatorGetTypeID()); + __CFGenericValidateType(identifier, CFStringGetTypeID()); + CFStringRef canonicalIdent = NULL; if (CFEqual(kCFCalendarIdentifierGregorian, identifier)) canonicalIdent = kCFCalendarIdentifierGregorian; else if (CFEqual(kCFCalendarIdentifierJapanese, identifier)) canonicalIdent = kCFCalendarIdentifierJapanese; @@ -600,54 +630,49 @@ static CFStringRef _CFCalendarGetCanonicalIdentifier(CFStringRef identifier) { else if (CFEqual(kCFCalendarIdentifierISO8601, identifier)) canonicalIdent = kCFCalendarIdentifierISO8601; else if (CFEqual(kCFCalendarIdentifierIslamicTabular, identifier)) canonicalIdent = kCFCalendarIdentifierIslamicTabular; else if (CFEqual(kCFCalendarIdentifierIslamicUmmAlQura, identifier)) canonicalIdent = kCFCalendarIdentifierIslamicUmmAlQura; - - return canonicalIdent; -} - -CF_CROSS_PLATFORM_EXPORT Boolean _CFCalendarInitWithIdentifier(CFCalendarRef calendar, CFStringRef identifier) { - CFStringRef canonicalIdent = _CFCalendarGetCanonicalIdentifier(identifier); - if (!canonicalIdent) ICU_LOG(" // _CFCalendarInitWithIdentifier exit false 1\n"); + if (!canonicalIdent) ICU_LOG(" // CFCalendarCreateWithIdentifier exit NULL 1\n"); if (!canonicalIdent) return false; - - calendar->_identifier = (CFStringRef)CFRetain(canonicalIdent); - calendar->_locale = CFRetain(CFLocaleGetSystem()); - calendar->_tz = CFTimeZoneCopyDefault(); - UCalendar *ucalendar = __CFCalendarCreateUCalendar(calendar->_identifier, CFLocaleGetIdentifier(calendar->_locale), calendar->_tz); - if (!ucalendar) { - ICU_LOG(" // _CFCalendarInitWithIdentifier exit false 2\n"); + calendar->_identifier = (CFStringRef)CFRetain(canonicalIdent); + calendar->_locale = locale ? CFLocaleCreateCopy(allocator, locale) : CFRetain(CFLocaleGetSystem()); + calendar->_tz = tz ? CFRetain(tz) : CFTimeZoneCopyDefault(); + calendar->_cal = __CFCalendarCreateUCalendar(calendar->_identifier, CFLocaleGetIdentifier(calendar->_locale), calendar->_tz); + if (!calendar->_cal) { + ICU_LOG(" // CFCalendarCreateWithIdentifier exit NULL 3\n"); return false; } - calendar->_cal = ucalendar; - - calendar->_firstWeekday = __cficu_ucal_getAttribute(calendar->_cal, UCAL_FIRST_DAY_OF_WEEK); - calendar->_minDaysInFirstWeek = __cficu_ucal_getAttribute(calendar->_cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK); + calendar->_firstWeekday = firstDayOfWeek == kCFNotFound ? __cficu_ucal_getAttribute(calendar->_cal, UCAL_FIRST_DAY_OF_WEEK) : firstDayOfWeek; + calendar->_minDaysInFirstWeek = minDaysInFirstWeek == kCFNotFound ? __cficu_ucal_getAttribute(calendar->_cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK) : minDaysInFirstWeek; ICU_LOG(" int32_t firstWeekday = ucal_getAttribute(cal, UCAL_FIRST_DAY_OF_WEEK);\n"); ICU_LOG(" int32_t minDaysInFirstWeek = ucal_getAttribute(cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK);\n"); if (kCFCalendarIdentifierGregorian == calendar->_identifier) { ICU_LOG(" UErrorCode status = U_ZERO_ERROR;\n"); ICU_LOG(" UDate udate = ucal_getGregorianChange(cal, &status);\n"); ICU_LOG(" CFAbsoluteTime gregorianStart = U_SUCCESS(status) ? (udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970) : -13197600000.0;\n"); + CFAbsoluteTime at = 0; + if (gregorianStartDate) { + at = CFDateGetAbsoluteTime(gregorianStartDate); + calendar->_gregorianStart = CFRetain(gregorianStartDate); + } else { + UErrorCode status = U_ZERO_ERROR; + UDate udate = __cficu_ucal_getGregorianChange(calendar->_cal, &status); + at = U_SUCCESS(status) ? (udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970) : -13197600000.0; // Oct 15, 1582 + calendar->_gregorianStart = CFDateCreate(CFGetAllocator(calendar), at); + } UErrorCode status = U_ZERO_ERROR; - UDate udate = __cficu_ucal_getGregorianChange(calendar->_cal, &status); - CFAbsoluteTime at = U_SUCCESS(status) ? (udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970) : -13197600000.0; // Oct 15, 1582 - calendar->_gregorianStart = CFDateCreate(CFGetAllocator(calendar), at); - udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0; - status = U_ZERO_ERROR; + UDate udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0; __cficu_ucal_setGregorianChange(calendar->_cal, udate, &status); } calendar->_userSet_firstWeekday = false; calendar->_userSet_minDaysInFirstWeek = false; calendar->_userSet_gregorianStart = false; - ICU_LOG(" // _CFCalendarInitWithIdentifier exit true\n"); + ICU_LOG(" // CFCalendarCreateWithIdentifier exit\n"); return true; } -CFCalendarRef CFCalendarCreateWithIdentifier(CFAllocatorRef allocator, CFStringRef identifier) { - ICU_LOG(" // CFCalendarCreateWithIdentifier enter\n"); +static CFCalendarRef _CFCalendarCreate(CFAllocatorRef allocator, CFStringRef identifier, CFTimeZoneRef tz, CFLocaleRef locale, CFIndex firstDayOfWeek, CFIndex minDaysInFirstWeek, CFDateRef gregorianStartDate) { if (allocator == NULL) allocator = __CFGetDefaultAllocator(); __CFGenericValidateType(allocator, CFAllocatorGetTypeID()); - __CFGenericValidateType(identifier, CFStringGetTypeID()); struct __CFCalendar *calendar = NULL; size_t size = sizeof(struct __CFCalendar) - sizeof(CFRuntimeBase); @@ -657,38 +682,60 @@ CFCalendarRef CFCalendarCreateWithIdentifier(CFAllocatorRef allocator, CFStringR return NULL; } - if (_CFCalendarInitWithIdentifier(calendar, identifier)) { - return calendar; - } else { + if (!_CFCalendarInitialize(calendar, allocator, identifier, tz, locale, firstDayOfWeek, minDaysInFirstWeek, gregorianStartDate)) { + // _CFCalendarInitialize will have already logged which exit path was taken. CFRelease(calendar); return NULL; } + + return calendar; } -CFCalendarRef _CFCalendarCreateCopy(CFAllocatorRef allocator, CFCalendarRef calendar) { - CFCalendarRef result = CFCalendarCreateWithIdentifier(allocator, CFCalendarGetIdentifier(calendar)); - - CFLocaleRef locale = CFCalendarCopyLocale(calendar); - if (locale) { - CFCalendarSetLocale(result, locale); +CFCalendarRef CFCalendarCopyCurrent(void) { + CFLocaleRef locale = CFLocaleCopyCurrent(); + CFStringRef calID = (CFStringRef)CFLocaleGetValue(locale, kCFLocaleCalendarIdentifierKey); + if (calID) { + CFCalendarRef calendar = _CFCalendarCreate(kCFAllocatorSystemDefault, calID, NULL, locale, kCFNotFound, kCFNotFound, NULL); + + // `calendar` has the default first weekday and other locale settings set on it. + // We need to explicitly apply the settings from the locale without creating a new copy of it (via `CFCalendarSetLocale`). + __CFCalendarApplyUserSettingsFromLocale(calendar, locale); + + CFRelease(locale); + return calendar; + } else if(locale) { CFRelease(locale); } - - CFTimeZoneRef tz = CFCalendarCopyTimeZone(calendar); - if (tz) { - CFCalendarSetTimeZone(result, tz); - CFRelease(tz); - } - - CFDateRef gsd = CFCalendarCopyGregorianStartDate(calendar); - if (gsd) { - CFCalendarSetGregorianStartDate(result, gsd); - CFRelease(gsd); + return NULL; +} + +CFCalendarRef CFCalendarCreateWithIdentifier(CFAllocatorRef allocator, CFStringRef identifier) { + return _CFCalendarCreate(allocator, identifier, NULL, NULL, kCFNotFound, kCFNotFound, NULL); +} + +CF_CROSS_PLATFORM_EXPORT Boolean _CFCalendarInitWithIdentifier(CFCalendarRef calendar, CFStringRef identifier) { + return _CFCalendarInitialize(calendar, kCFAllocatorSystemDefault, identifier, NULL, NULL, kCFNotFound, kCFNotFound, NULL) ? true : false; +} + +CFCalendarRef _CFCalendarCreateCopy(CFAllocatorRef allocator, CFCalendarRef calendar) { + //We should probably just conditionally call -copyWithZone: here but I'm concerned that it could expose incorrect third party subclasses that have just happened to get away with it until now + Boolean isObjC = CF_IS_OBJC(_kCFRuntimeIDCFCalendar, calendar); + CFCalendarRef result = NULL; + if (isObjC) { + CFTimeZoneRef tz = CFCalendarCopyTimeZone(calendar); + CFLocaleRef locale = CFCalendarCopyLocale(calendar); + CFDateRef gsd = CFCalendarCopyGregorianStartDate(calendar); + CFIndex firstWeekday = CFCalendarGetFirstWeekday(calendar); + CFIndex minDaysInFirstWeek = CFCalendarGetMinimumDaysInFirstWeek(calendar); + //Do not attempt to refactor _CFCalendarCreate to take fewer arguments with the idea of using the setter functions instead, the setters also set the _userSet_* flags + result = _CFCalendarCreate(allocator, CFCalendarGetIdentifier(calendar), tz, locale, firstWeekday, minDaysInFirstWeek, gsd); + if (tz) CFRelease(tz); + if (locale) CFRelease(locale); + if (gsd) CFRelease(gsd); + } else { + result = _CFCalendarCreate(allocator, calendar->_identifier, calendar->_tz, calendar->_locale, calendar->_firstWeekday, calendar->_minDaysInFirstWeek, calendar->_gregorianStart); } - CFCalendarSetFirstWeekday(result, CFCalendarGetFirstWeekday(calendar)); - CFCalendarSetMinimumDaysInFirstWeek(result, CFCalendarGetMinimumDaysInFirstWeek(calendar)); - return result; } @@ -760,40 +807,8 @@ void CFCalendarSetLocale(CFCalendarRef calendar, CFLocaleRef locale) { ICU_LOG(" UErrorCode status = U_ZERO_ERROR;\n"); ICU_LOG(" if (cal) ucal_setGregorianChange(cal, udate, &status);\n"); } - - CFDictionaryRef prefs = __CFLocaleGetPrefs(locale); - if (!calendar->_userSet_firstWeekday) { - CFPropertyListRef metapref = (CFPropertyListRef)(prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleFirstWeekday")) : NULL); - if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) { - metapref = (CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)metapref, calendar->_identifier); - } - if (NULL != metapref && CFGetTypeID(metapref) == CFNumberGetTypeID()) { - CFIndex wkdy; - if (CFNumberGetValue((CFNumberRef)metapref, kCFNumberCFIndexType, &wkdy)) { - calendar->_firstWeekday = wkdy; - if (calendar->_cal) { - __cficu_ucal_setAttribute(calendar->_cal, UCAL_FIRST_DAY_OF_WEEK, wkdy); - ICU_LOG(" ucal_setAttribute(cal, UCAL_FIRST_DAY_OF_WEEK, %ld);\n", wkdy); - } - } - } - } - if (!calendar->_userSet_minDaysInFirstWeek) { - CFPropertyListRef metapref = (CFPropertyListRef)(prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleMinDaysInFirstWeek")) : NULL); - if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) { - metapref = (CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)metapref, calendar->_identifier); - } - if (NULL != metapref && CFGetTypeID(metapref) == CFNumberGetTypeID()) { - CFIndex mwd; - if (CFNumberGetValue((CFNumberRef)metapref, kCFNumberCFIndexType, &mwd)) { - calendar->_minDaysInFirstWeek = mwd; - if (calendar->_cal) { - __cficu_ucal_setAttribute(calendar->_cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK, mwd); - ICU_LOG(" ucal_setAttribute(cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK, %ld);\n", mwd); - } - } - } - } + + __CFCalendarApplyUserSettingsFromLocale(calendar, locale); } ICU_LOG(" // CFCalendarSetLocale exit\n"); } diff --git a/CoreFoundation/Locale.subproj/CFCalendar.h b/CoreFoundation/Locale.subproj/CFCalendar.h index 75fbf7c98d..eb3685067d 100644 --- a/CoreFoundation/Locale.subproj/CFCalendar.h +++ b/CoreFoundation/Locale.subproj/CFCalendar.h @@ -1,7 +1,7 @@ /* CFCalendar.h - Copyright (c) 2004-2018, Apple Inc. and the Swift project authors + Copyright (c) 2004-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Locale.subproj/CFDateComponents.c b/CoreFoundation/Locale.subproj/CFDateComponents.c index 30973a2751..41f976701f 100644 --- a/CoreFoundation/Locale.subproj/CFDateComponents.c +++ b/CoreFoundation/Locale.subproj/CFDateComponents.c @@ -140,7 +140,7 @@ static void __CFDateComponentsDeallocate(CFTypeRef cf) { if (dc->_timeZone) CFRelease(dc->_timeZone); } -static const CFRuntimeClass __CFDateComponentsClass = { +const CFRuntimeClass __CFDateComponentsClass = { 0, "CFDateComponents", NULL, // init diff --git a/CoreFoundation/Locale.subproj/CFDateFormatter.c b/CoreFoundation/Locale.subproj/CFDateFormatter.c index 36613bdc91..2e3eabb073 100644 --- a/CoreFoundation/Locale.subproj/CFDateFormatter.c +++ b/CoreFoundation/Locale.subproj/CFDateFormatter.c @@ -1,11 +1,11 @@ /* CFDateFormatter.c - Copyright (c) 2002-2018, Apple Inc. and the Swift project authors + Copyright (c) 2002-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: David Smith + Responsibility: Itai Ferber */ #define U_SHOW_INTERNAL_API 1 @@ -592,7 +592,13 @@ static void __ResetUDateFormat(CFDateFormatterRef df, Boolean goingToHaveCustomF UChar tz_buffer[BUFFER_SIZE]; tz_buffer[0] = 0; CFStringRef tmpTZName = df->_property._TimeZone ? CFTimeZoneGetName(df->_property._TimeZone) : CFSTR("GMT"); - CFStringGetCharacters(tmpTZName, CFRangeMake(0, CFStringGetLength(tmpTZName)), (UniChar *)tz_buffer); + if (tmpTZName == NULL) { + os_log_error(_CFOSLog(), "Error: CFDateFormatter time zone has an empty name: %@", df->_property._TimeZone); + return; + } + + CFIndex const tz_length = __CFMin(BUFFER_SIZE, CFStringGetLength(tmpTZName)); + CFStringGetCharacters(tmpTZName, CFRangeMake(0, tz_length), (UniChar *)tz_buffer); int32_t udstyle = 0, utstyle = 0; // effectively this makes UDAT_FULL the default for unknown dateStyle/timeStyle values switch (df->_dateStyle) { @@ -616,7 +622,7 @@ static void __ResetUDateFormat(CFDateFormatterRef df, Boolean goingToHaveCustomF } UErrorCode status = U_ZERO_ERROR; - UDateFormat *icudf = __cficu_udat_open((UDateFormatStyle)utstyle, (UDateFormatStyle)udstyle, loc_buffer, tz_buffer, CFStringGetLength(tmpTZName), NULL, 0, &status); + UDateFormat *icudf = __cficu_udat_open((UDateFormatStyle)utstyle, (UDateFormatStyle)udstyle, loc_buffer, tz_buffer, tz_length, NULL, 0, &status); if (NULL == icudf || U_FAILURE(status)) { return; @@ -673,7 +679,6 @@ static void __ResetUDateFormat(CFDateFormatterRef df, Boolean goingToHaveCustomF __ApplyUDateFormatSymbol(df); - if (wantRelative && !hasFormat && kCFDateFormatterNoStyle != df->_dateStyle) { UChar dateBuffer[BUFFER_SIZE]; UChar timeBuffer[BUFFER_SIZE]; @@ -765,7 +770,7 @@ CFTypeID CFDateFormatterGetTypeID(void) { return _kCFRuntimeIDCFDateFormatter; } -static CFDateFormatterRef __SetUpCFDateFormatter(CFAllocatorRef allocator, CFLocaleRef locale, CFDateFormatterStyle dateStyle, CFDateFormatterStyle timeStyle, CFBooleanRef calculateISO8601) { +static CFDateFormatterRef __CreateCFDateFormatter(CFAllocatorRef allocator, CFLocaleRef locale, CFDateFormatterStyle dateStyle, CFDateFormatterStyle timeStyle, CFBooleanRef calculateISO8601) { struct __CFDateFormatter *memory; uint32_t size = sizeof(struct __CFDateFormatter) - sizeof(CFRuntimeBase); if (allocator == NULL) allocator = __CFGetDefaultAllocator(); @@ -775,70 +780,8 @@ static CFDateFormatterRef __SetUpCFDateFormatter(CFAllocatorRef allocator, CFLoc if (NULL == memory) { return NULL; } - memory->_df = NULL; - memory->_locale = NULL; - memory->_format = NULL; - memory->_defformat = NULL; memory->_dateStyle = dateStyle; memory->_timeStyle = timeStyle; - memory->_property._IsLenient = NULL; - memory->_property._DoesRelativeDateFormatting = NULL; - memory->_property._HasCustomFormat = NULL; - memory->_property._TimeZone = NULL; - memory->_property._Calendar = NULL; - memory->_property._CalendarName = NULL; - memory->_property._TwoDigitStartDate = NULL; - memory->_property._DefaultDate = NULL; - memory->_property._GregorianStartDate = NULL; - memory->_property._EraSymbols = NULL; - memory->_property._LongEraSymbols = NULL; - memory->_property._MonthSymbols = NULL; - memory->_property._ShortMonthSymbols = NULL; - memory->_property._VeryShortMonthSymbols = NULL; - memory->_property._StandaloneMonthSymbols = NULL; - memory->_property._ShortStandaloneMonthSymbols = NULL; - memory->_property._VeryShortStandaloneMonthSymbols = NULL; - memory->_property._WeekdaySymbols = NULL; - memory->_property._ShortWeekdaySymbols = NULL; - memory->_property._VeryShortWeekdaySymbols = NULL; - memory->_property._StandaloneWeekdaySymbols = NULL; - memory->_property._ShortStandaloneWeekdaySymbols = NULL; - memory->_property._VeryShortStandaloneWeekdaySymbols = NULL; - memory->_property._QuarterSymbols = NULL; - memory->_property._ShortQuarterSymbols = NULL; - memory->_property._StandaloneQuarterSymbols = NULL; - memory->_property._ShortStandaloneQuarterSymbols = NULL; - memory->_property._AMSymbol = NULL; - memory->_property._PMSymbol = NULL; - memory->_property._AmbiguousYearStrategy = NULL; - memory->_property._UsesCharacterDirection = NULL; - memory->_property._FormattingContext = NULL; - memory->_property._CustomEraSymbols = NULL; - memory->_property._CustomMonthSymbols = NULL; - memory->_property._CustomShortMonthSymbols = NULL; - memory->_property._CustomWeekdaySymbols = NULL; - memory->_property._CustomShortWeekdaySymbols = NULL; - memory->_property._CustomLongEraSymbols = NULL; - memory->_property._CustomVeryShortMonthSymbols = NULL; - memory->_property._CustomVeryShortWeekdaySymbols = NULL; - memory->_property._CustomStandaloneMonthSymbols = NULL; - memory->_property._CustomShortStandaloneMonthSymbols = NULL; - memory->_property._CustomVeryShortStandaloneMonthSymbols = NULL; - memory->_property._CustomStandaloneWeekdaySymbols = NULL; - memory->_property._CustomShortStandaloneWeekdaySymbols = NULL; - memory->_property._CustomVeryShortStandaloneWeekdaySymbols = NULL; - memory->_property._CustomQuarterSymbols = NULL; - memory->_property._CustomShortQuarterSymbols = NULL; - memory->_property._CustomStandaloneQuarterSymbols = NULL; - memory->_property._CustomShortStandaloneQuarterSymbols = NULL; - memory->_property._CustomDateFormat = NULL; - memory->_property._CustomTimeFormat = NULL; - memory->_property._Custom24Hour = NULL; - memory->_property._Custom12Hour = NULL; - memory->_property._CustomAMSymbol = NULL; - memory->_property._CustomPMSymbol = NULL; - memory->_property._CustomFirstWeekday = NULL; - memory->_property._CustomMinDaysInFirstWeek = NULL; switch (dateStyle) { case kCFDateFormatterNoStyle: @@ -1037,7 +980,7 @@ static CFMutableStringRef __createISO8601FormatString(CFISO8601DateFormatOptions CFDateFormatterRef CFDateFormatterCreateISO8601Formatter(CFAllocatorRef allocator, CFISO8601DateFormatOptions formatOptions) { CFStringRef localeStr = CFStringCreateWithCString(kCFAllocatorSystemDefault, "en_US_POSIX", kCFStringEncodingUTF8); CFLocaleRef locale = CFLocaleCreate(kCFAllocatorSystemDefault, localeStr); - CFDateFormatterRef ISO8601Formatter = __SetUpCFDateFormatter(allocator, locale, kCFDateFormatterNoStyle, kCFDateFormatterNoStyle, kCFBooleanTrue); // dateStyle and timeStyle are not relevant for ISO8601 + CFDateFormatterRef ISO8601Formatter = __CreateCFDateFormatter(allocator, locale, kCFDateFormatterNoStyle, kCFDateFormatterNoStyle, kCFBooleanTrue); // dateStyle and timeStyle are not relevant for ISO8601 if (formatOptions != 0) { CFStringRef formatStr = __createISO8601FormatString(formatOptions); @@ -1054,7 +997,7 @@ CFDateFormatterRef CFDateFormatterCreateISO8601Formatter(CFAllocatorRef allocato } CFDateFormatterRef CFDateFormatterCreate(CFAllocatorRef allocator, CFLocaleRef locale, CFDateFormatterStyle dateStyle, CFDateFormatterStyle timeStyle) { - return __SetUpCFDateFormatter(allocator, locale, dateStyle, timeStyle, kCFBooleanFalse); + return __CreateCFDateFormatter(allocator, locale, dateStyle, timeStyle, kCFBooleanFalse); } @@ -1328,7 +1271,13 @@ static CFStringRef __CFDateFormatterCreateForcedString(CFDateFormatterRef format #else Boolean success = false; #endif - return success && result && newPatternLen > 0 ? result : CFRetain(inString); + Boolean returnResult = success && result && newPatternLen > 0; + if (returnResult) { + return result; + } else { + if (result) CFRelease(result); + return CFRetain(inString); + } } CFLocaleRef CFDateFormatterGetLocale(CFDateFormatterRef formatter) { diff --git a/CoreFoundation/Locale.subproj/CFDateFormatter.h b/CoreFoundation/Locale.subproj/CFDateFormatter.h index 0b3b6624bb..0cae10f48a 100644 --- a/CoreFoundation/Locale.subproj/CFDateFormatter.h +++ b/CoreFoundation/Locale.subproj/CFDateFormatter.h @@ -1,7 +1,7 @@ /* CFDateFormatter.h - Copyright (c) 2003-2018, Apple Inc. and the Swift project authors + Copyright (c) 2003-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Locale.subproj/CFDateFormatter_Private.h b/CoreFoundation/Locale.subproj/CFDateFormatter_Private.h index 5454c9cb96..d7659e8972 100644 --- a/CoreFoundation/Locale.subproj/CFDateFormatter_Private.h +++ b/CoreFoundation/Locale.subproj/CFDateFormatter_Private.h @@ -1,7 +1,7 @@ /* CFDateFormatter_Private.h - Copyright (c) 2015-2018, Apple Inc. and the Swift project authors + Copyright (c) 2015-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Locale.subproj/CFICULogging.h b/CoreFoundation/Locale.subproj/CFICULogging.h index 1b35f9ff42..eb613283b2 100644 --- a/CoreFoundation/Locale.subproj/CFICULogging.h +++ b/CoreFoundation/Locale.subproj/CFICULogging.h @@ -1,8 +1,8 @@ /* CFICULogging.h - Copyright (c) 2008-2018, Apple Inc. and the Swift project authors + Copyright (c) 2008-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -19,8 +19,12 @@ #include #include #include +#include #include #include +#if __has_include() +#include +#endif #if !DEPLOYMENT_RUNTIME_SWIFT && __has_include() #include @@ -101,5 +105,9 @@ // unum #define __cficu_unum_setContext unum_setContext #define __cficu_unum_getContext unum_getContext - +// ureldatefmt +#define __cficu_ureldatefmt_open ureldatefmt_open +#define __cficu_ureldatefmt_formatNumeric ureldatefmt_formatNumeric +#define __cficu_ureldatefmt_format ureldatefmt_format +#define __cficu_ureldatefmt_close ureldatefmt_close #endif diff --git a/CoreFoundation/Locale.subproj/CFLocale.c b/CoreFoundation/Locale.subproj/CFLocale.c index 3cabdbd55b..4d1ae19ad7 100644 --- a/CoreFoundation/Locale.subproj/CFLocale.c +++ b/CoreFoundation/Locale.subproj/CFLocale.c @@ -1,7 +1,7 @@ /* CFLocale.c - Copyright (c) 2002-2018, Apple Inc. and the Swift project authors + Copyright (c) 2002-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -76,11 +76,11 @@ enum { }; struct key_table { - CFStringRef key; + CFStringRef const * key; bool (*get)(CFLocaleRef, bool user, CFTypeRef *, CFStringRef context); // returns an immutable copy & reference bool (*set)(CFMutableLocaleRef, CFTypeRef, CFStringRef context); bool (*name)(const char *, const char *, CFStringRef *); - CFStringRef context; + CFStringRef const * context; }; @@ -110,30 +110,29 @@ static bool __CFLocaleCurrencyFullName(const char *locale, const char *value, CF static bool __CFLocaleCopyCollatorID(CFLocaleRef locale, bool user, CFTypeRef *cf, CFStringRef context); static bool __CFLocaleCopyDelimiter(CFLocaleRef locale, bool user, CFTypeRef *cf, CFStringRef context); -// Note string members start with an extra &, and are fixed up at init time -static struct key_table __CFLocaleKeyTable[__kCFLocaleKeyTableCount] = { - {(CFStringRef)&kCFLocaleIdentifierKey, __CFLocaleCopyLocaleID, __CFLocaleSetNOP, __CFLocaleFullName, NULL}, - {(CFStringRef)&kCFLocaleLanguageCodeKey, __CFLocaleCopyCodes, __CFLocaleSetNOP, __CFLocaleLanguageName, (CFStringRef)&kCFLocaleLanguageCodeKey}, - {(CFStringRef)&kCFLocaleCountryCodeKey, __CFLocaleCopyCodes, __CFLocaleSetNOP, __CFLocaleCountryName, (CFStringRef)&kCFLocaleCountryCodeKey}, - {(CFStringRef)&kCFLocaleScriptCodeKey, __CFLocaleCopyCodes, __CFLocaleSetNOP, __CFLocaleScriptName, (CFStringRef)&kCFLocaleScriptCodeKey}, - {(CFStringRef)&kCFLocaleVariantCodeKey, __CFLocaleCopyCodes, __CFLocaleSetNOP, __CFLocaleVariantName, (CFStringRef)&kCFLocaleVariantCodeKey}, - {(CFStringRef)&kCFLocaleExemplarCharacterSetKey, __CFLocaleCopyExemplarCharSet, __CFLocaleSetNOP, __CFLocaleNoName, NULL}, - {(CFStringRef)&kCFLocaleCalendarIdentifierKey, __CFLocaleCopyCalendarID, __CFLocaleSetNOP, __CFLocaleCalendarName, NULL}, - {(CFStringRef)&kCFLocaleCalendarKey, __CFLocaleCopyCalendar, __CFLocaleSetNOP, __CFLocaleNoName, NULL}, - {(CFStringRef)&kCFLocaleCollationIdentifierKey, __CFLocaleCopyCollationID, __CFLocaleSetNOP, __CFLocaleCollationName, NULL}, - {(CFStringRef)&kCFLocaleUsesMetricSystemKey, __CFLocaleCopyUsesMetric, __CFLocaleSetNOP, __CFLocaleNoName, NULL}, - {(CFStringRef)&kCFLocaleMeasurementSystemKey, __CFLocaleCopyMeasurementSystem, __CFLocaleSetNOP, __CFLocaleNoName, NULL}, - {(CFStringRef)&kCFLocaleTemperatureUnitKey, __CFLocaleCopyTemperatureUnit, __CFLocaleSetNOP, __CFLocaleNoName, NULL}, - {(CFStringRef)&kCFLocaleDecimalSeparatorKey, __CFLocaleCopyNumberFormat, __CFLocaleSetNOP, __CFLocaleNoName, (CFStringRef)&kCFNumberFormatterDecimalSeparatorKey}, - {(CFStringRef)&kCFLocaleGroupingSeparatorKey, __CFLocaleCopyNumberFormat, __CFLocaleSetNOP, __CFLocaleNoName, (CFStringRef)&kCFNumberFormatterGroupingSeparatorKey}, - {(CFStringRef)&kCFLocaleCurrencySymbolKey, __CFLocaleCopyNumberFormat2, __CFLocaleSetNOP, __CFLocaleCurrencyShortName, (CFStringRef)&kCFNumberFormatterCurrencySymbolKey}, - {(CFStringRef)&kCFLocaleCurrencyCodeKey, __CFLocaleCopyNumberFormat2, __CFLocaleSetNOP, __CFLocaleCurrencyFullName, (CFStringRef)&kCFNumberFormatterCurrencyCodeKey}, - {(CFStringRef)&kCFLocaleCollatorIdentifierKey, __CFLocaleCopyCollatorID, __CFLocaleSetNOP, __CFLocaleNoName, NULL}, - {(CFStringRef)&__kCFLocaleCollatorID, __CFLocaleCopyCollatorID, __CFLocaleSetNOP, __CFLocaleNoName, NULL}, - {(CFStringRef)&kCFLocaleQuotationBeginDelimiterKey, __CFLocaleCopyDelimiter, __CFLocaleSetNOP, __CFLocaleNoName, (CFStringRef)&kCFLocaleQuotationBeginDelimiterKey}, - {(CFStringRef)&kCFLocaleQuotationEndDelimiterKey, __CFLocaleCopyDelimiter, __CFLocaleSetNOP, __CFLocaleNoName, (CFStringRef)&kCFLocaleQuotationEndDelimiterKey}, - {(CFStringRef)&kCFLocaleAlternateQuotationBeginDelimiterKey, __CFLocaleCopyDelimiter, __CFLocaleSetNOP, __CFLocaleNoName, (CFStringRef)&kCFLocaleAlternateQuotationBeginDelimiterKey}, - {(CFStringRef)&kCFLocaleAlternateQuotationEndDelimiterKey, __CFLocaleCopyDelimiter, __CFLocaleSetNOP, __CFLocaleNoName, (CFStringRef)&kCFLocaleAlternateQuotationEndDelimiterKey}, +static struct key_table const __CFLocaleKeyTable[__kCFLocaleKeyTableCount] = { + {&kCFLocaleIdentifierKey, __CFLocaleCopyLocaleID, __CFLocaleSetNOP, __CFLocaleFullName, NULL}, + {&kCFLocaleLanguageCodeKey, __CFLocaleCopyCodes, __CFLocaleSetNOP, __CFLocaleLanguageName, &kCFLocaleLanguageCodeKey}, + {&kCFLocaleCountryCodeKey, __CFLocaleCopyCodes, __CFLocaleSetNOP, __CFLocaleCountryName, &kCFLocaleCountryCodeKey}, + {&kCFLocaleScriptCodeKey, __CFLocaleCopyCodes, __CFLocaleSetNOP, __CFLocaleScriptName, &kCFLocaleScriptCodeKey}, + {&kCFLocaleVariantCodeKey, __CFLocaleCopyCodes, __CFLocaleSetNOP, __CFLocaleVariantName, &kCFLocaleVariantCodeKey}, + {&kCFLocaleExemplarCharacterSetKey, __CFLocaleCopyExemplarCharSet, __CFLocaleSetNOP, __CFLocaleNoName, NULL}, + {&kCFLocaleCalendarIdentifierKey, __CFLocaleCopyCalendarID, __CFLocaleSetNOP, __CFLocaleCalendarName, NULL}, + {&kCFLocaleCalendarKey, __CFLocaleCopyCalendar, __CFLocaleSetNOP, __CFLocaleNoName, NULL}, + {&kCFLocaleCollationIdentifierKey, __CFLocaleCopyCollationID, __CFLocaleSetNOP, __CFLocaleCollationName, NULL}, + {&kCFLocaleUsesMetricSystemKey, __CFLocaleCopyUsesMetric, __CFLocaleSetNOP, __CFLocaleNoName, NULL}, + {&kCFLocaleMeasurementSystemKey, __CFLocaleCopyMeasurementSystem, __CFLocaleSetNOP, __CFLocaleNoName, NULL}, + {&kCFLocaleTemperatureUnitKey, __CFLocaleCopyTemperatureUnit, __CFLocaleSetNOP, __CFLocaleNoName, NULL}, + {&kCFLocaleDecimalSeparatorKey, __CFLocaleCopyNumberFormat, __CFLocaleSetNOP, __CFLocaleNoName, &kCFNumberFormatterDecimalSeparatorKey}, + {&kCFLocaleGroupingSeparatorKey, __CFLocaleCopyNumberFormat, __CFLocaleSetNOP, __CFLocaleNoName, &kCFNumberFormatterGroupingSeparatorKey}, + {&kCFLocaleCurrencySymbolKey, __CFLocaleCopyNumberFormat2, __CFLocaleSetNOP, __CFLocaleCurrencyShortName, &kCFNumberFormatterCurrencySymbolKey}, + {&kCFLocaleCurrencyCodeKey, __CFLocaleCopyNumberFormat2, __CFLocaleSetNOP, __CFLocaleCurrencyFullName, &kCFNumberFormatterCurrencyCodeKey}, + {&kCFLocaleCollatorIdentifierKey, __CFLocaleCopyCollatorID, __CFLocaleSetNOP, __CFLocaleNoName, NULL}, + {&__kCFLocaleCollatorID, __CFLocaleCopyCollatorID, __CFLocaleSetNOP, __CFLocaleNoName, NULL}, + {&kCFLocaleQuotationBeginDelimiterKey, __CFLocaleCopyDelimiter, __CFLocaleSetNOP, __CFLocaleNoName, &kCFLocaleQuotationBeginDelimiterKey}, + {&kCFLocaleQuotationEndDelimiterKey, __CFLocaleCopyDelimiter, __CFLocaleSetNOP, __CFLocaleNoName, &kCFLocaleQuotationEndDelimiterKey}, + {&kCFLocaleAlternateQuotationBeginDelimiterKey, __CFLocaleCopyDelimiter, __CFLocaleSetNOP, __CFLocaleNoName, &kCFLocaleAlternateQuotationBeginDelimiterKey}, + {&kCFLocaleAlternateQuotationEndDelimiterKey, __CFLocaleCopyDelimiter, __CFLocaleSetNOP, __CFLocaleNoName, &kCFLocaleAlternateQuotationEndDelimiterKey}, }; @@ -144,7 +143,7 @@ static CFLock_t __CFLocaleGlobalLock = CFLockInit; struct __CFLocale { CFRuntimeBase _base; CFStringRef _identifier; // canonical identifier, never NULL - CFMutableDictionaryRef _cache; + _Atomic(CFMutableDictionaryRef) _cache; CFDictionaryRef _prefs; CFLock_t _lock; Boolean _nullLocale; @@ -192,6 +191,25 @@ CF_INLINE void __CFLocaleUnlock(CFLocaleRef locale) { __CFUnlock(&((struct __CFLocale *)locale)->_lock); } +CF_INLINE Boolean __CFLocaleCacheGetValueIfPresent(CFLocaleRef locale, CFLocaleKey key, CFTypeRef *value) { + CFDictionaryRef cache = atomic_load_explicit(&locale->_cache, memory_order_acquire); + if (!cache) { + *value = NULL; + return false; + } + + return CFDictionaryGetValueIfPresent(cache, key, value); +} + +CF_INLINE void __CFLocaleCacheSet_alreadyLocked(CFLocaleRef locale, CFLocaleKey key, CFTypeRef value) { + CFMutableDictionaryRef cache = atomic_load_explicit(&locale->_cache, memory_order_acquire); + if (!cache) { + cache = CFDictionaryCreateMutable(CFGetAllocator(locale), 0, NULL, &kCFTypeDictionaryValueCallBacks); + atomic_store_explicit(&((struct __CFLocale *)locale)->_cache, cache, memory_order_release); + } + + CFDictionarySetValue(cache, key, value); +} static Boolean __CFLocaleEqual(CFTypeRef cf1, CFTypeRef cf2) { CFLocaleRef locale1 = (CFLocaleRef)cf1; @@ -242,16 +260,6 @@ const CFRuntimeClass __CFLocaleClass = { }; CFTypeID CFLocaleGetTypeID(void) { - static dispatch_once_t initOnce; - dispatch_once(&initOnce, ^{ - for (CFIndex idx = 0; idx < __kCFLocaleKeyTableCount; idx++) { - // table fixup to workaround compiler/language limitations - __CFLocaleKeyTable[idx].key = *((CFStringRef *)__CFLocaleKeyTable[idx].key); - if (NULL != __CFLocaleKeyTable[idx].context) { - __CFLocaleKeyTable[idx].context = *((CFStringRef *)__CFLocaleKeyTable[idx].context); - } - } - }); return _kCFRuntimeIDCFLocale; } @@ -294,29 +302,32 @@ static void _setCachedCurrentLocale(CFLocaleRef newLocale) { #define FALLBACK_LOCALE_NAME CFSTR("") #elif TARGET_OS_IPHONE #define FALLBACK_LOCALE_NAME CFSTR("en_US") -#elif TARGET_OS_WINDOWS || TARGET_OS_LINUX || TARGET_OS_BSD || DEPLOYMENT_RUNTIME_SWIFT +#elif TARGET_OS_WIN32 || TARGET_OS_LINUX || TARGET_OS_BSD || DEPLOYMENT_RUNTIME_SWIFT #define FALLBACK_LOCALE_NAME CFSTR("en_US") #endif #if TARGET_OS_MAC || TARGET_OS_WIN32 static CFStringRef _CFLocaleCopyLocaleIdentifierByAddingLikelySubtags(CFStringRef localeID) { + if (!localeID) { + return NULL; + } CFStringRef result = NULL; - if (localeID) { - char bufLocaleID[ULOC_FULLNAME_CAPACITY]; - const char *cLocaleID = CFStringGetCStringPtr(localeID, kCFStringEncodingUTF8); - if (NULL == cLocaleID) { - if (CFStringGetCString(localeID, bufLocaleID, ULOC_FULLNAME_CAPACITY, kCFStringEncodingUTF8)) { - cLocaleID = bufLocaleID; - } - } - UErrorCode icuStatus = U_ZERO_ERROR; - char maximizedLocaleID[ULOC_FULLNAME_CAPACITY]; - int32_t bufSize = uloc_addLikelySubtags(cLocaleID, maximizedLocaleID, ULOC_FULLNAME_CAPACITY, &icuStatus); - if ((bufSize != -1) && U_SUCCESS(icuStatus)) { - result = CFStringCreateWithCString(NULL, maximizedLocaleID, kCFStringEncodingUTF8); + + char bufLocaleID[ULOC_FULLNAME_CAPACITY]; + const char *cLocaleID = CFStringGetCStringPtr(localeID, kCFStringEncodingUTF8); + if (NULL == cLocaleID) { + if (CFStringGetCString(localeID, bufLocaleID, ULOC_FULLNAME_CAPACITY, kCFStringEncodingUTF8)) { + cLocaleID = bufLocaleID; } } + UErrorCode icuStatus = U_ZERO_ERROR; + char maximizedLocaleID[ULOC_FULLNAME_CAPACITY]; + int32_t bufSize = uloc_addLikelySubtags(cLocaleID, maximizedLocaleID, ULOC_FULLNAME_CAPACITY, &icuStatus); + if ((bufSize != -1) && U_SUCCESS(icuStatus)) { + result = CFStringCreateWithCString(NULL, maximizedLocaleID, kCFStringEncodingUTF8); + } + return result ? : CFRetain(localeID); } @@ -528,9 +539,10 @@ CFStringRef _CFLocaleCreateLocaleIdentiferByReplacingLanguageCodeAndScriptCode(C #if TARGET_OS_MAC || TARGET_OS_WIN32 static CFArrayRef _CFLocaleCopyPreferredLanguagesFromPrefs(CFArrayRef languagesArray); +#endif /// Creates a new locale identifier by identifying the most preferred localization (using `availableLocalizations` and `preferredLanguages`) and then creating a locale based on the most preferred localization, while retaining any relevant attributes from `preferredLocaleID`, e.g. if `availableLocalizations` is `[ "en", "fr", "de" ]`, `preferredLanguages` is `[ "ar-AE", "en-AE" ]`, `preferredLocaleID` is `ar_AE@numbers=arab;calendar=islamic-civil`, it will return `en_AE@calendar=islamic-civil`, i.e. the language will be matched to `en` since that’s the only available localization that matches, `calendar` will be retained since it’s language-agnostic, but `numbers` will be discarded because the `arab` numbering system is not valid for `en`. -static CFStringRef _CFLocaleCreateLocaleIdentifierForAvailableLocalizations(CFArrayRef availableLocalizations, CFArrayRef preferredLanguages, CFStringRef preferredLocaleID) { +static CFStringRef _CFLocaleCreateLocaleIdentifierForAvailableLocalizations(CFArrayRef availableLocalizations, CFArrayRef preferredLanguages, CFStringRef preferredLocaleID, CFArrayRef *outCanonicalizedPreferredLanguages) { CFStringRef result = NULL; if (availableLocalizations && CFArrayGetCount(availableLocalizations) > 0 && preferredLanguages && CFArrayGetCount(preferredLanguages) > 0 && @@ -568,11 +580,14 @@ static CFStringRef _CFLocaleCreateLocaleIdentifierForAvailableLocalizations(CFAr } if (preferredLocalizations) { CFRelease(preferredLocalizations); } - if (canonicalizedPreferredLanguages) CFRelease(canonicalizedPreferredLanguages); + if (outCanonicalizedPreferredLanguages) { + *outCanonicalizedPreferredLanguages = canonicalizedPreferredLanguages; + } else if (canonicalizedPreferredLanguages) { + CFRelease(canonicalizedPreferredLanguages); + } } return result; } -#endif static CFLocaleRef _CFLocaleCopyCurrentGuts(CFStringRef name, Boolean useCache, CFDictionaryRef overridePrefs, Boolean disableBundleMatching) { /* @@ -593,6 +608,16 @@ static CFLocaleRef _CFLocaleCopyCurrentGuts(CFStringRef name, Boolean useCache, } if (name && (CFStringGetTypeID() == CFGetTypeID(name))) { ident = CFLocaleCreateCanonicalLocaleIdentifierFromString(kCFAllocatorSystemDefault, name); + if (os_log_debug_enabled(_CFOSLog())) { + CFDictionaryRef const components = CFLocaleCreateComponentsFromLocaleIdentifier(NULL, ident); + if (components) { + if (!CFDictionaryGetValue(components, kCFLocaleCountryCode)) { + os_log_debug(_CFOSLog(), "CFLocaleCopyCurrent() called with overriding locale identifier '%{public}@' which does not have a country code", ident); + } + + CFRelease(components); + } + } } if (name) CFRelease(name); @@ -603,13 +628,18 @@ static CFLocaleRef _CFLocaleCopyCurrentGuts(CFStringRef name, Boolean useCache, if (useCache) { CFLocaleRef cached = _cachedCurrentLocale(); - if (ident) { - if (!CFEqual(cached->_identifier, ident)) { + if (cached && ident) { + if (CFEqual(cached->_identifier, ident)) { + // We can just return what's in the cache. + CFRelease(ident); + ident = NULL; + } else { + // We'll replace what's in the cache with ident below. _setCachedCurrentLocale(NULL); cached = NULL; } - CFRelease(ident); } + if (cached) { #if DEPLOYMENT_RUNTIME_SWIFT CFRetain(cached); // In Swift, this object isn't immortal and needs to be correctly memory-managed. @@ -639,9 +669,22 @@ static CFLocaleRef _CFLocaleCopyCurrentGuts(CFStringRef name, Boolean useCache, #endif } __CFLocaleSetType(locale, __kCFLocaleUser); - if (NULL == ident) ident = (CFStringRef)CFRetain(FALLBACK_LOCALE_NAME); + + if (!ident) { + ident = (CFStringRef)CFRetain(FALLBACK_LOCALE_NAME); + + // CFLocaleCopyCurrent() failed to look up current locale -- gpsd dameon is not localized, does not interact directly with users + // This log was added to try to catch scenarios in which apps fail to look up the current locale thanks to sandboxing issues or CFPreferences issues. It turns out that in its current formulation, this log has a high false positive rate and is very confusing. + // Disabled for now. + /* + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + os_log_error(_CFOSLog(), "CFLocaleCopyCurrent() failed to look up current locale via 'AppleLocale' and 'AppleLanguages' in user preferences; falling back to locale identifier '%{public}@' as the default. Consider checking Console for sandbox violations from this process for reading from preferences, or enabling CoreFoundation debug logging for more information. This will only be logged once.", ident); + }); + */ + } + locale->_identifier = ident; - locale->_cache = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks); locale->_prefs = prefs; locale->_lock = CFLockInit; locale->_nullLocale = false; @@ -650,6 +693,10 @@ static CFLocaleRef _CFLocaleCopyCurrentGuts(CFStringRef name, Boolean useCache, if (NULL == _cachedCurrentLocale()) { _setCachedCurrentLocale(locale); } + + // useCache is enabled, the locale is made immortal. + // The clang analyzer doesn't know about __CFRuntimeSetRC, though, so it sees overwriting locale below as a leak. + _CLANG_ANALYZER_IGNORE_RETAIN(locale); locale = (struct __CFLocale *)_cachedCurrentLocale(); } return locale; @@ -697,7 +744,7 @@ Boolean _CFLocaleInit(CFLocaleRef locale, CFStringRef identifier) { __CFLocaleSetType(locale, __kCFLocaleOrdinary); ((struct __CFLocale *)locale)->_identifier = localeIdentifier; - ((struct __CFLocale *)locale)->_cache = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks); + ((struct __CFLocale *)locale)->_cache = NULL; ((struct __CFLocale *)locale)->_prefs = NULL; ((struct __CFLocale *)locale)->_lock = CFLockInit; @@ -722,13 +769,13 @@ CFLocaleRef CFLocaleCreate(CFAllocatorRef allocator, CFStringRef identifier) { // default allocator. if (!allocator) allocator = __CFGetDefaultAllocator(); Boolean canCache = _CFAllocatorIsSystemDefault(allocator); - static CFLock_t __CFLocaleCacheLock = CFLockInit; - __CFLock(&__CFLocaleCacheLock); + static os_unfair_lock __CFLocaleCacheLock = OS_UNFAIR_LOCK_INIT; + os_unfair_lock_lock_with_options(&__CFLocaleCacheLock, OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION); if (canCache && __CFLocaleCache) { CFLocaleRef locale = (CFLocaleRef)CFDictionaryGetValue(__CFLocaleCache, localeIdentifier); if (locale) { CFRetain(locale); - __CFUnlock(&__CFLocaleCacheLock); + os_unfair_lock_unlock(&__CFLocaleCacheLock); CFRelease(localeIdentifier); return locale; } @@ -742,7 +789,6 @@ CFLocaleRef CFLocaleCreate(CFAllocatorRef allocator, CFStringRef identifier) { } __CFLocaleSetType(locale, __kCFLocaleOrdinary); locale->_identifier = localeIdentifier; - locale->_cache = CFDictionaryCreateMutable(allocator, 0, NULL, &kCFTypeDictionaryValueCallBacks); locale->_prefs = NULL; locale->_lock = CFLockInit; if (canCache) { @@ -751,7 +797,7 @@ CFLocaleRef CFLocaleCreate(CFAllocatorRef allocator, CFStringRef identifier) { } CFDictionarySetValue(__CFLocaleCache, localeIdentifier, locale); } - __CFUnlock(&__CFLocaleCacheLock); + os_unfair_lock_unlock(&__CFLocaleCacheLock); return (CFLocaleRef)locale; } @@ -782,7 +828,6 @@ static CFLocaleRef _CFLocaleCreateCopyGuts(CFAllocatorRef allocator, CFLocaleRef } __CFLocaleSetType(loc, __CFLocaleGetType(locale)); loc->_identifier = localeIdentifier; - loc->_cache = CFDictionaryCreateMutable(allocator, 0, NULL, &kCFTypeDictionaryValueCallBacks); CFDictionaryRef prefs = __CFLocaleGetPrefs(locale); loc->_prefs = prefs ? CFRetain(prefs) : NULL; loc->_lock = CFLockInit; @@ -818,14 +863,14 @@ CFTypeRef CFLocaleGetValue(CFLocaleRef locale, CFStringRef key) { CF_OBJC_FUNCDISPATCHV(CFLocaleGetTypeID(), CFTypeRef, (NSLocale *)locale, objectForKey:(id)key); CFIndex idx, slot = -1; for (idx = 0; idx < __kCFLocaleKeyTableCount; idx++) { - if (__CFLocaleKeyTable[idx].key == key) { + if (*__CFLocaleKeyTable[idx].key == key) { slot = idx; break; } } if (-1 == slot && NULL != key) { for (idx = 0; idx < __kCFLocaleKeyTableCount; idx++) { - if (CFEqual(__CFLocaleKeyTable[idx].key, key)) { + if (CFEqual(*__CFLocaleKeyTable[idx].key, key)) { slot = idx; break; } @@ -836,18 +881,20 @@ CFTypeRef CFLocaleGetValue(CFLocaleRef locale, CFStringRef key) { } CFTypeRef value; __CFLocaleLock(locale); - if (CFDictionaryGetValueIfPresent(locale->_cache, __CFLocaleKeyTable[slot].key, &value)) { + struct key_table const entry = __CFLocaleKeyTable[slot]; + if (__CFLocaleCacheGetValueIfPresent(locale, *entry.key, &value)) { __CFLocaleUnlock(locale); return value; } - if (__kCFLocaleUser == __CFLocaleGetType(locale) && __CFLocaleKeyTable[slot].get(locale, true, &value, __CFLocaleKeyTable[slot].context)) { - if (value) CFDictionarySetValue(locale->_cache, __CFLocaleKeyTable[idx].key, value); + CFStringRef const context = entry.context ? *entry.context : NULL; + if (__kCFLocaleUser == __CFLocaleGetType(locale) && entry.get(locale, true, &value, context)) { + if (value) __CFLocaleCacheSet_alreadyLocked(locale, *entry.key, value); if (value) CFRelease(value); __CFLocaleUnlock(locale); return value; } - if (__CFLocaleKeyTable[slot].get(locale, false, &value, __CFLocaleKeyTable[slot].context)) { - if (value) CFDictionarySetValue(locale->_cache, __CFLocaleKeyTable[idx].key, value); + if (entry.get(locale, false, &value, context)) { + if (value) __CFLocaleCacheSet_alreadyLocked(locale, *entry.key, value); if (value) CFRelease(value); __CFLocaleUnlock(locale); return value; @@ -860,14 +907,14 @@ CFStringRef CFLocaleCopyDisplayNameForPropertyValue(CFLocaleRef displayLocale, C CF_OBJC_FUNCDISPATCHV(CFLocaleGetTypeID(), CFStringRef, (NSLocale *)displayLocale, _copyDisplayNameForKey:(id)key value:(id)value); CFIndex idx, slot = -1; for (idx = 0; idx < __kCFLocaleKeyTableCount; idx++) { - if (__CFLocaleKeyTable[idx].key == key) { + if (*__CFLocaleKeyTable[idx].key == key) { slot = idx; break; } } if (-1 == slot && NULL != key) { for (idx = 0; idx < __kCFLocaleKeyTableCount; idx++) { - if (CFEqual(__CFLocaleKeyTable[idx].key, key)) { + if (CFEqual(*__CFLocaleKeyTable[idx].key, key)) { slot = idx; break; } @@ -881,7 +928,7 @@ CFStringRef CFLocaleCopyDisplayNameForPropertyValue(CFLocaleRef displayLocale, C char cValue[ULOC_FULLNAME_CAPACITY+ULOC_KEYWORD_AND_VALUES_CAPACITY]; if (CFStringGetCString(displayLocale->_identifier, localeID, sizeof(localeID)/sizeof(localeID[0]), kCFStringEncodingASCII) && CFStringGetCString(value, cValue, sizeof(cValue)/sizeof(char), kCFStringEncodingASCII)) { CFStringRef result; - if ((NULL == displayLocale->_prefs) && __CFLocaleKeyTable[slot].name(localeID, cValue, &result)) { + if (__CFLocaleKeyTable[slot].name(localeID, cValue, &result)) { return result; } @@ -1137,9 +1184,14 @@ static CFArrayRef _CFLocaleCopyPreferredLanguagesFromPrefs(CFArrayRef languagesA } #endif -CFArrayRef CFLocaleCopyPreferredLanguages(void) { +static CFArrayRef __CFLocaleCopyPreferredLanguagesForCurrentUser(Boolean forCurrentUser) { #if TARGET_OS_MAC || TARGET_OS_WIN32 - CFArrayRef languagesArray = (CFArrayRef)CFPreferencesCopyAppValue(CFSTR("AppleLanguages"), kCFPreferencesCurrentApplication); + CFArrayRef languagesArray = NULL; + if (forCurrentUser) { + languagesArray = (CFArrayRef)CFPreferencesCopyValue(CFSTR("AppleLanguages"), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + } else { + languagesArray = (CFArrayRef)CFPreferencesCopyAppValue(CFSTR("AppleLanguages"), kCFPreferencesCurrentApplication); + } CFArrayRef result = _CFLocaleCopyPreferredLanguagesFromPrefs(languagesArray); if (languagesArray) CFRelease(languagesArray); return result; @@ -1148,6 +1200,14 @@ CFArrayRef CFLocaleCopyPreferredLanguages(void) { #endif } +CFArrayRef CFLocaleCopyPreferredLanguages(void) { + return __CFLocaleCopyPreferredLanguagesForCurrentUser(false); +} + +CFArrayRef _CFLocaleCopyPreferredLanguagesForCurrentUser(void) { + return __CFLocaleCopyPreferredLanguagesForCurrentUser(true); +} + // -------- -------- -------- -------- -------- -------- // These functions return true or false depending on the success or failure of the function. @@ -1164,20 +1224,30 @@ static bool __CFLocaleCopyLocaleID(CFLocaleRef locale, bool user, CFTypeRef *cf, static bool __CFLocaleCopyCodes(CFLocaleRef locale, bool user, CFTypeRef *cf, CFStringRef context) { + static CFStringRef const kCFLocaleCodesKey = CFSTR("__kCFLocaleCodes"); + + bool codesWasAllocated = false; CFDictionaryRef codes = NULL; - // this access of _cache is protected by the lock in CFLocaleGetValue() - if (!CFDictionaryGetValueIfPresent(locale->_cache, CFSTR("__kCFLocaleCodes"), (const void **)&codes)) { + if (!__CFLocaleCacheGetValueIfPresent(locale, kCFLocaleCodesKey, (const void **)&codes)) { codes = CFLocaleCreateComponentsFromLocaleIdentifier(kCFAllocatorSystemDefault, locale->_identifier); - if (codes) CFDictionarySetValue(locale->_cache, CFSTR("__kCFLocaleCodes"), codes); - if (codes) CFRelease(codes); + codesWasAllocated = (codes != NULL); + + // This function is only called from a __CFLocaleKeyTable[i].get(...) access, which only happens under a lock. + // We explicitly assign `NULL` into the cache here to prevent trying to call `CFLocaleCreateComponentsFromLocaleIdentifier` on every access of this — `locale->_identifier` is immutable, so the results would never change. + __CFLocaleCacheSet_alreadyLocked(locale, kCFLocaleCodesKey, codes); } - if (codes) { - CFStringRef value = (CFStringRef)CFDictionaryGetValue(codes, context); // context is one of kCFLocale*Code constants - if (value) CFRetain(value); - *cf = value; - return true; + + CFStringRef value = codes ? (CFStringRef)CFDictionaryGetValue(codes, context) : NULL; // context is one of kCFLocale*Code constants + if (codesWasAllocated) { + CFRelease(codes); + } + + if (value) { + *cf = CFRetain(value); + return true; + } else { + return false; } - return false; } #if TARGET_OS_MAC || TARGET_OS_WIN32 || TARGET_OS_LINUX diff --git a/CoreFoundation/Locale.subproj/CFLocale.h b/CoreFoundation/Locale.subproj/CFLocale.h index ff6acdf33e..6fda9a9ec7 100644 --- a/CoreFoundation/Locale.subproj/CFLocale.h +++ b/CoreFoundation/Locale.subproj/CFLocale.h @@ -1,7 +1,7 @@ /* CFLocale.h - Copyright (c) 2002-2018, Apple Inc. and the Swift project authors + Copyright (c) 2002-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Locale.subproj/CFLocaleIdentifier.c b/CoreFoundation/Locale.subproj/CFLocaleIdentifier.c index 9b8f3f32cc..bc8e6984bc 100644 --- a/CoreFoundation/Locale.subproj/CFLocaleIdentifier.c +++ b/CoreFoundation/Locale.subproj/CFLocaleIdentifier.c @@ -1,8 +1,8 @@ /* CFLocaleIdentifier.c - Copyright (c) 2002-2018, Apple Inc. and the Swift project authors + Copyright (c) 2002-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -919,6 +919,7 @@ static const KeyStringToResultString localeStringPrefixToDefaults[] = { { "ak-", "-Latn" }, // Akan { "am-", "-Ethi" }, // Amharic { "ar-", "-Arab" }, // Arabic + { "ars-", "-Arab" }, // Arabic, Najdi { "as-", "-Beng" }, // Assamese { "asa-", "-Latn" }, // Asu { "ay-", "-Latn" }, // Aymara @@ -997,6 +998,7 @@ static const KeyStringToResultString localeStringPrefixToDefaults[] = { { "kn-", "-Knda" }, // Kannada { "ko-", "-Hang" }, // Korean (? not Suppress-Script) { "kok-", "-Deva" }, // Konkani + { "ks-", "-Aran" }, // Kashmiri (Arabic [Nastaliq]) { "ksb-", "-Latn" }, // Shambala { "ksf-", "-Latn" }, // Bafia { "kw-", "-Latn" }, // Cornish @@ -1081,8 +1083,8 @@ static const KeyStringToResultString localeStringPrefixToDefaults[] = { { "twq-", "-Latn" }, // Tasawaq { "tzm-", "-Latn" }, // Central Morocco Tamazight { "uk-", "-Cyrl" }, // Ukrainian - { "ur-", "-Arab" }, // Urdu - { "uz-", "-Cyrl" }, // Uzbek + { "ur-", "-Aran" }, // Urdu (Arabic [Nastaliq]) + { "uz-", "-Latn" }, // Uzbek { "vai-", "-Vaii" }, // Vai { "vi-", "-Latn" }, // Vietnamese { "vun-", "-Latn" }, // Vunjo diff --git a/CoreFoundation/Locale.subproj/CFLocaleInternal.h b/CoreFoundation/Locale.subproj/CFLocaleInternal.h index ff4ccad0ba..8b5125689c 100644 --- a/CoreFoundation/Locale.subproj/CFLocaleInternal.h +++ b/CoreFoundation/Locale.subproj/CFLocaleInternal.h @@ -1,8 +1,8 @@ /* CFLocaleInternal.h - Copyright (c) 2008-2018, Apple Inc. and the Swift project authors + Copyright (c) 2008-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Locale.subproj/CFLocaleKeys.c b/CoreFoundation/Locale.subproj/CFLocaleKeys.c index 96510c43e3..9dddc2d976 100644 --- a/CoreFoundation/Locale.subproj/CFLocaleKeys.c +++ b/CoreFoundation/Locale.subproj/CFLocaleKeys.c @@ -1,11 +1,10 @@ /* CFLocaleKeys.c - Copyright (c) 2008-2018, Apple Inc. and the Swift project authors + Copyright (c) 2008-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Christopher Kane */ #include "CFInternal.h" diff --git a/CoreFoundation/Locale.subproj/CFLocale_Private.h b/CoreFoundation/Locale.subproj/CFLocale_Private.h index 05139bf136..f7d0c181fc 100644 --- a/CoreFoundation/Locale.subproj/CFLocale_Private.h +++ b/CoreFoundation/Locale.subproj/CFLocale_Private.h @@ -1,7 +1,7 @@ /* CFLocale_Private.h - Copyright (c) 2016-2018, Apple Inc. and the Swift project authors + Copyright (c) 2016-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Locale.subproj/CFNumberFormatter.c b/CoreFoundation/Locale.subproj/CFNumberFormatter.c index 2f28d8f4e1..7f109b9d11 100644 --- a/CoreFoundation/Locale.subproj/CFNumberFormatter.c +++ b/CoreFoundation/Locale.subproj/CFNumberFormatter.c @@ -1,11 +1,11 @@ /* CFNumberFormatter.c - Copyright (c) 2002-2018, Apple Inc. and the Swift project authors + Copyright (c) 2002-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: David Smith + Responsibility: Itai Ferber */ #include @@ -84,16 +84,6 @@ CFNumberFormatterRef CFNumberFormatterCreate(CFAllocatorRef allocator, CFLocaleR if (NULL == memory) { return NULL; } - memory->_nf = NULL; - memory->_locale = NULL; - memory->_format = NULL; - memory->_defformat = NULL; - memory->_compformat = NULL; - memory->_multiplier = NULL; - memory->_zeroSym = NULL; - memory->_isLenient = false; - memory->_userSetMultiplier = false; - memory->_usesCharacterDirection = false; if (NULL == locale) locale = CFLocaleGetSystem(); memory->_style = style; uint32_t ustyle; @@ -134,7 +124,6 @@ CFNumberFormatterRef CFNumberFormatterCreate(CFAllocatorRef allocator, CFLocaleR CFRelease(memory); return NULL; } - if (kCFNumberFormatterNoStyle == style) { UChar ubuff[1]; status = U_ZERO_ERROR; @@ -156,8 +145,11 @@ CFNumberFormatterRef CFNumberFormatterCreate(CFAllocatorRef allocator, CFLocaleR memory->_format = CFStringCreateWithCharacters(allocator, (const UniChar *)ubuffer, ret); } } - memory->_defformat = memory->_format ? (CFStringRef)CFRetain(memory->_format) : NULL; - memory->_compformat = memory->_format ? __CFNumberFormatterCreateCompressedString(memory->_format, true, NULL) : NULL; + if (memory->_format) { + memory->_defformat = CFRetain(memory->_format); + memory->_compformat = __CFNumberFormatterCreateCompressedString(memory->_format, true, NULL); + } + if (kCFNumberFormatterSpellOutStyle != memory->_style && kCFNumberFormatterOrdinalStyle != memory->_style && kCFNumberFormatterCurrencyPluralStyle != memory->_style && kCFNumberFormatterDurationStyle != memory->_style) { int32_t n = __cficu_unum_getAttribute(memory->_nf, UNUM_MULTIPLIER); if (1 != n) { @@ -292,19 +284,30 @@ static CFStringRef __CFNumberFormatterCreateCompressedString(CFStringRef inStrin // Should not be called for rule-based ICU formatters; not supported static void __CFNumberFormatterApplySymbolPrefs(const void *key, const void *value, void *context) { if (CFGetTypeID(key) == CFStringGetTypeID() && CFGetTypeID(value) == CFStringGetTypeID()) { - CFNumberFormatterRef formatter = (CFNumberFormatterRef)context; - UNumberFormatSymbol sym = (UNumberFormatSymbol)CFStringGetIntValue((CFStringRef)key); - CFStringRef item = (CFStringRef)value; + CFNumberFormatterRef const formatter = (CFNumberFormatterRef)context; + UNumberFormatSymbol const sym = (UNumberFormatSymbol)CFStringGetIntValue((CFStringRef)key); + CFStringRef const item = (CFStringRef)value; + + UErrorCode status = U_ZERO_ERROR; CFIndex item_cnt = CFStringGetLength(item); - STACK_BUFFER_DECL(UChar, item_buffer, item_cnt); - UChar *item_ustr = (UChar *)CFStringGetCharactersPtr(item); - if (NULL == item_ustr) { - CFStringGetCharacters(item, CFRangeMake(0, __CFMin(BUFFER_SIZE, item_cnt)), (UniChar *)item_buffer); - item_ustr = item_buffer; + if (item_cnt > 0) { + CFIndex const buffer_size = __CFMin(BUFFER_SIZE, item_cnt); + STACK_BUFFER_DECL(UChar, item_buffer, buffer_size); + + UChar *item_ustr = (UChar *)CFStringGetCharactersPtr(item); + if (NULL == item_ustr) { + CFStringGetCharacters(item, CFRangeMake(0, buffer_size), (UniChar *)item_buffer); + item_ustr = item_buffer; + item_cnt = buffer_size; + } + + __cficu_unum_setSymbol(formatter->_nf, sym, item_ustr, item_cnt, &status); + } else { + UChar ubuff[1]; + ubuff[0] = '#'; + __cficu_unum_setSymbol(formatter->_nf, sym, ubuff, 1, &status); } - UErrorCode status = U_ZERO_ERROR; - __cficu_unum_setSymbol(formatter->_nf, sym, item_ustr, item_cnt, &status); - } + } } // Should not be called for rule-based ICU formatters @@ -639,15 +642,33 @@ Boolean CFNumberFormatterGetValueFromString(CFNumberFormatterRef formatter, CFSt } CFRelease(zeroSym); } - if (1024 < range.length) range.length = 1024; + if (range.length > 1024) { + range.length = 1024; + } else if (range.length <= 0) { + range.length = 0; + } + const UChar *ustr = (const UChar *)CFStringGetCharactersPtr(stringToParse); - STACK_BUFFER_DECL(UChar, ubuffer, (NULL == ustr) ? range.length : 1); + // This set of conditionals is designed to avoid allocating a large stack buffer unless CFStringGetCharactersPtr returned null (meaning we need space to put the result). + // The if line above this limits this stack buffer to 1024 total in case of stack allocation. + // If ustr is non-null OR range.length == 0, use a value of 1 (because allocating a zero length stack buffer is not allowed). We won't use the buffer in either of these cases, however. In the first case we have a pointer to the bytes directly. In the second we skip filling the buffer. + // Otherwise, use range.length. + CFIndex const length = (ustr != NULL || range.length == 0) ? 1 : range.length; + STACK_BUFFER_DECL(UChar, ubuffer, length); if (NULL == ustr) { - CFStringGetCharacters(stringToParse, range, (UniChar *)ubuffer); - ustr = ubuffer; + if (range.length > 0) { + CFStringGetCharacters(stringToParse, range, (UniChar *)ubuffer); + ustr = ubuffer; + } } else if (!formatter->_isLenient) { ustr += range.location; } + + if (ustr == NULL) { + if (stringToParse) { CFRelease(stringToParse); } + return false; + } + CFNumberRef multiplierRef = formatter->_multiplier; formatter->_multiplier = NULL; if (formatter->_isLenient) { diff --git a/CoreFoundation/Locale.subproj/CFNumberFormatter.h b/CoreFoundation/Locale.subproj/CFNumberFormatter.h index 33520238ae..300064b220 100644 --- a/CoreFoundation/Locale.subproj/CFNumberFormatter.h +++ b/CoreFoundation/Locale.subproj/CFNumberFormatter.h @@ -1,7 +1,7 @@ /* CFNumberFormatter.h - Copyright (c) 2003-2018, Apple Inc. and the Swift project authors + Copyright (c) 2003-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/NumberDate.subproj/CFBigNumber.c b/CoreFoundation/NumberDate.subproj/CFBigNumber.c index 0854f19eac..b26dadcadb 100644 --- a/CoreFoundation/NumberDate.subproj/CFBigNumber.c +++ b/CoreFoundation/NumberDate.subproj/CFBigNumber.c @@ -1,16 +1,17 @@ /* CFBigNumber.c - Copyright (c) 2012-2018, Apple Inc. and the Swift project authors + Copyright (c) 2012-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Christopher Kane + Responsibility: Philippe Hausler Original author: Zhi Feng Huang */ #include #include +#include #include #include #include @@ -18,15 +19,6 @@ #include "CFInternal.h" -typedef struct { - int64_t high; - uint64_t low; -} CFSInt128Struct; - -#define kCFNumberSInt128Type 17 - -CF_EXPORT CFNumberType _CFNumberGetType2(CFNumberRef number); - #if TARGET_RT_64_BIT #ifndef _INT128_T diff --git a/CoreFoundation/NumberDate.subproj/CFBigNumber.h b/CoreFoundation/NumberDate.subproj/CFBigNumber.h index ff196df117..e73cf9f432 100644 --- a/CoreFoundation/NumberDate.subproj/CFBigNumber.h +++ b/CoreFoundation/NumberDate.subproj/CFBigNumber.h @@ -1,7 +1,7 @@ /* CFBigNumber.h - Copyright (c) 2012-2018, Apple Inc. and the Swift project authors + Copyright (c) 2012-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/NumberDate.subproj/CFDate.c b/CoreFoundation/NumberDate.subproj/CFDate.c index 975eebb752..51966a13be 100644 --- a/CoreFoundation/NumberDate.subproj/CFDate.c +++ b/CoreFoundation/NumberDate.subproj/CFDate.c @@ -1,11 +1,11 @@ /* CFDate.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Christopher Kane + Responsibility: Kevin Perry */ #include @@ -17,6 +17,7 @@ #include "CFInternal.h" #include "CFRuntime_Internal.h" #include +#include #if __HAS_DISPATCH__ #include @@ -196,7 +197,7 @@ CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at) { CFDateRef memory; uint32_t size; size = sizeof(struct __CFDate) - sizeof(CFRuntimeBase); - memory = (CFDateRef)_CFRuntimeCreateInstance(allocator, CFDateGetTypeID(), size, NULL); + memory = (CFDateRef)_CFRuntimeCreateInstance(allocator, _kCFRuntimeIDCFDate, size, NULL); if (NULL == memory) { return NULL; } @@ -205,20 +206,20 @@ CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at) { } CFTimeInterval CFDateGetAbsoluteTime(CFDateRef date) { - CF_OBJC_FUNCDISPATCHV(CFDateGetTypeID(), CFTimeInterval, (NSDate *)date, timeIntervalSinceReferenceDate); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDate, CFTimeInterval, (NSDate *)date, timeIntervalSinceReferenceDate); __CFGenericValidateType(date, CFDateGetTypeID()); return date->_time; } CFTimeInterval CFDateGetTimeIntervalSinceDate(CFDateRef date, CFDateRef otherDate) { - CF_OBJC_FUNCDISPATCHV(CFDateGetTypeID(), CFTimeInterval, (NSDate *)date, timeIntervalSinceDate:(NSDate *)otherDate); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDate, CFTimeInterval, (NSDate *)date, timeIntervalSinceDate:(NSDate *)otherDate); __CFGenericValidateType(date, CFDateGetTypeID()); __CFGenericValidateType(otherDate, CFDateGetTypeID()); return date->_time - otherDate->_time; } CFComparisonResult CFDateCompare(CFDateRef date, CFDateRef otherDate, void *context) { - CF_OBJC_FUNCDISPATCHV(CFDateGetTypeID(), CFComparisonResult, (NSDate *)date, compare:(NSDate *)otherDate); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFDate, CFComparisonResult, (NSDate *)date, compare:(NSDate *)otherDate); __CFGenericValidateType(date, CFDateGetTypeID()); __CFGenericValidateType(otherDate, CFDateGetTypeID()); if (date->_time < otherDate->_time) return kCFCompareLessThan; @@ -242,7 +243,8 @@ CF_INLINE double __CFDoubleMod(double d, int32_t modulus) { #define INVALID_MONTH_RESULT (0xffff) #define CHECK_BOUNDS(month, array) ((month) >= 0 && (month) < (sizeof(array) / sizeof(*(array)))) -#define ASSERT_VALID_MONTH(month) do { if (!((month) >= 1 && (month) <= 12)) { /* os_log_error(OS_LOG_DEFAULT, "Month %d is out of bounds", (int)month); HALT */ } } while(0) +#define IS_VALID_MONTH(month) ((month) >= 1 && (month) <= 12) +#define ASSERT_VALID_MONTH(month) do { if (!IS_VALID_MONTH(month)) { os_log_error(OS_LOG_DEFAULT, "Month %d is out of bounds", (int)month); /* HALT */ } } while(0) static const uint8_t daysInMonth[16] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0, 0, 0}; static const uint16_t daysBeforeMonth[16] = {INVALID_MONTH_RESULT, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, INVALID_MONTH_RESULT, INVALID_MONTH_RESULT}; @@ -307,12 +309,10 @@ static void __CFYMDFromAbsolute(int64_t absolute, int64_t *year, int8_t *month, int8_t m = absolute / 33 + 1; /* search from the approximation */ bool leap = isleap(y); - // Calculations above should guarantee that 0 <= absolute < 336, meaning 1 <= m <= 11 and that __CFDaysBeforeMonth(m + 1, …) will at some point be > absolute. + // Calculations above should guarantee that 0 <= absolute < 365, meaning 1 <= m <= 12. However, m+1 may well become out of bounds. ASSERT_VALID_MONTH(m); - ASSERT_VALID_MONTH(m + 1); - while (__CFDaysBeforeMonth(m + 1, y, leap) <= absolute) { + while (IS_VALID_MONTH(m + 1) && __CFDaysBeforeMonth(m + 1, y, leap) <= absolute) { m++; - ASSERT_VALID_MONTH(m + 1); } if (month) *month = m; if (day) *day = absolute - __CFDaysBeforeMonth(m, y, leap) + 1; diff --git a/CoreFoundation/NumberDate.subproj/CFDate.h b/CoreFoundation/NumberDate.subproj/CFDate.h index 07a33c580a..58eed27b75 100644 --- a/CoreFoundation/NumberDate.subproj/CFDate.h +++ b/CoreFoundation/NumberDate.subproj/CFDate.h @@ -1,7 +1,7 @@ /* CFDate.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -62,7 +62,7 @@ typedef struct { SInt8 hour; SInt8 minute; double second; -} CFGregorianDate CF_CALENDAR_DEPRECATED(10_4, 10_10, 2_0, 8_0, "Use CFCalendar or NSCalendar API instead"); +} CFGregorianDate API_DEPRECATED("Use CFCalendar or NSCalendar API instead", macos(10.4, 10.10), ios(2.0, 8.0), watchos(2.0, 2.0), tvos(9.0, 9.0)); typedef struct { SInt32 years; @@ -71,41 +71,41 @@ typedef struct { SInt32 hours; SInt32 minutes; double seconds; -} CFGregorianUnits CF_CALENDAR_DEPRECATED(10_4, 10_10, 2_0, 8_0, "Use CFCalendar or NSCalendar API instead"); +} CFGregorianUnits API_DEPRECATED("Use CFCalendar or NSCalendar API instead", macos(10.4, 10.10), ios(2.0, 8.0), watchos(2.0, 2.0), tvos(9.0, 9.0)); typedef CF_OPTIONS(CFOptionFlags, CFGregorianUnitFlags) { - kCFGregorianUnitsYears CF_CALENDAR_ENUM_DEPRECATED(10_4, 10_10, 2_0, 8_0, "Use CFCalendar or NSCalendar API instead") = (1UL << 0), - kCFGregorianUnitsMonths CF_CALENDAR_ENUM_DEPRECATED(10_4, 10_10, 2_0, 8_0, "Use CFCalendar or NSCalendar API instead") = (1UL << 1), - kCFGregorianUnitsDays CF_CALENDAR_ENUM_DEPRECATED(10_4, 10_10, 2_0, 8_0, "Use CFCalendar or NSCalendar API instead") = (1UL << 2), - kCFGregorianUnitsHours CF_CALENDAR_ENUM_DEPRECATED(10_4, 10_10, 2_0, 8_0, "Use CFCalendar or NSCalendar API instead") = (1UL << 3), - kCFGregorianUnitsMinutes CF_CALENDAR_ENUM_DEPRECATED(10_4, 10_10, 2_0, 8_0, "Use CFCalendar or NSCalendar API instead") = (1UL << 4), - kCFGregorianUnitsSeconds CF_CALENDAR_ENUM_DEPRECATED(10_4, 10_10, 2_0, 8_0, "Use CFCalendar or NSCalendar API instead") = (1UL << 5), - kCFGregorianAllUnits CF_CALENDAR_ENUM_DEPRECATED(10_4, 10_10, 2_0, 8_0, "Use CFCalendar or NSCalendar API instead") = 0x00FFFFFF + kCFGregorianUnitsYears API_DEPRECATED("Use CFCalendar or NSCalendar API instead", macos(10.4, 10.10), ios(2.0, 8.0), watchos(2.0, 2.0), tvos(9.0, 9.0)) = (1UL << 0), + kCFGregorianUnitsMonths API_DEPRECATED("Use CFCalendar or NSCalendar API instead", macos(10.4, 10.10), ios(2.0, 8.0), watchos(2.0, 2.0), tvos(9.0, 9.0)) = (1UL << 1), + kCFGregorianUnitsDays API_DEPRECATED("Use CFCalendar or NSCalendar API instead", macos(10.4, 10.10), ios(2.0, 8.0), watchos(2.0, 2.0), tvos(9.0, 9.0)) = (1UL << 2), + kCFGregorianUnitsHours API_DEPRECATED("Use CFCalendar or NSCalendar API instead", macos(10.4, 10.10), ios(2.0, 8.0), watchos(2.0, 2.0), tvos(9.0, 9.0)) = (1UL << 3), + kCFGregorianUnitsMinutes API_DEPRECATED("Use CFCalendar or NSCalendar API instead", macos(10.4, 10.10), ios(2.0, 8.0), watchos(2.0, 2.0), tvos(9.0, 9.0)) = (1UL << 4), + kCFGregorianUnitsSeconds API_DEPRECATED("Use CFCalendar or NSCalendar API instead", macos(10.4, 10.10), ios(2.0, 8.0), watchos(2.0, 2.0), tvos(9.0, 9.0)) = (1UL << 5), + kCFGregorianAllUnits API_DEPRECATED("Use CFCalendar or NSCalendar API instead", macos(10.4, 10.10), ios(2.0, 8.0), watchos(2.0, 2.0), tvos(9.0, 9.0)) = 0x00FFFFFF }; CF_EXPORT -Boolean CFGregorianDateIsValid(CFGregorianDate gdate, CFOptionFlags unitFlags) CF_CALENDAR_DEPRECATED(10_4, 10_10, 2_0, 8_0, "Use CFCalendar or NSCalendar API instead"); +Boolean CFGregorianDateIsValid(CFGregorianDate gdate, CFOptionFlags unitFlags) API_DEPRECATED("Use CFCalendar or NSCalendar API instead", macos(10.4, 10.10), ios(2.0, 8.0), watchos(2.0, 2.0), tvos(9.0, 9.0)); CF_EXPORT -CFAbsoluteTime CFGregorianDateGetAbsoluteTime(CFGregorianDate gdate, CFTimeZoneRef tz) CF_CALENDAR_DEPRECATED(10_4, 10_10, 2_0, 8_0, "Use CFCalendar or NSCalendar API instead"); +CFAbsoluteTime CFGregorianDateGetAbsoluteTime(CFGregorianDate gdate, CFTimeZoneRef tz) API_DEPRECATED("Use CFCalendar or NSCalendar API instead", macos(10.4, 10.10), ios(2.0, 8.0), watchos(2.0, 2.0), tvos(9.0, 9.0)); CF_EXPORT -CFGregorianDate CFAbsoluteTimeGetGregorianDate(CFAbsoluteTime at, CFTimeZoneRef tz) CF_CALENDAR_DEPRECATED(10_4, 10_10, 2_0, 8_0, "Use CFCalendar or NSCalendar API instead"); +CFGregorianDate CFAbsoluteTimeGetGregorianDate(CFAbsoluteTime at, CFTimeZoneRef tz) API_DEPRECATED("Use CFCalendar or NSCalendar API instead", macos(10.4, 10.10), ios(2.0, 8.0), watchos(2.0, 2.0), tvos(9.0, 9.0)); CF_EXPORT -CFAbsoluteTime CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTime at, CFTimeZoneRef tz, CFGregorianUnits units) CF_CALENDAR_DEPRECATED(10_4, 10_10, 2_0, 8_0, "Use CFCalendar or NSCalendar API instead"); +CFAbsoluteTime CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTime at, CFTimeZoneRef tz, CFGregorianUnits units) API_DEPRECATED("Use CFCalendar or NSCalendar API instead", macos(10.4, 10.10), ios(2.0, 8.0), watchos(2.0, 2.0), tvos(9.0, 9.0)); CF_EXPORT -CFGregorianUnits CFAbsoluteTimeGetDifferenceAsGregorianUnits(CFAbsoluteTime at1, CFAbsoluteTime at2, CFTimeZoneRef tz, CFOptionFlags unitFlags) CF_CALENDAR_DEPRECATED(10_4, 10_10, 2_0, 8_0, "Use CFCalendar or NSCalendar API instead"); +CFGregorianUnits CFAbsoluteTimeGetDifferenceAsGregorianUnits(CFAbsoluteTime at1, CFAbsoluteTime at2, CFTimeZoneRef tz, CFOptionFlags unitFlags) API_DEPRECATED("Use CFCalendar or NSCalendar API instead", macos(10.4, 10.10), ios(2.0, 8.0), watchos(2.0, 2.0), tvos(9.0, 9.0)); CF_EXPORT -SInt32 CFAbsoluteTimeGetDayOfWeek(CFAbsoluteTime at, CFTimeZoneRef tz) CF_CALENDAR_DEPRECATED(10_4, 10_10, 2_0, 8_0, "Use CFCalendar or NSCalendar API instead"); +SInt32 CFAbsoluteTimeGetDayOfWeek(CFAbsoluteTime at, CFTimeZoneRef tz) API_DEPRECATED("Use CFCalendar or NSCalendar API instead", macos(10.4, 10.10), ios(2.0, 8.0), watchos(2.0, 2.0), tvos(9.0, 9.0)); CF_EXPORT -SInt32 CFAbsoluteTimeGetDayOfYear(CFAbsoluteTime at, CFTimeZoneRef tz) CF_CALENDAR_DEPRECATED(10_4, 10_10, 2_0, 8_0, "Use CFCalendar or NSCalendar API instead"); +SInt32 CFAbsoluteTimeGetDayOfYear(CFAbsoluteTime at, CFTimeZoneRef tz) API_DEPRECATED("Use CFCalendar or NSCalendar API instead", macos(10.4, 10.10), ios(2.0, 8.0), watchos(2.0, 2.0), tvos(9.0, 9.0)); CF_EXPORT -SInt32 CFAbsoluteTimeGetWeekOfYear(CFAbsoluteTime at, CFTimeZoneRef tz) CF_CALENDAR_DEPRECATED(10_4, 10_10, 2_0, 8_0, "Use CFCalendar or NSCalendar API instead"); +SInt32 CFAbsoluteTimeGetWeekOfYear(CFAbsoluteTime at, CFTimeZoneRef tz) API_DEPRECATED("Use CFCalendar or NSCalendar API instead", macos(10.4, 10.10), ios(2.0, 8.0), watchos(2.0, 2.0), tvos(9.0, 9.0)); CF_EXTERN_C_END diff --git a/CoreFoundation/NumberDate.subproj/CFNumber.c b/CoreFoundation/NumberDate.subproj/CFNumber.c index 9133dc2828..75bd9a1515 100644 --- a/CoreFoundation/NumberDate.subproj/CFNumber.c +++ b/CoreFoundation/NumberDate.subproj/CFNumber.c @@ -1,7 +1,7 @@ /* CFNumber.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -13,14 +13,12 @@ #include "CFInternal.h" #include "CFRuntime_Internal.h" #include +#include #include #include +#include -enum { - kCFNumberSInt128Type = 17 -}; - typedef CF_ENUM(uint8_t, _CFNumberCanonicalTypeIndex) { kCFNumberSInt8CanonicalTypeIndex = 0x0, kCFNumberSInt16CanonicalTypeIndex = 0x1, @@ -192,11 +190,6 @@ static const Float64Bits doubleOneBits = {.floatValue = 1.0f}; #error Unknown or unspecified DEPLOYMENT_TARGET #endif -typedef struct { // NOTE WELL: these two fields may switch position someday, do not use '= {high, low}' -style initialization - int64_t high; - uint64_t low; -} CFSInt128Struct; - static uint8_t isNeg128(const CFSInt128Struct *in) { return in->high < 0; } @@ -1005,7 +998,7 @@ CFTypeID CFNumberGetTypeID(void) { dispatch_once(&initOnce, ^{ - const char *caching = __CFgetenv("CFNumberDisableCache"); // "all" to disable caching and tagging; anything else to disable caching; nothing to leave both enabled + const char *caching = getenv("CFNumberDisableCache"); // "all" to disable caching and tagging; anything else to disable caching; nothing to leave both enabled if (caching) __CFNumberCaching = (!strcmp(caching, "all")) ? kCFNumberCachingFullyDisabled : kCFNumberCachingDisabled; // initial state above is kCFNumberCachingEnabled }); return _kCFRuntimeIDCFNumber; @@ -1174,8 +1167,8 @@ CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType type, const vo } CFNumberType CFNumberGetType(CFNumberRef number) { - CF_OBJC_FUNCDISPATCHV(CFNumberGetTypeID(), CFNumberType, (NSNumber *)number, _cfNumberType); - CF_SWIFT_FUNCDISPATCHV(CFNumberGetTypeID(), CFNumberType, (CFSwiftRef)number, NSNumber._cfNumberGetType); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFNumber, CFNumberType, (NSNumber *)number, _cfNumberType); + CF_SWIFT_FUNCDISPATCHV(_kCFRuntimeIDCFNumber, CFNumberType, (CFSwiftRef)number, NSNumber._cfNumberGetType); __CFAssertIsNumber(number); CFNumberType type = __CFNumberGetType(number); if (kCFNumberSInt128Type == type) type = kCFNumberSInt64Type; // must hide this type, since it is not public @@ -1183,7 +1176,7 @@ CFNumberType CFNumberGetType(CFNumberRef number) { } CF_EXPORT CFNumberType _CFNumberGetType2(CFNumberRef number) { - CF_OBJC_FUNCDISPATCHV(CFNumberGetTypeID(), CFNumberType, (NSNumber *)number, _cfNumberType); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFNumber, CFNumberType, (NSNumber *)number, _cfNumberType); __CFAssertIsNumber(number); return __CFNumberGetType(number); } @@ -1203,8 +1196,8 @@ Boolean CFNumberIsFloatType(CFNumberRef number) { Boolean CFNumberGetValue(CFNumberRef number, CFNumberType type, void *valuePtr) { //printf("+ [%p] CFNumberGetValue(%p, %d, %p)\n", pthread_self(), number, type, valuePtr); - CF_OBJC_FUNCDISPATCHV(CFNumberGetTypeID(), Boolean, (NSNumber *)number, _getValue:(void *)valuePtr forType:(CFNumberType)__CFNumberTypeTable[type].canonicalType); - CF_SWIFT_FUNCDISPATCHV(CFNumberGetTypeID(), Boolean, (CFSwiftRef)number, NSNumber._getValue, valuePtr, (CFNumberType)__CFNumberTypeTable[type].canonicalType); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFNumber, Boolean, (NSNumber *)number, _getValue:(void *)valuePtr forType:(CFNumberType)__CFNumberTypeTable[type].canonicalType); + CF_SWIFT_FUNCDISPATCHV(_kCFRuntimeIDCFNumber, Boolean, (CFSwiftRef)number, NSNumber._getValue, valuePtr, (CFNumberType)__CFNumberTypeTable[type].canonicalType); __CFAssertIsNumber(number); __CFAssertIsValidNumberType(type); uint8_t localMemory[128]; @@ -1213,8 +1206,8 @@ Boolean CFNumberGetValue(CFNumberRef number, CFNumberType type, void *valuePtr) } static CFComparisonResult CFNumberCompare_new(CFNumberRef number1, CFNumberRef number2, void *context) { - CF_OBJC_FUNCDISPATCHV(CFNumberGetTypeID(), CFComparisonResult, (NSNumber *)number1, compare:(NSNumber *)number2); - CF_OBJC_FUNCDISPATCHV(CFNumberGetTypeID(), CFComparisonResult, (NSNumber *)number2, _reverseCompare:(NSNumber *)number1); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFNumber, CFComparisonResult, (NSNumber *)number1, compare:(NSNumber *)number2); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFNumber, CFComparisonResult, (NSNumber *)number2, _reverseCompare:(NSNumber *)number1); __CFAssertIsNumber(number1); __CFAssertIsNumber(number2); diff --git a/CoreFoundation/NumberDate.subproj/CFNumber.h b/CoreFoundation/NumberDate.subproj/CFNumber.h index 1a77a0d8e1..0e0c361c91 100644 --- a/CoreFoundation/NumberDate.subproj/CFNumber.h +++ b/CoreFoundation/NumberDate.subproj/CFNumber.h @@ -1,7 +1,7 @@ /* CFNumber.h - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/NumberDate.subproj/CFNumber_Private.h b/CoreFoundation/NumberDate.subproj/CFNumber_Private.h new file mode 100644 index 0000000000..c604bea514 --- /dev/null +++ b/CoreFoundation/NumberDate.subproj/CFNumber_Private.h @@ -0,0 +1,30 @@ +/* CFNumber_Private.h + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors + + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors + Licensed under Apache License v2.0 with Runtime Library Exception + See http://swift.org/LICENSE.txt for license information + See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors + */ + +#if !defined(__COREFOUNDATION_CFNUMBER_PRIVATE__) +#define __COREFOUNDATION_CFNUMBER_PRIVATE__ 1 + +#include + +CF_IMPLICIT_BRIDGING_ENABLED +CF_EXTERN_C_BEGIN + +typedef struct { + int64_t high; + uint64_t low; +} CFSInt128Struct; + +enum { + kCFNumberSInt128Type = 17 +}; + +CF_EXTERN_C_END +CF_IMPLICIT_BRIDGING_DISABLED + +#endif /* ! __COREFOUNDATION_CFNUMBER_PRIVATE__ */ diff --git a/CoreFoundation/NumberDate.subproj/CFTimeZone.c b/CoreFoundation/NumberDate.subproj/CFTimeZone.c index 88b60ce027..973cf1cceb 100644 --- a/CoreFoundation/NumberDate.subproj/CFTimeZone.c +++ b/CoreFoundation/NumberDate.subproj/CFTimeZone.c @@ -1,11 +1,11 @@ /* CFTimeZone.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Christopher Kane + Responsibility: Itai Ferber */ @@ -894,6 +894,15 @@ static CFTimeZoneRef __CFTimeZoneCreateSystem(void) { CFRelease(name); if (result) return result; } +#if TARGET_OS_ANDROID + // Timezone database by name not available on Android. + // Approximate with gmtoff - could be general default. + struct tm info; + time_t now = time(NULL); + if (NULL != localtime_r(&now, &info)) { + return CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorSystemDefault, info.tm_gmtoff); + } +#endif return CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorSystemDefault, 0.0); } @@ -1110,18 +1119,19 @@ static int32_t __tryParseGMTName(CFStringRef name) { CFStringGetCharacters(name, CFRangeMake(0, len), ustr); ustr[len] = 0; - // GMT, GMT{+|-}HH, GMT{+|-}HHMM, GMT{+|-}{H|HH}{:|.}MM - // UTC, UTC{+|-}HH, UTC{+|-}HHMM, UTC{+|-}{H|HH}{:|.}MM + // GMT, GMT{+|-}H, GMT{+|-}HH, GMT{+|-}HHMM, GMT{+|-}{H|HH}{:|.}MM + // UTC, UTC{+|-}H, UTC{+|-}HH, UTC{+|-}HHMM, UTC{+|-}{H|HH}{:|.}MM // where "00" <= HH <= "18", "00" <= MM <= "59", and if HH==18, then MM must == 00 - + Boolean isGMT = ('G' == ustr[0] && 'M' == ustr[1] && 'T' == ustr[2]); Boolean isUTC = ('U' == ustr[0] && 'T' == ustr[1] && 'C' == ustr[2]); if (!isGMT && !isUTC) return -1; if (3 == len) return 0; - if (len < 6) return -1; + if (len < 5) return -1; if (!('+' == ustr[3] || '-' == ustr[3])) return -1; if (!('0' <= ustr[4] && ustr[4] <= '9')) return -1; + if (5 == len) return (('-' == ustr[3]) ? -1 : 1) * (ustr[4] - '0') * 3600; // GMT{+|-}H Boolean twoHourDigits = ('0' <= ustr[5] && ustr[5] <= '9'); Boolean fiveIsPunct = (':' == ustr[5] || '.' == ustr[5]); if (!(twoHourDigits || fiveIsPunct)) return -1; diff --git a/CoreFoundation/NumberDate.subproj/CFTimeZone.h b/CoreFoundation/NumberDate.subproj/CFTimeZone.h index e4beab8095..c3f8b723ca 100644 --- a/CoreFoundation/NumberDate.subproj/CFTimeZone.h +++ b/CoreFoundation/NumberDate.subproj/CFTimeZone.h @@ -1,7 +1,7 @@ /* CFTimeZone.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Parsing.subproj/CFBinaryPList.c b/CoreFoundation/Parsing.subproj/CFBinaryPList.c index fc0cf00eef..0a68abfe94 100644 --- a/CoreFoundation/Parsing.subproj/CFBinaryPList.c +++ b/CoreFoundation/Parsing.subproj/CFBinaryPList.c @@ -1,7 +1,7 @@ /* CFBinaryPList.c - Copyright (c) 2000-2018, Apple Inc. and the Swift project authors + Copyright (c) 2000-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -22,6 +22,7 @@ #include #include #include +#include #include "CFBasicHash.h" #include #include @@ -30,15 +31,6 @@ #include "CFRuntime_Internal.h" #include -typedef struct { - int64_t high; - uint64_t low; -} CFSInt128Struct; - -enum { - kCFNumberSInt128Type = 17 -}; - enum { CF_NO_ERROR = 0, CF_OVERFLOW_ERROR = (1 << 0), @@ -339,8 +331,6 @@ static void _appendString(__CFBinaryPlistWriteBuffer *buf, CFStringRef str, Bool if (bytes != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, bytes); } -CF_EXPORT CFNumberType _CFNumberGetType2(CFNumberRef number); - static void _appendNumber(__CFBinaryPlistWriteBuffer *buf, CFNumberRef num, Boolean dryRun) { uint8_t marker; uint64_t bigint; @@ -560,7 +550,7 @@ CF_PRIVATE CFIndex __CFBinaryPlistWriteOrPresize(CFPropertyListRef plist, CFType */ CFBasicHashCallbacks callbacks = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; objtable = (CFMutableDictionaryRef)CFBasicHashCreate(kCFAllocatorSystemDefault, kCFBasicHashHasKeys | kCFBasicHashLinearHashing | kCFBasicHashAggressiveGrowth, &callbacks); - _CFRuntimeSetInstanceTypeIDAndIsa(objtable, CFDictionaryGetTypeID()); + _CFRuntimeSetInstanceTypeIDAndIsa(objtable, _kCFRuntimeIDCFDictionary); const CFArrayCallBacks arrayCallbacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, 0, 0}; objlist = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &arrayCallbacks); @@ -708,7 +698,7 @@ CF_PRIVATE CFDataRef __CFBinaryPlistCreateDataUsingExternalBufferAllocator(CFPro #define FAIL_FALSE do { return false; } while (0) #define FAIL_NULL do { return NULL; } while (0) -CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFSetRef keyPaths, CFPropertyListRef *plist); +CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFSetRef keyPaths, CFPropertyListRef *plist, CFTypeID *outPlistTypeID); /* Grab a valSize-bytes integer out of the buffer pointed at by data and return it. */ @@ -821,9 +811,8 @@ bool __CFBinaryPlistGetTopLevelInfo(const uint8_t *databytes, uint64_t datalen, return true; } -CF_INLINE Boolean _plistIsPrimitive(CFPropertyListRef pl) { - CFTypeID type = CFGetTypeID(pl); - if (_kCFRuntimeIDCFDictionary == type || _kCFRuntimeIDCFArray == type || _kCFRuntimeIDCFSet == type) FAIL_FALSE; +CF_INLINE Boolean _typeIsPlistPrimitive(CFTypeID type) { + if (_kCFRuntimeIDCFDictionary == type || _kCFRuntimeIDCFArray == type || _kCFRuntimeIDCFSet == type || _kCFRuntimeNotATypeID == type) FAIL_FALSE; return true; } @@ -885,7 +874,7 @@ bool __CFBinaryPlistIsArray(const uint8_t *databytes, uint64_t datalen, uint64_t return result; } -bool __CFBinaryPlistGetOffsetForValueFromArray2(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFIndex idx, uint64_t *offset, CFMutableDictionaryRef objects) { +bool __CFBinaryPlistGetOffsetForValueFromArray2(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFIndex idx, uint64_t *offset, CFMutableDictionaryRef _Nullable unused) { const uint8_t *ptr; uint8_t marker; uint64_t objectsRangeEnd; @@ -998,8 +987,8 @@ CFSetRef __CFBinaryPlistCopyTopLevelKeys(CFAllocatorRef allocator, const uint8_t // Unlike in __CFBinaryPlistGetOffsetForValueFromDictionary3, we're accumulating keys, so we go through the CFObjectRef case always. CFPropertyListRef keyInData = NULL; - if (!(__CFBinaryPlistCreateObjectFiltered(databytes, datalen, off, trailer, allocator, kCFPropertyListImmutable, NULL, NULL, 0, NULL, &keyInData) && - CFGetTypeID(keyInData) == _kCFRuntimeIDCFString)) { + CFTypeID typeID = _kCFRuntimeNotATypeID; + if (!(__CFBinaryPlistCreateObjectFiltered(databytes, datalen, off, trailer, allocator, kCFPropertyListImmutable, NULL, NULL, 0, NULL, &keyInData, &typeID) && typeID == _kCFRuntimeIDCFString)) { bad = true; if (keyInData) { // we're not storing keyInData in the buffer, so we need to free it now; buffered keys are cleaned below @@ -1054,10 +1043,11 @@ CFSetRef __CFBinaryPlistCopyTopLevelKeys(CFAllocatorRef allocator, const uint8_t @param objects Used for caching objects. Should be a valid CFMutableDictionaryRef. @return True if the key was found, false otherwise. */ -bool __CFBinaryPlistGetOffsetForValueFromDictionary3(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFTypeRef key, uint64_t *koffset, uint64_t *voffset, Boolean unused, CFMutableDictionaryRef objects) { +bool __CFBinaryPlistGetOffsetForValueFromDictionary3(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFTypeRef key, uint64_t *koffset, uint64_t *voffset, Boolean unused, CFMutableDictionaryRef _Nullable unused2) { // Require a key that is a plist primitive - if (!key || !_plistIsPrimitive(key)) FAIL_FALSE; + CFTypeID const keyTypeID = key ? CFGetTypeID(key) : _kCFRuntimeNotATypeID; + if (!_typeIsPlistPrimitive(keyTypeID)) FAIL_FALSE; uint64_t cnt = 0; const uint8_t *ptr = NULL; @@ -1068,7 +1058,7 @@ bool __CFBinaryPlistGetOffsetForValueFromDictionary3(const uint8_t *databytes, u // For short keys (15 bytes or less) in ASCII form, we can do a quick comparison check // We get the pointer or copy the buffer here, outside of the loop CFIndex stringKeyLen = -1; - if (CFGetTypeID(key) == _kCFRuntimeIDCFString) { + if (keyTypeID == _kCFRuntimeIDCFString) { stringKeyLen = CFStringGetLength((CFStringRef)key); } @@ -1139,7 +1129,8 @@ bool __CFBinaryPlistGetOffsetForValueFromDictionary3(const uint8_t *databytes, u // (what allocator __CFBinaryPlistCreateObjectFiltered() or __CFBinaryPlistCreateObject() // will eventually be called with which results in that object) keyInData = NULL; - if (!__CFBinaryPlistCreateObjectFiltered(databytes, datalen, off, trailer, kCFAllocatorSystemDefault, kCFPropertyListImmutable, NULL /*objects*/, NULL, 0, NULL, &keyInData) || !_plistIsPrimitive(keyInData)) { + CFTypeID typeID = _kCFRuntimeNotATypeID; + if (!__CFBinaryPlistCreateObjectFiltered(databytes, datalen, off, trailer, kCFAllocatorSystemDefault, kCFPropertyListImmutable, NULL /*objects*/, NULL, 0, NULL, &keyInData, &typeID) || !_typeIsPlistPrimitive(typeID)) { if (keyInData) CFRelease(keyInData); FAIL_FALSE; } @@ -1167,15 +1158,16 @@ extern CFSetRef __CFSetCreateTransfer(CFAllocatorRef allocator, const void * *kl extern CFArrayRef __CFArrayCreateTransfer(CFAllocatorRef allocator, const void * *klist, CFIndex numValues); CF_PRIVATE void __CFPropertyListCreateSplitKeypaths(CFAllocatorRef allocator, CFSetRef currentKeys, CFSetRef *theseKeys, CFSetRef *nextKeys); -CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFSetRef keyPaths, CFPropertyListRef *plist) { +CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFSetRef keyPaths, CFPropertyListRef *outPlist, CFTypeID *outPlistTypeID) { - if (objects) { - *plist = CFDictionaryGetValue(objects, (const void *)(uintptr_t)startOffset); - if (*plist) { + if (objects && outPlist) { + *outPlist = CFDictionaryGetValue(objects, (const void *)(uintptr_t)startOffset); + if (*outPlist) { // have to assume that '*plist' was previously created with same allocator that is now being passed in - CFRetain(*plist); - return true; - } + CFRetain(*outPlist); + if (outPlistTypeID) *outPlistTypeID = CFGetTypeID(*outPlist); + return true; + } } // at any one invocation of this function, set should contain the offsets in the "path" down to this object @@ -1188,20 +1180,23 @@ CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, ui if (startOffset < objectsRangeStart || objectsRangeEnd < startOffset) FAIL_FALSE; uint64_t off; - CFPropertyListRef *list; + CFPropertyListRef *list = NULL; uint8_t marker = *(databytes + startOffset); switch (marker & 0xf0) { case kCFBinaryPlistMarkerNull: switch (marker) { case kCFBinaryPlistMarkerNull: - *plist = kCFNull; + if (outPlist) *outPlist = kCFNull; + if (outPlistTypeID) *outPlistTypeID = _kCFRuntimeIDCFNull; return true; case kCFBinaryPlistMarkerFalse: - *plist = CFRetain(kCFBooleanFalse); + if (outPlist) *outPlist = kCFBooleanFalse; + if (outPlistTypeID) *outPlistTypeID = _kCFRuntimeIDCFBoolean; return true; case kCFBinaryPlistMarkerTrue: - *plist = CFRetain(kCFBooleanTrue); + if (outPlist) *outPlist = kCFBooleanTrue; + if (outPlistTypeID) *outPlistTypeID = _kCFRuntimeIDCFBoolean; return true; } FAIL_FALSE; @@ -1221,19 +1216,27 @@ CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, ui // negative 1, 2, 4-byte integers are always emitted as 8 bytes in format '00' // integers are not required to be in the most compact possible representation, but only the last 64 bits are significant currently uint64_t bigint = _getSizedInt(ptr, cnt); - if (8 < cnt) { - CFSInt128Struct val; - val.high = 0; - val.low = bigint; - *plist = CFNumberCreate(allocator, kCFNumberSInt128Type, &val); - } else { - *plist = CFNumberCreate(allocator, kCFNumberSInt64Type, &bigint); - } - // these are always immutable - if (objects && *plist) { - CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist); - } - return (*plist) ? true : false; + if (outPlistTypeID) *outPlistTypeID = _kCFRuntimeIDCFNumber; + if (outPlist) { + CFNumberRef number = NULL; + if (8 < cnt) { + CFSInt128Struct val; + val.high = 0; + val.low = bigint; + number = CFNumberCreate(allocator, kCFNumberSInt128Type, &val); + } else { + number = CFNumberCreate(allocator, kCFNumberSInt64Type, &bigint); + } + // these are always immutable + if (objects && number) { + CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, number); + } + *outPlist = number; + return number ? true : false; + } else { + // Assume CFNumber creation would always succeed. + return true; + } } case kCFBinaryPlistMarkerReal: switch (marker & 0x0f) { @@ -1248,12 +1251,19 @@ CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, ui CFSwappedFloat32 swapped32; memmove(&swapped32, ptr, 4); float f = CFConvertFloat32SwappedToHost(swapped32); - *plist = CFNumberCreate(allocator, kCFNumberFloat32Type, &f); - // these are always immutable - if (objects && *plist) { - CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist); - } - return (*plist) ? true : false; + if (outPlistTypeID) *outPlistTypeID = _kCFRuntimeIDCFNumber; + if (outPlist) { + CFNumberRef number = CFNumberCreate(allocator, kCFNumberFloat32Type, &f); + // these are always immutable + if (objects && number) { + CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, number); + } + *outPlist = number; + return number ? true : false; + } else { + // Assume CFNumber creation would always succeed. + return true; + } } case 3: { const uint8_t *ptr = (databytes + startOffset); @@ -1266,12 +1276,19 @@ CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, ui CFSwappedFloat64 swapped64; memmove(&swapped64, ptr, 8); double d = CFConvertFloat64SwappedToHost(swapped64); - *plist = CFNumberCreate(allocator, kCFNumberFloat64Type, &d); - // these are always immutable - if (objects && *plist) { - CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist); - } - return (*plist) ? true : false; + if (outPlistTypeID) *outPlistTypeID = _kCFRuntimeIDCFNumber; + if (outPlist) { + CFNumberRef number = CFNumberCreate(allocator, kCFNumberFloat64Type, &d); + // these are always immutable + if (objects && number) { + CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, number); + } + *outPlist = number; + return number ? true : false; + } else { + // Assume CFNumber creation would always succeed. + return true; + } } } FAIL_FALSE; @@ -1288,12 +1305,19 @@ CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, ui CFSwappedFloat64 swapped64; memmove(&swapped64, ptr, 8); double d = CFConvertFloat64SwappedToHost(swapped64); - *plist = CFDateCreate(allocator, d); - // these are always immutable - if (objects && *plist) { - CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist); - } - return (*plist) ? true : false; + if (outPlistTypeID) *outPlistTypeID = _kCFRuntimeIDCFDate; + if (outPlist) { + CFDateRef date = CFDateCreate(allocator, d); + // these are always immutable + if (objects && date) { + CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, date); + } + *outPlist = date; + return date ? true : false; + } else { + // Assume CFDate creation would always succeed. + return true; + } } } FAIL_FALSE; @@ -1312,16 +1336,24 @@ CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, ui const uint8_t *extent = check_ptr_add(ptr, cnt, &err) - 1; if (CF_NO_ERROR != err) FAIL_FALSE; if (databytes + objectsRangeEnd < extent) FAIL_FALSE; - if (mutabilityOption == kCFPropertyListMutableContainersAndLeaves) { - *plist = CFDataCreateMutable(allocator, 0); - if (*plist) CFDataAppendBytes((CFMutableDataRef)*plist, ptr, cnt); - } else { - *plist = CFDataCreate(allocator, ptr, cnt); - } - if (objects && *plist && (mutabilityOption != kCFPropertyListMutableContainersAndLeaves)) { - CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist); - } - return (*plist) ? true : false; + if (outPlistTypeID) *outPlistTypeID = _kCFRuntimeIDCFData; + if (outPlist) { + CFDataRef data = NULL; + if (mutabilityOption == kCFPropertyListMutableContainersAndLeaves) { + data = CFDataCreateMutable(allocator, 0); + if (data) CFDataAppendBytes((CFMutableDataRef)data, ptr, cnt); + } else { + data = CFDataCreate(allocator, ptr, cnt); + } + if (objects && data && (mutabilityOption != kCFPropertyListMutableContainersAndLeaves)) { + CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, data); + } + *outPlist = data; + return data ? true : false; + } else { + // Assume CFData creation would always succeed + return true; + } } case kCFBinaryPlistMarkerASCIIString: { const uint8_t *ptr = databytes + startOffset; @@ -1338,17 +1370,25 @@ CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, ui const uint8_t *extent = check_ptr_add(ptr, cnt, &err) - 1; if (CF_NO_ERROR != err) FAIL_FALSE; if (databytes + objectsRangeEnd < extent) FAIL_FALSE; - if (mutabilityOption == kCFPropertyListMutableContainersAndLeaves) { - CFStringRef str = CFStringCreateWithBytes(allocator, ptr, cnt, kCFStringEncodingASCII, false); - *plist = str ? CFStringCreateMutableCopy(allocator, 0, str) : NULL; - if (str) CFRelease(str); - } else { - *plist = CFStringCreateWithBytes(allocator, ptr, cnt, kCFStringEncodingASCII, false); - } - if (objects && *plist && (mutabilityOption != kCFPropertyListMutableContainersAndLeaves)) { - CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist); - } - return (*plist) ? true : false; + if (outPlistTypeID) *outPlistTypeID = _kCFRuntimeIDCFString; + if (outPlist) { + CFStringRef string = CFStringCreateWithBytes(allocator, ptr, cnt, kCFStringEncodingASCII, false); + if (mutabilityOption == kCFPropertyListMutableContainersAndLeaves) { + if (string) { + CFStringRef tmp = string; + string = CFStringCreateMutableCopy(allocator, 0, string); + CFRelease(tmp); + } + } + if (objects && string && (mutabilityOption != kCFPropertyListMutableContainersAndLeaves)) { + CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, string); + } + *outPlist = string; + return string ? true : false; + } else { + // Assume CFString creation with kCFStringEncodingASCII would always succeed. + return true; + } } case kCFBinaryPlistMarkerUnicode16String: { const uint8_t *ptr = databytes + startOffset; @@ -1368,24 +1408,32 @@ CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, ui if (databytes + objectsRangeEnd < extent) FAIL_FALSE; size_t byte_cnt = check_size_t_mul(cnt, sizeof(UniChar), &err); if (CF_NO_ERROR != err) FAIL_FALSE; - UniChar *chars = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, byte_cnt, 0); - if (!chars) FAIL_FALSE; - memmove(chars, ptr, byte_cnt); - for (CFIndex idx = 0; idx < cnt; idx++) { - chars[idx] = CFSwapInt16BigToHost(chars[idx]); - } - if (mutabilityOption == kCFPropertyListMutableContainersAndLeaves) { - CFStringRef str = CFStringCreateWithCharacters(allocator, chars, cnt); - *plist = str ? CFStringCreateMutableCopy(allocator, 0, str) : NULL; - if (str) CFRelease(str); - } else { - *plist = CFStringCreateWithCharacters(allocator, chars, cnt); - } - CFAllocatorDeallocate(kCFAllocatorSystemDefault, chars); - if (objects && *plist && (mutabilityOption != kCFPropertyListMutableContainersAndLeaves)) { - CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist); - } - return (*plist) ? true : false; + if (outPlistTypeID) *outPlistTypeID = _kCFRuntimeIDCFString; + if (outPlist) { + UniChar *chars = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, byte_cnt, 0); + if (!chars) FAIL_FALSE; + memmove(chars, ptr, byte_cnt); + for (CFIndex idx = 0; idx < cnt; idx++) { + chars[idx] = CFSwapInt16BigToHost(chars[idx]); + } + CFStringRef string = CFStringCreateWithCharacters(allocator, chars, cnt); + if (mutabilityOption == kCFPropertyListMutableContainersAndLeaves) { + if (string) { + CFStringRef tmp = string; + string = CFStringCreateMutableCopy(allocator, 0, string); + CFRelease(tmp); + } + } + CFAllocatorDeallocate(kCFAllocatorSystemDefault, chars); + if (objects && string && (mutabilityOption != kCFPropertyListMutableContainersAndLeaves)) { + CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, string); + } + *outPlist = string; + return string ? true : false; + } else { + // Assume CFStringCreateWithCharacters would always succeed. + return true; + } } case kCFBinaryPlistMarkerUID: { const uint8_t *ptr = databytes + startOffset; @@ -1399,12 +1447,19 @@ CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, ui // uids are not required to be in the most compact possible representation, but only the last 64 bits are significant currently uint64_t bigint = _getSizedInt(ptr, cnt); if (UINT32_MAX < bigint) FAIL_FALSE; - *plist = _CFKeyedArchiverUIDCreate(allocator, (uint32_t)bigint); - // these are always immutable - if (objects && *plist) { - CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist); - } - return (*plist) ? true : false; + if (outPlistTypeID) *outPlistTypeID = _kCFRuntimeIDCFKeyedArchiverUID; + if (outPlist) { + CFKeyedArchiverUIDRef uid = _CFKeyedArchiverUIDCreate(allocator, (uint32_t)bigint); + // these are always immutable + if (objects && uid) { + CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, uid); + } + *outPlist = uid; + return (uid) ? true : false; + } else { + // Assume CFKeyedArchiverUID creation would always succeed. + return true; + } } case kCFBinaryPlistMarkerArray: case kCFBinaryPlistMarkerSet: { @@ -1426,27 +1481,31 @@ CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, ui if (databytes + objectsRangeEnd < extent) FAIL_FALSE; byte_cnt = check_size_t_mul(arrayCount, sizeof(CFPropertyListRef), &err); if (CF_NO_ERROR != err) FAIL_FALSE; - STACK_BUFFER_DECL(CFPropertyListRef, buffer, (arrayCount > 0 && arrayCount <= 256) ? arrayCount : 1); - list = (arrayCount <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, byte_cnt, 0); - if (!list) FAIL_FALSE; - Boolean madeSet = false; + STACK_BUFFER_DECL(CFPropertyListRef, buffer, arrayCount <= 256 ? arrayCount : 1); + if (outPlist) { + list = (arrayCount <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, byte_cnt, 0); + if (!list) FAIL_FALSE; + } + _CFReleaseDeferred CFMutableSetRef madeSet = NULL; if (!set && 15 < curDepth) { - set = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, NULL); - madeSet = set ? true : false; + madeSet = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, NULL); + set = madeSet; } + Boolean success = true; + CFTypeID typeID = _kCFRuntimeNotATypeID; if (set) CFSetAddValue(set, (const void *)(uintptr_t)startOffset); if ((marker & 0xf0) == kCFBinaryPlistMarkerArray && keyPaths) { // Only get a subset of this array CFSetRef theseKeys, nextKeys; __CFPropertyListCreateSplitKeypaths(kCFAllocatorSystemDefault, keyPaths, &theseKeys, &nextKeys); - - Boolean success = true; + CFMutableArrayRef array = CFArrayCreateMutable(allocator, CFSetGetCount(theseKeys), &kCFTypeArrayCallBacks); if (theseKeys) { CFTypeRef *keys = (CFTypeRef *)malloc(CFSetGetCount(theseKeys) * sizeof(CFTypeRef)); CFSetGetValues(theseKeys, keys); - for (CFIndex i = 0; i < CFSetGetCount(theseKeys); i++) { + CFIndex theseKeysCount = CFSetGetCount(theseKeys); + for (CFIndex i = 0; i < theseKeysCount; i++) { CFStringRef key = (CFStringRef)keys[i]; SInt32 intValue = CFStringGetIntValue(key); if ((intValue == 0 && CFStringCompare(CFSTR("0"), key, 0) != kCFCompareEqualTo) || intValue == INT_MAX || intValue == INT_MIN || intValue < 0) { @@ -1455,11 +1514,13 @@ CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, ui uint64_t valueOffset; Boolean found = __CFBinaryPlistGetOffsetForValueFromArray2(databytes, datalen, startOffset, trailer, (CFIndex)intValue, &valueOffset, objects); if (found) { - CFPropertyListRef result; - success = __CFBinaryPlistCreateObjectFiltered(databytes, datalen, valueOffset, trailer, allocator, mutabilityOption, objects, set, curDepth + 1, nextKeys, &result); + CFPropertyListRef result = NULL; + success = __CFBinaryPlistCreateObjectFiltered(databytes, datalen, valueOffset, trailer, allocator, mutabilityOption, objects, set, curDepth + 1, nextKeys, outPlist ? &result : NULL, NULL); if (success) { - CFArrayAppendValue(array, result); - CFRelease(result); + if (result) { + CFArrayAppendValue(array, result); + CFRelease(result); + } } else { break; } @@ -1472,73 +1533,82 @@ CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, ui } if (nextKeys) CFRelease(nextKeys); - if (success) { + if (success && outPlist) { if (!(mutabilityOption == kCFPropertyListMutableContainers || mutabilityOption == kCFPropertyListMutableContainersAndLeaves)) { // make immutable - *plist = CFArrayCreateCopy(allocator, array); + *outPlist = CFArrayCreateCopy(allocator, array); CFRelease(array); } else { - *plist = array; + *outPlist = array; } } else if (array) { CFRelease(array); } + typeID = _kCFRuntimeIDCFArray; } else { - for (CFIndex idx = 0; idx < arrayCount; idx++) { - CFPropertyListRef pl; + for (CFIndex idx = 0; idx < arrayCount; idx++) { if (!_getOffsetOfRefAt(databytes, ptr, trailer, &off)) { - while (idx--) { - CFRelease(list[idx]); + if (list) { + while (idx--) { + CFRelease(list[idx]); + } + if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list); } - if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list); - if (madeSet) { CFRelease(set); } FAIL_FALSE; } - if (!__CFBinaryPlistCreateObjectFiltered(databytes, datalen, off, trailer, allocator, mutabilityOption, objects, set, curDepth + 1, NULL, &pl)) { - while (idx--) { - CFRelease(list[idx]); - } - if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list); - if (madeSet) { CFRelease(set); } + CFPropertyListRef pl = NULL; + if (!__CFBinaryPlistCreateObjectFiltered(databytes, datalen, off, trailer, allocator, mutabilityOption, objects, set, curDepth + 1, NULL, outPlist ? &pl : NULL, NULL)) { + if (list) { + while (idx--) { + CFRelease(list[idx]); + } + if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list); + } FAIL_FALSE; } - *((void **)list + idx) = (void *)pl; + if (list) { + *((void **)list + idx) = (void *)pl; + } ptr += trailer->_objectRefSize; - } + } + success = true; if ((marker & 0xf0) == kCFBinaryPlistMarkerArray) { - if (mutabilityOption != kCFPropertyListImmutable) { - *plist = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); - CFArrayReplaceValues((CFMutableArrayRef)*plist, CFRangeMake(0, 0), list, arrayCount); - for (CFIndex idx = 0; idx < arrayCount; idx++) { - CFRelease(list[idx]); + if (outPlist) { + if (mutabilityOption != kCFPropertyListImmutable) { + *outPlist = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); + CFArrayReplaceValues((CFMutableArrayRef)*outPlist, CFRangeMake(0, 0), list, arrayCount); + for (CFIndex idx = 0; idx < arrayCount; idx++) { + CFRelease(list[idx]); + } + } else { + *outPlist = __CFArrayCreateTransfer(allocator, list, arrayCount); } - } else { - *plist = __CFArrayCreateTransfer(allocator, list, arrayCount); } + typeID = _kCFRuntimeIDCFArray; } else { - if (mutabilityOption != kCFPropertyListImmutable) { - *plist = CFSetCreateMutable(allocator, 0, &kCFTypeSetCallBacks); - for (CFIndex idx = 0; idx < arrayCount; idx++) { - CFSetAddValue((CFMutableSetRef)*plist, list[idx]); - } - for (CFIndex idx = 0; idx < arrayCount; idx++) { - CFRelease(list[idx]); + if (outPlist) { + if (mutabilityOption != kCFPropertyListImmutable) { + *outPlist = CFSetCreateMutable(allocator, 0, &kCFTypeSetCallBacks); + for (CFIndex idx = 0; idx < arrayCount; idx++) { + CFSetAddValue((CFMutableSetRef)*outPlist, list[idx]); + } + for (CFIndex idx = 0; idx < arrayCount; idx++) { + CFRelease(list[idx]); + } + } else { + *outPlist = __CFSetCreateTransfer(allocator, list, arrayCount); } - } else { - *plist = __CFSetCreateTransfer(allocator, list, arrayCount); } + typeID = _kCFRuntimeIDCFSet; } } + if (outPlistTypeID) *outPlistTypeID = typeID; if (set) CFSetRemoveValue(set, (const void *)(uintptr_t)startOffset); - if (madeSet) { - CFRelease(set); - set = NULL; - } - if (objects && *plist && (mutabilityOption == kCFPropertyListImmutable)) { - CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist); + if (objects && success && outPlist && (mutabilityOption == kCFPropertyListImmutable)) { + CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *outPlist); } - if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list); - return (*plist) ? true : false; + if (list && list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list); + return success; } case kCFBinaryPlistMarkerDict: { const uint8_t *ptr = databytes + startOffset; @@ -1562,21 +1632,23 @@ CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, ui byte_cnt = check_size_t_mul(dictionaryCount, sizeof(CFPropertyListRef), &err); if (CF_NO_ERROR != err) FAIL_FALSE; STACK_BUFFER_DECL(CFPropertyListRef, buffer, 0 < dictionaryCount && dictionaryCount <= 256 ? dictionaryCount : 1); - list = (dictionaryCount <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, byte_cnt, 0); - if (!list) FAIL_FALSE; - Boolean madeSet = false; + if (outPlist) { + list = (dictionaryCount <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, byte_cnt, 0); + if (!list) FAIL_FALSE; + } + _CFReleaseDeferred CFMutableSetRef madeSet = NULL; if (!set && 15 < curDepth) { - set = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, NULL); - madeSet = set ? true : false; + madeSet = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, NULL); + set = madeSet; } + Boolean success = true; if (set) CFSetAddValue(set, (const void *)(uintptr_t)startOffset); if (keyPaths) { // Only get a subset of this dictionary CFSetRef theseKeys, nextKeys; __CFPropertyListCreateSplitKeypaths(kCFAllocatorSystemDefault, keyPaths, &theseKeys, &nextKeys); - Boolean success = true; CFMutableDictionaryRef dict = CFDictionaryCreateMutable(allocator, CFSetGetCount(theseKeys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (theseKeys) { CFTypeRef *keys = (CFTypeRef *)malloc(CFSetGetCount(theseKeys) * sizeof(CFTypeRef)); @@ -1586,11 +1658,13 @@ CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, ui uint64_t keyOffset, valueOffset; Boolean found = __CFBinaryPlistGetOffsetForValueFromDictionary3(databytes, datalen, startOffset, trailer, key, &keyOffset, &valueOffset, false, objects); if (found) { - CFPropertyListRef result; - success = __CFBinaryPlistCreateObjectFiltered(databytes, datalen, valueOffset, trailer, allocator, mutabilityOption, objects, set, curDepth + 1, nextKeys, &result); + CFPropertyListRef result = NULL; + success = __CFBinaryPlistCreateObjectFiltered(databytes, datalen, valueOffset, trailer, allocator, mutabilityOption, objects, set, curDepth + 1, nextKeys, outPlist ? &result : NULL, NULL); if (success) { - CFDictionarySetValue(dict, key, result); - CFRelease(result); + if (result) { + CFDictionarySetValue(dict, key, result); + CFRelease(result); + } } else { break; } @@ -1602,63 +1676,68 @@ CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, ui } if (nextKeys) CFRelease(nextKeys); - if (success) { + if (success && outPlist) { if (!(mutabilityOption == kCFPropertyListMutableContainers || mutabilityOption == kCFPropertyListMutableContainersAndLeaves)) { // make immutable - *plist = CFDictionaryCreateCopy(allocator, dict); + *outPlist = CFDictionaryCreateCopy(allocator, dict); CFRelease(dict); } else { - *plist = dict; + *outPlist = dict; } } else if (dict) { CFRelease(dict); } } else { + CFIndex const halfDictionaryCount = dictionaryCount / 2; for (CFIndex idx = 0; idx < dictionaryCount; idx++) { - CFPropertyListRef pl = NULL; if (!_getOffsetOfRefAt(databytes, ptr, trailer, &off)) { - if (pl) CFRelease(pl); - while (idx--) { - CFRelease(list[idx]); + if (list) { + while (idx--) { + CFRelease(list[idx]); + } + if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list); } - if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list); - if (madeSet) { CFRelease(set); } FAIL_FALSE; } - if (!__CFBinaryPlistCreateObjectFiltered(databytes, datalen, off, trailer, allocator, mutabilityOption, objects, set, curDepth + 1, NULL, &pl) || (idx < dictionaryCount / 2 && !_plistIsPrimitive(pl))) { + CFPropertyListRef pl = NULL; + CFTypeID typeID = _kCFRuntimeNotATypeID; + if (!__CFBinaryPlistCreateObjectFiltered(databytes, datalen, off, trailer, allocator, mutabilityOption, objects, set, curDepth + 1, NULL, (outPlist ? &pl : NULL), &typeID) || (idx < halfDictionaryCount && !_typeIsPlistPrimitive(typeID))) { if (pl) CFRelease(pl); - while (idx--) { - CFRelease(list[idx]); + if (list) { + while (idx--) { + CFRelease(list[idx]); + } + if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list); } - if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list); - if (madeSet) { CFRelease(set); } FAIL_FALSE; } - *((void **)list + idx) = (void *)pl; - ptr += trailer->_objectRefSize; - } - if (mutabilityOption != kCFPropertyListImmutable) { - *plist = CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - for (CFIndex idx = 0; idx < dictionaryCount / 2; idx++) { - CFDictionaryAddValue((CFMutableDictionaryRef)*plist, list[idx], list[idx + dictionaryCount / 2]); + if (list) { + *((void **)list + idx) = (void *)pl; } - for (CFIndex idx = 0; idx < dictionaryCount; idx++) { - CFRelease(list[idx]); + ptr += trailer->_objectRefSize; + } + if (outPlist) { + if (mutabilityOption != kCFPropertyListImmutable) { + CFMutableDictionaryRef dict = CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + for (CFIndex idx = 0; idx < halfDictionaryCount; idx++) { + CFDictionaryAddValue((CFMutableDictionaryRef)dict, list[idx], list[idx + halfDictionaryCount]); + } + for (CFIndex idx = 0; idx < dictionaryCount; idx++) { + CFRelease(list[idx]); + } + *outPlist = dict; + } else { + *outPlist = __CFDictionaryCreateTransfer(allocator, list, list + halfDictionaryCount, halfDictionaryCount); } - } else { - *plist = __CFDictionaryCreateTransfer(allocator, list, list + dictionaryCount / 2, dictionaryCount / 2); } + if (outPlistTypeID) *outPlistTypeID = _kCFRuntimeIDCFDictionary; } if (set) CFSetRemoveValue(set, (const void *)(uintptr_t)startOffset); - if (madeSet) { - CFRelease(set); - set = NULL; - } - if (objects && *plist && (mutabilityOption == kCFPropertyListImmutable)) { - CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist); + if (objects && success && outPlist && (mutabilityOption == kCFPropertyListImmutable)) { + CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *outPlist); } - if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list); - return (*plist) ? true : false; + if (list && list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list); + return success; } } FAIL_FALSE; @@ -1666,7 +1745,7 @@ CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, ui bool __CFBinaryPlistCreateObject(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFPropertyListRef *plist) { // for compatibility with Foundation's use, need to leave this here - return __CFBinaryPlistCreateObjectFiltered(databytes, datalen, startOffset, trailer, allocator, mutabilityOption, objects, NULL, 0, NULL, plist); + return __CFBinaryPlistCreateObjectFiltered(databytes, datalen, startOffset, trailer, allocator, mutabilityOption, objects, NULL, 0, NULL, plist, NULL); } CF_PRIVATE bool __CFTryParseBinaryPlist(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFPropertyListRef *plist, CFStringRef *errorString) { @@ -1687,7 +1766,7 @@ CF_PRIVATE bool __CFTryParseBinaryPlist(CFAllocatorRef allocator, CFDataRef data _CFDictionarySetCapacity(objects, trailer._numObjects); CFPropertyListRef pl = NULL; bool result = true; - if (__CFBinaryPlistCreateObjectFiltered(databytes, datalen, offset, &trailer, allocator, option, objects, NULL, 0, NULL, &pl)) { + if (__CFBinaryPlistCreateObjectFiltered(databytes, datalen, offset, &trailer, allocator, option, objects, NULL, 0, NULL, &pl, NULL)) { if (plist) *plist = pl; #if 0 // code to check the 1.5 version code against any binary plist successfully parsed above diff --git a/CoreFoundation/Parsing.subproj/CFOldStylePList.c b/CoreFoundation/Parsing.subproj/CFOldStylePList.c index 59a34bd657..fc33350303 100644 --- a/CoreFoundation/Parsing.subproj/CFOldStylePList.c +++ b/CoreFoundation/Parsing.subproj/CFOldStylePList.c @@ -1,7 +1,7 @@ /* CFOldStylePList.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -37,11 +37,18 @@ typedef struct { CFMutableSetRef stringSet; // set of all strings involved in this parse; allows us to share non-mutable strings in the returned plist } _CFStringsFileParseInfo; -static void parseInfo_setError(_CFStringsFileParseInfo *const pInfo, CFErrorRef const error) { +static void parseInfo_setError(_CFStringsFileParseInfo *const pInfo, CFErrorRef _Nonnull const CF_RELEASES_ARGUMENT error) { CFErrorRef oldError = pInfo->error; - if (oldError != error) { - pInfo->error = error; - if (oldError) { CFRelease(oldError); } + if (oldError) { + CFRelease(oldError); + } + pInfo->error = error; +} + +static void parseInfo_clearError(_CFStringsFileParseInfo *const pInfo) { + if (pInfo->error) { + CFRelease(pInfo->error); + pInfo->error = NULL; } } @@ -129,30 +136,25 @@ static UniChar getSlashedChar(_CFStringsFileParseInfo *pInfo) { uint8_t num = ch - '0'; UniChar result; CFIndex usedCharLen; - if (pInfo->curr < pInfo->end) { - /* three digits maximum to avoid reading \000 followed by 5 as \5 ! */ - if ((ch = *(pInfo->curr)) >= '0' && ch <= '7') { // we use in this test the fact that the buffer is zero-terminated - pInfo->curr ++; + + /* three digits maximum to avoid reading \000 followed by 5 as \5 ! */ + // We've already read the first character here, so repeat at most two more times. + for (uint8_t i = 0; i < 2; i += 1) { + // Hitting the end of the plist is not a meaningful error here. + // We parse the characters we have and allow the parent context (parseQuotedPlistString, the only current call site of getSlashedChar) to produce a more meaningful error message (e.g. it will at least expect a close quote after this character). + if (pInfo->curr >= pInfo->end) { + break; + } + + if ((ch = *(pInfo->curr)) >= '0' && ch <= '7') { num = (num << 3) + ch - '0'; - if (pInfo->curr < pInfo->end) { - if ((ch = *(pInfo->curr)) >= '0' && ch <= '7') { - pInfo->curr ++; - num = (num << 3) + ch - '0'; - } else { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Invalid octal while parsing plist"))); - return 0; - } - } else { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected EOF while parsing plist"))); - return 0; - } + pInfo->curr ++; } else { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Invalid octal while parsing plist"))); - return 0; + // Non-octal characters are not explicitly an error either: "\05" is a valid character which evaluates to 005. (We read a '0', a '5', and then a '"'; we can't bail on seeing '"' though.) + // Is this an ambiguous format? Probably. But it has to remain this way for backwards compatibility. + // See + break; } - } else { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected EOF while parsing plist"))); - return 0; } const uint32_t conversionResult = CFStringEncodingBytesToUnicode(kCFStringEncodingNextStepLatin, 0, &num, sizeof(uint8_t), NULL, &result, 1, &usedCharLen); @@ -312,7 +314,7 @@ static CFStringRef parseQuotedPlistString(_CFStringsFileParseInfo *pInfo, UniCha pInfo->curr ++; // Advance past the quote character before returning. // this is a success path, so clear errors (NOTE: this seems weird, but is historical) - parseInfo_setError(pInfo, NULL); + parseInfo_clearError(pInfo); return str; } @@ -414,7 +416,7 @@ static CFTypeRef parsePlistArray(_CFStringsFileParseInfo *pInfo, uint32_t depth) } // this is a success path, so clear errors (NOTE: this seems weird, but is historical) - parseInfo_setError(pInfo, NULL); + parseInfo_clearError(pInfo); pInfo->curr ++; // consume the ) return array; @@ -489,7 +491,7 @@ static CFDictionaryRef parsePlistDictContent(_CFStringsFileParseInfo *pInfo, con } // this is a success path, so clear errors (NOTE: this seems weird, but is historical) - parseInfo_setError(pInfo, NULL); + parseInfo_clearError(pInfo); return dict; } @@ -570,7 +572,7 @@ static CFTypeRef parsePlistData(_CFStringsFileParseInfo *pInfo) CF_RETURNS_RETAI } // this is a success path, so clear errors (NOTE: this seems weird, but is historical) - parseInfo_setError(pInfo, NULL); + parseInfo_clearError(pInfo); if (pInfo->curr < pInfo->end && *(pInfo->curr) == '>') { pInfo->curr ++; // Move past '>' @@ -642,6 +644,7 @@ CF_PRIVATE CFTypeRef __CFCreateOldStylePropertyListOrStringsFile(CFAllocatorRef const CFIndex length = CFStringGetLength(plistString); if (!length) { if (outError) *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Conversion of string failed. The string is empty.")); + CFRelease(plistString); return NULL; } @@ -650,6 +653,7 @@ CF_PRIVATE CFTypeRef __CFCreateOldStylePropertyListOrStringsFile(CFAllocatorRef buf = (UniChar *)CFAllocatorAllocate(allocator, length * sizeof(UniChar), 0); if (!buf) { CRSetCrashLogMessage("CFPropertyList ran out of memory while attempting to allocate temporary storage."); + CFRelease(plistString); return NULL; } CFStringGetCharacters(plistString, CFRangeMake(0, length), buf); diff --git a/CoreFoundation/Parsing.subproj/CFPropertyList.c b/CoreFoundation/Parsing.subproj/CFPropertyList.c index d92ab5a86a..d268bd5434 100644 --- a/CoreFoundation/Parsing.subproj/CFPropertyList.c +++ b/CoreFoundation/Parsing.subproj/CFPropertyList.c @@ -1,11 +1,11 @@ /* CFPropertyList.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Tony Parker + Responsibility: Itai Ferber */ #include @@ -18,6 +18,7 @@ #include #include #include +#include #include "CFInternal.h" #include "CFRuntime_Internal.h" #include @@ -35,8 +36,6 @@ #include "CFOverflow.h" -CF_EXPORT CFNumberType _CFNumberGetType2(CFNumberRef number); - #define PLIST_IX 0 #define ARRAY_IX 1 #define DICT_IX 2 @@ -1293,7 +1292,7 @@ static Boolean parsePListTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) { static int allowImmutableCollections = -1; static void checkImmutableCollections(void) { - allowImmutableCollections = (NULL == __CFgetenv("CFPropertyListAllowImmutableCollections")) ? 0 : 1; + allowImmutableCollections = (NULL == getenv("CFPropertyListAllowImmutableCollections")) ? 0 : 1; } // This converts the input value, a set of strings, into the form that's efficient for using during recursive decent parsing, a set of arrays @@ -1349,6 +1348,7 @@ CF_PRIVATE void __CFPropertyListCreateSplitKeypaths(CFAllocatorRef allocator, CF } } + free_cftype_array(currentKeyPaths); *theseKeys = outTheseKeys; *nextKeys = outNextKeys; @@ -1834,15 +1834,6 @@ static Boolean parseRealTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) { } \ ch = *(pInfo->curr) -typedef struct { - int64_t high; - uint64_t low; -} CFSInt128Struct; - -enum { - kCFNumberSInt128Type = 17 -}; - CF_INLINE bool isWhitespace(const char *utf8bytes, const char *end) { // Converted UTF-16 isWhitespace from CFString to UTF8 bytes to get full list of UTF8 whitespace /* @@ -2323,15 +2314,15 @@ static CFStringEncoding encodingForXMLData(CFDataRef data, CFErrorRef *error, CF #if TARGET_OS_MAC || TARGET_OS_WIN32 || TARGET_OS_LINUX CFStringEncoding enc = CFStringConvertIANACharSetNameToEncoding(encodingName); if (enc != kCFStringEncodingInvalidId) { - CFRelease(encodingName); + if (encodingName) {CFRelease(encodingName); } return enc; } #endif - if (error) { *error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unknown encoding (%@)"), encodingName); - CFRelease(encodingName); } + if (encodingName) { CFRelease(encodingName); } + return 0; } } @@ -2639,7 +2630,7 @@ CFTypeRef _CFPropertyListCreateFromXMLString(CFAllocatorRef allocator, CFStringR return result; } -CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFSetRef keyPaths, CFPropertyListRef *plist); +CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFSetRef keyPaths, CFPropertyListRef *plist, CFTypeID *outPlistTypeID); // Returns a subset of the property list, only including the key paths in the CFSet. Boolean _CFPropertyListCreateFiltered(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFSetRef keyPaths, CFPropertyListRef *value, CFErrorRef *error) { @@ -2665,7 +2656,7 @@ Boolean _CFPropertyListCreateFiltered(CFAllocatorRef allocator, CFDataRef data, // Create a dictionary to cache objects in CFMutableDictionaryRef objects = CFDictionaryCreateMutable(allocator, 0, NULL, &kCFTypeDictionaryValueCallBacks); - success = __CFBinaryPlistCreateObjectFiltered(databytes, datalen, valueOffset, &trailer, allocator, option, objects, NULL, 0, splitKeyPaths, &out); + success = __CFBinaryPlistCreateObjectFiltered(databytes, datalen, valueOffset, &trailer, allocator, option, objects, NULL, 0, splitKeyPaths, &out, NULL); CFRelease(splitKeyPaths); CFRelease(objects); @@ -2745,7 +2736,7 @@ Boolean _CFPropertyListCreateSingleValue(CFAllocatorRef allocator, CFDataRef dat // value could be null if the caller wanted to check for the existence of a key but not bother creating it if (success && value) { CFPropertyListRef pl; - success = __CFBinaryPlistCreateObjectFiltered(databytes, datalen, valueOffset, &trailer, allocator, option, objects, NULL, 0, NULL, &pl); + success = __CFBinaryPlistCreateObjectFiltered(databytes, datalen, valueOffset, &trailer, allocator, option, objects, NULL, 0, NULL, &pl, NULL); if (success) { // caller's responsibility to release the created object *value = pl; @@ -3116,6 +3107,35 @@ CFPropertyListRef CFPropertyListCreateFromStream(CFAllocatorRef allocator, CFRea return result; } +bool _CFPropertyListValidateData(CFDataRef data, CFTypeID *outTopLevelTypeID) { + uint8_t marker; + CFBinaryPlistTrailer trailer; + uint64_t offset; + const uint8_t *databytes = CFDataGetBytePtr(data); + uint64_t datalen = CFDataGetLength(data); + + bool result = true; + if (8 <= datalen && __CFBinaryPlistGetTopLevelInfo(databytes, datalen, &marker, &offset, &trailer)) { + // Object-less plist parsing does not use an objects dictionary. + CFTypeID typeID = _kCFRuntimeNotATypeID; + if (!__CFBinaryPlistCreateObjectFiltered(databytes, datalen, offset, &trailer, kCFAllocatorSystemDefault, 0, NULL, NULL, 0, NULL, NULL, &typeID)) { + result = false; + } + if (outTopLevelTypeID) *outTopLevelTypeID = typeID; + } else { + // Try an XML property list + // Note: This is currently not any more efficient than grabbing the whole thing. This could be improved in the future. + CFPropertyListRef plist = CFPropertyListCreateWithData(kCFAllocatorSystemDefault, data, kCFPropertyListMutableContainers, NULL, NULL); + if (plist) { + if (outTopLevelTypeID) *outTopLevelTypeID = CFGetTypeID(plist); + CFRelease(plist); + } else { + result = false; + } + } + return result; +} + #pragma mark - #pragma mark Property List Copies @@ -3166,7 +3186,7 @@ CFPropertyListRef CFPropertyListCreateDeepCopy(CFAllocatorRef allocator, CFPrope CFAssert1(propertyList != NULL, __kCFLogAssertion, "%s(): cannot copy a NULL property list", __PRETTY_FUNCTION__); __CFAssertIsPList(propertyList); CFAssert2(mutabilityOption == kCFPropertyListImmutable || mutabilityOption == kCFPropertyListMutableContainers || mutabilityOption == kCFPropertyListMutableContainersAndLeaves, __kCFLogAssertion, "%s(): Unrecognized option %lu", __PRETTY_FUNCTION__, mutabilityOption); - if (!CFPropertyListIsValid(propertyList, kCFPropertyListBinaryFormat_v1_0)) return NULL; + if (!CFPropertyListIsValid(propertyList, kCFPropertyListBinaryFormat_v1_0)) return NULL; CFTypeID typeID = CFGetTypeID(propertyList); if (typeID == _kCFRuntimeIDCFDictionary) { diff --git a/CoreFoundation/Parsing.subproj/CFPropertyList.h b/CoreFoundation/Parsing.subproj/CFPropertyList.h index f5483c5018..5907130223 100644 --- a/CoreFoundation/Parsing.subproj/CFPropertyList.h +++ b/CoreFoundation/Parsing.subproj/CFPropertyList.h @@ -1,7 +1,7 @@ /* CFPropertyList.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Parsing.subproj/CFXMLInputStream.c b/CoreFoundation/Parsing.subproj/CFXMLInputStream.c deleted file mode 100644 index ae266ff762..0000000000 --- a/CoreFoundation/Parsing.subproj/CFXMLInputStream.c +++ /dev/null @@ -1,715 +0,0 @@ -/* CFXMLInputStream.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors - - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors - Licensed under Apache License v2.0 with Runtime Library Exception - See http://swift.org/LICENSE.txt for license information - See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: David Smith -*/ - -#include "CFXMLInputStream.h" -#include -#include -#include "CFStringEncodingConverter.h" -#include "CFUniChar.h" - -/* Utility functions used in parsing */ -static Boolean determineEncoding(_CFXMLInputStream *stream) { - const uint8_t *bytes = (uint8_t *)CFDataGetBytePtr(stream->data); - UInt32 length = CFDataGetLength(stream->data); - const uint8_t *idx = 0L, *end = 0L; - const uint8_t *base = 0L; - char quote = ' '; - Boolean useUTF8 = false; - - // Check for the byte order mark first - if (length > 2) { - // This clause checks for the unicode byte order mark, or a Unicode sequence lacking the BOM; technically an error, but this check is recommended by the XML spec - if ((*bytes == 0xFF && *(bytes+1) == 0xFE) ||*(bytes+1) == 0x00) { -#if __BIG_ENDIAN__ - stream->flags |= ENCODING_IS_UNICODE_SWAPPED; -#else - stream->flags |= ENCODING_IS_UNICODE_NATURAL; -#endif - if (*bytes == 0xFF) { - stream->currentByte = bytes + 2; - } - stream->encoding = kCFStringEncodingUnicode; - return true; - } else if ((*bytes == 0xFE && *(bytes+1) == 0xFF) || *bytes == 0x00) { -#if __BIG_ENDIAN__ - stream->flags |= ENCODING_IS_UNICODE_NATURAL; -#else - stream->flags |= ENCODING_IS_UNICODE_SWAPPED; -#endif - if (*bytes == 0xFE) { - stream->currentByte = bytes + 2; - } - stream->encoding = kCFStringEncodingUnicode; - return true; - } else if(*bytes == 0xEF && *(bytes+1) == 0xBB && *(bytes+2) == 0xBF) { - if(*bytes == 0xEF) { - stream->currentByte = bytes + 3; - } - stream->encoding = kCFStringEncodingUTF8; - stream->flags |= ENCODING_MATCHES_ASCII; - return true; - } - } - // Scan for the opening - if (length < 5 || strncmp((char const *) bytes, "') { - useUTF8 = true; - break; - } - idx ++; - scan = idx; - if (ch == 'e' && *scan++ == 'n' && *scan++ == 'c' && *scan++ == 'o' && *scan++ == 'd' && *scan++ == 'i' && *scan++ == 'n' && *scan++ == 'g' && *scan++ == '=') { - idx = scan; - break; - } - } - if (!useUTF8 && idx >= end) { - useUTF8 = true; - } - } - if (!useUTF8) { - // Found "encoding="; see if we've got an honest-to-goodness encoding name - quote = *idx; - if (quote != '\'' && quote != '\"') { - useUTF8 = true; - } - } - if (!useUTF8) { - base = idx + 1; // Move past the quote character - idx ++; - while (idx < end && *idx != quote) idx ++; - if (idx >= end) { - useUTF8 = true; - } - } - if (!useUTF8) { - UInt32 len = idx - base; - if (len == 5 && (*base == 'u' || *base == 'U') && (base[1] == 't' || base[1] == 'T') && (base[2] == 'f' || base[2] == 'F') && (base[3] == '-') && (base[4] == '8')) { - useUTF8 = true; - } else { - CFStringRef encodingName = CFStringCreateWithBytes(stream->allocator, base, len, kCFStringEncodingISOLatin1, false); - stream->encoding = CFStringConvertIANACharSetNameToEncoding(encodingName); - CFRelease(encodingName); - } - } - if (useUTF8) { - stream->encoding = kCFStringEncodingUTF8; - stream->flags |= ENCODING_MATCHES_ASCII; - return true; - } else if (stream->encoding == kCFStringEncodingInvalidId) { - return false; - } else if (__CFStringEncodingIsSupersetOfASCII(stream->encoding)) { - stream->flags |= ENCODING_MATCHES_ASCII; - } - return true; -} - -CF_INLINE void _fillStringWithCharacters(CFMutableStringRef string, UniChar *characters, CFIndex numChars) { - CFStringDelete(string, CFRangeMake(0, CFStringGetLength(string))); - if (numChars) { - CFStringAppendCharacters(string, characters, numChars); - } -} - -CF_PRIVATE Boolean _openInputStream(_CFXMLInputStream *stream) { - if (NULL == stream->data) { - return false; - } else { - stream->currentByte = CFDataGetBytePtr(stream->data); - if (determineEncoding(stream)) { - stream->flags |= STREAM_OPEN; - return true; - } else { - return false; - } - } -} - -CF_PRIVATE void _initializeInputStream(_CFXMLInputStream *stream, CFAllocatorRef alloc, CFURLRef dataSource, CFDataRef xmlData) { - stream->data = xmlData ? (CFDataRef)CFRetain(xmlData) : NULL; - stream->url = dataSource ? (CFURLRef)CFRetain(dataSource) : NULL; - stream->encoding = kCFStringEncodingInvalidId; - stream->currentByte = NULL; - - stream->allocator = (CFAllocatorRef)CFRetain(alloc); - stream->charBuffer = NULL; - stream->currentChar = NULL; - stream->mark = NULL; - stream->parserMark = NULL; - stream->bufferLength = 0; - stream->bufferCapacity = 0; - - stream->charIndex = 1; - stream->lineNum = 1; - - stream->flags = 0; - stream->nameSet = NULL; - stream->tempString = NULL; -} - - -CF_PRIVATE void _freeInputStream(_CFXMLInputStream *stream) { - if (stream->data) CFRelease(stream->data); - if (stream->url) CFRelease(stream->url); - if (stream->charBuffer) CFAllocatorDeallocate(stream->allocator, stream->charBuffer); - if (stream->nameSet) CFRelease(stream->nameSet); - if (stream->tempString) CFRelease(stream->tempString); - CFRelease(stream->allocator); -} - -CF_PRIVATE CFStringEncoding _inputStreamGetEncoding(_CFXMLInputStream *stream) { - return stream->encoding; -} - -CF_PRIVATE CFIndex _inputStreamCurrentLocation(_CFXMLInputStream *stream) { - return stream->charIndex; -} - -CF_PRIVATE CFIndex _inputStreamCurrentLine(_CFXMLInputStream *stream) { - return stream->lineNum; -} - -CF_PRIVATE Boolean _inputStreamAtEOF(_CFXMLInputStream *stream) { - if (!(stream->flags & STREAM_OPEN)) return false; - if (stream->currentChar) return false; - if (stream->currentByte - CFDataGetBytePtr(stream->data) < CFDataGetLength(stream->data)) return false; - return true; -} - -CF_PRIVATE Boolean _inputStreamComposingErrorOccurred(_CFXMLInputStream *stream) { - return stream->flags & ENCODING_COMPOSITION_ERROR; -} - -#define INITIAL_BUFFER_SIZE 64 -static void growCharacterBuffer(_CFXMLInputStream *stream) { - if (!stream->charBuffer) { - stream->charBuffer = (UniChar *)CFAllocatorAllocate(stream->allocator, INITIAL_BUFFER_SIZE*sizeof(UniChar), 0); - stream->bufferCapacity = INITIAL_BUFFER_SIZE; - } else { - CFIndex currCharDelta = stream->currentChar ? stream->currentChar - stream->charBuffer : -1; - CFIndex markDelta = stream->mark ? stream->mark - stream->charBuffer: -1; - CFIndex parserMarkDelta = stream->parserMark ? stream->parserMark - stream->charBuffer: -1; - UniChar *newBuffer = __CFSafelyReallocateWithAllocator(stream->allocator, stream->charBuffer, stream->bufferCapacity * 2 * sizeof(UniChar), 0, NULL); - stream->bufferCapacity *= 2; - if (newBuffer != stream->charBuffer) { - stream->charBuffer = newBuffer; - if (currCharDelta != -1) { - stream->currentChar = newBuffer + currCharDelta; - } - if (markDelta != -1) { - stream->mark = newBuffer + markDelta; - } - if (parserMarkDelta != -1) { - stream->parserMark = newBuffer + parserMarkDelta; - } - } - } -} - -static CFIndex loadCharacters(UniChar *base, CFIndex maxLength, _CFXMLInputStream *stream) { - const uint8_t *dataEnd = CFDataGetBytePtr(stream->data) + CFDataGetLength(stream->data); - if (stream->flags & (ENCODING_IS_UNICODE_NATURAL|ENCODING_IS_UNICODE_SWAPPED) ) { - CFIndex charsToTranslate = (dataEnd - stream->currentByte) / sizeof(UniChar); - if (charsToTranslate > maxLength) { - charsToTranslate = maxLength; - } - if (stream->flags & ENCODING_IS_UNICODE_NATURAL) { - memmove(base, stream->currentByte, charsToTranslate * sizeof(UniChar)); - stream->currentByte += (charsToTranslate * sizeof(UniChar)); - } else { - CFIndex i; - uint8_t *baseBytePtr = (uint8_t *)base; - for (i = 0; i < charsToTranslate; i ++) { - *(baseBytePtr + 1) = *stream->currentByte; - *baseBytePtr = *(stream->currentByte + 1); - baseBytePtr += 2; - stream->currentByte += 2; - } - } - return charsToTranslate; - } else { - CFIndex lengthConsumed = 0; - CFIndex usedByteLength, usedCharLength; - UInt32 conversionResult; - if (stream->flags & ENCODING_MATCHES_ASCII) { - while (stream->currentByte < dataEnd && lengthConsumed < maxLength) { - if (*stream->currentByte > 0x7f) break; - *base = *stream->currentByte; - base ++; - stream->currentByte ++; - lengthConsumed ++; - } - if (stream->currentByte == dataEnd || lengthConsumed == maxLength) { - return lengthConsumed; - } - } - conversionResult = CFStringEncodingBytesToUnicode(stream->encoding, 0, stream->currentByte, dataEnd - stream->currentByte, &usedByteLength, base, maxLength-lengthConsumed, &usedCharLength); - if(kCFStringEncodingConversionSuccess != conversionResult) { - switch(conversionResult) { - case kCFStringEncodingConverterUnavailable: - case kCFStringEncodingInvalidInputStream: - stream->flags |= ENCODING_COMPOSITION_ERROR; - break; - case kCFStringEncodingInsufficientOutputBufferLength: - default: - break; - } - } - if (usedByteLength > 0) { - stream->currentByte += usedByteLength; - lengthConsumed += usedCharLength; - } - return lengthConsumed; - } -} - -// returns number of characters filled -CF_INLINE CFIndex fillToCapacity(_CFXMLInputStream *stream) { - CFIndex numFilled; - if (stream->bufferLength >= stream->bufferCapacity) return 0; - // Try and fill in the remaining characters - numFilled = loadCharacters(stream->charBuffer+stream->bufferLength, stream->bufferCapacity - stream->bufferLength, stream); - if (numFilled != 0) { - stream->currentChar = stream->charBuffer + stream->bufferLength; - stream->bufferLength += numFilled; - } - return numFilled; -} - -// we are expected to move mark & parserMark relative to any moved characters, set currentChar to the first new character fetched, update bufferLength, and advance currentByte as appropriate. Does not check for EOF; it is the caller's responsibility to verify this. -static void fillCharacterBuffer(_CFXMLInputStream *stream) { - if (!stream->charBuffer) { - growCharacterBuffer(stream); - } - if (!stream->mark && !stream->parserMark) { - // This is the easy case; we can freely overwrite the buffer; if either mark or parserMark is set, we must not remove any characters from those marks and the end of the buffer - CFIndex fillLength = stream->bufferCapacity-5; // We leave a few characters at the end, b/c we don't want to reallocate (doubling the amount of memory used) just b/c we're matching a small string near the end of the filled buffer - stream->bufferLength = loadCharacters(stream->charBuffer, fillLength, stream); - CFAssert(stream->bufferLength != 0, __kCFLogAssertion, "CF internal error: XML parser input stream corruption"); - stream->currentChar = stream->charBuffer; - } else { - // We do everything we can not to allocate; first we fill any remaining characters. If that doesn't work, we try shifting the characters starting at the earlier of mark or parserMark to the beginning of buffer, then filling the newly-freed characters. - Boolean done; - - // First try just filling the remaining capacity - done = (fillToCapacity(stream) != 0); - if (!done) { - const UniChar *leftMostMark; - if (stream->mark && !stream->parserMark) { - leftMostMark = stream->mark; - } else if (stream->parserMark && !stream->mark) { - leftMostMark = stream->parserMark; - } else if (stream->parserMark < stream->mark) { - leftMostMark = stream->parserMark; - } else { - leftMostMark = stream->mark; - } - if (leftMostMark > stream->charBuffer) { - CFIndex delta = leftMostMark - stream->charBuffer; - memmove(stream->charBuffer, leftMostMark, (stream->bufferLength - delta) * sizeof(UniChar)); - stream->bufferLength -= delta; - if (stream->mark) { - stream->mark -= delta; - } - if (stream->parserMark) { - stream->parserMark -= delta; - } - // Now try to fill the newly-opened space - done = (fillToCapacity(stream) != 0); - delta = loadCharacters(stream->charBuffer + stream->bufferLength, stream->bufferCapacity - stream->bufferLength, stream); - } - } - if (!done) { - // No help for it; now we must allocate - growCharacterBuffer(stream); - fillToCapacity(stream); // If this doesn't work, we give up. - } - } -} - -/* The guts of getCharacter() have been separated in order to allow getCharacter() to be small and more easily inline-able. Note that a check late in the 10.3 development cycle indicates that getCharacter() should call getCharacterGuts() less than 2% of the time. (In 29000 calls, less than 400 called this. Note that a majority of calls have advanceStream set, so that was left in the inline version. Also note that some calls to getCharacter() were changed to go through the functions _inputStreamGetCharacter() or _inputStreamPeekCharacter(), as the expansion in using the inline version didn't seem worthwhile. See 3275503 for some data supporting this. -*/ -static Boolean getCharacterGuts(_CFXMLInputStream *stream, UniChar *ch, Boolean advanceStream) { - if (stream->currentByte - CFDataGetBytePtr(stream->data) >= CFDataGetLength(stream->data)) { - return false; // EOF - } else if (!((stream->mark || stream->parserMark) && advanceStream) && - (((stream->flags & ENCODING_MATCHES_ASCII) && *(stream->currentByte) < 0x7F) || - (stream->flags & (ENCODING_IS_UNICODE_NATURAL | ENCODING_IS_UNICODE_SWAPPED)))) { - // We can only perform optimizations if neither mark is set (if the mark is set, we must fill the character buffer so we can retrieve the characters later), and the encoding is Unicode, or the encoding matches ASCII and we're looking at a low-byte character. - if (stream->flags & ENCODING_MATCHES_ASCII) { - *ch = (UniChar)*(stream->currentByte); - if (advanceStream) { - stream->currentByte ++; - } - } else if (stream->flags & ENCODING_IS_UNICODE_NATURAL) { - *ch = *(UniChar *)(stream->currentByte); - if (advanceStream) { - stream->currentByte += 2; - } - } else { - // Unicode with swapped bytes - *ch = CFSwapInt16(*(UniChar *)(stream->currentByte)); - if (advanceStream) { - stream->currentByte += 2; - } - } - } else { - fillCharacterBuffer(stream); // this takes into account markIsSet to make sure and do the right thing - if (!stream->charBuffer || !stream->currentChar) { - return false; - } else { - *ch = *(stream->currentChar); - if (advanceStream) { - stream->currentChar ++; - if (stream->currentChar == stream->charBuffer + stream->bufferLength) { - stream->currentChar = NULL; - } - } - } - } - return true; -} - -/* See comments above getCharacterGuts() -*/ -CF_INLINE Boolean getCharacter(_CFXMLInputStream *stream, UniChar *ch, Boolean advanceStream) { - if (!(stream->flags & STREAM_OPEN)) { - return false; - } else if (stream->currentChar) { - *ch = *stream->currentChar; - if (advanceStream) { - stream->currentChar ++; - if (stream->currentChar == stream->charBuffer + stream->bufferLength) { - stream->currentChar = NULL; - } - } - } else { - if (!getCharacterGuts(stream, ch, advanceStream)) return false; - } - if (advanceStream) { - UniChar nextChar; - stream->charIndex ++; - if ((*ch == '\n') || ((*ch == '\r') && (!_inputStreamPeekCharacter(stream, &nextChar) || nextChar != '\n'))) stream->lineNum ++; - } - return true; -} - -CF_PRIVATE Boolean _inputStreamPeekCharacter(_CFXMLInputStream *stream, UniChar *ch) { - return getCharacter(stream, ch, false); -} - -CF_PRIVATE Boolean _inputStreamGetCharacter(_CFXMLInputStream *stream, UniChar *ch) { - return getCharacter(stream, ch, true); -} - -CF_PRIVATE Boolean _inputStreamReturnCharacter(_CFXMLInputStream *stream, UniChar ch) { - Boolean decrementLineNum = false; - if (ch == '\n') { - decrementLineNum = true; - } else if (ch == '\r') { - UniChar nextChar; - if (!_inputStreamPeekCharacter(stream, &nextChar) || nextChar != '\n') { - decrementLineNum = true; - } - } - - if (!(stream->flags & STREAM_OPEN)) { - return false; - } else if (stream->currentChar) { - if (stream->currentChar != stream->charBuffer) { - stream->currentChar --; - } else { - // Yuck; we're unlucky and are returning a character _before_ the first character in charBuffer - if (stream->bufferLength >= stream->bufferCapacity) { - growCharacterBuffer(stream); - } - memmove(stream->charBuffer + 1, stream->charBuffer, stream->bufferLength * sizeof(UniChar)); - *stream->charBuffer = ch; - stream->bufferLength ++; - if (stream->mark) { - stream->mark ++; - } - if (stream->parserMark) { - stream->parserMark ++; - } - } - } else if ((stream->mark || stream->parserMark) && stream->bufferLength) { - // We've been collecting characters in charBuffer; the only reason stream->currentChar is NULL is that we've processed the last character thusfar translated from data. That last character is the one being returned. - stream->currentChar = stream->charBuffer + stream->bufferLength - 1; - } else if (stream->charBuffer) { - // We have processed all the meaningful characters from charBuffer and have no reason to preserve them. We use charBuffer to hold this one character that has been returned to us. - *stream->charBuffer = ch; - stream->currentChar = stream->charBuffer; - stream->bufferLength = 1; - if (stream->mark) { - stream->mark ++; - } - if (stream->parserMark) { - stream->parserMark ++; - } - } else if (stream->currentByte > CFDataGetBytePtr(stream->data)) { - // We have no character buffer available, so that means one of two things - either we've never needed a character buffer because all the characters could come directly out of the byte stream, or we've not yet processed the first character. The former means we can just back up the byte pointer; the latter means Bad Things have happened. - if (stream->flags & ENCODING_MATCHES_ASCII) { - stream->currentByte --; - } else { // Must be Unicode - stream->currentByte -= 2; - } - } else { - return false; - } - stream->charIndex --; - if (decrementLineNum) { - stream->lineNum --; - } - return true; -} - -// Returns the pointer to hold as the mark -static UniChar *dropMark(_CFXMLInputStream *stream) { - if (stream->currentChar) { - return stream->currentChar; - } else if (stream->mark || stream->parserMark) { - return stream->charBuffer + stream->bufferLength; - } else { - if (!stream->charBuffer) { - growCharacterBuffer(stream); - } - stream->bufferLength = 0; // This will be sufficient to force a fetch into the buffer when the next character is requested - return stream->charBuffer; - } - -} - -CF_PRIVATE void _inputStreamSetMark(_CFXMLInputStream *stream) { - CFAssert(stream->mark == NULL, __kCFLogAssertion, "CF internal error: parser input stream malformed"); - stream->mark = dropMark(stream); -} - -CF_PRIVATE void _inputStreamClearMark(_CFXMLInputStream *stream) { - CFAssert(stream->mark != NULL, __kCFLogAssertion, "CF internal error: parser input stream malformed"); - stream->mark = NULL; -} - -CF_PRIVATE void _inputStreamGetCharactersFromMark(_CFXMLInputStream *stream, CFMutableStringRef string) { - UniChar *end = stream->currentChar ? stream->currentChar : stream->charBuffer + stream->bufferLength; - CFIndex numChars = end - stream->mark; - CFAssert(stream->mark, __kCFLogAssertion, "CF internal error: malformed XML input stream"); - _fillStringWithCharacters(string, stream->mark, numChars); -} - -static void restoreToMark(_CFXMLInputStream *stream, UniChar *mark) { - UniChar *end = stream->currentChar ? stream->currentChar : stream->charBuffer + stream->bufferLength; - if (end > mark) { - CFIndex numChars = end - mark; - stream->charIndex -= numChars; - stream->currentChar = mark; - - // This is annoying; to keep the line count accurate, if the first character we are returning is a CR, we must decrement the line count iff the next character is NOT a LF - if (*(end - 1) == '\r') { - UniChar nextChar; - if (_inputStreamPeekCharacter(stream, &nextChar) && nextChar == '\n') { - end --; - } - } - while (end != mark) { - end --; - if (*end == '\r') { - stream->lineNum --; - } else if (*end == '\n') { - stream->lineNum --; - if (end != mark && *(end - 1) == '\r') { - end --; - } - } - } - } -} - -CF_PRIVATE void _inputStreamBackUpToMark(_CFXMLInputStream *stream) { - CFAssert(stream->mark != NULL || stream->charBuffer == NULL, __kCFLogAssertion, "CF internal error: malformed XML input stream"); - restoreToMark(stream, stream->mark); -} - -CF_INLINE Boolean isWhitespaceChar(UniChar ch) { - return (ch == '\n' || ch == '\r' || ch == ' ' || ch == '\t'); -} - -CF_PRIVATE CFIndex _inputStreamSkipWhitespace(_CFXMLInputStream *stream, CFMutableStringRef str) { - UniChar ch; - CFIndex len = 0; - if (str) { - stream->parserMark = dropMark(stream); - } - while (getCharacter(stream, &ch, true) && isWhitespaceChar(ch)) { - len ++; - } - if (!isWhitespaceChar(ch)) { - _inputStreamReturnCharacter(stream, ch); - } - if (str) { - _fillStringWithCharacters(str, stream->parserMark, len); - stream->parserMark = NULL; - } - return len; -} - -// false return means EOF was encountered without finding scanChars -CF_PRIVATE Boolean _inputStreamScanToCharacters(_CFXMLInputStream *stream, const UniChar *scanChars, CFIndex numChars, CFMutableStringRef str) { - Boolean done = false; - CFIndex firstRepeatIndex = -1; - CFIndex len = 0; - stream->parserMark = dropMark(stream); - do { - UniChar ch; - while (_inputStreamGetCharacter(stream, &ch) && ch != scanChars[0]) { - len ++; - } - if (ch != scanChars[0]) { - restoreToMark(stream, stream->parserMark); - stream->parserMark = NULL; - return false; - } else { - CFIndex i; - for (i = 1; i < numChars; i ++) { - if (!_inputStreamGetCharacter(stream, &ch)) break; - if (ch != scanChars[i]) break; - } - if (i == numChars) { - done = true; - } else { - if (firstRepeatIndex == -1) { - CFIndex j; - for (j = 1; j < numChars; j ++) { - if (scanChars[0] == scanChars[j]) { - break; - } - } - firstRepeatIndex = j; - } - _inputStreamReturnCharacter(stream, ch); - while (i > firstRepeatIndex) { - i --; - _inputStreamReturnCharacter(stream, scanChars[i]); - } - len += i; - } - } - } while (!done); - if (str) { - _fillStringWithCharacters(str, stream->parserMark, len); - } - stream->parserMark = NULL; - return true; -} - -CF_PRIVATE Boolean _inputStreamMatchString(_CFXMLInputStream *stream, const UniChar *stringToMatch, CFIndex length) { - const UniChar *end = stringToMatch+length; - const UniChar *sPtr=stringToMatch; - stream->parserMark = dropMark(stream); - while (sPtr < end) { - UniChar ch; - if (!_inputStreamGetCharacter(stream, &ch)) break; - if (ch != *sPtr) break; - sPtr ++; - } - if (sPtr != end) { - restoreToMark(stream, stream->parserMark); - stream->parserMark = NULL; - return false; - } else { - stream->parserMark = NULL; - return true; - } -} - -CF_PRIVATE Boolean _inputStreamScanQuotedString(_CFXMLInputStream *stream, CFMutableStringRef str) { - UniChar ch; - if (!_inputStreamPeekCharacter(stream, &ch)) return false; - if (ch != '\'' && ch != '\"') return false; - - _inputStreamGetCharacter(stream, &ch); - if (!_inputStreamScanToCharacters(stream, &ch, 1, str)) { - return false; - } - return true; -} - -/* - [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender - [5] Name ::= (Letter | '_' | ':') (NameChar)* - [7] Nmtoken ::= (NameChar)+ - [84] Letter ::= BaseChar | Ideographic - - We don't do this quite right; we rely on the Unicode charsets to do this analysis. While - the productions in the XML spec are based on the Unicode character sets, the definitions - differ slightly to avoid those areas where the Unicode standard is still being resolved. - At any rate, I'd lay money that using the Unicode charsets, we will be more correct than - the vast majority of parsers out there. - - Letter == kCFUniCharLetterCharacterSet - Digit == kCFUniCharDecimalDigitCharacterSet - CombiningChar == kCFUniCharNonBaseCharacterSet - Extender - complex, and not represented by a uniform character set. - */ -CF_PRIVATE Boolean _inputStreamScanXMLName(_CFXMLInputStream *stream, Boolean isNMToken, CFStringRef *str) { - UniChar ch; - Boolean success = true; - stream->parserMark = dropMark(stream); - if (!isNMToken) { - // Only difference between an NMToken and a Name is Names have a stricter condition on the first character - if (!getCharacter(stream, &ch, false)) { - success = false; - } else if (!CFUniCharIsMemberOf(ch, kCFUniCharLetterCharacterSet) && ch != '_' && ch != ':') { - success = false; - } else { - getCharacter(stream, &ch, true); - } - } - if (success) { - while (getCharacter(stream, &ch, true)) { - if (!CFUniCharIsMemberOf(ch, kCFUniCharLetterCharacterSet) && !CFUniCharIsMemberOf(ch, kCFUniCharDecimalDigitCharacterSet) && ch != '.' && ch != '-' && ch != '_' && ch != ':' && !CFUniCharIsMemberOf(ch, kCFUniCharNonBaseCharacterSet)) { - _inputStreamReturnCharacter(stream, ch); - break; - } - } - if (NULL == stream->currentChar || stream->currentChar == stream->parserMark) { - success = false; // Must have processed at least one character - } - } - if (success) { - if (str) { - if (!stream->nameSet) { - stream->nameSet = CFSetCreateMutable(stream->allocator, 0, &kCFTypeSetCallBacks); - stream->tempString = CFStringCreateMutableWithExternalCharactersNoCopy(stream->allocator, NULL, 0, 0, kCFAllocatorNull); - } - CFStringSetExternalCharactersNoCopy(stream->tempString, stream->parserMark, stream->currentChar-stream->parserMark, stream->currentChar-stream->parserMark); - if (!CFSetGetValueIfPresent(stream->nameSet, stream->tempString, (const void **)str)) { - *str = (CFStringRef)CFStringCreateCopy(stream->allocator, stream->tempString); - CFSetAddValue(stream->nameSet, *str); - CFRelease(*str); - } - } - } else { - restoreToMark(stream, stream->parserMark); - } - stream->parserMark = NULL; - return success; -} - - diff --git a/CoreFoundation/Parsing.subproj/CFXMLInputStream.h b/CoreFoundation/Parsing.subproj/CFXMLInputStream.h deleted file mode 100644 index 828793fdae..0000000000 --- a/CoreFoundation/Parsing.subproj/CFXMLInputStream.h +++ /dev/null @@ -1,91 +0,0 @@ -/* CFXMLInputStream.h - Copyright (c) 2000-2018, Apple Inc. and the Swift project authors - - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors - Licensed under Apache License v2.0 with Runtime Library Exception - See http://swift.org/LICENSE.txt for license information - See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -*/ - -#if !defined(__COREFOUNDATION_CFXMLINPUTSTREAM__) -#define __COREFOUNDATION_CFXMLINPUTSTREAM__ 1 - -#include -#include "CFInternal.h" -#include -#include -#include - -struct __CFXMLNode { - // additionalData currently always points off the bottom of this struct; we could just eliminate it. Also, we may want to add a flags/version argument, and could use it to mark whether the node was the special one that CFXMLParser mucks with, as well as whether the allocator was "special" (could save us the alloc instance variable, below) -- REW, 3/8/2000 - CFRuntimeBase _cfBase; - CFIndex version; - CFXMLNodeTypeCode dataTypeID; - CFStringRef dataString; - void *additionalData; -}; - -struct __CFXMLInputStream { - CFDataRef data; // The XML data - CFURLRef url; // the source URL for the data - CFStringEncoding encoding; // the data's encoding - const UInt8 *currentByte; // pointer into data at the first byte not yet translated to a character - - UniChar *charBuffer; // the buffer of characters translated from data - UniChar *currentChar; // pointer into charBuffer at the current stream location. MUST be NULL if there are no more characters in charBuffer to consume. - UniChar *mark; // The point at which the mark was dropped. NULL if the mark is currently unset. - UniChar *parserMark; // mark available only for the parser's use - CFIndex bufferLength; // The number of meaningful characters in charBuffer - CFIndex bufferCapacity; // The current maximum capacity of charBuffer in UniChars - - CFIndex charIndex, lineNum; // location in the file - UInt32 flags; // See #defines below for bit flag meanings - CFMutableSetRef nameSet; // set of all names we've encountered; used for uniquing - CFMutableStringRef tempString; - - CFAllocatorRef allocator; // This is unfortunate; this is always the same as the parser's allocator. We'd like to get rid of it at some point, but that would mean adding an allocator to all the function calls, which means risking that the allocator passed in gets out-of-sync. Maybe once we have CFStreams, we can encapsulate it all in that. REW, 5/22/2000 -}; - -// whether the stream has been opened for reading -#define STREAM_OPEN 0x1 -// whether the encoding matches ASCII over 0x0-0x7F -#define ENCODING_MATCHES_ASCII 0x2 -// whether the encoding is Unicode with the "natural" byte ordering -#define ENCODING_IS_UNICODE_NATURAL 0x4 -// whether the encoding is Unicode with the bytes swapped -#define ENCODING_IS_UNICODE_SWAPPED 0x8 -// whether the stream has encountered an error in encodings. -#define ENCODING_COMPOSITION_ERROR 0x10 - -typedef struct __CFXMLInputStream _CFXMLInputStream; - -void _initializeInputStream(_CFXMLInputStream *stream, CFAllocatorRef alloc, CFURLRef dataSource, CFDataRef xmlData); -Boolean _openInputStream(_CFXMLInputStream *stream); // None of the subsequent calls will work until the input stream has been opened -void _freeInputStream(_CFXMLInputStream *stream); - -CFStringEncoding _inputStreamGetEncoding(_CFXMLInputStream *stream); -CFIndex _inputStreamCurrentLocation(_CFXMLInputStream *stream); -CFIndex _inputStreamCurrentLine(_CFXMLInputStream *stream); -Boolean _inputStreamAtEOF(_CFXMLInputStream *stream); -Boolean _inputStreamComposingErrorOccurred(_CFXMLInputStream *stream); - -Boolean _inputStreamPeekCharacter(_CFXMLInputStream *stream, UniChar *ch); -Boolean _inputStreamGetCharacter(_CFXMLInputStream *stream, UniChar *ch); -Boolean _inputStreamReturnCharacter(_CFXMLInputStream *stream, UniChar ch); -void _inputStreamSetMark(_CFXMLInputStream *stream); -void _inputStreamClearMark(_CFXMLInputStream *stream); -void _inputStreamGetCharactersFromMark(_CFXMLInputStream *stream, CFMutableStringRef string); -void _inputStreamBackUpToMark(_CFXMLInputStream *stream); -void _inputStringInitialize(_CFXMLInputStream *stream, UniChar *characters, CFIndex length); -CFIndex _inputStreamSkipWhitespace(_CFXMLInputStream *stream, CFMutableStringRef str); -Boolean _inputStreamScanToCharacters(_CFXMLInputStream *stream, const UniChar *scanChars, CFIndex numChars, CFMutableStringRef str); -Boolean _inputStreamMatchString(_CFXMLInputStream *stream, const UniChar *stringToMatch, CFIndex length); -Boolean _inputStreamScanQuotedString(_CFXMLInputStream *stream, CFMutableStringRef str); -Boolean _inputStreamScanXMLName(_CFXMLInputStream *stream, Boolean isNMToken, CFStringRef *str); - -/* Returns the character index within the current line of the current parse location */ -/* To add someday -- CF_EXPORT -CFIndex CFXMLParserGetOffsetInCurrentLine(CFXMLParserRef parser); */ - -#endif /* ! __COREFOUNDATION_CFXMLINPUTSTREAM__ */ - diff --git a/CoreFoundation/Parsing.subproj/CFXMLNode.c b/CoreFoundation/Parsing.subproj/CFXMLNode.c deleted file mode 100644 index f7a73ad1ff..0000000000 --- a/CoreFoundation/Parsing.subproj/CFXMLNode.c +++ /dev/null @@ -1,348 +0,0 @@ -/* CFXMLNode.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors - - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors - Licensed under Apache License v2.0 with Runtime Library Exception - See http://swift.org/LICENSE.txt for license information - See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: David Smith -*/ - -#include -#include -#include "CFInternal.h" -#include "CFRuntime_Internal.h" -#include "CFXMLInputStream.h" - -CF_INLINE Boolean _nullSafeCFEqual(CFTypeRef cf1, CFTypeRef cf2) { - if (cf1 && !cf2) return false; - if (cf2 && !cf1) return false; - if (cf1) return CFEqual(cf1, cf2); - return true; -} - -static Boolean externalIDEqual(CFXMLExternalID *ext1, CFXMLExternalID *ext2) { - return _nullSafeCFEqual(ext1->systemID, ext2->systemID) && _nullSafeCFEqual(ext1->publicID, ext2->publicID); -} - -static Boolean __CFXMLNodeEqual(CFTypeRef cf1, CFTypeRef cf2) { - CFXMLNodeRef desc1 = (CFXMLNodeRef)cf1, desc2 = (CFXMLNodeRef)cf2; - if (desc1 == desc2) return true; - if (!desc1 || !desc2) return false; - if (desc1->dataTypeID != desc2->dataTypeID) return false; - if ((desc1->dataString && !desc2->dataString) || (!desc1->dataString && desc2->dataString)) return false; - if (desc1->dataString && !CFEqual(desc1->dataString, desc2->dataString)) return false; - if ((desc1->additionalData && !desc2->additionalData) || (!desc1->additionalData && desc2->additionalData)) return false; - if (!desc1->additionalData) return true; - switch (desc1->dataTypeID) { - case kCFXMLNodeTypeDocument:{ - CFURLRef url1, url2; - url1 = ((CFXMLDocumentInfo *)desc1->additionalData)->sourceURL; - url2 = ((CFXMLDocumentInfo *)desc2->additionalData)->sourceURL; - return _nullSafeCFEqual(url1, url2); - } - case kCFXMLNodeTypeElement: { - CFXMLElementInfo *elt1, *elt2; - elt1 = (CFXMLElementInfo *)desc1->additionalData; - elt2 = (CFXMLElementInfo *)desc2->additionalData; - if (elt1->isEmpty != elt2->isEmpty) return false; - if (elt1->attributes == elt2->attributes) return true; - if (!elt1->attributes) return (CFDictionaryGetCount(elt2->attributes) == 0); - if (!elt2->attributes) return (CFDictionaryGetCount(elt1->attributes) == 0); - return CFEqual(elt1->attributes, elt2->attributes); - } - case kCFXMLNodeTypeProcessingInstruction: { - CFStringRef str1, str2; - str1 = ((CFXMLProcessingInstructionInfo *)desc1->additionalData)->dataString; - str2 = ((CFXMLProcessingInstructionInfo *)desc2->additionalData)->dataString; - return _nullSafeCFEqual(str1, str2); - } - case kCFXMLNodeTypeEntity: { - CFXMLEntityInfo *data1, *data2; - data1 = (CFXMLEntityInfo *)desc1->additionalData; - data2 = (CFXMLEntityInfo *)desc2->additionalData; - if (data1->entityType != data2->entityType) return false; - if (!_nullSafeCFEqual(data1->replacementText, data2->replacementText)) return false; - if (!_nullSafeCFEqual(data1->notationName, data2->notationName)) return false; - return externalIDEqual(&data1->entityID, &data2->entityID); - } - case kCFXMLNodeTypeEntityReference: { - return ((CFXMLEntityReferenceInfo *)(desc1->additionalData))->entityType == ((CFXMLEntityReferenceInfo *)(desc2->additionalData))->entityType; - } - case kCFXMLNodeTypeNotation: { - CFXMLNotationInfo *data1, *data2; - data1 = (CFXMLNotationInfo *)desc1->additionalData; - data2 = (CFXMLNotationInfo *)desc2->additionalData; - return externalIDEqual(&(data1->externalID), &(data2->externalID)); - } - case kCFXMLNodeTypeDocumentType: { - CFXMLDocumentTypeInfo *data1, *data2; - data1 = (CFXMLDocumentTypeInfo *)desc1->additionalData; - data2 = (CFXMLDocumentTypeInfo *)desc2->additionalData; - return externalIDEqual(&(data1->externalID), &(data2->externalID)); - } - case kCFXMLNodeTypeElementTypeDeclaration: { - CFXMLElementTypeDeclarationInfo *d1 = (CFXMLElementTypeDeclarationInfo *)desc1->additionalData; - CFXMLElementTypeDeclarationInfo *d2 = (CFXMLElementTypeDeclarationInfo *)desc2->additionalData; - return _nullSafeCFEqual(d1->contentDescription, d2->contentDescription); - } - case kCFXMLNodeTypeAttributeListDeclaration: { - CFXMLAttributeListDeclarationInfo *attList1 = (CFXMLAttributeListDeclarationInfo *)desc1->additionalData; - CFXMLAttributeListDeclarationInfo *attList2 = (CFXMLAttributeListDeclarationInfo *)desc2->additionalData; - CFIndex idx; - if (attList1->numberOfAttributes != attList2->numberOfAttributes) return false; - for (idx = 0; idx < attList1->numberOfAttributes; idx ++) { - CFXMLAttributeDeclarationInfo *attr1 = &(attList1->attributes[idx]); - CFXMLAttributeDeclarationInfo *attr2 = &(attList2->attributes[idx]); - if (!_nullSafeCFEqual(attr1->attributeName, attr2->attributeName)) return false; - if (!_nullSafeCFEqual(attr1->typeString, attr2->typeString)) return false; - if (!_nullSafeCFEqual(attr1->defaultString, attr2->defaultString)) return false; - } - return true; - } - default: - return false; - } - return true; -} - -static CFHashCode __CFXMLNodeHash(CFTypeRef cf) { - CFXMLNodeRef node = (CFXMLNodeRef)cf; - if (node->dataString) { - return CFHash(node->dataString); - } - if (node->dataTypeID == kCFXMLNodeTypeDocument) { - CFURLRef url = ((CFXMLDocumentInfo *)node->additionalData)->sourceURL; - return url ? CFHash(url) : (CFHashCode)cf; - } else { - CFAssert2(false, __kCFLogAssertion, "%s(): Saw unexpected XML type code %ld", __PRETTY_FUNCTION__, node->dataTypeID); - return CFHash(cf); - } -} - -static CFStringRef __CFXMLNodeCopyDescription(CFTypeRef cf) { - struct __CFXMLNode *node = (struct __CFXMLNode *)cf; - return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("CFXMLNode %p>{typeID = %ld, string = %@}"), cf, (unsigned long)node->dataTypeID, node->dataString); -} - -static void __CFXMLNodeDeallocate(CFTypeRef cf) { - struct __CFXMLNode *node = (struct __CFXMLNode *)cf; - if (node->dataString) CFRelease(node->dataString); - if (node->additionalData) { - switch (node->dataTypeID) { - case kCFXMLNodeTypeDocument: - if (((CFXMLDocumentInfo *)node->additionalData)->sourceURL) { - CFRelease(((CFXMLDocumentInfo *)node->additionalData)->sourceURL); - } - break; - case kCFXMLNodeTypeElement: - if (((CFXMLElementInfo *)node->additionalData)->attributes) { - CFRelease(((CFXMLElementInfo *)node->additionalData)->attributes); - CFRelease(((CFXMLElementInfo *)node->additionalData)->attributeOrder); - } - break; - case kCFXMLNodeTypeProcessingInstruction: - if (((CFXMLProcessingInstructionInfo *)node->additionalData)->dataString) { - CFRelease(((CFXMLProcessingInstructionInfo *)node->additionalData)->dataString); - } - break; - case kCFXMLNodeTypeEntity: - { - CFXMLEntityInfo *data = (CFXMLEntityInfo *)node->additionalData; - if (data->replacementText) CFRelease(data->replacementText); - if (data->entityID.systemID) CFRelease(data->entityID.systemID); - if (data->entityID.publicID) CFRelease(data->entityID.publicID); - if (data->notationName) CFRelease(data->notationName); - break; - } - case kCFXMLNodeTypeEntityReference: - { - // Do nothing; additionalData has no structure of its own, with dependent pieces to release. -- REW, 2/11/2000 - break; - } - case kCFXMLNodeTypeDocumentType: - case kCFXMLNodeTypeNotation: - // We get away with this because CFXMLNotationInfo and CFXMLDocumentTypeInfo have identical formats - { - CFXMLNotationInfo *data = (CFXMLNotationInfo *)node->additionalData; - if (data->externalID.systemID) CFRelease(data->externalID.systemID); - if (data->externalID.publicID) CFRelease(data->externalID.publicID); - break; - } - case kCFXMLNodeTypeElementTypeDeclaration: - if (((CFXMLElementTypeDeclarationInfo *)node->additionalData)->contentDescription) { - CFRelease(((CFXMLElementTypeDeclarationInfo *)node->additionalData)->contentDescription); - } - break; - case kCFXMLNodeTypeAttributeListDeclaration: - { - CFXMLAttributeListDeclarationInfo *data = (CFXMLAttributeListDeclarationInfo *)node->additionalData; - CFIndex idx; - for (idx = 0; idx < data->numberOfAttributes; idx ++) { - CFRelease(data->attributes[idx].attributeName); - CFRelease(data->attributes[idx].typeString); - CFRelease(data->attributes[idx].defaultString); - } - CFAllocatorDeallocate(CFGetAllocator(node), data->attributes); - break; - } - default: - CFAssert2(false, __kCFLogAssertion, "%s(): Encountered unexpected typeID %ld (additionalData should be empty)", __PRETTY_FUNCTION__, node->dataTypeID); - } - } -} - -const CFRuntimeClass __CFXMLNodeClass = { - 0, - "CFXMLNode", - NULL, // init - NULL, // copy - __CFXMLNodeDeallocate, - __CFXMLNodeEqual, - __CFXMLNodeHash, - NULL, // - __CFXMLNodeCopyDescription -}; - -CFTypeID CFXMLNodeGetTypeID(void) { - return _kCFRuntimeIDCFXMLNode; -} - -CFXMLNodeRef CFXMLNodeCreateCopy(CFAllocatorRef alloc, CFXMLNodeRef origNode) { - return CFXMLNodeCreate(alloc, origNode->dataTypeID, origNode->dataString, origNode->additionalData, origNode->version); -} - -static void _copyAddlDataForType(CFAllocatorRef alloc, CFXMLNodeTypeCode xmlType, const void *src, void *dest) { - switch(xmlType) { - case kCFXMLNodeTypeDocument: { - CFXMLDocumentInfo *srcData = (CFXMLDocumentInfo *)src; - CFXMLDocumentInfo *destData = (CFXMLDocumentInfo *)dest; - destData->sourceURL = srcData->sourceURL ? (CFURLRef)CFRetain(srcData->sourceURL) : NULL; - destData->encoding = srcData->encoding; - break; - } - case kCFXMLNodeTypeElement: { - CFXMLElementInfo *srcData = (CFXMLElementInfo *)src; - CFXMLElementInfo *destData = (CFXMLElementInfo *)dest; - if (srcData->attributes && CFDictionaryGetCount(srcData->attributes) != 0) { - destData->attributes = (CFDictionaryRef)CFPropertyListCreateDeepCopy(alloc, srcData->attributes, kCFPropertyListImmutable); - destData->attributeOrder = (CFArrayRef)CFPropertyListCreateDeepCopy(alloc, srcData->attributeOrder, kCFPropertyListImmutable); - } else { - destData->attributes = NULL; - destData->attributeOrder = NULL; - } - destData->isEmpty = srcData->isEmpty; - break; - } - case kCFXMLNodeTypeProcessingInstruction: { - CFXMLProcessingInstructionInfo *srcData = (CFXMLProcessingInstructionInfo *)src; - CFXMLProcessingInstructionInfo *destData = (CFXMLProcessingInstructionInfo *)dest; - destData->dataString = srcData->dataString ? (CFStringRef)CFStringCreateCopy(alloc, srcData->dataString) : NULL; - break; - } - case kCFXMLNodeTypeEntity: - { - CFXMLEntityInfo *sourceData = (CFXMLEntityInfo *)src; - CFXMLEntityInfo *destData = (CFXMLEntityInfo *)dest; - destData->entityType = sourceData->entityType; - destData->replacementText = sourceData->replacementText ? (CFStringRef)CFStringCreateCopy(alloc, sourceData->replacementText) : NULL; - destData->entityID.systemID = sourceData->entityID.systemID ? (CFURLRef)CFRetain(sourceData->entityID.systemID) : NULL; - destData->entityID.publicID = sourceData->entityID.publicID ? (CFStringRef)CFStringCreateCopy(alloc, sourceData->entityID.publicID) : NULL; - destData->notationName = sourceData->notationName ? (CFStringRef)CFStringCreateCopy(alloc, sourceData->notationName) : NULL; - break; - } - case kCFXMLNodeTypeEntityReference: - { - CFXMLEntityReferenceInfo *srcData = (CFXMLEntityReferenceInfo *)src; - CFXMLEntityReferenceInfo *destData = (CFXMLEntityReferenceInfo *)dest; - destData->entityType = srcData->entityType; - break; - } - case kCFXMLNodeTypeDocumentType: - case kCFXMLNodeTypeNotation: - { - // We can get away with this because the structures of CFXMLNotationInfo and CFXMLDocumentTypeInfo match. -- REW, 3/8/2000 - CFXMLNotationInfo *srcData = (CFXMLNotationInfo *)src; - CFXMLNotationInfo *destData = (CFXMLNotationInfo *)dest; - destData->externalID.systemID = srcData->externalID.systemID ? (CFURLRef)CFRetain(srcData->externalID.systemID) : NULL; - destData->externalID.publicID = srcData->externalID.publicID ? (CFStringRef)CFStringCreateCopy(alloc, srcData->externalID.publicID) : NULL; - break; - } - case kCFXMLNodeTypeElementTypeDeclaration: { - CFXMLElementTypeDeclarationInfo *srcData = (CFXMLElementTypeDeclarationInfo *)src; - CFXMLElementTypeDeclarationInfo *destData = (CFXMLElementTypeDeclarationInfo *)dest; - destData->contentDescription = srcData->contentDescription ? (CFStringRef)CFStringCreateCopy(alloc, srcData->contentDescription) : NULL; - break; - } - case kCFXMLNodeTypeAttributeListDeclaration: - { - CFXMLAttributeListDeclarationInfo *sourceData = (CFXMLAttributeListDeclarationInfo *)src; - CFXMLAttributeListDeclarationInfo *destData = (CFXMLAttributeListDeclarationInfo *)dest; - CFIndex idx; - destData->numberOfAttributes = sourceData->numberOfAttributes; - destData->attributes = sourceData->numberOfAttributes ? (CFXMLAttributeDeclarationInfo *)CFAllocatorAllocate(alloc, sizeof(CFXMLAttributeDeclarationInfo)*sourceData->numberOfAttributes, 0) : NULL; - for (idx = 0; idx < sourceData->numberOfAttributes; idx ++) { - CFXMLAttributeDeclarationInfo sourceAttr = sourceData->attributes[idx]; - CFXMLAttributeDeclarationInfo *destAttr = &(destData->attributes[idx]); - destAttr->attributeName = (CFStringRef)CFStringCreateCopy(alloc, sourceAttr.attributeName); - destAttr->typeString = (CFStringRef)CFStringCreateCopy(alloc, sourceAttr.typeString); - destAttr->defaultString = (CFStringRef)CFStringCreateCopy(alloc, sourceAttr.defaultString); - } - break; - } - default: - CFAssert2(false, __kCFLogAssertion, "%s(): Encountered unexpected typeID %ld (additionalData should be empty)", __PRETTY_FUNCTION__, xmlType); - } -} - -// Designated initializer; all node creation (except the wonky one created by the parser) should happen here. -CFXMLNodeRef CFXMLNodeCreate(CFAllocatorRef alloc, CFXMLNodeTypeCode xmlType, CFStringRef dataString, const void *additionalData, CFIndex version) { - struct __CFXMLNode *node; - UInt32 extraSize; - // Add assertions checking xmlType against the presence/absence of additionalData & dataString - switch (xmlType) { - case kCFXMLNodeTypeDocument: extraSize = sizeof(CFXMLDocumentInfo); break; - case kCFXMLNodeTypeElement: extraSize = sizeof(CFXMLElementInfo); break; - case kCFXMLNodeTypeProcessingInstruction: extraSize = sizeof(CFXMLProcessingInstructionInfo); break; - case kCFXMLNodeTypeEntity: extraSize = sizeof(CFXMLEntityInfo); break; - case kCFXMLNodeTypeEntityReference: extraSize = sizeof(CFXMLEntityReferenceInfo); break; - case kCFXMLNodeTypeDocumentType: extraSize = sizeof(CFXMLDocumentTypeInfo); break; - case kCFXMLNodeTypeNotation: extraSize = sizeof(CFXMLNotationInfo); break; - case kCFXMLNodeTypeElementTypeDeclaration: extraSize = sizeof(CFXMLElementTypeDeclarationInfo); break; - case kCFXMLNodeTypeAttributeListDeclaration: extraSize = sizeof(CFXMLAttributeListDeclarationInfo); break; - default: extraSize = 0; - } - - node = (struct __CFXMLNode *)_CFRuntimeCreateInstance(alloc, CFXMLNodeGetTypeID(), sizeof(struct __CFXMLNode) + extraSize - sizeof(CFRuntimeBase), NULL); - if (node) { - alloc = CFGetAllocator(node); - node->version = version; - node->dataTypeID = xmlType; - node->dataString = dataString ? (CFStringRef)CFStringCreateCopy(alloc, dataString) : NULL; - if (extraSize != 0) { - node->additionalData = (void *)((uint8_t *)node + sizeof(struct __CFXMLNode)); - _copyAddlDataForType(alloc, xmlType, additionalData, node->additionalData); - } else { - node->additionalData = NULL; - } - } - return node; -} - -CFXMLNodeTypeCode CFXMLNodeGetTypeCode(CFXMLNodeRef node) { - return node->dataTypeID; -} - -CFStringRef CFXMLNodeGetString(CFXMLNodeRef node) { - return node->dataString; -} - -const void *CFXMLNodeGetInfoPtr(CFXMLNodeRef node) { - return node->additionalData; -} - -CFIndex CFXMLNodeGetVersion(CFXMLNodeRef node) { - return node->version; -} - - diff --git a/CoreFoundation/Parsing.subproj/CFXMLNode.h b/CoreFoundation/Parsing.subproj/CFXMLNode.h deleted file mode 100644 index b770abe1cc..0000000000 --- a/CoreFoundation/Parsing.subproj/CFXMLNode.h +++ /dev/null @@ -1,196 +0,0 @@ -/* CFXMLNode.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors - - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors - Licensed under Apache License v2.0 with Runtime Library Exception - See http://swift.org/LICENSE.txt for license information - See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -*/ - -/* CFXMLParser (and thus CFXMLNode) are deprecated as of Mac OS X 10.8 and iOS 6.0. The suggested replacements are the Foundation classes NSXMLParser and NSXMLDocument, or the libxml2 library. */ - -#if !defined(__COREFOUNDATION_CFXMLNODE__) -#define __COREFOUNDATION_CFXMLNODE__ 1 - -#include -#include -#include -#include -#include - -CF_IMPLICIT_BRIDGING_ENABLED -CF_EXTERN_C_BEGIN - -#define __CFXMLNode_DEPRECATION_MSG "CFXMLNode is deprecated, use NSXMLParser, NSXMLDocument or libxml2 library instead" - -CF_ENUM(CFIndex) { - kCFXMLNodeCurrentVersion = 1 -}; - -typedef const struct __CFXMLNode * CFXMLNodeRef; -typedef CFTreeRef CFXMLTreeRef; - -/* An CFXMLNode describes an individual XML construct - like a tag, or a comment, or a string - of character data. Each CFXMLNode contains 3 main pieces of information - the node's type, - the data string, and a pointer to an additional data structure. The node's type ID is an enum - value of type CFXMLNodeTypeID. The data string is always a CFStringRef; the meaning of the - string is dependent on the node's type ID. The format of the additional data is also dependent - on the node's type; in general, there is a custom structure for each type that requires - additional data. See below for the mapping from type ID to meaning of the data string and - structure of the additional data. Note that these structures are versioned, and may change - as the parser changes. The current version can always be identified by kCFXMLNodeCurrentVersion; - earlier versions can be identified and used by passing earlier values for the version number - (although the older structures would have been removed from the header). - - An CFXMLTree is simply a CFTree whose context data is known to be an CFXMLNodeRef. As - such, an CFXMLTree can be used to represent an entire XML document; the CFTree - provides the tree structure of the document, while the CFXMLNodes identify and describe - the nodes of the tree. An XML document can be parsed to a CFXMLTree, and a CFXMLTree - can generate the data for the equivalent XML document - see CFXMLParser.h for more - information on parsing XML. - */ - -/* Type codes for the different possible XML nodes; this list may grow.*/ -typedef CF_ENUM(CFIndex, CFXMLNodeTypeCode) { - kCFXMLNodeTypeDocument = 1, - kCFXMLNodeTypeElement = 2, - kCFXMLNodeTypeAttribute = 3, - kCFXMLNodeTypeProcessingInstruction = 4, - kCFXMLNodeTypeComment = 5, - kCFXMLNodeTypeText = 6, - kCFXMLNodeTypeCDATASection = 7, - kCFXMLNodeTypeDocumentFragment = 8, - kCFXMLNodeTypeEntity = 9, - kCFXMLNodeTypeEntityReference = 10, - kCFXMLNodeTypeDocumentType = 11, - kCFXMLNodeTypeWhitespace = 12, - kCFXMLNodeTypeNotation = 13, - kCFXMLNodeTypeElementTypeDeclaration = 14, - kCFXMLNodeTypeAttributeListDeclaration = 15 -}; - -typedef struct { - CFDictionaryRef attributes; - CFArrayRef attributeOrder; - Boolean isEmpty; - char _reserved[3]; -} CFXMLElementInfo; - -typedef struct { - CFStringRef dataString; -} CFXMLProcessingInstructionInfo; - -typedef struct { - CFURLRef sourceURL; - CFStringEncoding encoding; -} CFXMLDocumentInfo; - -typedef struct { - CFURLRef systemID; - CFStringRef publicID; -} CFXMLExternalID; - -typedef struct { - CFXMLExternalID externalID; -} CFXMLDocumentTypeInfo; - -typedef struct { - CFXMLExternalID externalID; -} CFXMLNotationInfo; - -typedef struct { - /* This is expected to change in future versions */ - CFStringRef contentDescription; -} CFXMLElementTypeDeclarationInfo; - -typedef struct { - /* This is expected to change in future versions */ - CFStringRef attributeName; - CFStringRef typeString; - CFStringRef defaultString; -} CFXMLAttributeDeclarationInfo; - -typedef struct { - CFIndex numberOfAttributes; - CFXMLAttributeDeclarationInfo *attributes; -} CFXMLAttributeListDeclarationInfo; - -typedef CF_ENUM(CFIndex, CFXMLEntityTypeCode) { - kCFXMLEntityTypeParameter, /* Implies parsed, internal */ - kCFXMLEntityTypeParsedInternal, - kCFXMLEntityTypeParsedExternal, - kCFXMLEntityTypeUnparsed, - kCFXMLEntityTypeCharacter -}; - -typedef struct { - CFXMLEntityTypeCode entityType; - CFStringRef replacementText; /* NULL if entityType is external or unparsed */ - CFXMLExternalID entityID; /* entityID.systemID will be NULL if entityType is internal */ - CFStringRef notationName; /* NULL if entityType is parsed */ -} CFXMLEntityInfo; - -typedef struct { - CFXMLEntityTypeCode entityType; -} CFXMLEntityReferenceInfo; - -/* - dataTypeCode meaning of dataString format of infoPtr - =========== ===================== ================= - kCFXMLNodeTypeDocument CFXMLDocumentInfo * - kCFXMLNodeTypeElement tag name CFXMLElementInfo * - kCFXMLNodeTypeAttribute - kCFXMLNodeTypeProcessingInstruction name of the target CFXMLProcessingInstructionInfo * - kCFXMLNodeTypeComment text of the comment NULL - kCFXMLNodeTypeText the text's contents NULL - kCFXMLNodeTypeCDATASection text of the CDATA NULL - kCFXMLNodeTypeDocumentFragment - kCFXMLNodeTypeEntity name of the entity CFXMLEntityInfo * - kCFXMLNodeTypeEntityReference name of the referenced entity CFXMLEntityReferenceInfo * - kCFXMLNodeTypeDocumentType name given as top-level element CFXMLDocumentTypeInfo * - kCFXMLNodeTypeWhitespace text of the whitespace NULL - kCFXMLNodeTypeNotation notation name CFXMLNotationInfo * - kCFXMLNodeTypeElementTypeDeclaration tag name CFXMLElementTypeDeclarationInfo * - kCFXMLNodeTypeAttributeListDeclaration tag name CFXMLAttributeListDeclarationInfo * -*/ - -CF_EXPORT -CFTypeID CFXMLNodeGetTypeID(void) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); - -/* Creates a new node based on xmlType, dataString, and additionalInfoPtr. version (together with xmlType) determines the expected structure of additionalInfoPtr */ -CF_EXPORT -CFXMLNodeRef CFXMLNodeCreate(CFAllocatorRef alloc, CFXMLNodeTypeCode xmlType, CFStringRef dataString, const void *additionalInfoPtr, CFIndex version) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); - -/* Creates a copy of origNode (which may not be NULL). */ -CF_EXPORT -CFXMLNodeRef CFXMLNodeCreateCopy(CFAllocatorRef alloc, CFXMLNodeRef origNode) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); - -CF_EXPORT -CFXMLNodeTypeCode CFXMLNodeGetTypeCode(CFXMLNodeRef node) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); - -CF_EXPORT -CFStringRef CFXMLNodeGetString(CFXMLNodeRef node) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); - -CF_EXPORT -const void *CFXMLNodeGetInfoPtr(CFXMLNodeRef node) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); - -CF_EXPORT -CFIndex CFXMLNodeGetVersion(CFXMLNodeRef node) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); - -/* CFXMLTreeRef */ - -/* Creates a childless, parentless tree from node */ -CF_EXPORT -CFXMLTreeRef CFXMLTreeCreateWithNode(CFAllocatorRef allocator, CFXMLNodeRef node) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); - -/* Extracts and returns the node stored in xmlTree */ -CF_EXPORT -CFXMLNodeRef CFXMLTreeGetNode(CFXMLTreeRef xmlTree) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); - -#undef __CFXMLNode_DEPRECATION_MSG - -CF_EXTERN_C_END -CF_IMPLICIT_BRIDGING_DISABLED - -#endif /* ! __COREFOUNDATION_CFXMLNODE__ */ - diff --git a/CoreFoundation/Parsing.subproj/CFXMLParser.c b/CoreFoundation/Parsing.subproj/CFXMLParser.c deleted file mode 100644 index e847a5b778..0000000000 --- a/CoreFoundation/Parsing.subproj/CFXMLParser.c +++ /dev/null @@ -1,2028 +0,0 @@ -/* CFXMLParser.c - Copyright (c) 1999-2018, Apple Inc. All rights reserved. - Responsibility: David Smith -*/ - -#include -#include -#include "CFXMLInputStream.h" -#include "CFUniChar.h" -#include "CFInternal.h" -#include "CFRuntime_Internal.h" - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - -struct __CFXMLParser { - CFRuntimeBase _cfBase; - - _CFXMLInputStream input; - - void **stack; - void **top; - UInt32 capacity; - - struct __CFXMLNode *node; // Our private node; we use it to report back information - CFMutableDictionaryRef argDict; - CFMutableArrayRef argArray; - - UInt32 options; - CFXMLParserCallBacks callBacks; - CFXMLParserContext context; - - CFXMLParserStatusCode status; - CFStringRef errorString; -}; - -static CFStringRef __CFXMLParserCopyDescription(CFTypeRef cf) { - const struct __CFXMLParser *parser = (const struct __CFXMLParser *)cf; - return CFStringCreateWithFormat(CFGetAllocator(cf), NULL, CFSTR(""), parser); -} - -static void __CFXMLParserDeallocate(CFTypeRef cf) { - struct __CFXMLParser *parser = (struct __CFXMLParser *)cf; - CFAllocatorRef alloc = CFGetAllocator(parser); - _freeInputStream(&(parser->input)); - if (parser->argDict) CFRelease(parser->argDict); - if (parser->argArray) CFRelease(parser->argArray); - if (parser->errorString) CFRelease(parser->errorString); - if (parser->node) CFRelease(parser->node); - CFAllocatorDeallocate(alloc, parser->stack); - if (parser->context.info && parser->context.release) { - parser->context.release(parser->context.info); - } -} - -const CFRuntimeClass __CFXMLParserClass = { - 0, - "CFXMLParser", - NULL, // init - NULL, // copy - __CFXMLParserDeallocate, - NULL, - NULL, - NULL, // - __CFXMLParserCopyDescription -}; - -CFTypeID CFXMLParserGetTypeID(void) { - return _kCFRuntimeIDCFXMLParser; -} - -void CFXMLParserGetContext(CFXMLParserRef parser, CFXMLParserContext *context) { - CFAssert1(parser != NULL, __kCFLogAssertion, "%s(): NULL parser not permitted", __PRETTY_FUNCTION__); - __CFGenericValidateType(parser, CFXMLParserGetTypeID()); - if (context) { - context->version = parser->context.version; - context->info = parser->context.info; - context->retain = parser->context.retain; - context->release = parser->context.release; - context->copyDescription = parser->context.copyDescription; - UNFAULT_CALLBACK(context->retain); - UNFAULT_CALLBACK(context->release); - UNFAULT_CALLBACK(context->copyDescription); - } -} - -void CFXMLParserGetCallBacks(CFXMLParserRef parser, CFXMLParserCallBacks *callBacks) { - __CFGenericValidateType(parser, CFXMLParserGetTypeID()); - if (callBacks) { - callBacks->version = parser->callBacks.version; - callBacks->createXMLStructure = parser->callBacks.createXMLStructure; - callBacks->addChild = parser->callBacks.addChild; - callBacks->endXMLStructure = parser->callBacks.endXMLStructure; - callBacks->resolveExternalEntity = parser->callBacks.resolveExternalEntity; - callBacks->handleError = parser->callBacks.handleError; - UNFAULT_CALLBACK(callBacks->createXMLStructure); - UNFAULT_CALLBACK(callBacks->addChild); - UNFAULT_CALLBACK(callBacks->endXMLStructure); - UNFAULT_CALLBACK(callBacks->resolveExternalEntity); - UNFAULT_CALLBACK(callBacks->handleError); - } -} - -CFURLRef CFXMLParserGetSourceURL(CFXMLParserRef parser) { - __CFGenericValidateType(parser, CFXMLParserGetTypeID()); - return parser->input.url; -} - -/* Returns the character index or line number of the current parse location */ -CFIndex CFXMLParserGetLocation(CFXMLParserRef parser) { - __CFGenericValidateType(parser, CFXMLParserGetTypeID()); - return _inputStreamCurrentLocation(&parser->input); -} - -CFIndex CFXMLParserGetLineNumber(CFXMLParserRef parser) { - __CFGenericValidateType(parser, CFXMLParserGetTypeID()); - return _inputStreamCurrentLine(&parser->input); -} - -/* Returns the top-most object returned by the createXMLStructure callback */ -void *CFXMLParserGetDocument(CFXMLParserRef parser) { - __CFGenericValidateType(parser, CFXMLParserGetTypeID()); - if (parser->capacity > 0) - return parser->stack[0]; - else - return NULL; -} - -CFXMLParserStatusCode CFXMLParserGetStatusCode(CFXMLParserRef parser) { - __CFGenericValidateType(parser, CFXMLParserGetTypeID()); - return parser->status; -} - -CFStringRef CFXMLParserCopyErrorDescription(CFXMLParserRef parser) { - __CFGenericValidateType(parser, CFXMLParserGetTypeID()); - return (CFStringRef)CFRetain(parser->errorString); -} - -void CFXMLParserAbort(CFXMLParserRef parser, CFXMLParserStatusCode errorCode, CFStringRef errorDescription) { - __CFGenericValidateType(parser, CFXMLParserGetTypeID()); - CFAssert1(errorCode > 0, __kCFLogAssertion, "%s(): errorCode must be greater than zero", __PRETTY_FUNCTION__); - CFAssert1(errorDescription != NULL, __kCFLogAssertion, "%s(): errorDescription may not be NULL", __PRETTY_FUNCTION__); - __CFGenericValidateType(errorDescription, CFStringGetTypeID()); - - parser->status = errorCode; - if (parser->errorString) CFRelease(parser->errorString); - parser->errorString = (CFStringRef)CFStringCreateCopy(kCFAllocatorSystemDefault, errorDescription); -} - - -static Boolean parseXML(CFXMLParserRef parser); -static Boolean parseComment(CFXMLParserRef parser, Boolean report); -static Boolean parseProcessingInstruction(CFXMLParserRef parser, Boolean report); -static Boolean parseInlineDTD(CFXMLParserRef parser); -static Boolean parseDTD(CFXMLParserRef parser); -static Boolean parsePhysicalEntityReference(CFXMLParserRef parser); -static Boolean parseCDSect(CFXMLParserRef parser); -static Boolean parseEntityReference(CFXMLParserRef parser, Boolean report); -static Boolean parsePCData(CFXMLParserRef parser); -static Boolean parseWhitespace(CFXMLParserRef parser); -static Boolean parseAttributeListDeclaration(CFXMLParserRef parser); -static Boolean parseNotationDeclaration(CFXMLParserRef parser); -static Boolean parseElementDeclaration(CFXMLParserRef parser); -static Boolean parseEntityDeclaration(CFXMLParserRef parser); -static Boolean parseExternalID(CFXMLParserRef parser, Boolean alsoAcceptPublicID, CFXMLExternalID *extID); -static Boolean parseCloseTag(CFXMLParserRef parser, CFStringRef tag); -static Boolean parseTagContent(CFXMLParserRef parser); -static Boolean parseTag(CFXMLParserRef parser); -static Boolean parseAttributes(CFXMLParserRef parser); -static Boolean parseAttributeValue(CFXMLParserRef parser, CFMutableStringRef str); - -// Utilities; may need to make these accessible to the property list parser to avoid code duplication -static void _CFReportError(CFXMLParserRef parser, CFXMLParserStatusCode errNum, const char *str); -static Boolean reportNewLeaf(CFXMLParserRef parser); // Assumes parser->node has been set and is ready to go -static void pushXMLNode(CFXMLParserRef parser, void *node); - -static CFXMLParserRef __CFXMLParserInit(CFAllocatorRef alloc, CFURLRef dataSource, CFOptionFlags options, CFDataRef xmlData, CFIndex version, CFXMLParserCallBacks *callBacks, CFXMLParserContext *context) { - struct __CFXMLParser *parser = (struct __CFXMLParser *)_CFRuntimeCreateInstance(alloc, CFXMLParserGetTypeID(), sizeof(struct __CFXMLParser) - sizeof(CFRuntimeBase), NULL); - struct __CFXMLNode *node = (struct __CFXMLNode *)_CFRuntimeCreateInstance(alloc, CFXMLNodeGetTypeID(), sizeof(struct __CFXMLNode) - sizeof(CFRuntimeBase), NULL); - UniChar *buf; - if (parser && node) { - alloc = CFGetAllocator(parser); - _initializeInputStream(&(parser->input), alloc, dataSource, xmlData); - parser->top = parser->stack; - parser->stack = NULL; - parser->capacity = 0; - - buf = (UniChar *)CFAllocatorAllocate(alloc, 128*sizeof(UniChar), 0); - parser->node = node; - parser->node->dataString = CFStringCreateMutableWithExternalCharactersNoCopy(alloc, buf, 0, 128, alloc); - parser->node->additionalData = NULL; - parser->node->version = version; - parser->argDict = NULL; // don't create these until necessary - parser->argArray = NULL; - - parser->options = options; - parser->callBacks = *callBacks; - - FAULT_CALLBACK((void **)&(parser->callBacks.createXMLStructure)); - FAULT_CALLBACK((void **)&(parser->callBacks.addChild)); - FAULT_CALLBACK((void **)&(parser->callBacks.endXMLStructure)); - FAULT_CALLBACK((void **)&(parser->callBacks.resolveExternalEntity)); - FAULT_CALLBACK((void **)&(parser->callBacks.handleError)); - - if (context) { - parser->context = *context; - if (parser->context.info && parser->context.retain) { - parser->context.retain(parser->context.info); - } - } else { - parser->context.version = 0; - parser->context.info = NULL; - parser->context.retain = NULL; - parser->context.release = NULL; - parser->context.copyDescription = NULL; - } - parser->status = kCFXMLStatusParseNotBegun; - parser->errorString = NULL; - } else { - if (parser) CFRelease(parser); - if (node) CFRelease(node); - parser = NULL; - } - return parser; -} - -CFXMLParserRef CFXMLParserCreate(CFAllocatorRef allocator, CFDataRef xmlData, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes, CFXMLParserCallBacks *callBacks, CFXMLParserContext *context) { - CFAssert1(xmlData != NULL, __kCFLogAssertion, "%s(): NULL data not permitted", __PRETTY_FUNCTION__); - __CFGenericValidateType(xmlData, CFDataGetTypeID()); - CFAssert1(dataSource == NULL || CFGetTypeID(dataSource) == CFURLGetTypeID(), __kCFLogAssertion, "%s(): dataSource is not a valid CFURL", __PRETTY_FUNCTION__); - CFAssert1(callBacks != NULL && callBacks->createXMLStructure != NULL && callBacks->addChild != NULL && callBacks->endXMLStructure != NULL, __kCFLogAssertion, "%s(): callbacks createXMLStructure, addChild, and endXMLStructure must all be non-NULL", __PRETTY_FUNCTION__); - CFAssert2(versionOfNodes <= 1, __kCFLogAssertion, "%s(): version number %ld is higher than supported by CFXMLParser", __PRETTY_FUNCTION__, versionOfNodes); - CFAssert1(versionOfNodes != 0, __kCFLogAssertion, "%s(): version number 0 is no longer supported by CFXMLParser", __PRETTY_FUNCTION__); - return __CFXMLParserInit(allocator, dataSource, parseOptions, xmlData, versionOfNodes, callBacks, context); -} - -CFXMLParserRef CFXMLParserCreateWithDataFromURL(CFAllocatorRef allocator, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes, CFXMLParserCallBacks *callBacks, CFXMLParserContext *context) { - CFAssert1(dataSource == NULL || CFGetTypeID(dataSource) == CFURLGetTypeID(), __kCFLogAssertion, "%s(): dataSource is not a valid CFURL", __PRETTY_FUNCTION__); - CFAssert1(callBacks != NULL && callBacks->createXMLStructure != NULL && callBacks->addChild != NULL && callBacks->endXMLStructure != NULL, __kCFLogAssertion, "%s(): callbacks createXMLStructure, addChild, and endXMLStructure must all be non-NULL", __PRETTY_FUNCTION__); - CFAssert2(versionOfNodes <= 1, __kCFLogAssertion, "%s(): version number %ld is higher than supported by CFXMLParser", __PRETTY_FUNCTION__, versionOfNodes); - CFAssert1(versionOfNodes != 0, __kCFLogAssertion, "%s(): version number 0 is no longer supported by CFXMLParser", __PRETTY_FUNCTION__); - - return __CFXMLParserInit(allocator, dataSource, parseOptions, NULL, versionOfNodes, callBacks, context); -} - -Boolean CFXMLParserParse(CFXMLParserRef parser) { - CFXMLDocumentInfo docData; - __CFGenericValidateType(parser, CFXMLParserGetTypeID()); - if (parser->status != kCFXMLStatusParseNotBegun) return false; - parser->status = kCFXMLStatusParseInProgress; - - if (!_openInputStream(&parser->input)) { - if (!parser->input.data) { - // couldn't load URL - parser->status = kCFXMLErrorNoData; - parser->errorString = CFStringCreateWithFormat(CFGetAllocator(parser), NULL, CFSTR("No data found at %@"), CFURLGetString(parser->input.url)); - } else { - // couldn't figure out the encoding - CFAssert(parser->input.encoding == kCFStringEncodingInvalidId, __kCFLogAssertion, "CFXMLParser internal error: input stream could not be opened"); - parser->status = kCFXMLErrorUnknownEncoding; - parser->errorString = CFStringCreateWithCString(CFGetAllocator(parser), "Encountered unknown encoding", kCFStringEncodingASCII); - } - if (parser->callBacks.handleError) { - INVOKE_CALLBACK3(parser->callBacks.handleError, parser, parser->status, parser->context.info); - } - return false; - } - - // Create the document - parser->stack = (void **)CFAllocatorAllocate(CFGetAllocator(parser), 16 * sizeof(void *), 0); - parser->capacity = 16; - parser->node->dataTypeID = kCFXMLNodeTypeDocument; - docData.encoding = _inputStreamGetEncoding(&parser->input); - docData.sourceURL = parser->input.url; - parser->node->additionalData = &docData; - parser->stack[0] = (void *)INVOKE_CALLBACK3(parser->callBacks.createXMLStructure, parser, parser->node, parser->context.info); - parser->top = parser->stack; - parser->node->additionalData = NULL; - - // Client may have called CFXMLParserAbort() during any callback, so we must always check to see if we have an error status after a callback - if (parser->status != kCFXMLStatusParseInProgress) { - _CFReportError(parser, parser->status, NULL); - return false; - } - return parseXML(parser); -} - -/* The next several functions are all intended to parse past a particular XML structure. They expect parser->curr to be set to the first content character of their structure (e.g. parseXMLComment expects parser->curr to be set just past ""), CFXMLNodeGetString(CFXMLTreeGetNode(tree))); - break; - case kCFXMLNodeTypeText: - CFStringAppend(str, CFXMLNodeGetString(CFXMLTreeGetNode(tree))); - break; - case kCFXMLNodeTypeCDATASection: - CFStringAppendFormat(str, NULL, CFSTR(""), CFXMLNodeGetString(CFXMLTreeGetNode(tree))); - break; - case kCFXMLNodeTypeDocumentFragment: - break; - case kCFXMLNodeTypeEntity: { - CFXMLEntityInfo *data = (CFXMLEntityInfo *)CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(tree)); - CFStringAppendCString(str, "entityType == kCFXMLEntityTypeParameter) { - CFStringAppend(str, CFSTR("% ")); - } - CFStringAppend(str, CFXMLNodeGetString(CFXMLTreeGetNode(tree))); - CFStringAppend(str, CFSTR(" ")); - if (data->replacementText) { - appendQuotedString(str, data->replacementText); - CFStringAppendCString(str, ">", kCFStringEncodingASCII); - } else { - appendExternalID(str, &(data->entityID)); - if (data->notationName) { - CFStringAppendFormat(str, NULL, CFSTR(" NDATA %@"), data->notationName); - } - CFStringAppendCString(str, ">", kCFStringEncodingASCII); - } - break; - } - case kCFXMLNodeTypeEntityReference: - { - CFXMLEntityTypeCode entityType = ((CFXMLEntityReferenceInfo *)CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(tree)))->entityType; - if (entityType == kCFXMLEntityTypeParameter) { - CFStringAppendFormat(str, NULL, CFSTR("%%%@;"), CFXMLNodeGetString(CFXMLTreeGetNode(tree))); - } else { - CFStringAppendFormat(str, NULL, CFSTR("&%@;"), CFXMLNodeGetString(CFXMLTreeGetNode(tree))); - } - break; - } - case kCFXMLNodeTypeDocumentType: - CFStringAppendCString(str, "externalID; - appendExternalID(str, extID); - } - CFStringAppendCString(str, " [", kCFStringEncodingASCII); - break; - case kCFXMLNodeTypeWhitespace: - CFStringAppend(str, CFXMLNodeGetString(CFXMLTreeGetNode(tree))); - break; - case kCFXMLNodeTypeNotation: { - CFXMLNotationInfo *data = (CFXMLNotationInfo *)CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(tree)); - CFStringAppendFormat(str, NULL, CFSTR("externalID)); - CFStringAppendCString(str, ">", kCFStringEncodingASCII); - break; - } - case kCFXMLNodeTypeElementTypeDeclaration: - CFStringAppendFormat(str, NULL, CFSTR(""), CFXMLNodeGetString(CFXMLTreeGetNode(tree)), ((CFXMLElementTypeDeclarationInfo *)CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(tree)))->contentDescription); - break; - case kCFXMLNodeTypeAttributeListDeclaration: { - CFXMLAttributeListDeclarationInfo *attListData = (CFXMLAttributeListDeclarationInfo *)CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(tree)); - CFIndex idx; - CFStringAppendCString(str, "numberOfAttributes; idx ++) { - CFXMLAttributeDeclarationInfo *attr = &(attListData->attributes[idx]); - CFStringAppendFormat(str, NULL, CFSTR("\n\t%@ %@ %@"), attr->attributeName, attr->typeString, attr->defaultString); - } - CFStringAppendCString(str, ">", kCFStringEncodingASCII); - break; - } - default: - CFAssert1(false, __kCFLogAssertion, "Encountered unexpected XMLDataTypeID %ld", CFXMLNodeGetTypeCode(CFXMLTreeGetNode(tree))); - } -} - -static void _CFAppendXMLEpilog(CFMutableStringRef str, CFXMLTreeRef tree) { - CFXMLNodeTypeCode typeID = CFXMLNodeGetTypeCode(CFXMLTreeGetNode(tree)); - if (typeID == kCFXMLNodeTypeElement) { - if (((CFXMLElementInfo *)CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(tree)))->isEmpty) return; - CFStringAppendFormat(str, NULL, CFSTR(""), CFXMLNodeGetString(CFXMLTreeGetNode(tree))); - } else if (typeID == kCFXMLNodeTypeDocumentType) { - CFIndex len = CFStringGetLength(str); - if (CFStringHasSuffix(str, CFSTR(" ["))) { - // There were no in-line DTD elements - CFStringDelete(str, CFRangeMake(len-2, 2)); - } else { - CFStringAppendCString(str, "]", kCFStringEncodingASCII); - } - CFStringAppendCString(str, ">", kCFStringEncodingASCII); - } -} - -#pragma GCC diagnostic pop diff --git a/CoreFoundation/PlugIn.subproj/CFBundle.c b/CoreFoundation/PlugIn.subproj/CFBundle.c index 951c7c89ee..c4182d7d6a 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle.c +++ b/CoreFoundation/PlugIn.subproj/CFBundle.c @@ -1,7 +1,7 @@ /* CFBundle.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -48,7 +48,6 @@ #endif -static void _CFBundleFlushBundleCachesAlreadyLocked(CFBundleRef bundle, Boolean alreadyLocked); static void _CFBundleUnloadScheduledBundles(void); #define LOG_BUNDLE_LOAD 0 @@ -199,6 +198,15 @@ CF_PRIVATE os_log_t _CFBundleLocalizedStringLogger(void) { return _log; } +CF_PRIVATE os_log_t _CFBundleLoadingLogger(void) { + static os_log_t _log; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _log = os_log_create("com.apple.CFBundle", "loading"); + }); + return _log; +} + #pragma mark - #if TARGET_OS_OSX @@ -436,7 +444,8 @@ CF_EXPORT CFBundleRef _CFBundleCreateIfMightBeBundle(CFAllocatorRef allocator, C return bundle; } -static void _CFBundleFlushBundleCachesAlreadyLocked(CFBundleRef bundle, Boolean alreadyLocked) { +CF_EXPORT void _CFBundleFlushBundleCaches(CFBundleRef bundle) { + __CFLock(&bundle->_lock); CFDictionaryRef oldInfoDict = bundle->_infoDict; CFTypeRef val; @@ -465,37 +474,15 @@ static void _CFBundleFlushBundleCachesAlreadyLocked(CFBundleRef bundle, Boolean CFRelease(bundle->_stringTable); bundle->_stringTable = NULL; } - CFBundleGetInfoDictionary(bundle); + _CFBundleRefreshInfoDictionaryAlreadyLocked(bundle); if (oldInfoDict) { if (!bundle->_infoDict) bundle->_infoDict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); val = CFDictionaryGetValue(oldInfoDict, _kCFBundlePrincipalClassKey); if (val) CFDictionarySetValue((CFMutableDictionaryRef)bundle->_infoDict, _kCFBundlePrincipalClassKey, val); CFRelease(oldInfoDict); } - _CFBundleFlushQueryTableCache(bundle); -} - -CF_EXPORT void _CFBundleFlushBundleCaches(CFBundleRef bundle) { - _CFBundleFlushBundleCachesAlreadyLocked(bundle, false); -} - -#if !(__OBJC__ || __OBJC2__) -static void _CFBundleArrayApplyFlushBundleCaches(const void *value, void *unusedContext) { - _CFBundleFlushBundleCachesAlreadyLocked((CFBundleRef)value, true); -} -#endif - -CF_PRIVATE void _CFBundleFlushAllBundleCaches(void) { - _CFMutexLock(&CFBundleGlobalDataLock); -#if __OBJC__ || __OBJC2__ - for (id value in (id)_allBundles) { - _CFBundleFlushBundleCachesAlreadyLocked((CFBundleRef)value, true); - } -#else - CFArrayApplyFunction(_allBundles, CFRangeMake(0, CFArrayGetCount(_allBundles)), &_CFBundleArrayApplyFlushBundleCaches, NULL); -#endif - _CFMutexUnlock(&CFBundleGlobalDataLock); + __CFUnlock(&bundle->_lock); } CFBundleRef CFBundleGetBundleWithIdentifier(CFStringRef bundleID) { @@ -651,9 +638,6 @@ const CFRuntimeClass __CFBundleClass = { __CFBundleCopyDescription }; -// From CFBundle_Resources.c -CF_PRIVATE void _CFBundleResourcesInitialize(void); - CFTypeID CFBundleGetTypeID(void) { return _kCFRuntimeIDCFBundle; } @@ -673,6 +657,7 @@ CFBundleRef _CFBundleGetExistingBundleWithBundleURL(CFURLRef bundleURL) { // First check the main bundle; otherwise fallback to the other tables CFBundleRef main = CFBundleGetMainBundle(); if (main->_url && newURL && CFEqual(main->_url, newURL)) { + CFRelease(newURL); return main; } @@ -731,27 +716,18 @@ static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, #endif bundle->_version = localVersion; - bundle->_infoDict = NULL; - bundle->_localInfoDict = NULL; - bundle->_searchLanguages = NULL; - bundle->_executablePath = NULL; - bundle->_developmentRegion = NULL; - bundle->_infoPlistUrl = NULL; - bundle->_developmentRegionCalculated = 0; + #if defined(BINARY_SUPPORT_DYLD) /* We'll have to figure it out later */ bundle->_binaryType = __CFBundleUnknownBinary; #elif defined(BINARY_SUPPORT_DLL) /* We support DLL only */ bundle->_binaryType = __CFBundleDLLBinary; - bundle->_hModule = NULL; #else /* We'll have to figure it out later */ bundle->_binaryType = __CFBundleUnknownBinary; #endif /* BINARY_SUPPORT_DYLD */ - bundle->_isLoaded = false; - bundle->_sharesStringsFiles = false; bundle->_isUnique = unique; #if TARGET_OS_MAC @@ -760,51 +736,33 @@ static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, (strncmp(buff + strlen(buff) - 10, ".framework", 10) == 0)) bundle->_sharesStringsFiles = true; #endif - bundle->_connectionCookie = NULL; - bundle->_handleCookie = NULL; - bundle->_imageCookie = NULL; - bundle->_moduleCookie = NULL; - - bundle->_resourceData._executableLacksResourceFork = false; - bundle->_resourceData._infoDictionaryFromResourceFork = false; - - bundle->_stringTable = NULL; - - bundle->_plugInData._isPlugIn = false; - bundle->_plugInData._loadOnDemand = false; - bundle->_plugInData._isDoingDynamicRegistration = false; - bundle->_plugInData._instanceCount = 0; - bundle->_plugInData._registeredFactory = false; - bundle->_plugInData._factories = NULL; - _CFMutexCreate(&(bundle->_bundleLoadingLock)); bundle->_lock = CFLockInit; - bundle->_resourceDirectoryContents = NULL; - - bundle->_localizations = NULL; - bundle->_lookedForLocalizations = false; - bundle->_queryLock = CFLockInit; - bundle->_queryTable = NULL; + CFURLRef absoURL = CFURLCopyAbsoluteURL(bundle->_url); bundle->_bundleBasePath = CFURLCopyFileSystemPath(absoURL, PLATFORM_PATH_STYLE); CFRelease(absoURL); bundle->_additionalResourceLock = CFLockInit; - bundle->_additionalResourceBundles = NULL; CFBundleGetInfoDictionary(bundle); // Do this so that we can use the dispatch_once on the ivar of this bundle safely OSMemoryBarrier(); + + // _CFBundleCreateUnique will never load plugins + if (!unique && doFinalProcessing) { + // We have to do this before adding the bundle to the tables, otherwise another thread coming along and fetching the bundle will get the bundle ref but the factories for PlugIn have not yet been registered. + _CFBundleInitPlugIn(bundle); + } if (addToTables) { _CFBundleAddToTables(bundle); } if (doFinalProcessing) { - _CFBundleInitPlugIn(bundle); } return bundle; @@ -839,14 +797,20 @@ CFArrayRef CFBundleCreateBundlesFromDirectory(CFAllocatorRef alloc, CFURLRef dir CFMutableArrayRef bundles = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks); CFArrayRef URLs = _CFCreateContentsOfDirectory(alloc, NULL, NULL, directoryURL, bundleType); if (URLs) { - CFIndex i, c = CFArrayGetCount(URLs); + CFIndex c = CFArrayGetCount(URLs); CFURLRef curURL; CFBundleRef curBundle; - for (i = 0; i < c; i++) { + for (CFIndex i = 0; i < c; i++) { curURL = (CFURLRef)CFArrayGetValueAtIndex(URLs, i); curBundle = CFBundleCreate(alloc, curURL); - if (curBundle) CFArrayAppendValue(bundles, curBundle); + if (curBundle) { + CFArrayAppendValue(bundles, curBundle); +#ifdef __clang_analyzer__ + // The contract of this function is that the bundles created inside here are 'not released'. + CFRelease(curBundle); +#endif + } } CFRelease(URLs); } @@ -1240,7 +1204,9 @@ Boolean _CFBundleLoadExecutableAndReturnError(CFBundleRef bundle, Boolean forceG } break; } - if (result && bundle->_plugInData._isPlugIn) _CFBundlePlugInLoaded(bundle); + if (result && bundle->_plugInData._isPlugIn) { + _CFBundlePlugInLoaded(bundle); + } if (!result && error) *error = localError; return result; } @@ -1397,12 +1363,14 @@ CF_PRIVATE void _CFBundleScheduleForUnloading(CFBundleRef bundle) { _bundlesToUnload = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, &nonRetainingCallbacks); } CFSetAddValue(_bundlesToUnload, bundle); + os_log_debug(_CFBundleLoadingLogger(), "Bundle %@ is now scheduled for unloading", bundle); _CFMutexUnlock(&CFBundleGlobalDataLock); } CF_PRIVATE void _CFBundleUnscheduleForUnloading(CFBundleRef bundle) { _CFMutexLock(&CFBundleGlobalDataLock); if (_bundlesToUnload) CFSetRemoveValue(_bundlesToUnload, bundle); + os_log_debug(_CFBundleLoadingLogger(), "Bundle %@ is now unscheduled for unloading", bundle); _CFMutexUnlock(&CFBundleGlobalDataLock); } @@ -1416,7 +1384,9 @@ static void _CFBundleUnloadScheduledBundles(void) { _scheduledBundlesAreUnloading = true; for (i = 0; i < c; i++) { // This will cause them to be removed from the set. (Which is why we copied all the values out of the set up front.) - CFBundleUnloadExecutable(unloadThese[i]); + CFBundleRef unloadMe = unloadThese[i]; + os_log_debug(_CFBundleLoadingLogger(), "Bundle %@ is about to be unloaded", unloadMe); + CFBundleUnloadExecutable(unloadMe); } _scheduledBundlesAreUnloading = false; CFAllocatorDeallocate(kCFAllocatorSystemDefault, unloadThese); @@ -1609,6 +1579,13 @@ static void _CFBundleEnsureBundlesUpToDateWithHint(CFStringRef hint) { } } +CFBundleRef _CFBundleGetBundleWithIdentifierAndLibraryName(CFStringRef bundleID, CFStringRef libraryName) { + if (libraryName) { + _CFBundleEnsureBundlesUpToDateWithHint(libraryName); + } + return _CFBundleGetFromTables(bundleID); +} + static void _CFBundleEnsureAllBundlesUpToDate(void) { // This method returns all the statically linked bundles. This includes the main bundle as well as any frameworks that the process was linked against at launch time. It does not include frameworks or opther bundles that were loaded dynamically. CFArrayRef imagePaths = NULL; diff --git a/CoreFoundation/PlugIn.subproj/CFBundle.h b/CoreFoundation/PlugIn.subproj/CFBundle.h index e6c11020f9..a9137a9724 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle.h +++ b/CoreFoundation/PlugIn.subproj/CFBundle.h @@ -1,5 +1,5 @@ /* CFBundle.h - Copyright (c) 1999-2018, Apple Inc. All rights reserved. + Copyright (c) 1999-2019, Apple Inc. All rights reserved. */ #if !defined(__COREFOUNDATION_CFBUNDLE__) @@ -311,7 +311,7 @@ typedef SInt16 CFBundleRefNum; #endif CF_EXPORT -CFBundleRefNum CFBundleOpenBundleResourceMap(CFBundleRef bundle); +CFBundleRefNum CFBundleOpenBundleResourceMap(CFBundleRef bundle) API_DEPRECATED("The Carbon Resource Manager is deprecated. This should only be used to access Resource Manager-style resources in old bundles.", macosx(10.0, 10.15)) API_UNAVAILABLE(ios, watchos, tvos); /* This function opens the non-localized and the localized resource files */ /* (if any) for the bundle, creates and makes current a single read-only */ /* resource map combining both, and returns a reference number for it. */ @@ -319,12 +319,12 @@ CFBundleRefNum CFBundleOpenBundleResourceMap(CFBundleRef bundle); /* and returns distinct reference numbers. */ CF_EXPORT -SInt32 CFBundleOpenBundleResourceFiles(CFBundleRef bundle, CFBundleRefNum *refNum, CFBundleRefNum *localizedRefNum); +SInt32 CFBundleOpenBundleResourceFiles(CFBundleRef bundle, CFBundleRefNum *refNum, CFBundleRefNum *localizedRefNum) API_DEPRECATED("The Carbon Resource Manager is deprecated. This should only be used to access Resource Manager-style resources in old bundles.", macosx(10.0, 10.15)) API_UNAVAILABLE(ios, watchos, tvos); /* Similar to CFBundleOpenBundleResourceMap(), except that it creates two */ /* separate resource maps and returns reference numbers for both. */ CF_EXPORT -void CFBundleCloseBundleResourceMap(CFBundleRef bundle, CFBundleRefNum refNum); +void CFBundleCloseBundleResourceMap(CFBundleRef bundle, CFBundleRefNum refNum) API_DEPRECATED("The Carbon Resource Manager is deprecated. This should only be used to access Resource Manager-style resources in old bundles.", macosx(10.0, 10.15)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXTERN_C_END CF_IMPLICIT_BRIDGING_DISABLED diff --git a/CoreFoundation/PlugIn.subproj/CFBundlePriv.h b/CoreFoundation/PlugIn.subproj/CFBundlePriv.h index 3892daec5d..0b031ce8d9 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundlePriv.h +++ b/CoreFoundation/PlugIn.subproj/CFBundlePriv.h @@ -1,7 +1,7 @@ /* CFBundlePriv.h - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -242,7 +242,11 @@ Boolean _CFBundleGetStringsFilesShared(CFBundleRef bundle); CF_EXPORT CFURLRef _CFBundleCopyFrameworkURLForExecutablePath(CFStringRef executablePath); -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) +/* This function returns the bundle with the identifier from already loaded (in-memory) bundles, after ensuring that any loaded (i.e. linked in the current process) library matching the specified name has its bundle loaded first. The libraryName should be the name of the executable in the bundle (e.g. "CoreFoundation"). If the libraryName doesn't match any library in the process, only bundle IDs of already-loaded bundles are considered, unlike CFBundleGetBundleWithIdentifier which will load the bundle for every library in the process when necessary to try and find the bundle identifier. Therefore, because this method avoids creating CFBundle instances for bundles as it searches, it can yield significantly faster lookups for a specific bundle when the name of the library is known, but when the bundle isn't already loaded and the library name does not match, it can return nil in cases where CFBundleGetBundleWithIdentifier wouldn't. */ +CF_EXPORT +CFBundleRef _CFBundleGetBundleWithIdentifierAndLibraryName(CFStringRef bundleID, CFStringRef libraryName) API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); + +#if TARGET_OS_OSX || TARGET_OS_IPHONE #include CF_EXPORT void _CFBundleSetupXPCBootstrap(xpc_object_t bootstrap) API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Binary.c b/CoreFoundation/PlugIn.subproj/CFBundle_Binary.c index 295d26a6cb..881605a43a 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Binary.c +++ b/CoreFoundation/PlugIn.subproj/CFBundle_Binary.c @@ -1,7 +1,7 @@ /* CFBundle_Binary.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -549,7 +549,8 @@ CF_EXPORT Boolean _CFBundleDlfcnPreflight(CFBundleRef bundle, CFErrorRef *error) } CF_PRIVATE Boolean _CFBundleDlfcnLoadBundle(CFBundleRef bundle, Boolean forceGlobal, CFErrorRef *error) { - CFErrorRef localError = NULL, *subError = (error ? &localError : NULL); + CFErrorRef localError = NULL; + CFErrorRef *subError = (error ? &localError : NULL); if (!bundle->_isLoaded) { CFURLRef executableURL = CFBundleCopyExecutableURL(bundle); char buff[CFMaxPathSize]; @@ -591,7 +592,11 @@ CF_PRIVATE Boolean _CFBundleDlfcnLoadBundle(CFBundleRef bundle, Boolean forceGlo } if (executableURL) CFRelease(executableURL); } - if (!bundle->_isLoaded && error) *error = localError; + if (!bundle->_isLoaded && error) { + *error = localError; + } else if (localError) { + CFRelease(localError); + } return bundle->_isLoaded; } @@ -625,6 +630,7 @@ CF_PRIVATE Boolean _CFBundleDlfcnLoadFramework(CFBundleRef bundle, CFErrorRef *e } else { CFStringRef executableString = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, buff); CFLog(__kCFLogBundle, CFSTR("Error loading %@: %@"), executableString, errorString ? errorString : CFSTR("(no additional info)")); + CFRelease(executableString); } if (errorString) CFRelease(errorString); } @@ -637,7 +643,11 @@ CF_PRIVATE Boolean _CFBundleDlfcnLoadFramework(CFBundleRef bundle, CFErrorRef *e } if (executableURL) CFRelease(executableURL); } - if (!bundle->_isLoaded && error) *error = localError; + if (!bundle->_isLoaded && error) { + *error = localError; + } else if (localError) { + CFRelease(localError); + } return bundle->_isLoaded; } diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_BinaryTypes.h b/CoreFoundation/PlugIn.subproj/CFBundle_BinaryTypes.h index 850d94f272..7528e80eb1 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_BinaryTypes.h +++ b/CoreFoundation/PlugIn.subproj/CFBundle_BinaryTypes.h @@ -1,7 +1,7 @@ /* CFBundle_BinaryTypes.h - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Grok.c b/CoreFoundation/PlugIn.subproj/CFBundle_Grok.c index 22bb7d74a0..cc791e5baa 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Grok.c +++ b/CoreFoundation/PlugIn.subproj/CFBundle_Grok.c @@ -1,7 +1,7 @@ /* CFBundle_Grok.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_InfoPlist.c b/CoreFoundation/PlugIn.subproj/CFBundle_InfoPlist.c index ec913fc5e1..1c57f1ca4a 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_InfoPlist.c +++ b/CoreFoundation/PlugIn.subproj/CFBundle_InfoPlist.c @@ -1,7 +1,7 @@ /* CFBundle_InfoPlist.c - Copyright (c) 2012-2018, Apple Inc. and the Swift project authors + Copyright (c) 2012-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -24,65 +24,6 @@ #endif -// The following strings are initialized 'later' (i.e., not at static initialization time) because static init time is too early for CFSTR to work, on platforms without constant CF strings -#if !__CONSTANT_CFSTRINGS__ - -#define _CFBundleNumberOfPlatforms 7 -static CFStringRef _CFBundleSupportedPlatforms[_CFBundleNumberOfPlatforms] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; -static const char *_CFBundleSupportedPlatformStrings[_CFBundleNumberOfPlatforms] = { "iphoneos", "macos", "windows", "linux", "freebsd", "solaris", "hpux" }; - -#define _CFBundleNumberOfProducts 3 -static CFStringRef _CFBundleSupportedProducts[_CFBundleNumberOfProducts] = { NULL, NULL, NULL }; -static const char *_CFBundleSupportedProductStrings[_CFBundleNumberOfProducts] = { "iphone", "ipod", "ipad" }; - -#define _CFBundleNumberOfiPhoneOSPlatformProducts 3 -static CFStringRef _CFBundleSupportediPhoneOSPlatformProducts[_CFBundleNumberOfiPhoneOSPlatformProducts] = { NULL, NULL, NULL }; -static const char *_CFBundleSupportediPhoneOSPlatformProductStrings[_CFBundleNumberOfiPhoneOSPlatformProducts] = { "iphone", "ipod", "ipad" }; - -CF_PRIVATE void _CFBundleResourcesInitialize() { - for (unsigned int i = 0; i < _CFBundleNumberOfPlatforms; i++) _CFBundleSupportedPlatforms[i] = CFStringCreateWithCString(kCFAllocatorSystemDefault, _CFBundleSupportedPlatformStrings[i], kCFStringEncodingUTF8); - - for (unsigned int i = 0; i < _CFBundleNumberOfProducts; i++) _CFBundleSupportedProducts[i] = CFStringCreateWithCString(kCFAllocatorSystemDefault, _CFBundleSupportedProductStrings[i], kCFStringEncodingUTF8); - - for (unsigned int i = 0; i < _CFBundleNumberOfiPhoneOSPlatformProducts; i++) _CFBundleSupportediPhoneOSPlatformProducts[i] = CFStringCreateWithCString(kCFAllocatorSystemDefault, _CFBundleSupportediPhoneOSPlatformProductStrings[i], kCFStringEncodingUTF8); -} - -#else - -#if TARGET_OS_IPHONE -// On iOS, we only support one platform -#define _CFBundleNumberOfPlatforms 1 -static const CFStringRef _CFBundleSupportedPlatforms[_CFBundleNumberOfPlatforms] = { CFSTR("iphoneos") }; -#else -// On other platforms, we support the following platforms -#define _CFBundleNumberOfPlatforms 7 -STATIC_CONST_STRING_DECL(_CFBundleSupportedPlatform_iphoneos, "iphoneos"); -STATIC_CONST_STRING_DECL(_CFBundleSupportedPlatform_macos, "macos"); -STATIC_CONST_STRING_DECL(_CFBundleSupportedPlatform_windows, "windows"); -STATIC_CONST_STRING_DECL(_CFBundleSupportedPlatform_linux, "linux"); -STATIC_CONST_STRING_DECL(_CFBundleSupportedPlatform_freebsd, "freebsd"); -STATIC_CONST_STRING_DECL(_CFBundleSupportedPlatform_solaris, "solaris"); -STATIC_CONST_STRING_DECL(_CFBundleSupportedPlatform_hpux, "hpux"); -static const CFStringRef _CFBundleSupportedPlatforms[_CFBundleNumberOfPlatforms] = { - _CFBundleSupportedPlatform_iphoneos, - _CFBundleSupportedPlatform_macos, - _CFBundleSupportedPlatform_windows, - _CFBundleSupportedPlatform_linux, - _CFBundleSupportedPlatform_freebsd, - _CFBundleSupportedPlatform_solaris, - _CFBundleSupportedPlatform_hpux, -}; -#endif - -#define _CFBundleNumberOfProducts 3 -static const CFStringRef _CFBundleSupportedProducts[_CFBundleNumberOfProducts] = { _CFBundleiPhoneDeviceName, _CFBundleiPodDeviceName, _CFBundleiPadDeviceName }; - -#define _CFBundleNumberOfiPhoneOSPlatformProducts 3 -static const CFStringRef _CFBundleSupportediPhoneOSPlatformProducts[_CFBundleNumberOfiPhoneOSPlatformProducts] = { _CFBundleiPhoneDeviceName, _CFBundleiPodDeviceName, _CFBundleiPadDeviceName }; - -CF_PRIVATE void _CFBundleResourcesInitialize() { } -#endif - #pragma mark - #pragma mark Product and Platform Getters - Exported @@ -123,13 +64,29 @@ CF_EXPORT CFStringRef _CFGetProductName(void) { size_t buflen = sizeof(buffer); int ret = sysctlbyname("hw.machine", buffer, &buflen, NULL, 0); if (0 == ret || (-1 == ret && ENOMEM == errno)) { +#if TARGET_OS_IOS if (6 <= buflen && 0 == memcmp(buffer, "iPhone", 6)) { _cfBundlePlatform = _CFBundleiPhoneDeviceName; - } else if (4 <= buflen && 0 == memcmp(buffer, "iPod", 4)) { + } else + if (4 <= buflen && 0 == memcmp(buffer, "iPod", 4)) { _cfBundlePlatform = _CFBundleiPodDeviceName; - } else if (4 <= buflen && 0 == memcmp(buffer, "iPad", 4)) { + } else + if (4 <= buflen && 0 == memcmp(buffer, "iPad", 4)) { _cfBundlePlatform = _CFBundleiPadDeviceName; - } else { + } +#elif TARGET_OS_WATCH + if (5 <= buflen && 0 == memcmp(buffer, "Watch", 5)) { + _cfBundlePlatform = _CFBundleAppleWatchDeviceName; + } +#elif TARGET_OS_TV + if (7 <= buflen && 0 == memcmp(buffer, "AppleTV", 7)) { + _cfBundlePlatform = _CFBundleAppleTVDeviceName; + } +#else + // Fallback path for other TARGET_OS_IPHONE child macros we don't know or care about + if (false) { } +#endif + else { const char *env = __CFgetenv("SIMULATOR_LEGACY_ASSET_SUFFIX"); if (env) { if (0 == strcmp(env, "iphone")) { @@ -145,7 +102,8 @@ CF_EXPORT CFStringRef _CFGetProductName(void) { } } } - if (!_cfBundlePlatform) _cfBundlePlatform = _CFBundleiPhoneDeviceName; // fallback + // This used to fall back to "iphone" on all unknown TARGET_OS_IPHONE platforms, but since that macro covers a wide swath of platforms, it now falls back to an empty string. + if (!_cfBundlePlatform) _cfBundlePlatform = CFSTR(""); // fallback } return _cfBundlePlatform; #endif @@ -172,8 +130,15 @@ CF_PRIVATE CFStringRef _CFBundleGetProductNameSuffix(void) { CF_PRIVATE CFStringRef _CFBundleGetPlatformNameSuffix(void) { #if TARGET_OS_OSX return _CFBundleMacOSXPlatformNameSuffix; -#elif TARGET_OS_IPHONE +#elif TARGET_OS_IOS return _CFBundleiPhoneOSPlatformNameSuffix; +#elif TARGET_OS_WATCH + return _CFBundleWatchOSPlatformNameSuffix; +#elif TARGET_OS_TV + return _CFBundletvOSPlatformNameSuffix; +#elif TARGET_OS_IPHONE + // Fallback path for other TARGET_OS_IPHONE targets we do not know about + return CFSTR(""); #elif TARGET_OS_WIN32 return _CFBundleWindowsPlatformNameSuffix; #elif DEPLOYMENT_TARGET_SOLARIS @@ -193,8 +158,15 @@ CF_PRIVATE CFStringRef _CFBundleGetPlatformNameSuffix(void) { CF_EXPORT CFStringRef _CFGetPlatformName(void) { #if TARGET_OS_OSX return _CFBundleMacOSXPlatformName; -#elif TARGET_OS_IPHONE +#elif TARGET_OS_IOS return _CFBundleiPhoneOSPlatformName; +#elif TARGET_OS_WATCH + return _CFBundleWatchOSPlatformName; +#elif TARGET_OS_TV + return _CFBundletvOSPlatformName; +#elif TARGET_OS_IPHONE + // Fallback path for other TARGET_OS_IPHONE targets we do not know about + return CFSTR(""); #elif TARGET_OS_WIN32 return _CFBundleWindowsPlatformName; #elif DEPLOYMENT_TARGET_SOLARIS @@ -237,61 +209,45 @@ CF_EXPORT CFStringRef _CFGetAlternatePlatformName(void) { #pragma mark - #pragma mark Product and Platform Suffix Processing - Internal -// TODO: Merge with below function, they do the same thing -static Boolean _isValidPlatformSuffix(CFStringRef suffix) { - for (CFIndex idx = 0; idx < _CFBundleNumberOfPlatforms; idx++) { - if (CFEqual(suffix, _CFBundleSupportedPlatforms[idx])) return true; - } - return false; -} - -// Returns true if the searchRange of the fileName is equal to a valid platform name (e.g., macos, iphoneos) +// Returns true if the searchRange of the fileName is equal to a valid platform name (e.g., macos, iphoneos). CF_PRIVATE Boolean _CFBundleSupportedPlatformName(CFStringRef fileName, CFRange searchRange) { - for (CFIndex i = 0; i < _CFBundleNumberOfPlatforms; i++) { - if (CFStringFindWithOptions(fileName, _CFBundleSupportedPlatforms[i], searchRange, kCFCompareAnchored, NULL)) { - return true; - } - } - return false; -} - -// TODO: Merge with below function, they do the same thing -static Boolean _isValidProductSuffix(CFStringRef suffix) { - for (CFIndex idx = 0; idx < _CFBundleNumberOfProducts; idx++) { - if (CFEqual(suffix, _CFBundleSupportedProducts[idx])) return true; - } +#if TARGET_OS_IOS + return CFStringFindWithOptions(fileName, _CFBundleiPhoneOSPlatformName, searchRange, kCFCompareAnchored, NULL); +#elif TARGET_OS_WATCH + return CFStringFindWithOptions(fileName, _CFBundleWatchOSPlatformName , searchRange, kCFCompareAnchored, NULL); +#elif TARGET_OS_TV + return CFStringFindWithOptions(fileName, _CFBundletvOSPlatformName, searchRange, kCFCompareAnchored, NULL); +#elif TARGET_OS_OSX + return CFStringFindWithOptions(fileName, _CFBundleMacOSXPlatformName, searchRange, kCFCompareAnchored, NULL); +#else + // This OS supports no platform suffixes return false; +#endif } // Returns true if the searchRange of the fileName is equal to a a valid product name (e.g., ipod, ipad) CF_PRIVATE Boolean _CFBundleSupportedProductName(CFStringRef fileName, CFRange searchRange) { - for (CFIndex i = 0; i < _CFBundleNumberOfProducts; i++) { - if (CFStringFindWithOptions(fileName, _CFBundleSupportedProducts[i], searchRange, kCFCompareAnchored, NULL)) { +#if TARGET_OS_IOS +#define _CFBundleNumberOfPlatforms 3 + static const CFIndex numberOfPlatforms = 3; + static const CFStringRef platforms[numberOfPlatforms] = { CFSTR("iphone"), CFSTR("ipad"), CFSTR("ipod") }; + for (CFIndex i = 0; i < numberOfPlatforms; i++) { + if (CFStringFindWithOptions(fileName, platforms[i], searchRange, kCFCompareAnchored, NULL)) { return true; } } return false; -} - -static Boolean _isValidiPhoneOSPlatformProductSuffix(CFStringRef suffix) { - for (CFIndex idx = 0; idx < _CFBundleNumberOfiPhoneOSPlatformProducts; idx++) { - if (CFEqual(suffix, _CFBundleSupportediPhoneOSPlatformProducts[idx])) return true; - } +#elif TARGET_OS_WATCH + return CFStringFindWithOptions(fileName, CFSTR("applewatch"), searchRange, kCFCompareAnchored, NULL); +#elif TARGET_OS_TV + return CFStringFindWithOptions(fileName, CFSTR("appletv"), searchRange, kCFCompareAnchored, NULL); +#elif TARGET_OS_OSX + // MacOS uses an empty string for a product name. We do not distinguish at this time between kinds of Mac products return false; -} - -static Boolean _isValidPlatformAndProductSuffixPair(CFStringRef platform, CFStringRef product) { - if (!platform && !product) return true; - if (!platform) { - return _isValidProductSuffix(product); - } - if (!product) { - return _isValidPlatformSuffix(platform); - } - if (CFEqual(platform, _CFBundleiPhoneOSPlatformName)) { - return _isValidiPhoneOSPlatformProductSuffix(product); - } +#else + // This OS supports no product suffixes return false; +#endif } static Boolean _isBlacklistedKey(CFStringRef keyName) { @@ -306,7 +262,7 @@ static Boolean _isBlacklistedKey(CFStringRef keyName) { return false; } -static Boolean _isOverrideKey(CFStringRef fullKey, CFStringRef *outBaseKey, CFStringRef *outPlatformSuffix, CFStringRef *outProductSuffix) { +static Boolean _isPlatformAndProductKey(CFStringRef fullKey, Boolean const useFallbackKey, CFStringRef *outBaseKey, CFStringRef *outPlatformSuffix, CFStringRef *outProductSuffix) { if (outBaseKey) { *outBaseKey = NULL; } @@ -316,8 +272,7 @@ static Boolean _isOverrideKey(CFStringRef fullKey, CFStringRef *outBaseKey, CFSt if (outProductSuffix) { *outProductSuffix = NULL; } - if (!fullKey) - return false; + if (!fullKey) return false; CFRange minusRange = CFStringFind(fullKey, CFSTR("-"), kCFCompareBackwards); CFRange tildeRange = CFStringFind(fullKey, CFSTR("~"), kCFCompareBackwards); if (minusRange.location == kCFNotFound && tildeRange.location == kCFNotFound) return false; @@ -340,27 +295,72 @@ static Boolean _isOverrideKey(CFStringRef fullKey, CFStringRef *outBaseKey, CFSt if (platformRange.location != kCFNotFound && platformRange.length < 1) return false; if (productRange.location != kCFNotFound && productRange.length < 1) return false; - CFStringRef platform = (platformRange.location != kCFNotFound) ? CFStringCreateWithSubstring(kCFAllocatorSystemDefault, fullKey, platformRange) : NULL; - CFStringRef product = (productRange.location != kCFNotFound) ? CFStringCreateWithSubstring(kCFAllocatorSystemDefault, fullKey, productRange) : NULL; - Boolean result = _isValidPlatformAndProductSuffixPair(platform, product); + Boolean isValidPlatformAndProduct = true; + if (platformRange.location == kCFNotFound && productRange.location != kCFNotFound) { + // With no platform, only check the product + isValidPlatformAndProduct = _CFBundleSupportedProductName(fullKey, productRange); + } else if (platformRange.location != kCFNotFound && productRange.location == kCFNotFound) { + // With no product, check only the platform + isValidPlatformAndProduct = _CFBundleSupportedPlatformName(fullKey, platformRange); + } else { + // Check both + isValidPlatformAndProduct = _CFBundleSupportedProductName(fullKey, productRange) && _CFBundleSupportedPlatformName(fullKey, platformRange); + } - if (result) { + + if (isValidPlatformAndProduct) { if (outBaseKey) { *outBaseKey = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, fullKey, baseKeyRange); } if (outPlatformSuffix) { + CFStringRef platform = (platformRange.location != kCFNotFound) ? CFStringCreateWithSubstring(kCFAllocatorSystemDefault, fullKey, platformRange) : NULL; *outPlatformSuffix = platform; - } else { - if (platform) CFRelease(platform); } if (outProductSuffix) { + CFStringRef product = (productRange.location != kCFNotFound) ? CFStringCreateWithSubstring(kCFAllocatorSystemDefault, fullKey, productRange) : NULL; *outProductSuffix = product; - } else { - if (product) CFRelease(product); } - } else { - if (platform) CFRelease(platform); - if (product) CFRelease(product); + } + return isValidPlatformAndProduct; +} + + +static Boolean _isValidSpecialCase(CFStringRef specialCase) { + // NOTE: Adding any special case to this check must be paired with adding the suffix in __addSuffixesToKeys + return false; +} + +// Special case keys replace base keys in Info.plist and InfoPlist.strings files. They take the form of KeyName#SpecialCase. The special cases are checked in _isValidSpecialCase. If this function returns true then the special case key exists and the replacement behavior should be triggered, according to whatever the criteria are. +static Boolean _isSpecialCaseKey(CFStringRef fullKey, CFStringRef *outBaseKey, CFStringRef *outSpecialCase) { + if (outBaseKey) { + *outBaseKey = NULL; + } + if (outSpecialCase) { + *outSpecialCase = NULL; + } + if (!fullKey) return false; + + CFRange hashRange = CFStringFind(fullKey, CFSTR("#"), kCFCompareBackwards); + if (hashRange.location == kCFNotFound) return false; + CFRange baseKeyRange = CFRangeMake(0, hashRange.location); + if (baseKeyRange.length < 1) return false; + CFIndex strLen = CFStringGetLength(fullKey); + CFIndex specialCaseStart = hashRange.location + hashRange.length; + CFRange specialCaseRange = CFRangeMake(specialCaseStart, strLen - specialCaseStart); + CFStringRef specialCase = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, fullKey, specialCaseRange); + Boolean result = _isValidSpecialCase(specialCase); + + if (result) { + if (outBaseKey) { + *outBaseKey = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, fullKey, baseKeyRange); + } + if (outSpecialCase) { + *outSpecialCase = specialCase; + } else if (specialCase) { + CFRelease(specialCase); + } + } else if (specialCase) { + CFRelease(specialCase); } return result; } @@ -377,7 +377,7 @@ static Boolean _isCurrentPlatformAndProduct(CFStringRef platform, CFStringRef pr return CFEqual(_CFGetProductName(), product) && CFEqual(_CFGetPlatformName(), platform); } -static CFArrayRef _CopySortedOverridesForBaseKey(CFStringRef keyName, CFDictionaryRef dict) { +static CFArrayRef _CopySortedOverridesForBaseKey(CFStringRef keyName, CFDictionaryRef dict, Boolean const useFallbackKey) { CFMutableArrayRef overrides = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks); CFStringRef keyNameWithBoth = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@-%@~%@"), keyName, _CFGetPlatformName(), _CFGetProductName()); CFStringRef keyNameWithProduct = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@~%@"), keyName, _CFGetProductName()); @@ -408,6 +408,7 @@ static CFArrayRef _CopySortedOverridesForBaseKey(CFStringRef keyName, CFDictiona break; } } + for (CFIndex idx = 0; idx < count; idx++) { if (CFEqual(keys[idx], keyName)) { CFArrayAppendValue(overrides, keys[idx]); @@ -438,11 +439,28 @@ CF_PRIVATE void _CFBundleInfoPlistProcessInfoDictionary(CFMutableDictionaryRef d CFDictionaryGetKeysAndValues(dict, keys, values); for (CFIndex idx = 0; idx < count; idx++) { - CFStringRef keyPlatformSuffix, keyProductSuffix, keyName; - if (_isOverrideKey((CFStringRef)keys[idx], &keyName, &keyPlatformSuffix, &keyProductSuffix)) { + CFStringRef keyPlatformSuffix, keyProductSuffix, keySpecialCaseSuffix, keyName; + CFStringRef key = (CFStringRef)keys[idx]; + + Boolean const useFallbackPlatformAndProductKey = false; + if (_isSpecialCaseKey(key, &keyName, &keySpecialCaseSuffix)) { + // This special case key overrides the base value + CFDictionarySetValue(dict, keyName, CFDictionaryGetValue(dict, key)); + + // Remove the special case key + CFDictionaryRemoveValue(dict, key); + + CFRelease(keyName); + if (keySpecialCaseSuffix) CFRelease(keySpecialCaseSuffix); + + } else if (_isPlatformAndProductKey(key, useFallbackPlatformAndProductKey, &keyName, &keyPlatformSuffix, &keyProductSuffix)) { CFArrayRef keysForBaseKey = NULL; - if (_isCurrentPlatformAndProduct(keyPlatformSuffix, keyProductSuffix) && !_isBlacklistedKey(keyName) && CFDictionaryContainsKey(dict, keys[idx])) { - keysForBaseKey = _CopySortedOverridesForBaseKey(keyName, dict); + + Boolean isSupportedPlatformAndProduct = _isCurrentPlatformAndProduct(keyPlatformSuffix, keyProductSuffix); + + + if (isSupportedPlatformAndProduct && !_isBlacklistedKey(keyName) && CFDictionaryContainsKey(dict, key)) { + keysForBaseKey = _CopySortedOverridesForBaseKey(keyName, dict, useFallbackPlatformAndProductKey); CFIndex keysForBaseKeyCount = CFArrayGetCount(keysForBaseKey); //make sure the other keys for this base key don't get released out from under us until we're done @@ -452,14 +470,15 @@ CF_PRIVATE void _CFBundleInfoPlistProcessInfoDictionary(CFMutableDictionaryRef d CFTypeRef highestPriorityKey = CFArrayGetValueAtIndex(keysForBaseKey, 0); CFDictionarySetValue(dict, keyName, CFDictionaryGetValue(dict, highestPriorityKey)); - //remove everything except the now-overridden key; this will cause them to fail the CFDictionaryContainsKey(dict, keys[idx]) check in the enclosing if() and not be reprocessed + //remove everything except the now-overridden key; this will cause them to fail the CFDictionaryContainsKey(dict, key) check in the enclosing if() and not be reprocessed for (CFIndex presentKeysIdx = 0; presentKeysIdx < keysForBaseKeyCount; presentKeysIdx++) { CFStringRef currentKey = (CFStringRef)CFArrayGetValueAtIndex(keysForBaseKey, presentKeysIdx); - if (!CFEqual(currentKey, keyName)) + if (!CFEqual(currentKey, keyName)) { CFDictionaryRemoveValue(dict, currentKey); + } } } else { - CFDictionaryRemoveValue(dict, keys[idx]); + CFDictionaryRemoveValue(dict, key); } @@ -977,8 +996,7 @@ static void _CFBundleInfoPlistFixupInfoDictionary(CFBundleRef bundle, CFMutableD } } -CFDictionaryRef CFBundleGetInfoDictionary(CFBundleRef bundle) { - __CFLock(&bundle->_lock); +CF_PRIVATE void _CFBundleRefreshInfoDictionaryAlreadyLocked(CFBundleRef bundle) { if (!bundle->_infoDict) { CFURLRef infoPlistUrl = NULL; bundle->_infoDict = _CFBundleCopyInfoDictionaryInDirectoryWithVersion(kCFAllocatorSystemDefault, bundle->_url, &infoPlistUrl, bundle->_version); @@ -990,8 +1008,12 @@ CFDictionaryRef CFBundleGetInfoDictionary(CFBundleRef bundle) { // Add or fixup any keys that will be expected later if (bundle->_infoDict) _CFBundleInfoPlistFixupInfoDictionary(bundle, (CFMutableDictionaryRef)bundle->_infoDict); } +} + +CFDictionaryRef CFBundleGetInfoDictionary(CFBundleRef bundle) { + __CFLock(&bundle->_lock); + _CFBundleRefreshInfoDictionaryAlreadyLocked(bundle); __CFUnlock(&bundle->_lock); - return bundle->_infoDict; } @@ -1068,8 +1090,7 @@ CFStringRef CFBundleGetIdentifier(CFBundleRef bundle) { return bundleID; } - -static void __addPlatformAndProductNamesToKeys(const void *value, void *context) { +static void __addSuffixesToKeys(const void *value, void *context) { CFMutableSetRef newKeys = (CFMutableSetRef)context; CFStringRef key = (CFStringRef)value; CFStringRef firstPartOfKey = NULL; @@ -1095,11 +1116,17 @@ static void __addPlatformAndProductNamesToKeys(const void *value, void *context) CFSetAddValue(newKeys, newKeyWithProduct); CFSetAddValue(newKeys, newKeyWithProductAndPlatform); - if (firstPartOfKey) CFRelease(firstPartOfKey); - if (restOfKey) CFRelease(restOfKey); CFRelease(newKeyWithPlatform); CFRelease(newKeyWithProduct); CFRelease(newKeyWithProductAndPlatform); + + // Add special case keys + CFStringRef overrideSpecialCase = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@#override%@%@"), firstPartOfKey, restOfKey ? CFSTR(":") : CFSTR(""), restOfKey ? restOfKey : CFSTR("")); + CFSetAddValue(newKeys, overrideSpecialCase); + CFRelease(overrideSpecialCase); + + if (firstPartOfKey) CFRelease(firstPartOfKey); + if (restOfKey) CFRelease(restOfKey); } // from CFUtilities.c @@ -1131,7 +1158,7 @@ static CFPropertyListRef _CFBundleCreateFilteredInfoPlistWithURL(CFURLRef infoPl CFDataRef infoPlistData = CFDataCreateWithBytesNoCopy(kCFAllocatorSystemDefault, (const UInt8 *)bytes, length, kCFAllocatorNull); // We need to include all possible variants of the platform/product combo as possible keys. CFMutableSetRef newKeyPaths = CFSetCreateMutable(kCFAllocatorSystemDefault, CFSetGetCount(keyPaths), &kCFTypeSetCallBacks); - CFSetApplyFunction(keyPaths, __addPlatformAndProductNamesToKeys, newKeyPaths); + CFSetApplyFunction(keyPaths, __addSuffixesToKeys, newKeyPaths); success = _CFPropertyListCreateFiltered(kCFAllocatorSystemDefault, infoPlistData, kCFPropertyListMutableContainers, newKeyPaths, &result, NULL); diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Internal.h b/CoreFoundation/PlugIn.subproj/CFBundle_Internal.h index 0d58b694df..6534b3e3ea 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Internal.h +++ b/CoreFoundation/PlugIn.subproj/CFBundle_Internal.h @@ -1,7 +1,7 @@ /* CFBundle_Internal.h - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -22,7 +22,6 @@ CF_EXTERN_C_BEGIN #define __kCFLogBundle 3 -#define __kCFLogPlugIn 3 #if TARGET_OS_WIN32 #define PLATFORM_PATH_STYLE kCFURLWindowsPathStyle @@ -70,6 +69,7 @@ typedef struct __CFPlugInData { Boolean _isPlugIn; Boolean _loadOnDemand; Boolean _isDoingDynamicRegistration; + Boolean _needsDynamicRegistration; Boolean _registeredFactory; UInt32 _instanceCount; CFMutableArrayRef _factories; @@ -89,7 +89,7 @@ struct __CFBundle { CFArrayRef _searchLanguages; __CFPBinaryType _binaryType; - Boolean _isLoaded; + _Atomic(Boolean) _isLoaded; uint8_t _version; Boolean _sharesStringsFiles; Boolean _isUnique; @@ -157,7 +157,6 @@ CF_EXPORT CFStringRef _CFGetPlatformName(void); CF_EXPORT CFStringRef _CFGetAlternatePlatformName(void); CF_PRIVATE void _CFBundleFlushQueryTableCache(CFBundleRef bundle); -CF_PRIVATE void _CFBundleFlushAllBundleCaches(void); CF_PRIVATE SInt32 _CFBundleCurrentArchitecture(void); CF_PRIVATE Boolean _CFBundleGetObjCImageInfo(CFBundleRef bundle, uint32_t *objcVersion, uint32_t *objcFlags); @@ -196,6 +195,8 @@ CF_PRIVATE CFStringRef _CFBundleCopyBundleDevelopmentRegionFromVersResource(CFBu CF_PRIVATE CFDictionaryRef _CFBundleCopyInfoDictionaryInExecutable(CFURLRef url); CF_PRIVATE CFArrayRef _CFBundleCopyArchitecturesForExecutable(CFURLRef url); +CF_PRIVATE void _CFBundleRefreshInfoDictionaryAlreadyLocked(CFBundleRef bundle); + CF_PRIVATE CFStringRef _CFBundleGetPlatformExecutablesSubdirectoryName(void); CF_PRIVATE void _CFBundleScheduleForUnloading(CFBundleRef bundle); @@ -244,12 +245,6 @@ extern void _CFBundleDeallocatePlugIn(CFBundleRef bundle); extern void _CFPlugInWillUnload(CFPlugInRef plugIn); -extern void _CFPlugInAddPlugInInstance(CFPlugInRef plugIn); -extern void _CFPlugInRemovePlugInInstance(CFPlugInRef plugIn); - -extern void _CFPlugInAddFactory(CFPlugInRef plugIn, _CFPFactoryRef factory); -extern void _CFPlugInRemoveFactory(CFPlugInRef plugIn, _CFPFactoryRef factory); - /* Strings for parsing bundle structure */ #define _CFBundleSupportFilesDirectoryName1 CFSTR("Support Files") #define _CFBundleSupportFilesDirectoryName2 CFSTR("Contents") @@ -344,6 +339,8 @@ extern void _CFPlugInRemoveFactory(CFPlugInRef plugIn, _CFPFactoryRef factory); #define _CFBundleMacOSXPlatformName CFSTR("macos") #define _CFBundleAlternateMacOSXPlatformName CFSTR("macosx") #define _CFBundleiPhoneOSPlatformName CFSTR("iphoneos") +#define _CFBundleWatchOSPlatformName CFSTR("watchos") +#define _CFBundletvOSPlatformName CFSTR("tvos") #define _CFBundleWindowsPlatformName CFSTR("windows") #define _CFBundleHPUXPlatformName CFSTR("hpux") #define _CFBundleSolarisPlatformName CFSTR("solaris") @@ -352,6 +349,8 @@ extern void _CFPlugInRemoveFactory(CFPlugInRef plugIn, _CFPFactoryRef factory); #define _CFBundleMacOSXPlatformNameSuffix CFSTR("-macos") #define _CFBundleAlternateMacOSXPlatformNameSuffix CFSTR("-macosx") #define _CFBundleiPhoneOSPlatformNameSuffix CFSTR("-iphoneos") +#define _CFBundleWatchOSPlatformNameSuffix CFSTR("-watchos") +#define _CFBundletvOSPlatformNameSuffix CFSTR("-tvos") #define _CFBundleWindowsPlatformNameSuffix CFSTR("-windows") #define _CFBundleHPUXPlatformNameSuffix CFSTR("-hpux") #define _CFBundleSolarisPlatformNameSuffix CFSTR("-solaris") @@ -379,9 +378,6 @@ CF_PRIVATE CFStringRef _CFBundleGetPlatformNameSuffix(void); #define _CFBundleSiblingResourceDirectoryExtension CFSTR("resources") -#define _CFBundleMacOSXInfoPlistPlatformName_OLD CFSTR("macos") -#define _CFBundleWindowsInfoPlistPlatformName_OLD CFSTR("win32") - CF_EXTERN_C_END #endif /* ! __COREFOUNDATION_CFBUNDLE_INTERNAL__ */ diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Locale.c b/CoreFoundation/PlugIn.subproj/CFBundle_Locale.c index 2a1a47b4b9..7ae492145a 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Locale.c +++ b/CoreFoundation/PlugIn.subproj/CFBundle_Locale.c @@ -1,7 +1,7 @@ /* CFBundle_Locale.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -16,9 +16,8 @@ #if __HAS_APPLE_ICU__ #include -#else -#include #endif +#include #include static CFStringRef _CFBundleCopyLanguageFoundInLocalizations(CFArrayRef localizations, CFStringRef language); @@ -300,6 +299,7 @@ CF_EXPORT Boolean CFBundleGetLocalizationInfoForLocalization(CFStringRef localiz } if (!languages) languages = _CFBundleCopyUserLanguages(); if (languages && CFArrayGetCount(languages) > 0) localizationName = (CFStringRef)CFArrayGetValueAtIndex(languages, 0); + if (languages) CFRelease(languages); } if (localizationName) { LangCode langCode = -1; @@ -489,7 +489,7 @@ CF_EXPORT CFArrayRef CFBundleCopyBundleLocalizations(CFBundleRef bundle) { // Cache the result. __CFLock(&bundle->_lock); - if (bundle->_lookedForLocalizations && result) { + if (bundle->_lookedForLocalizations) { // Another thread beat us to it. Release our result and return the existing answer. CFRelease(result); result = (CFArrayRef)CFRetain(bundle->_localizations); @@ -531,10 +531,22 @@ CF_EXPORT CFArrayRef CFBundleCopyLocalizationsForURL(CFURLRef url) { +static CFArrayRef _CFBundleUserLanguages = NULL; +static os_unfair_lock _CFBundleUserLanguagesLock = OS_UNFAIR_LOCK_INIT; + +CF_PRIVATE void _CFBundleFlushUserLanguagesCache() { + os_unfair_lock_lock(&_CFBundleUserLanguagesLock); + if (_CFBundleUserLanguages) { + CFRelease(_CFBundleUserLanguages); + _CFBundleUserLanguages = NULL; + } + os_unfair_lock_unlock(&_CFBundleUserLanguagesLock); +} + CF_PRIVATE CFArrayRef _CFBundleCopyUserLanguages() { - static CFArrayRef _CFBundleUserLanguages = NULL; - static dispatch_once_t once = 0; - dispatch_once(&once, ^{ + os_unfair_lock_lock(&_CFBundleUserLanguagesLock); + + if (_CFBundleUserLanguages == NULL) { CFArrayRef preferencesArray = NULL; if (__CFAppleLanguages) { CFDataRef data; @@ -559,16 +571,19 @@ CF_PRIVATE CFArrayRef _CFBundleCopyUserLanguages() { _CFBundleUserLanguages = NULL; } if (preferencesArray) CFRelease(preferencesArray); - }); + } + + CFArrayRef result = NULL; if (_CFBundleUserLanguages) { - CFRetain(_CFBundleUserLanguages); - return _CFBundleUserLanguages; - } else { - return NULL; + result = CFRetain(_CFBundleUserLanguages); } + os_unfair_lock_unlock(&_CFBundleUserLanguagesLock); + + return result; } + CF_EXPORT void _CFBundleGetLanguageAndRegionCodes(SInt32 *languageCode, SInt32 *regionCode) { // an attempt to answer the question, "what language are we running in?" // note that the question cannot be answered fully since it may depend on the bundle @@ -678,7 +693,7 @@ static CFMutableArrayRef _CFBundleCreateMutableArrayOfFallbackLanguages(CFArrayR CFIndex listCount = CFArrayGetCount(list); if (listCount == 0) return (char *)NULL; - size_t bufferSize = listCount * sizeof(char) * (UALANGDATA_CODELEN + 1); // entries are only allowed to be UALANGDATA_CODELEN long, and we null terminate each one + size_t bufferSize = listCount * sizeof(char) * ULOC_FULLNAME_CAPACITY; // entries are only allowed to be ULOC_FULLNAME_CAPACITY long with terminating null. char *stringBuffer = malloc(bufferSize); if (!stringBuffer) return (char *)NULL; @@ -691,7 +706,7 @@ static CFMutableArrayRef _CFBundleCreateMutableArrayOfFallbackLanguages(CFArrayR // The max size available is -1 because we need to reserve space for the last NULL byte. CFIndex theLocalizationLength = CFStringGetLength(theLocalization); - CFIndex charactersConverted = CFStringGetBytes(theLocalization, CFRangeMake(0, theLocalizationLength), kCFStringEncodingUTF8, 0, false, (UInt8 *)strings, last - strings - 1, &usedLength); + CFIndex charactersConverted = CFStringGetBytes(theLocalization, CFRangeMake(0, MIN(theLocalizationLength, ULOC_FULLNAME_CAPACITY - 1)), kCFStringEncodingASCII, 0, false, (UInt8 *)strings, last - strings - 1, &usedLength); if (charactersConverted == theLocalizationLength) { stringPointers[i] = strings; diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Main.c b/CoreFoundation/PlugIn.subproj/CFBundle_Main.c index 5073940df3..c8e14800bd 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Main.c +++ b/CoreFoundation/PlugIn.subproj/CFBundle_Main.c @@ -1,7 +1,7 @@ /* CFBundle_Main.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Resources.c b/CoreFoundation/PlugIn.subproj/CFBundle_Resources.c index de49b5e926..df3f127cdc 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Resources.c +++ b/CoreFoundation/PlugIn.subproj/CFBundle_Resources.c @@ -1,7 +1,7 @@ /* CFBundle_Resources.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -9,6 +9,7 @@ */ #include "CFBundle_Internal.h" +#include "CFBundle_SplitFileName.h" #include #include #include @@ -366,13 +367,6 @@ static void _CFBundleAddValueForType(CFStringRef type, CFMutableDictionaryRef qu } } -typedef enum { - _CFBundleFileVersionNoProductNoPlatform = 1, - _CFBundleFileVersionWithProductNoPlatform, - _CFBundleFileVersionNoProductWithPlatform, - _CFBundleFileVersionWithProductWithPlatform, - _CFBundleFileVersionUnmatched -} _CFBundleFileVersion; static _CFBundleFileVersion _CFBundleCheckFileProductAndPlatform(CFStringRef file, CFRange searchRange, CFStringRef product, CFStringRef platform) { @@ -416,125 +410,11 @@ static _CFBundleFileVersion _CFBundleCheckFileProductAndPlatform(CFStringRef fil return version; } -static _CFBundleFileVersion _CFBundleVersionForFileName(CFStringRef fileName, CFStringRef expectedProduct, CFStringRef expectedPlatform, CFRange *outProductRange, CFRange *outPlatformRange) { - // Search for a product name, e.g.: foo~iphone.jpg or bar~ipad - Boolean foundProduct = false; - Boolean foundPlatform = false; - CFIndex fileNameLen = CFStringGetLength(fileName); - CFRange productRange; - CFRange platformRange; - - CFIndex dotLocation = fileNameLen; - for (CFIndex i = fileNameLen - 1; i > 0; i--) { - UniChar c = CFStringGetCharacterAtIndex(fileName, i); - if (c == '.') { - dotLocation = i; - } -#if TARGET_OS_IPHONE - // Product names are only supported on iOS - // ref docs here: "iOS Supports Device-Specific Resources" in "Resource Programming Guide" - else if (c == '~' && !foundProduct) { - productRange = CFRangeMake(i, dotLocation - i); - foundProduct = (CFStringCompareWithOptions(fileName, expectedProduct, productRange, kCFCompareAnchored) == kCFCompareEqualTo); - if (foundProduct && outProductRange) *outProductRange = productRange; - } -#endif - else if (c == '-') { - if (foundProduct) { - platformRange = CFRangeMake(i, productRange.location - i); - } else { - platformRange = CFRangeMake(i, dotLocation - i); - } - foundPlatform = (CFStringCompareWithOptions(fileName, expectedPlatform, platformRange, kCFCompareAnchored) == kCFCompareEqualTo); - if (foundPlatform && outPlatformRange) *outPlatformRange = platformRange; - break; - } - } - - _CFBundleFileVersion version; - if (foundPlatform && foundProduct) { - version = _CFBundleFileVersionWithProductWithPlatform; - } else if (foundPlatform) { - version = _CFBundleFileVersionNoProductWithPlatform; - } else if (foundProduct) { - version = _CFBundleFileVersionWithProductNoPlatform; - } else { - version = _CFBundleFileVersionNoProductNoPlatform; - } - return version; -} - -// Splits up a string into its various parts. Note that the out-types must be released by the caller if they exist. -static void _CFBundleSplitFileName(CFStringRef fileName, CFStringRef *noProductOrPlatform, CFStringRef *endType, CFStringRef *startType, CFStringRef expectedProduct, CFStringRef expectedPlatform, _CFBundleFileVersion *version) { - CFIndex fileNameLen = CFStringGetLength(fileName); - - if (endType || startType) { - // Search for the type from the end (type defined as everything after the last '.') - // e.g., a file name like foo.jpg has a type of 'jpg' - Boolean foundDot = false; - uint16_t dotLocation = 0; - for (CFIndex i = fileNameLen; i > 0; i--) { - if (CFStringGetCharacterAtIndex(fileName, i - 1) == '.') { - foundDot = true; - dotLocation = i - 1; - break; - } - } - - if (foundDot && dotLocation != fileNameLen - 1) { - if (endType) *endType = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, fileName, CFRangeMake(dotLocation + 1, CFStringGetLength(fileName) - dotLocation - 1)); - } - - // Search for the type from the beginning (type defined as everything after the first '.') - // e.g., a file name like foo.jpg.gz has a type of 'jpg.gz' - if (startType) { - for (CFIndex i = 0; i < fileNameLen; i++) { - if (CFStringGetCharacterAtIndex(fileName, i) == '.') { - // no need to create this again if it's the same as previous - if (i != dotLocation) { - *startType = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, fileName, CFRangeMake(i + 1, CFStringGetLength(fileName) - i - 1)); - } - break; - } - } - } - } - - CFRange productRange, platformRange; - *version = _CFBundleVersionForFileName(fileName, expectedProduct, expectedPlatform, &productRange, &platformRange); - - Boolean foundPlatform = (*version == _CFBundleFileVersionNoProductWithPlatform || *version == _CFBundleFileVersionWithProductWithPlatform); - Boolean foundProduct = (*version == _CFBundleFileVersionWithProductNoPlatform || *version == _CFBundleFileVersionWithProductWithPlatform); - // Create a string that excludes both platform and product name - // e.g., foo-iphone~iphoneos.jpg -> foo.jpg - if (foundPlatform || foundProduct) { - CFMutableStringRef fileNameScratch = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, fileName); - CFIndex start, length = 0; - - // Because the platform always comes first and is immediately followed by product if it exists, we'll use the platform start location as the start of our range to delete. - if (foundPlatform) { - start = platformRange.location; - } else { - start = productRange.location; - } - - if (foundPlatform && foundProduct) { - length = platformRange.length + productRange.length; - } else if (foundPlatform) { - length = platformRange.length; - } else if (foundProduct) { - length = productRange.length; - } - CFStringDelete(fileNameScratch, CFRangeMake(start, length)); - *noProductOrPlatform = (CFStringRef)fileNameScratch; - } -} - static Boolean _CFBundleReadDirectory(CFStringRef pathOfDir, CFStringRef subdirectory, CFMutableArrayRef allFiles, Boolean hasFileAdded, CFMutableDictionaryRef queryTable, CFMutableDictionaryRef typeDir, CFMutableDictionaryRef addedTypes, Boolean firstLproj, CFStringRef lprojName) { CFStringRef product = _CFBundleGetProductNameSuffix(); CFStringRef platform = _CFBundleGetPlatformNameSuffix(); - + CFArrayRef stuffToPrefix = NULL; if (lprojName && subdirectory) { CFTypeRef thingsInTheArray[2] = {lprojName, subdirectory}; @@ -544,12 +424,14 @@ static Boolean _CFBundleReadDirectory(CFStringRef pathOfDir, CFStringRef subdire } else if (subdirectory) { stuffToPrefix = CFArrayCreate(kCFAllocatorSystemDefault, (const void **)&subdirectory, 1, &kCFTypeArrayCallBacks); } - + + Boolean searchForFallbackProduct = false; + // If this file is a directory, the path needs to include a trailing slash so we can later create the right kind of CFURL object _CFIterateDirectory(pathOfDir, true, stuffToPrefix, ^Boolean(CFStringRef fileName, CFStringRef pathToFile, uint8_t fileType) { CFStringRef startType = NULL, endType = NULL, noProductOrPlatform = NULL; _CFBundleFileVersion fileVersion; - _CFBundleSplitFileName(fileName, &noProductOrPlatform, &endType, &startType, product, platform, &fileVersion); + _CFBundleSplitFileName(fileName, &noProductOrPlatform, &endType, &startType, product, platform, searchForFallbackProduct, &fileVersion); // put it into all file array if (!hasFileAdded) { @@ -1027,7 +909,7 @@ static CFTypeRef _copyResourceURLsFromBundle(CFBundleRef bundle, CFURLRef bundle // Research shows that by far the most common scenario is to pass in a bundle object, a resource name, and a resource type, using the default localization. // It is probably the case that more than a few resources will be looked up, making the cost of a readdir less than repeated stats. But it is a relative waste of memory to create strings for every file name in the bundle, especially since those are not what are returned to the caller (URLs are). So, an idea: cache the existence of the most common file names (Info.plist, en.lproj, etc) instead of creating entries for them. If other resources are requested, then go ahead and do the readdir and cache the rest of the file names. // Another idea: if you want caching, you should create a bundle object. Otherwise we'll happily readdir each time. -CF_EXPORT CFTypeRef _CFBundleCopyFindResources(CFBundleRef bundle, CFURLRef bundleURL, CFArrayRef _unused_pass_null_, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subPath, CFStringRef lproj, Boolean returnArray, Boolean localized, Boolean (^predicate)(CFStringRef filename, Boolean *stop)) +CF_EXPORT CFTypeRef _Nullable _CFBundleCopyFindResources(CFBundleRef bundle, CFURLRef bundleURL, CFArrayRef _unused_pass_null_, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subPath, CFStringRef lproj, Boolean returnArray, Boolean localized, Boolean (^predicate)(CFStringRef filename, Boolean *stop)) { CFTypeRef returnValue = NULL; diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_SplitFileName.c b/CoreFoundation/PlugIn.subproj/CFBundle_SplitFileName.c new file mode 100644 index 0000000000..9c8bdfbfe9 --- /dev/null +++ b/CoreFoundation/PlugIn.subproj/CFBundle_SplitFileName.c @@ -0,0 +1,137 @@ +/* CFBundle_SplitFileName.c + Copyright (c) 2019, Apple Inc. All rights reserved. +*/ + +#include "CFBundle_SplitFileName.h" + +#include + +#define _CFBundleiPadDeviceNameSuffix CFSTR("~ipad") + +static Boolean _CFBundleFileVersionFoundMatchingPlatform(_CFBundleFileVersion version) { + return version == _CFBundleFileVersionNoProductWithPlatform || version == _CFBundleFileVersionWithProductWithPlatform; +} + +static Boolean _CFBundleFileVersionFoundMatchingProduct(_CFBundleFileVersion version) { + return version == _CFBundleFileVersionWithProductNoPlatform || version == _CFBundleFileVersionWithProductWithPlatform; +} + +static _CFBundleFileVersion _CFBundleVersionForFileName(CFStringRef fileName, Boolean searchProduct, CFStringRef expectedProduct, CFStringRef expectedPlatform, CFRange *outProductRange, CFRange *outPlatformRange) { + // Search for a product name, e.g.: foo~iphone.jpg or bar~ipad + Boolean foundProduct = false; + Boolean foundPlatform = false; + CFIndex fileNameLen = CFStringGetLength(fileName); + CFRange productRange; + CFRange platformRange; + + CFIndex dotLocation = fileNameLen; + for (CFIndex i = fileNameLen - 1; i > 0; i--) { + UniChar c = CFStringGetCharacterAtIndex(fileName, i); + if (c == '.') { + dotLocation = i; + } + + if (searchProduct && c == '~' && !foundProduct) { + productRange = CFRangeMake(i, dotLocation - i); + foundProduct = (CFStringCompareWithOptions(fileName, expectedProduct, productRange, kCFCompareAnchored) == kCFCompareEqualTo); + if (foundProduct && outProductRange) *outProductRange = productRange; + } else if (c == '-') { + if (foundProduct) { + platformRange = CFRangeMake(i, productRange.location - i); + } else { + platformRange = CFRangeMake(i, dotLocation - i); + } + foundPlatform = (CFStringCompareWithOptions(fileName, expectedPlatform, platformRange, kCFCompareAnchored) == kCFCompareEqualTo); + if (foundPlatform && outPlatformRange) *outPlatformRange = platformRange; + break; + } + } + + _CFBundleFileVersion version; + if (foundPlatform && foundProduct) { + version = _CFBundleFileVersionWithProductWithPlatform; + } else if (foundPlatform) { + version = _CFBundleFileVersionNoProductWithPlatform; + } else if (foundProduct) { + version = _CFBundleFileVersionWithProductNoPlatform; + } else { + version = _CFBundleFileVersionNoProductNoPlatform; + } + return version; +} + +// Splits up a string into its various parts. Note that the out-types must be released by the caller if they exist. +CF_PRIVATE void _CFBundleSplitFileName(CFStringRef fileName, CFStringRef *noProductOrPlatform, CFStringRef *endType, CFStringRef *startType, CFStringRef expectedProduct, CFStringRef expectedPlatform, Boolean searchForFallbackProduct, _CFBundleFileVersion *version) { + CFIndex fileNameLen = CFStringGetLength(fileName); + + if (endType || startType) { + // Search for the type from the end (type defined as everything after the last '.') + // e.g., a file name like foo.jpg has a type of 'jpg' + Boolean foundDot = false; + uint16_t dotLocation = 0; + for (CFIndex i = fileNameLen; i > 0; i--) { + if (CFStringGetCharacterAtIndex(fileName, i - 1) == '.') { + foundDot = true; + dotLocation = i - 1; + break; + } + } + + if (foundDot && dotLocation != fileNameLen - 1) { + if (endType) *endType = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, fileName, CFRangeMake(dotLocation + 1, CFStringGetLength(fileName) - dotLocation - 1)); + } + + // Search for the type from the beginning (type defined as everything after the first '.') + // e.g., a file name like foo.jpg.gz has a type of 'jpg.gz' + if (startType) { + for (CFIndex i = 0; i < fileNameLen; i++) { + if (CFStringGetCharacterAtIndex(fileName, i) == '.') { + // no need to create this again if it's the same as previous + if (i != dotLocation) { + *startType = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, fileName, CFRangeMake(i + 1, CFStringGetLength(fileName) - i - 1)); + } + break; + } + } + } + } + + CFRange productRange, platformRange; + + // Product names are only supported on iOS. + // Ref docs here: "iOS Supports Device-Specific Resources" in "Resource Programming Guide" +#if TARGET_OS_IPHONE + Boolean searchForProductName = true; +#else + Boolean searchForProductName = false; +#endif + *version = _CFBundleVersionForFileName(fileName, searchForProductName, expectedProduct, expectedPlatform, &productRange, &platformRange); + + Boolean foundPlatform = _CFBundleFileVersionFoundMatchingPlatform(*version); + Boolean foundProduct = _CFBundleFileVersionFoundMatchingProduct(*version); + + + // Create a string that excludes both platform and product name + // e.g., foo-iphone~iphoneos.jpg -> foo.jpg + if (foundPlatform || foundProduct) { + CFMutableStringRef fileNameScratch = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, fileName); + CFIndex start, length = 0; + + // Because the platform always comes first and is immediately followed by product if it exists, we'll use the platform start location as the start of our range to delete. + if (foundPlatform) { + start = platformRange.location; + } else { + start = productRange.location; + } + + if (foundPlatform && foundProduct) { + length = platformRange.length + productRange.length; + } else if (foundPlatform) { + length = platformRange.length; + } else if (foundProduct) { + length = productRange.length; + } + CFStringDelete(fileNameScratch, CFRangeMake(start, length)); + *noProductOrPlatform = (CFStringRef)fileNameScratch; + } +} diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_SplitFileName.h b/CoreFoundation/PlugIn.subproj/CFBundle_SplitFileName.h new file mode 100644 index 0000000000..89af5eebf4 --- /dev/null +++ b/CoreFoundation/PlugIn.subproj/CFBundle_SplitFileName.h @@ -0,0 +1,20 @@ +/* CFBundle_SplitFileName.h + Copyright (c) 2019, Apple Inc. All rights reserved. +*/ + +#ifndef CFBundle_SplitFileName_h +#define CFBundle_SplitFileName_h + +#include + +typedef enum { + _CFBundleFileVersionNoProductNoPlatform = 1, + _CFBundleFileVersionWithProductNoPlatform, + _CFBundleFileVersionNoProductWithPlatform, + _CFBundleFileVersionWithProductWithPlatform, + _CFBundleFileVersionUnmatched +} _CFBundleFileVersion; + +CF_PRIVATE void _CFBundleSplitFileName(CFStringRef fileName, CFStringRef *noProductOrPlatform, CFStringRef *endType, CFStringRef *startType, CFStringRef expectedProduct, CFStringRef expectedPlatform, Boolean searchForFallbackProduct, _CFBundleFileVersion *version); + +#endif /* CFBundle_SplitFileName_h */ diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Strings.c b/CoreFoundation/PlugIn.subproj/CFBundle_Strings.c index 7599957310..fd72f09378 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Strings.c +++ b/CoreFoundation/PlugIn.subproj/CFBundle_Strings.c @@ -1,7 +1,7 @@ /* CFBundle_Strings.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/PlugIn.subproj/CFPlugIn.c b/CoreFoundation/PlugIn.subproj/CFPlugIn.c index db278107a0..649e351bf5 100644 --- a/CoreFoundation/PlugIn.subproj/CFPlugIn.c +++ b/CoreFoundation/PlugIn.subproj/CFPlugIn.c @@ -1,7 +1,7 @@ /* CFPlugIn.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -10,6 +10,39 @@ #include "CFBundle_Internal.h" #include "CFInternal.h" +#include "CFRuntime_Internal.h" + + +// MARK: - Declarations + +static os_log_t _CFBundlePluginLogger(void); + +static _CFPFactoryRef _CFPFactoryCommonCreateLocked(CFAllocatorRef allocator, CFUUIDRef factoryID); + +static _CFPFactoryRef _CFPFactoryFindLocked(CFUUIDRef factoryID, Boolean enabled); + +static CFUUIDRef _CFPFactoryCopyFactoryIDLocked(_CFPFactoryRef factory); +static CFPlugInRef _CFPFactoryCopyPlugInLocked(_CFPFactoryRef factory); + +static void _CFPlugInRegisterFactoryFunctionByNameLocked(CFUUIDRef factoryID, CFPlugInRef plugIn, CFStringRef functionName); +static void _CFPlugInRegisterPlugInTypeLocked(CFUUIDRef factoryID, CFUUIDRef typeID); + +static void *_CFPFactoryCreateInstanceLocked(CFAllocatorRef allocator, _CFPFactoryRef factory, CFUUIDRef typeID); +static void _CFPFactoryDisableLocked(_CFPFactoryRef factory); + +static void _CFPFactoryAddTypeLocked(_CFPFactoryRef factory, CFUUIDRef typeID); +static void _CFPFactoryRemoveTypeLocked(_CFPFactoryRef factory, CFUUIDRef typeID); +static Boolean _CFPFactorySupportsTypeLocked(_CFPFactoryRef factory, CFUUIDRef typeID); + +/* These methods are called by CFPlugInInstance when an instance is created or destroyed. If a factory's instance count goes to 0 and the factory has been disabled, the factory is destroyed. */ +static void _CFPFactoryAddInstanceLocked(_CFPFactoryRef factory); +static void _CFPFactoryRemoveInstanceLocked(_CFPFactoryRef factory); + +static void _CFPlugInAddPlugInInstanceLocked(CFPlugInRef plugIn); +static void _CFPlugInRemovePlugInInstanceLocked(CFPlugInRef plugIn); + +static void _CFPlugInAddFactoryLocked(CFPlugInRef plugIn, _CFPFactoryRef factory); +static void _CFPlugInRemoveFactoryLocked(CFPlugInRef plugIn, _CFPFactoryRef factory); CONST_STRING_DECL(kCFPlugInDynamicRegistrationKey, "CFPlugInDynamicRegistration") CONST_STRING_DECL(kCFPlugInDynamicRegisterFunctionKey, "CFPlugInDynamicRegisterFunction") @@ -17,20 +50,100 @@ CONST_STRING_DECL(kCFPlugInUnloadFunctionKey, "CFPlugInUnloadFunction") CONST_STRING_DECL(kCFPlugInFactoriesKey, "CFPlugInFactories") CONST_STRING_DECL(kCFPlugInTypesKey, "CFPlugInTypes") +struct __CFPlugInInstance { + CFRuntimeBase _base; + + _CFPFactoryRef factory; + + CFPlugInInstanceGetInterfaceFunction getInterfaceFunction; + CFPlugInInstanceDeallocateInstanceDataFunction deallocateInstanceDataFunction; + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4200) +#endif //_MSC_VER + uint8_t _instanceData[0]; +#ifdef _MSC_VER +#pragma warning(pop) +#endif //_MSC_VER +}; + + +struct __CFPFactory { + CFRuntimeBase _base; + + // All protected by CFPlugInGlobalDataLock + CFUUIDRef _uuid; + Boolean _enabled; + char _padding[3]; + + CFPlugInFactoryFunction _func; + + CFPlugInRef _plugIn; + CFStringRef _funcName; + + CFMutableArrayRef _types; +}; + +// Plugin state is stored in several places: +// 1. The following factories by factory/typeID tables +// 2. The list of supported types in each factory instance +// 3. The enabled flag in each factory instance +// 4. The plugInData inside each bundle instance (except isPlugIn, which is constant after init) +// In order to synchronize all of this, there is one global lock for all of it. +#if __has_include() +static os_unfair_recursive_lock CFPlugInGlobalDataLock = OS_UNFAIR_RECURSIVE_LOCK_INIT; +#define _CFPlugInGlobalDataLockAcquire() os_unfair_recursive_lock_lock_with_options(&CFPlugInGlobalDataLock, OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION) +#define _CFPlugInGlobalDataLockRelease() os_unfair_recursive_lock_unlock(&CFPlugInGlobalDataLock) +#else +static _CFRecursiveMutex CFPlugInGlobalDataLock; + +static void _CFPlugInGlobalDataLockAcquire() { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _CFRecursiveMutexCreate(&CFPlugInGlobalDataLock); + }); + _CFRecursiveMutexLock(&CFPlugInGlobalDataLock); +} + +static void _CFPlugInGlobalDataLockRelease() { + _CFRecursiveMutexUnlock(&CFPlugInGlobalDataLock); +} + +#endif + +static CFMutableDictionaryRef _factoriesByFactoryID = NULL; /* Value is _CFPFactoryRef */ +static CFMutableDictionaryRef _factoriesByTypeID = NULL; /* Value is array of _CFPFactoryRef */ + +// MARK: - Plugin + +static os_log_t _CFBundlePluginLogger(void) { + static os_log_t _log; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _log = os_log_create("com.apple.CFBundle", "plugin"); + }); + return _log; +} + CF_EXPORT void *CFPlugInInstanceCreate(CFAllocatorRef allocator, CFUUIDRef factoryID, CFUUIDRef typeID) { - _CFPFactoryRef factory = _CFPFactoryFind(factoryID, true); + _CFPlugInGlobalDataLockAcquire(); + + _CFPFactoryRef factory = _CFPFactoryFindLocked(factoryID, true); void *result = NULL; if (!factory) { - /* MF:!!! No such factory. */ - CFLog(__kCFLogPlugIn, CFSTR("Cannot find factory %@"), factoryID); + os_log_error(_CFBundlePluginLogger(), "Cannot find factory %{public}@", factoryID); } else { - if (!_CFPFactorySupportsType(factory, typeID)) { - /* MF:!!! Factory does not support type. */ - CFLog(__kCFLogPlugIn, CFSTR("Factory %@ does not support type %@"), factoryID, typeID); + if (!_CFPFactorySupportsTypeLocked(factory, typeID)) { + os_log_error(_CFBundlePluginLogger(), "Factory %{public}@ does not support type %{public}@", factoryID, typeID); } else { - result = _CFPFactoryCreateInstance(allocator, factory, typeID); + result = _CFPFactoryCreateInstanceLocked(allocator, factory, typeID); } } + + _CFPlugInGlobalDataLockRelease(); + + os_log_debug(_CFBundlePluginLogger(), "Created instance of plugin for factory %{public}@ type %{public}@", factoryID, typeID); return result; } @@ -41,49 +154,88 @@ CF_EXPORT void *CFPlugInInstanceCreate(CFAllocatorRef allocator, CFUUIDRef facto CF_EXPORT Boolean CFPlugInRegisterFactoryFunction(CFUUIDRef factoryID, CFPlugInFactoryFunction func) { // Create factories without plugIns from default allocator // MF:!!! Should probably check that this worked, and maybe do some pre-checking to see if it already exists - // _CFPFactoryRef factory = - (void)_CFPFactoryCreate(kCFAllocatorSystemDefault, factoryID, func); + + _CFPlugInGlobalDataLockAcquire(); + + _CFPFactoryRef factory = _CFPFactoryCommonCreateLocked(kCFAllocatorSystemDefault, factoryID); + factory->_func = func; + factory->_plugIn = NULL; + factory->_funcName = NULL; + + _CFPlugInGlobalDataLockRelease(); + return true; } CF_EXPORT Boolean CFPlugInRegisterFactoryFunctionByName(CFUUIDRef factoryID, CFPlugInRef plugIn, CFStringRef functionName) { // Create factories with plugIns from plugIn's allocator // MF:!!! Should probably check that this worked, and maybe do some pre-checking to see if it already exists - // _CFPFactoryRef factory = - (void)_CFPFactoryCreateByName(CFGetAllocator(plugIn), factoryID, plugIn, functionName); + _CFPlugInGlobalDataLockAcquire(); + _CFPlugInRegisterFactoryFunctionByNameLocked(factoryID, plugIn, functionName); + _CFPlugInGlobalDataLockRelease(); + return true; } +static void _CFPlugInRegisterFactoryFunctionByNameLocked(CFUUIDRef factoryID, CFPlugInRef plugIn, CFStringRef functionName) { + _CFPFactoryRef factory = _CFPFactoryCommonCreateLocked(kCFAllocatorSystemDefault, factoryID); + factory->_func = NULL; + factory->_plugIn = (CFPlugInRef)CFRetain(plugIn); + if (plugIn) _CFPlugInAddFactoryLocked(plugIn, factory); + factory->_funcName = (functionName ? (CFStringRef)CFStringCreateCopy(kCFAllocatorSystemDefault, functionName) : NULL); +} + + CF_EXPORT Boolean CFPlugInUnregisterFactory(CFUUIDRef factoryID) { - _CFPFactoryRef factory = _CFPFactoryFind(factoryID, true); + _CFPlugInGlobalDataLockAcquire(); + + _CFPFactoryRef factory = _CFPFactoryFindLocked(factoryID, true); if (!factory) { /* MF:!!! Error. No factory registered for this ID. */ + os_log_error(_CFBundlePluginLogger(), "UnregisterFactory: No factory registered for id %{public}@", factoryID); } else { - _CFPFactoryDisable(factory); + _CFPFactoryDisableLocked(factory); } + _CFPlugInGlobalDataLockRelease(); + return true; } CF_EXPORT Boolean CFPlugInRegisterPlugInType(CFUUIDRef factoryID, CFUUIDRef typeID) { - _CFPFactoryRef factory = _CFPFactoryFind(factoryID, true); + _CFPlugInGlobalDataLockAcquire(); + _CFPlugInRegisterPlugInTypeLocked(factoryID, typeID); + _CFPlugInGlobalDataLockRelease(); + + return true; +} +static void _CFPlugInRegisterPlugInTypeLocked(CFUUIDRef factoryID, CFUUIDRef typeID) { + _CFPFactoryRef factory = _CFPFactoryFindLocked(factoryID, true); + if (!factory) { /* MF:!!! Error. Factory must be registered (and not disabled) before types can be associated with it. */ + os_log_error(_CFBundlePluginLogger(), "RegisterPlugInType: No factory registered for id %{public}@", factoryID); } else { - _CFPFactoryAddType(factory, typeID); + _CFPFactoryAddTypeLocked(factory, typeID); } - return true; } + CF_EXPORT Boolean CFPlugInUnregisterPlugInType(CFUUIDRef factoryID, CFUUIDRef typeID) { - _CFPFactoryRef factory = _CFPFactoryFind(factoryID, true); + _CFPlugInGlobalDataLockAcquire(); + + _CFPFactoryRef factory = _CFPFactoryFindLocked(factoryID, true); if (!factory) { /* MF:!!! Error. Could not find factory. */ + os_log_error(_CFBundlePluginLogger(), "UnregisterPlugInType: No factory registered for id %{public}@ type %{public}@", factoryID, typeID); } else { - _CFPFactoryRemoveType(factory, typeID); + _CFPFactoryRemoveTypeLocked(factory, typeID); } + + _CFPlugInGlobalDataLockRelease(); + return true; } @@ -93,21 +245,622 @@ CF_EXPORT Boolean CFPlugInUnregisterPlugInType(CFUUIDRef factoryID, CFUUIDRef ty /* This means that an instance must keep track of the CFUUIDRef of the factory that created it so it can unregister when it goes away. */ CF_EXPORT void CFPlugInAddInstanceForFactory(CFUUIDRef factoryID) { - _CFPFactoryRef factory = _CFPFactoryFind(factoryID, true); + _CFPlugInGlobalDataLockAcquire(); + + _CFPFactoryRef factory = _CFPFactoryFindLocked(factoryID, true); if (!factory) { /* MF:!!! Error. Could not find factory. */ + os_log_error(_CFBundlePluginLogger(), "AddInstanceForFactory: No factory registered for id %{public}@", factoryID); } else { - _CFPFactoryAddInstance(factory); + _CFPFactoryAddInstanceLocked(factory); } + + _CFPlugInGlobalDataLockRelease(); } CF_EXPORT void CFPlugInRemoveInstanceForFactory(CFUUIDRef factoryID) { - _CFPFactoryRef factory = _CFPFactoryFind(factoryID, true); + _CFPlugInGlobalDataLockAcquire(); + + _CFPFactoryRef factory = _CFPFactoryFindLocked(factoryID, true); if (!factory) { /* MF:!!! Error. Could not find factory. */ + os_log_error(_CFBundlePluginLogger(), "RemoveInstanceForFactory: No factory registered for id %{public}@", factoryID); + } else { + _CFPFactoryRemoveInstanceLocked(factory); + } + + _CFPlugInGlobalDataLockRelease(); +} + +// MARK: Plugin - Internals + +static void _registerFactoryLocked(const void *key, const void *val, void *context) { + CFStringRef factoryIDStr = (CFStringRef)key; + CFStringRef factoryFuncStr = (CFStringRef)val; + CFBundleRef bundle = (CFBundleRef)context; + CFUUIDRef factoryID = (CFGetTypeID(factoryIDStr) == CFStringGetTypeID()) ? CFUUIDCreateFromString(kCFAllocatorSystemDefault, factoryIDStr) : NULL; + if (!factoryID) factoryID = (CFUUIDRef)CFRetain(factoryIDStr); + if (CFGetTypeID(factoryFuncStr) != CFStringGetTypeID() || CFStringGetLength(factoryFuncStr) <= 0) factoryFuncStr = NULL; + + os_log_debug(_CFBundlePluginLogger(), "Registering static factory %{public}@ %{public}@ bundle %{public}p", factoryID, factoryFuncStr ?: CFSTR(""), bundle); + + _CFPlugInRegisterFactoryFunctionByNameLocked(factoryID, bundle, factoryFuncStr); + if (factoryID) CFRelease(factoryID); +} + +static void _registerTypeLocked(const void *key, const void *val, void *context) { + CFStringRef typeIDStr = (CFStringRef)key; + CFArrayRef factoryIDStrArray = (CFArrayRef)val; + CFBundleRef bundle = (CFBundleRef)context; + SInt32 i, c = (CFGetTypeID(factoryIDStrArray) == CFArrayGetTypeID()) ? CFArrayGetCount(factoryIDStrArray) : 0; + CFStringRef curFactoryIDStr; + CFUUIDRef typeID = (CFGetTypeID(typeIDStr) == CFStringGetTypeID()) ? CFUUIDCreateFromString(kCFAllocatorSystemDefault, typeIDStr) : NULL; + CFUUIDRef curFactoryID; + if (!typeID) typeID = (CFUUIDRef)CFRetain(typeIDStr); + if (0 == c && CFGetTypeID(factoryIDStrArray) != CFArrayGetTypeID()) { + curFactoryIDStr = (CFStringRef)val; + curFactoryID = (CFGetTypeID(curFactoryIDStr) == CFStringGetTypeID()) ? CFUUIDCreateFromString(CFGetAllocator(bundle), curFactoryIDStr) : NULL; + if (!curFactoryID) curFactoryID = (CFUUIDRef)CFRetain(curFactoryIDStr); + os_log_debug(_CFBundlePluginLogger(), "Registering factory %{public}@ type %{public}@", curFactoryID, typeID); + _CFPlugInRegisterPlugInTypeLocked(curFactoryID, typeID); + if (curFactoryID) CFRelease(curFactoryID); + } else for (i = 0; i < c; i++) { + curFactoryIDStr = (CFStringRef)CFArrayGetValueAtIndex(factoryIDStrArray, i); + curFactoryID = (CFGetTypeID(curFactoryIDStr) == CFStringGetTypeID()) ? CFUUIDCreateFromString(CFGetAllocator(bundle), curFactoryIDStr) : NULL; + if (!curFactoryID) curFactoryID = (CFUUIDRef)CFRetain(curFactoryIDStr); + os_log_debug(_CFBundlePluginLogger(), "Registering factory %{public}@ type %{public}@", curFactoryID, typeID); + _CFPlugInRegisterPlugInTypeLocked(curFactoryID, typeID); + if (curFactoryID) CFRelease(curFactoryID); + } + if (typeID) CFRelease(typeID); +} + +CF_PRIVATE void _CFBundleInitPlugIn(CFBundleRef bundle) { + CFArrayCallBacks _pluginFactoryArrayCallbacks = {0, NULL, NULL, NULL, NULL}; + Boolean doDynamicReg = false; + CFDictionaryRef infoDict; + CFDictionaryRef factoryDict; + CFDictionaryRef typeDict; + CFStringRef tempStr; + + infoDict = CFBundleGetInfoDictionary(bundle); + if (!infoDict) return; + + factoryDict = (CFDictionaryRef)CFDictionaryGetValue(infoDict, kCFPlugInFactoriesKey); + if (factoryDict && CFGetTypeID(factoryDict) != CFDictionaryGetTypeID()) factoryDict = NULL; + tempStr = (CFStringRef)CFDictionaryGetValue(infoDict, kCFPlugInDynamicRegistrationKey); + if (tempStr && CFGetTypeID(tempStr) == CFStringGetTypeID() && CFStringCompare(tempStr, CFSTR("YES"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) doDynamicReg = true; + if (!factoryDict && !doDynamicReg) return; // This is not a plug-in. + + _CFPlugInGlobalDataLockAcquire(); + + if (__CFBundleGetPlugInData(bundle)->_registeredFactory) { + // We already registered - don't do it again + _CFPlugInGlobalDataLockRelease(); + return; + } + + /* loadOnDemand is true by default if the plugIn does not do dynamic registration. It is false, by default if it does do dynamic registration. The dynamic register function can set this. */ + __CFBundleGetPlugInData(bundle)->_isPlugIn = true; + __CFBundleGetPlugInData(bundle)->_loadOnDemand = true; + __CFBundleGetPlugInData(bundle)->_isDoingDynamicRegistration = false; + __CFBundleGetPlugInData(bundle)->_needsDynamicRegistration = false; + __CFBundleGetPlugInData(bundle)->_instanceCount = 0; + __CFBundleGetPlugInData(bundle)->_registeredFactory = true; + + __CFBundleGetPlugInData(bundle)->_factories = CFArrayCreateMutable(CFGetAllocator(bundle), 0, &_pluginFactoryArrayCallbacks); + + /* Now do the registration */ + + /* First do static registrations, if any. */ + if (factoryDict) CFDictionaryApplyFunction(factoryDict, _registerFactoryLocked, bundle); + typeDict = (CFDictionaryRef)CFDictionaryGetValue(infoDict, kCFPlugInTypesKey); + if (typeDict && CFGetTypeID(typeDict) != CFDictionaryGetTypeID()) typeDict = NULL; + if (typeDict) CFDictionaryApplyFunction(typeDict, _registerTypeLocked, bundle); + + _CFPlugInGlobalDataLockRelease(); + + /* Now set key for dynamic registration if necessary */ + if (doDynamicReg) { + __CFBundleGetPlugInData(bundle)->_needsDynamicRegistration = true; + if (CFBundleIsExecutableLoaded(bundle)) _CFBundlePlugInLoaded(bundle); + } +} + +static void __CFPLUGIN_IS_CALLING_OUT_TO_A_DYNAMIC_REGISTRATION_FUNCTION__(CFPlugInDynamicRegisterFunction f, CFBundleRef bundle) __attribute__((noinline)); + +static void __CFPLUGIN_IS_CALLING_OUT_TO_A_DYNAMIC_REGISTRATION_FUNCTION__(CFPlugInDynamicRegisterFunction f, CFBundleRef bundle) { + f(bundle); + __asm __volatile__(""); // thwart tail-call optimization +} + +CF_PRIVATE void _CFBundlePlugInLoaded(CFBundleRef bundle) { + _CFPlugInData *plugIn = __CFBundleGetPlugInData(bundle); + if (!plugIn->_isPlugIn || !CFBundleIsExecutableLoaded(bundle)) { + return; + } + + _CFPlugInGlobalDataLockAcquire(); + + if (plugIn->_isDoingDynamicRegistration) { + _CFPlugInGlobalDataLockRelease(); + return; + } + + if (plugIn->_needsDynamicRegistration) { + plugIn->_needsDynamicRegistration = false; + CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle); + CFStringRef tempStr = (CFStringRef)CFDictionaryGetValue(infoDict, kCFPlugInDynamicRegisterFunctionKey); + if (!tempStr || CFGetTypeID(tempStr) != CFStringGetTypeID() || CFStringGetLength(tempStr) <= 0) tempStr = CFSTR("CFPlugInDynamicRegister"); + plugIn->_loadOnDemand = false; + + plugIn->_isDoingDynamicRegistration = true; + + CFPlugInDynamicRegisterFunction func = (CFPlugInDynamicRegisterFunction)CFBundleGetFunctionPointerForName(bundle, tempStr); + if (func) { + __CFPLUGIN_IS_CALLING_OUT_TO_A_DYNAMIC_REGISTRATION_FUNCTION__(func, bundle); + } + + plugIn->_isDoingDynamicRegistration = false; + + if (plugIn->_loadOnDemand && plugIn->_instanceCount == 0) CFBundleUnloadExecutable(bundle); // Unload now if we can/should. + } + + _CFPlugInGlobalDataLockRelease(); +} + +CF_PRIVATE void _CFBundleDeallocatePlugIn(CFBundleRef bundle) { + _CFPlugInData *plugIn = __CFBundleGetPlugInData(bundle); + _CFPlugInGlobalDataLockAcquire(); + if (plugIn->_isPlugIn) { + /* Go through factories disabling them. Disabling these factories should cause them to dealloc since we wouldn't be deallocating if any of the factories had outstanding instances. So go backwards. */ + SInt32 c = CFArrayGetCount(plugIn->_factories); + while (c-- > 0) _CFPFactoryDisableLocked((_CFPFactoryRef)CFArrayGetValueAtIndex(plugIn->_factories, c)); + CFRelease(plugIn->_factories); + + plugIn->_isPlugIn = false; + } + _CFPlugInGlobalDataLockRelease(); +} + +CF_EXPORT CFTypeID CFPlugInGetTypeID(void) { + return CFBundleGetTypeID(); +} + +CF_EXPORT CFPlugInRef CFPlugInCreate(CFAllocatorRef allocator, CFURLRef plugInURL) { + CFBundleRef bundle = CFBundleCreate(allocator, plugInURL); + return (CFPlugInRef)bundle; +} + +CF_EXPORT CFBundleRef CFPlugInGetBundle(CFPlugInRef plugIn) { + return (CFBundleRef)plugIn; +} + +CF_EXPORT void CFPlugInSetLoadOnDemand(CFPlugInRef plugIn, Boolean flag) { + _CFPlugInData *plugInData = __CFBundleGetPlugInData(plugIn); + if (plugInData->_isPlugIn) { + _CFPlugInGlobalDataLockAcquire(); + + plugInData->_loadOnDemand = flag; + if (plugInData->_loadOnDemand && !plugInData->_isDoingDynamicRegistration && plugInData->_instanceCount == 0) + { + /* Unload now if we can/should. */ + /* If we are doing dynamic registration currently, do not unload. The unloading will happen when dynamic registration is done, if necessary. */ + _CFPlugInGlobalDataLockRelease(); + + CFBundleUnloadExecutable(plugIn); + } else if (!plugInData->_loadOnDemand) { + + _CFPlugInGlobalDataLockRelease(); + + /* Make sure we're loaded now. */ + CFBundleLoadExecutable(plugIn); + } else { + _CFPlugInGlobalDataLockRelease(); + } + } +} + +CF_EXPORT Boolean CFPlugInIsLoadOnDemand(CFPlugInRef plugIn) { + if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) { + // Checking this is a race no matter what, so don't bother with the lock + return __CFBundleGetPlugInData(plugIn)->_loadOnDemand; + } else { + return false; + } +} + +CF_PRIVATE void _CFPlugInWillUnload(CFPlugInRef plugIn) { + if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) { + _CFPlugInGlobalDataLockAcquire(); + + SInt32 c = CFArrayGetCount(__CFBundleGetPlugInData(plugIn)->_factories); + /* First, flush all the function pointers that may be cached by our factories. */ + while (c-- > 0) { + _CFPFactoryRef factory = (_CFPFactoryRef)CFArrayGetValueAtIndex(__CFBundleGetPlugInData(plugIn)->_factories, c); + factory->_func = NULL; + } + + _CFPlugInGlobalDataLockRelease(); + } +} + +static void _CFPlugInAddPlugInInstanceLocked(CFPlugInRef plugIn) { + if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) { + if (__CFBundleGetPlugInData(plugIn)->_instanceCount == 0 && __CFBundleGetPlugInData(plugIn)->_loadOnDemand) { _CFBundleUnscheduleForUnloading(CFPlugInGetBundle(plugIn)); // Make sure we are not scheduled for unloading + } + __CFBundleGetPlugInData(plugIn)->_instanceCount++; + /* Instances also retain the CFBundle */ + CFRetain(plugIn); + } +} + +static void _CFPlugInRemovePlugInInstanceLocked(CFPlugInRef plugIn) { + if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) { + /* MF:!!! Assert that instanceCount > 0. */ + __CFBundleGetPlugInData(plugIn)->_instanceCount--; + if (__CFBundleGetPlugInData(plugIn)->_instanceCount == 0 && __CFBundleGetPlugInData(plugIn)->_loadOnDemand) { + // We unload the code lazily because the code that caused this function to be called is probably code from the plugin itself. If we unload now, we will hose things. + _CFBundleScheduleForUnloading(CFPlugInGetBundle(plugIn)); + } + /* Instances also retain the CFPlugIn */ + /* MF:!!! This will cause immediate unloading if it was the last ref on the plugin. */ + CFRelease(plugIn); + } +} + +static void _CFPlugInAddFactoryLocked(CFPlugInRef plugIn, _CFPFactoryRef factory) { + if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) CFArrayAppendValue(__CFBundleGetPlugInData(plugIn)->_factories, factory); +} + +static void _CFPlugInRemoveFactoryLocked(CFPlugInRef plugIn, _CFPFactoryRef factory) { + if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) { + SInt32 idx = CFArrayGetFirstIndexOfValue(__CFBundleGetPlugInData(plugIn)->_factories, CFRangeMake(0, CFArrayGetCount(__CFBundleGetPlugInData(plugIn)->_factories)), factory); + if (idx >= 0) CFArrayRemoveValueAtIndex(__CFBundleGetPlugInData(plugIn)->_factories, idx); + } +} + +// MARK: Plugin - Factory + +static void _CFPFactoryDeallocate(CFTypeRef factory); + +const CFRuntimeClass __CFPFactoryClass = { + 0, + "_CFPFactory", + NULL, // init + NULL, // copy + _CFPFactoryDeallocate, + NULL, // equal + NULL, // hash + NULL, // formatting desc + NULL, // debug desc +}; + +static CFTypeID _CFPFactoryGetTypeID(void) { + return _kCFRuntimeIDCFPFactory; +} + +static void _CFPFactoryAddToTableLocked(_CFPFactoryRef factory) { + CFUUIDRef uuid = factory->_uuid; + + if (!_factoriesByFactoryID) { + CFDictionaryValueCallBacks _factoryDictValueCallbacks = {0, NULL, NULL, NULL, NULL}; + _factoriesByFactoryID = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &_factoryDictValueCallbacks); + } + CFDictionarySetValue(_factoriesByFactoryID, uuid, factory); + + os_log_debug(_CFBundlePluginLogger(), "Registered factory %{public}@ (%{public}@)", factory, uuid); +} + +static void _CFPFactoryRemoveFromTableLocked(_CFPFactoryRef factory) { + CFUUIDRef uuid = factory->_uuid; + if (uuid && _factoriesByTypeID) CFDictionaryRemoveValue(_factoriesByFactoryID, uuid); + + os_log_debug(_CFBundlePluginLogger(), "Unregistered factory %{public}@ (%{public}@)", factory, uuid); +} + +static _CFPFactoryRef _CFPFactoryFindLocked(CFUUIDRef factoryID, Boolean enabled) { + _CFPFactoryRef result = NULL; + + if (_factoriesByFactoryID) { + result = (_CFPFactoryRef )CFDictionaryGetValue(_factoriesByFactoryID, factoryID); + if (result && result->_enabled != enabled) result = NULL; + } + + return result; +} + +static void _CFPFactoryDeallocate(CFTypeRef ty) { + SInt32 c; + _CFPFactoryRef factory = (_CFPFactoryRef)ty; + + _CFPlugInGlobalDataLockAcquire(); + + _CFPFactoryRemoveFromTableLocked(factory); + + if (factory->_plugIn) { + _CFPlugInRemoveFactoryLocked(factory->_plugIn, factory); + CFRelease(factory->_plugIn); + } + + /* Remove all types for this factory. */ + c = CFArrayGetCount(factory->_types); + while (c-- > 0) _CFPFactoryRemoveTypeLocked(factory, (CFUUIDRef)CFArrayGetValueAtIndex(factory->_types, c)); + CFRelease(factory->_types); + + _CFPlugInGlobalDataLockRelease(); + + if (factory->_funcName) CFRelease(factory->_funcName); + if (factory->_uuid) CFRelease(factory->_uuid); +} + +static _CFPFactoryRef _CFPFactoryCommonCreateLocked(CFAllocatorRef allocator, CFUUIDRef factoryID) { + _CFPFactoryRef factory; + uint32_t size; + size = sizeof(struct __CFPFactory) - sizeof(CFRuntimeBase); + factory = (_CFPFactoryRef)_CFRuntimeCreateInstance(allocator, _CFPFactoryGetTypeID(), size, NULL); + if (!factory) return NULL; + + factory->_uuid = (CFUUIDRef)CFRetain(factoryID); + factory->_enabled = true; + factory->_types = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); + + _CFPFactoryAddToTableLocked(factory); + + return factory; +} + +static CFUUIDRef _CFPFactoryCopyFactoryIDLocked(_CFPFactoryRef factory) { + CFUUIDRef uuid = factory->_uuid; + if (uuid) CFRetain(uuid); + return uuid; +} + +static CFPlugInRef _CFPFactoryCopyPlugInLocked(_CFPFactoryRef factory) { + CFPlugInRef result = factory->_plugIn; + if (result) CFRetain(result); + return result; +} + +static void *__CFPLUGIN_IS_CALLING_OUT_TO_A_FACTORY_FUNCTION__(CFPlugInFactoryFunction, CFAllocatorRef, CFUUIDRef) __attribute__((noinline)); + +static void *__CFPLUGIN_IS_CALLING_OUT_TO_A_FACTORY_FUNCTION__(CFPlugInFactoryFunction f, CFAllocatorRef allocator, CFUUIDRef typeID) { + FAULT_CALLBACK((void **)&(f)); + void *result = (void *)INVOKE_CALLBACK2(f, allocator, typeID); + __asm __volatile__(""); // thwart tail-call optimization + return result; +} + +static void *_CFPFactoryCreateInstanceLocked(CFAllocatorRef allocator, _CFPFactoryRef factory, CFUUIDRef typeID) { + void *result = NULL; + + if (factory->_enabled) { + if (!factory->_func) { + factory->_func = (CFPlugInFactoryFunction)CFBundleGetFunctionPointerForName(factory->_plugIn, factory->_funcName); + + if (!factory->_func) { + os_log_error(_CFBundlePluginLogger(), "Cannot find function pointer %{public}@ for factory %{public}@ in %{public}@", factory->_funcName, factory->_uuid, factory->_plugIn); + } + } + if (factory->_func) { + CFPlugInFactoryFunction f = factory->_func; + result = __CFPLUGIN_IS_CALLING_OUT_TO_A_FACTORY_FUNCTION__(f, allocator, typeID); + } } else { - _CFPFactoryRemoveInstance(factory); + os_log_debug(_CFBundlePluginLogger(), "Atempted to create instance, but factory %{public}@ is disabled", factory->_uuid); + } + + return result; +} + +static void _CFPFactoryDisableLocked(_CFPFactoryRef factory) { + factory->_enabled = false; + os_log_debug(_CFBundlePluginLogger(), "Factory %{public}@ has been disabled", factory->_uuid); + CFRelease(factory); +} + +static void _CFPFactoryAddTypeLocked(_CFPFactoryRef factory, CFUUIDRef typeID) { + /* Add the type to the factory's type list */ + CFArrayAppendValue(factory->_types, typeID); + + if (!_factoriesByTypeID) _factoriesByTypeID = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFMutableArrayRef array = (CFMutableArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID); + if (!array) { + CFArrayCallBacks _factoryArrayCallbacks = {0, NULL, NULL, NULL, NULL}; + // Create this from default allocator + array = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &_factoryArrayCallbacks); + CFDictionarySetValue(_factoriesByTypeID, typeID, array); + CFRelease(array); } + CFArrayAppendValue(array, factory); + os_log_debug(_CFBundlePluginLogger(), "Type %{public}@ added to factory %{public}@", typeID, factory->_uuid); +} + +static void _CFPFactoryRemoveTypeLocked(_CFPFactoryRef factory, CFUUIDRef typeID) { + /* Remove it from the factory's type list */ + SInt32 idx = CFArrayGetFirstIndexOfValue(factory->_types, CFRangeMake(0, CFArrayGetCount(factory->_types)), typeID); + if (idx >= 0) CFArrayRemoveValueAtIndex(factory->_types, idx); + + /* Remove the factory from the type's list of factories */ + if (_factoriesByTypeID) { + CFMutableArrayRef array = (CFMutableArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID); + if (array) { + idx = CFArrayGetFirstIndexOfValue(array, CFRangeMake(0, CFArrayGetCount(array)), factory); + if (idx >= 0) { + CFArrayRemoveValueAtIndex(array, idx); + if (CFArrayGetCount(array) == 0) CFDictionaryRemoveValue(_factoriesByTypeID, typeID); + } + } + } + os_log_debug(_CFBundlePluginLogger(), "Type %{public}@ removed from factory %{public}@", typeID, factory->_uuid); +} + +static Boolean _CFPFactorySupportsTypeLocked(_CFPFactoryRef factory, CFUUIDRef typeID) { + SInt32 idx = CFArrayGetFirstIndexOfValue(factory->_types, CFRangeMake(0, CFArrayGetCount(factory->_types)), typeID); + return (idx >= 0 ? true : false); +} + +/* These methods are called by CFPlugInInstance when an instance is created or destroyed. If a factory's instance count goes to 0 and the factory has been disabled, the factory is destroyed. */ +static void _CFPFactoryAddInstanceLocked(_CFPFactoryRef factory) { + CFPlugInRef plugin = factory->_plugIn; + if (plugin) { + _CFPlugInAddPlugInInstanceLocked(plugin); + } +} + +static void _CFPFactoryRemoveInstanceLocked(_CFPFactoryRef factory) { + CFPlugInRef plugin = factory->_plugIn; + if (plugin) { + _CFPlugInRemovePlugInInstanceLocked(plugin); + } +} + +#pragma mark - + +/* ===================== Finding factories and creating instances ===================== */ +/* For plugIn hosts. */ +/* Functions for finding factories to create specific types and actually creating instances of a type. */ + +CF_EXPORT CFArrayRef CFPlugInFindFactoriesForPlugInType(CFUUIDRef typeID) CF_RETURNS_RETAINED { + _CFPlugInGlobalDataLockAcquire(); + CFArrayRef array = NULL; + if (_factoriesByTypeID) { + array = (CFArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID); + } + + CFMutableArrayRef result = NULL; + if (array) { + result = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks); + + CFIndex c = CFArrayGetCount(array); + for (CFIndex i = 0; i < c; i++) { + CFUUIDRef factoryId = _CFPFactoryCopyFactoryIDLocked((_CFPFactoryRef)CFArrayGetValueAtIndex(array, i)); + if (factoryId) { + CFArrayAppendValue(result, factoryId); + CFRelease(factoryId); + } + } + } + + _CFPlugInGlobalDataLockRelease(); + os_log_debug(_CFBundlePluginLogger(), "%{public}ld factories found for requested plugin type %{public}@", result ? CFArrayGetCount(result) : 0, typeID); + return result; +} + +CF_EXPORT CFArrayRef CFPlugInFindFactoriesForPlugInTypeInPlugIn(CFUUIDRef typeID, CFPlugInRef plugIn) CF_RETURNS_RETAINED { + _CFPlugInGlobalDataLockAcquire(); + CFArrayRef array = NULL; + if (_factoriesByTypeID) { + array = (CFArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID); + } + + + CFMutableArrayRef result = NULL; + if (array) { + CFIndex c = CFArrayGetCount(array); + result = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks); + for (CFIndex i = 0; i < c; i++) { + _CFPFactoryRef factory = (_CFPFactoryRef)CFArrayGetValueAtIndex(array, i); + CFPlugInRef factoryPlugIn = _CFPFactoryCopyPlugInLocked(factory); + if (factoryPlugIn == plugIn) { + CFUUIDRef factoryId = _CFPFactoryCopyFactoryIDLocked(factory); + CFArrayAppendValue(result, factoryId); + CFRelease(factoryId); + } + if (factoryPlugIn) CFRelease(factoryPlugIn); + } + } + + _CFPlugInGlobalDataLockRelease(); + os_log_debug(_CFBundlePluginLogger(), "%{public}ld factories found for requested plugin type %{public}@ in plugin %{public}@", result ? CFArrayGetCount(result) : 0, typeID, plugIn); + return result; +} + +// MARK: Plugin - Instance + +static CFStringRef __CFPlugInInstanceCopyDescription(CFTypeRef cf) { + /* MF:!!! Implement me */ + return CFSTR("Some CFPlugInInstance"); +} + +static void __CFPlugInInstanceDeallocate(CFTypeRef cf) { + CFPlugInInstanceRef instance = (CFPlugInInstanceRef)cf; + + __CFGenericValidateType(cf, CFPlugInInstanceGetTypeID()); + + _CFPlugInGlobalDataLockAcquire(); + + if (instance->deallocateInstanceDataFunction) { + FAULT_CALLBACK((void **)&(instance->deallocateInstanceDataFunction)); + (void)INVOKE_CALLBACK1(instance->deallocateInstanceDataFunction, (void *)(&instance->_instanceData[0])); + } + + if (instance->factory) _CFPFactoryRemoveInstanceLocked(instance->factory); + + _CFPlugInGlobalDataLockRelease(); +} + +const CFRuntimeClass __CFPlugInInstanceClass = { + 0, + "CFPlugInInstance", + NULL, // init + NULL, // copy + __CFPlugInInstanceDeallocate, + NULL, // equal + NULL, // hash + NULL, // + __CFPlugInInstanceCopyDescription +}; + +CFTypeID CFPlugInInstanceGetTypeID(void) { + return _kCFRuntimeIDCFPlugInInstance; +} + +CF_EXPORT CFPlugInInstanceRef CFPlugInInstanceCreateWithInstanceDataSize(CFAllocatorRef allocator, CFIndex instanceDataSize, CFPlugInInstanceDeallocateInstanceDataFunction deallocateInstanceFunction, CFStringRef factoryName, CFPlugInInstanceGetInterfaceFunction getInterfaceFunction) { + CFPlugInInstanceRef instance; + UInt32 size; + size = sizeof(struct __CFPlugInInstance) + instanceDataSize - sizeof(CFRuntimeBase); + instance = (CFPlugInInstanceRef)_CFRuntimeCreateInstance(allocator, CFPlugInInstanceGetTypeID(), size, NULL); + if (!instance) return NULL; + + _CFPlugInGlobalDataLockAcquire(); + + instance->factory = _CFPFactoryFindLocked((CFUUIDRef)factoryName, true); + if (instance->factory) _CFPFactoryAddInstanceLocked(instance->factory); + instance->getInterfaceFunction = getInterfaceFunction; + instance->deallocateInstanceDataFunction = deallocateInstanceFunction; + + _CFPlugInGlobalDataLockRelease(); + + return instance; +} + +CF_EXPORT Boolean CFPlugInInstanceGetInterfaceFunctionTable(CFPlugInInstanceRef instance, CFStringRef interfaceName, void **ftbl) { + void *myFtbl; + Boolean result = false; + + if (instance->getInterfaceFunction) { + FAULT_CALLBACK((void **)&(instance->getInterfaceFunction)); + result = INVOKE_CALLBACK3(instance->getInterfaceFunction, instance, interfaceName, &myFtbl) ? true : false; + } + if (ftbl) *ftbl = (result ? myFtbl : NULL); + return result; +} + +CF_EXPORT CFStringRef CFPlugInInstanceGetFactoryName(CFPlugInInstanceRef instance) { + _CFPlugInGlobalDataLockAcquire(); + + // This function leaks, but it's the only safe way to access the factory name (on 10.8 or later). + // On 10.9 we added the CF_RETURNS_RETAINED annotation to the header. + CFUUIDRef factoryId = _CFPFactoryCopyFactoryIDLocked(instance->factory); + + _CFPlugInGlobalDataLockRelease(); + + return (CFStringRef)factoryId; +} + +CF_EXPORT void *CFPlugInInstanceGetInstanceData(CFPlugInInstanceRef instance) { + return (void *)(&instance->_instanceData[0]); } diff --git a/CoreFoundation/PlugIn.subproj/CFPlugIn.h b/CoreFoundation/PlugIn.subproj/CFPlugIn.h index ce4e1f8bea..c20463b59d 100644 --- a/CoreFoundation/PlugIn.subproj/CFPlugIn.h +++ b/CoreFoundation/PlugIn.subproj/CFPlugIn.h @@ -1,7 +1,7 @@ /* CFPlugIn.h - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/PlugIn.subproj/CFPlugInCOM.h b/CoreFoundation/PlugIn.subproj/CFPlugInCOM.h index 60eeb1460c..8c796ab83f 100644 --- a/CoreFoundation/PlugIn.subproj/CFPlugInCOM.h +++ b/CoreFoundation/PlugIn.subproj/CFPlugInCOM.h @@ -1,7 +1,7 @@ /* CFPlugInCOM.h - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/PlugIn.subproj/CFPlugIn_Factory.c b/CoreFoundation/PlugIn.subproj/CFPlugIn_Factory.c deleted file mode 100644 index 2dfde6c72b..0000000000 --- a/CoreFoundation/PlugIn.subproj/CFPlugIn_Factory.c +++ /dev/null @@ -1,353 +0,0 @@ -/* CFPlugIn_Factory.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors - - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors - Licensed under Apache License v2.0 with Runtime Library Exception - See http://swift.org/LICENSE.txt for license information - See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Tony Parker -*/ - -#include "CFBundle_Internal.h" -#include "CFInternal.h" -#include "CFRuntime_Internal.h" - -struct __CFPFactory { - CFRuntimeBase _base; - - CFUUIDRef _uuid; - Boolean _enabled; - char _padding[3]; - - CFPlugInFactoryFunction _func; - - CFPlugInRef _plugIn; - CFStringRef _funcName; - - CFMutableArrayRef _types; - CFLock_t _lock; -}; - -static void _CFPFactoryDeallocate(CFTypeRef factory); - -const CFRuntimeClass __CFPFactoryClass = { - 0, - "_CFPFactory", - NULL, // init - NULL, // copy - _CFPFactoryDeallocate, - NULL, // equal - NULL, // hash - NULL, // formatting desc - NULL, // debug desc -}; - -static CFTypeID _CFPFactoryGetTypeID(void) { - return _kCFRuntimeIDCFPFactory; -} - -static CFLock_t CFPlugInGlobalDataLock = CFLockInit; -static CFMutableDictionaryRef _factoriesByFactoryID = NULL; /* Value is _CFPFactoryRef */ -static CFMutableDictionaryRef _factoriesByTypeID = NULL; /* Value is array of _CFPFactoryRef */ - -static void _CFPFactoryAddToTable(_CFPFactoryRef factory) { - __CFLock(&factory->_lock); - CFUUIDRef uuid = (CFUUIDRef)CFRetain(factory->_uuid); - CFRetain(factory); - __CFUnlock(&factory->_lock); - - __CFLock(&CFPlugInGlobalDataLock); - if (!_factoriesByFactoryID) { - CFDictionaryValueCallBacks _factoryDictValueCallbacks = {0, NULL, NULL, NULL, NULL}; - _factoriesByFactoryID = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &_factoryDictValueCallbacks); - } - CFDictionarySetValue(_factoriesByFactoryID, uuid, factory); - __CFUnlock(&CFPlugInGlobalDataLock); - - if (uuid) CFRelease(uuid); - CFRelease(factory); -} - -static void _CFPFactoryRemoveFromTable(_CFPFactoryRef factory) { - __CFLock(&factory->_lock); - CFUUIDRef uuid = factory->_uuid; - if (uuid) CFRetain(uuid); - __CFUnlock(&factory->_lock); - - __CFLock(&CFPlugInGlobalDataLock); - if (uuid && _factoriesByTypeID) CFDictionaryRemoveValue(_factoriesByFactoryID, uuid); - __CFUnlock(&CFPlugInGlobalDataLock); - - if (uuid) CFRelease(uuid); -} - -CF_PRIVATE _CFPFactoryRef _CFPFactoryFind(CFUUIDRef factoryID, Boolean enabled) { - _CFPFactoryRef result = NULL; - - __CFLock(&CFPlugInGlobalDataLock); - if (_factoriesByFactoryID) { - result = (_CFPFactoryRef )CFDictionaryGetValue(_factoriesByFactoryID, factoryID); - if (result && result->_enabled != enabled) result = NULL; - } - __CFUnlock(&CFPlugInGlobalDataLock); - return result; -} - -static void _CFPFactoryDeallocate(CFTypeRef ty) { - SInt32 c; - _CFPFactoryRef factory = (_CFPFactoryRef)ty; - - _CFPFactoryRemoveFromTable(factory); - - if (factory->_plugIn) { - _CFPlugInRemoveFactory(factory->_plugIn, factory); - CFRelease(factory->_plugIn); - } - - /* Remove all types for this factory. */ - c = CFArrayGetCount(factory->_types); - while (c-- > 0) _CFPFactoryRemoveType(factory, (CFUUIDRef)CFArrayGetValueAtIndex(factory->_types, c)); - CFRelease(factory->_types); - - if (factory->_funcName) CFRelease(factory->_funcName); - if (factory->_uuid) CFRelease(factory->_uuid); -} - -static _CFPFactoryRef _CFPFactoryCommonCreate(CFAllocatorRef allocator, CFUUIDRef factoryID) { - _CFPFactoryRef factory; - uint32_t size; - size = sizeof(struct __CFPFactory) - sizeof(CFRuntimeBase); - factory = (_CFPFactoryRef)_CFRuntimeCreateInstance(allocator, _CFPFactoryGetTypeID(), size, NULL); - if (!factory) return NULL; - - factory->_uuid = (CFUUIDRef)CFRetain(factoryID); - factory->_enabled = true; - factory->_types = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); - factory->_lock = CFLockInit; // WARNING: grab global lock before this lock - - _CFPFactoryAddToTable(factory); - - return factory; -} - -CF_PRIVATE _CFPFactoryRef _CFPFactoryCreate(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInFactoryFunction func) { - _CFPFactoryRef factory = _CFPFactoryCommonCreate(allocator, factoryID); - - __CFLock(&factory->_lock); - factory->_func = func; - factory->_plugIn = NULL; - factory->_funcName = NULL; - __CFUnlock(&factory->_lock); - - return factory; -} - -CF_PRIVATE _CFPFactoryRef _CFPFactoryCreateByName(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInRef plugIn, CFStringRef funcName) { - _CFPFactoryRef factory = _CFPFactoryCommonCreate(allocator, factoryID); - - __CFLock(&factory->_lock); - factory->_func = NULL; - factory->_plugIn = (CFPlugInRef)CFRetain(plugIn); - if (plugIn) _CFPlugInAddFactory(plugIn, factory); - factory->_funcName = (funcName ? (CFStringRef)CFStringCreateCopy(allocator, funcName) : NULL); - __CFUnlock(&factory->_lock); - - return factory; -} - -CF_PRIVATE CFUUIDRef _CFPFactoryCopyFactoryID(_CFPFactoryRef factory) { - __CFLock(&factory->_lock); - CFUUIDRef uuid = factory->_uuid; - if (uuid) CFRetain(uuid); - __CFUnlock(&factory->_lock); - return uuid; -} - -CF_PRIVATE CFPlugInRef _CFPFactoryCopyPlugIn(_CFPFactoryRef factory) { - __CFLock(&factory->_lock); - CFPlugInRef result = factory->_plugIn; - if (result) CFRetain(result); - __CFUnlock(&factory->_lock); - return result; -} - -CF_PRIVATE void *_CFPFactoryCreateInstance(CFAllocatorRef allocator, _CFPFactoryRef factory, CFUUIDRef typeID) { - void *result = NULL; - - __CFLock(&factory->_lock); - if (factory->_enabled) { - if (!factory->_func) { - factory->_func = (CFPlugInFactoryFunction)CFBundleGetFunctionPointerForName(factory->_plugIn, factory->_funcName); - if (!factory->_func) CFLog(__kCFLogPlugIn, CFSTR("Cannot find function pointer %@ for factory %@ in %@"), factory->_funcName, factory->_uuid, factory->_plugIn); - } - if (factory->_func) { - // UPPGOOP - CFPlugInFactoryFunction f = factory->_func; - __CFUnlock(&factory->_lock); - FAULT_CALLBACK((void **)&(f)); - result = (void *)INVOKE_CALLBACK2(f, allocator, typeID); - __CFLock(&factory->_lock); - } - } else { - CFLog(__kCFLogPlugIn, CFSTR("Factory %@ is disabled"), factory->_uuid); - } - __CFUnlock(&factory->_lock); - - return result; -} - -CF_PRIVATE void _CFPFactoryDisable(_CFPFactoryRef factory) { - __CFLock(&factory->_lock); - factory->_enabled = false; - __CFUnlock(&factory->_lock); - CFRelease(factory); -} - -CF_PRIVATE void _CFPFactoryFlushFunctionCache(_CFPFactoryRef factory) { - /* MF:!!! Assert that this factory belongs to a plugIn. */ - /* This is called by the factory's plugIn when the plugIn unloads its code. */ - __CFLock(&factory->_lock); - factory->_func = NULL; - __CFUnlock(&factory->_lock); -} - -CF_PRIVATE void _CFPFactoryAddType(_CFPFactoryRef factory, CFUUIDRef typeID) { - /* Add the factory to the type's array of factories */ - __CFLock(&factory->_lock); - /* Add the type to the factory's type list */ - CFArrayAppendValue(factory->_types, typeID); - __CFUnlock(&factory->_lock); - - __CFLock(&CFPlugInGlobalDataLock); - if (!_factoriesByTypeID) _factoriesByTypeID = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFMutableArrayRef array = (CFMutableArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID); - if (!array) { - CFArrayCallBacks _factoryArrayCallbacks = {0, NULL, NULL, NULL, NULL}; - // Create this from default allocator - array = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &_factoryArrayCallbacks); - CFDictionarySetValue(_factoriesByTypeID, typeID, array); - CFRelease(array); - } - CFArrayAppendValue(array, factory); - __CFUnlock(&CFPlugInGlobalDataLock); -} - -CF_PRIVATE void _CFPFactoryRemoveType(_CFPFactoryRef factory, CFUUIDRef typeID) { - /* Remove it from the factory's type list */ - SInt32 idx; - - __CFLock(&factory->_lock); - idx = CFArrayGetFirstIndexOfValue(factory->_types, CFRangeMake(0, CFArrayGetCount(factory->_types)), typeID); - if (idx >= 0) CFArrayRemoveValueAtIndex(factory->_types, idx); - __CFUnlock(&factory->_lock); - - /* Remove the factory from the type's list of factories */ - __CFLock(&CFPlugInGlobalDataLock); - if (_factoriesByTypeID) { - CFMutableArrayRef array = (CFMutableArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID); - if (array) { - idx = CFArrayGetFirstIndexOfValue(array, CFRangeMake(0, CFArrayGetCount(array)), factory); - if (idx >= 0) { - CFArrayRemoveValueAtIndex(array, idx); - if (CFArrayGetCount(array) == 0) CFDictionaryRemoveValue(_factoriesByTypeID, typeID); - } - } - } - __CFUnlock(&CFPlugInGlobalDataLock); -} - -CF_PRIVATE Boolean _CFPFactorySupportsType(_CFPFactoryRef factory, CFUUIDRef typeID) { - SInt32 idx; - - __CFLock(&factory->_lock); - idx = CFArrayGetFirstIndexOfValue(factory->_types, CFRangeMake(0, CFArrayGetCount(factory->_types)), typeID); - __CFUnlock(&factory->_lock); - - return (idx >= 0 ? true : false); -} - -/* These methods are called by CFPlugInInstance when an instance is created or destroyed. If a factory's instance count goes to 0 and the factory has been disabled, the factory is destroyed. */ -CF_PRIVATE void _CFPFactoryAddInstance(_CFPFactoryRef factory) { - /* MF:!!! Assert that factory is enabled. */ - CFRetain(factory); - __CFLock(&factory->_lock); - CFPlugInRef plugin = factory->_plugIn; - if (plugin) CFRetain(plugin); - __CFUnlock(&factory->_lock); - if (plugin) { - _CFPlugInAddPlugInInstance(plugin); - CFRelease(plugin); - } -} - -CF_PRIVATE void _CFPFactoryRemoveInstance(_CFPFactoryRef factory) { - __CFLock(&factory->_lock); - CFPlugInRef plugin = factory->_plugIn; - if (plugin) CFRetain(plugin); - __CFUnlock(&factory->_lock); - if (plugin) { - _CFPlugInRemovePlugInInstance(factory->_plugIn); - CFRelease(plugin); - } - CFRelease(factory); -} - -#pragma mark - - -/* ===================== Finding factories and creating instances ===================== */ -/* For plugIn hosts. */ -/* Functions for finding factories to create specific types and actually creating instances of a type. */ - -CF_EXPORT CFArrayRef CFPlugInFindFactoriesForPlugInType(CFUUIDRef typeID) CF_RETURNS_RETAINED { - __CFLock(&CFPlugInGlobalDataLock); - CFArrayRef array = NULL; - if (_factoriesByTypeID) { - array = (CFArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID); - } - - CFMutableArrayRef result = NULL; - if (array) { - result = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks); - - CFIndex c = CFArrayGetCount(array); - for (CFIndex i = 0; i < c; i++) { - CFUUIDRef factoryId = _CFPFactoryCopyFactoryID((_CFPFactoryRef)CFArrayGetValueAtIndex(array, i)); - if (factoryId) { - CFArrayAppendValue(result, factoryId); - CFRelease(factoryId); - } - } - } - - __CFUnlock(&CFPlugInGlobalDataLock); - return result; -} - -CF_EXPORT CFArrayRef CFPlugInFindFactoriesForPlugInTypeInPlugIn(CFUUIDRef typeID, CFPlugInRef plugIn) CF_RETURNS_RETAINED { - __CFLock(&CFPlugInGlobalDataLock); - CFArrayRef array = NULL; - if (_factoriesByTypeID) { - array = (CFArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID); - } - - - CFMutableArrayRef result = NULL; - if (array) { - CFIndex c = CFArrayGetCount(array); - result = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks); - for (CFIndex i = 0; i < c; i++) { - _CFPFactoryRef factory = (_CFPFactoryRef)CFArrayGetValueAtIndex(array, i); - CFPlugInRef factoryPlugIn = _CFPFactoryCopyPlugIn(factory); - if (factoryPlugIn == plugIn) { - CFUUIDRef factoryId = _CFPFactoryCopyFactoryID(factory); - CFArrayAppendValue(result, factoryId); - CFRelease(factoryId); - } - if (factoryPlugIn) CFRelease(factoryPlugIn); - } - } - - __CFUnlock(&CFPlugInGlobalDataLock); - return result; -} - diff --git a/CoreFoundation/PlugIn.subproj/CFPlugIn_Factory.h b/CoreFoundation/PlugIn.subproj/CFPlugIn_Factory.h index 314c3ac215..eddce1fabb 100644 --- a/CoreFoundation/PlugIn.subproj/CFPlugIn_Factory.h +++ b/CoreFoundation/PlugIn.subproj/CFPlugIn_Factory.h @@ -1,7 +1,7 @@ /* CFPlugIn_Factory.h - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -16,28 +16,6 @@ CF_EXTERN_C_BEGIN typedef struct __CFPFactory *_CFPFactoryRef; -extern _CFPFactoryRef _CFPFactoryCreate(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInFactoryFunction func); -extern _CFPFactoryRef _CFPFactoryCreateByName(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInRef plugIn, CFStringRef funcName); - -extern _CFPFactoryRef _CFPFactoryFind(CFUUIDRef factoryID, Boolean enabled); - -extern CFUUIDRef _CFPFactoryCopyFactoryID(_CFPFactoryRef factory); -extern CFPlugInRef _CFPFactoryCopyPlugIn(_CFPFactoryRef factory); - -extern void *_CFPFactoryCreateInstance(CFAllocatorRef allocator, _CFPFactoryRef factory, CFUUIDRef typeID); -extern void _CFPFactoryDisable(_CFPFactoryRef factory); - -extern void _CFPFactoryFlushFunctionCache(_CFPFactoryRef factory); - -extern void _CFPFactoryAddType(_CFPFactoryRef factory, CFUUIDRef typeID); -extern void _CFPFactoryRemoveType(_CFPFactoryRef factory, CFUUIDRef typeID); - -extern Boolean _CFPFactorySupportsType(_CFPFactoryRef factory, CFUUIDRef typeID); - -/* These methods are called by CFPlugInInstance when an instance is created or destroyed. If a factory's instance count goes to 0 and the factory has been disabled, the factory is destroyed. */ -extern void _CFPFactoryAddInstance(_CFPFactoryRef factory); -extern void _CFPFactoryRemoveInstance(_CFPFactoryRef factory); - CF_EXTERN_C_END #endif /* ! __COREFOUNDATION_CFPLUGIN_FACTORY__ */ diff --git a/CoreFoundation/PlugIn.subproj/CFPlugIn_Instance.c b/CoreFoundation/PlugIn.subproj/CFPlugIn_Instance.c deleted file mode 100644 index 4cbdd52cc6..0000000000 --- a/CoreFoundation/PlugIn.subproj/CFPlugIn_Instance.c +++ /dev/null @@ -1,104 +0,0 @@ -/* CFPlugIn_Instance.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors - - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors - Licensed under Apache License v2.0 with Runtime Library Exception - See http://swift.org/LICENSE.txt for license information - See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Tony Parker -*/ - -#include "CFBundle_Internal.h" -#include "CFInternal.h" -#include "CFRuntime_Internal.h" - -struct __CFPlugInInstance { - CFRuntimeBase _base; - - _CFPFactoryRef factory; - - CFPlugInInstanceGetInterfaceFunction getInterfaceFunction; - CFPlugInInstanceDeallocateInstanceDataFunction deallocateInstanceDataFunction; - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4200) -#endif //_MSC_VER - uint8_t _instanceData[0]; -#ifdef _MSC_VER -#pragma warning(pop) -#endif //_MSC_VER -}; - -static CFStringRef __CFPlugInInstanceCopyDescription(CFTypeRef cf) { - /* MF:!!! Implement me */ - return CFSTR("Some CFPlugInInstance"); -} - -static void __CFPlugInInstanceDeallocate(CFTypeRef cf) { - CFPlugInInstanceRef instance = (CFPlugInInstanceRef)cf; - - __CFGenericValidateType(cf, CFPlugInInstanceGetTypeID()); - - if (instance->deallocateInstanceDataFunction) { - FAULT_CALLBACK((void **)&(instance->deallocateInstanceDataFunction)); - (void)INVOKE_CALLBACK1(instance->deallocateInstanceDataFunction, (void *)(&instance->_instanceData[0])); - } - - if (instance->factory) _CFPFactoryRemoveInstance(instance->factory); -} - -const CFRuntimeClass __CFPlugInInstanceClass = { - 0, - "CFPlugInInstance", - NULL, // init - NULL, // copy - __CFPlugInInstanceDeallocate, - NULL, // equal - NULL, // hash - NULL, // - __CFPlugInInstanceCopyDescription -}; - -CFTypeID CFPlugInInstanceGetTypeID(void) { - return _kCFRuntimeIDCFPlugInInstance; -} - -CF_EXPORT CFPlugInInstanceRef CFPlugInInstanceCreateWithInstanceDataSize(CFAllocatorRef allocator, CFIndex instanceDataSize, CFPlugInInstanceDeallocateInstanceDataFunction deallocateInstanceFunction, CFStringRef factoryName, CFPlugInInstanceGetInterfaceFunction getInterfaceFunction) { - CFPlugInInstanceRef instance; - UInt32 size; - size = sizeof(struct __CFPlugInInstance) + instanceDataSize - sizeof(CFRuntimeBase); - instance = (CFPlugInInstanceRef)_CFRuntimeCreateInstance(allocator, CFPlugInInstanceGetTypeID(), size, NULL); - if (!instance) return NULL; - - instance->factory = _CFPFactoryFind((CFUUIDRef)factoryName, true); - if (instance->factory) _CFPFactoryAddInstance(instance->factory); - instance->getInterfaceFunction = getInterfaceFunction; - instance->deallocateInstanceDataFunction = deallocateInstanceFunction; - - return instance; -} - -CF_EXPORT Boolean CFPlugInInstanceGetInterfaceFunctionTable(CFPlugInInstanceRef instance, CFStringRef interfaceName, void **ftbl) { - void *myFtbl; - Boolean result = false; - - if (instance->getInterfaceFunction) { - FAULT_CALLBACK((void **)&(instance->getInterfaceFunction)); - result = INVOKE_CALLBACK3(instance->getInterfaceFunction, instance, interfaceName, &myFtbl) ? true : false; - } - if (ftbl) *ftbl = (result ? myFtbl : NULL); - return result; -} - -CF_EXPORT CFStringRef CFPlugInInstanceGetFactoryName(CFPlugInInstanceRef instance) { - // This function leaks, but it's the only safe way to access the factory name (on 10.8 or later). - // On 10.9 we added the CF_RETURNS_RETAINED annotation to the header. - CFUUIDRef factoryId = _CFPFactoryCopyFactoryID(instance->factory); - return (CFStringRef)factoryId; -} - -CF_EXPORT void *CFPlugInInstanceGetInstanceData(CFPlugInInstanceRef instance) { - return (void *)(&instance->_instanceData[0]); -} - diff --git a/CoreFoundation/PlugIn.subproj/CFPlugIn_PlugIn.c b/CoreFoundation/PlugIn.subproj/CFPlugIn_PlugIn.c deleted file mode 100644 index 477358ea6f..0000000000 --- a/CoreFoundation/PlugIn.subproj/CFPlugIn_PlugIn.c +++ /dev/null @@ -1,215 +0,0 @@ -/* CFPlugIn_PlugIn.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors - - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors - Licensed under Apache License v2.0 with Runtime Library Exception - See http://swift.org/LICENSE.txt for license information - See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Tony Parker -*/ - -#include "CFBundle_Internal.h" -#include "CFInternal.h" - - -static void _registerFactory(const void *key, const void *val, void *context) { - CFStringRef factoryIDStr = (CFStringRef)key; - CFStringRef factoryFuncStr = (CFStringRef)val; - CFBundleRef bundle = (CFBundleRef)context; - CFUUIDRef factoryID = (CFGetTypeID(factoryIDStr) == CFStringGetTypeID()) ? CFUUIDCreateFromString(kCFAllocatorSystemDefault, factoryIDStr) : NULL; - if (!factoryID) factoryID = (CFUUIDRef)CFRetain(factoryIDStr); - if (CFGetTypeID(factoryFuncStr) != CFStringGetTypeID() || CFStringGetLength(factoryFuncStr) <= 0) factoryFuncStr = NULL; - CFPlugInRegisterFactoryFunctionByName(factoryID, bundle, factoryFuncStr); - if (factoryID) CFRelease(factoryID); -} - -static void _registerType(const void *key, const void *val, void *context) { - CFStringRef typeIDStr = (CFStringRef)key; - CFArrayRef factoryIDStrArray = (CFArrayRef)val; - CFBundleRef bundle = (CFBundleRef)context; - SInt32 i, c = (CFGetTypeID(factoryIDStrArray) == CFArrayGetTypeID()) ? CFArrayGetCount(factoryIDStrArray) : 0; - CFStringRef curFactoryIDStr; - CFUUIDRef typeID = (CFGetTypeID(typeIDStr) == CFStringGetTypeID()) ? CFUUIDCreateFromString(kCFAllocatorSystemDefault, typeIDStr) : NULL; - CFUUIDRef curFactoryID; - if (!typeID) typeID = (CFUUIDRef)CFRetain(typeIDStr); - if (0 == c && CFGetTypeID(factoryIDStrArray) != CFArrayGetTypeID()) { - curFactoryIDStr = (CFStringRef)val; - curFactoryID = (CFGetTypeID(curFactoryIDStr) == CFStringGetTypeID()) ? CFUUIDCreateFromString(CFGetAllocator(bundle), curFactoryIDStr) : NULL; - if (!curFactoryID) curFactoryID = (CFUUIDRef)CFRetain(curFactoryIDStr); - CFPlugInRegisterPlugInType(curFactoryID, typeID); - if (curFactoryID) CFRelease(curFactoryID); - } else for (i = 0; i < c; i++) { - curFactoryIDStr = (CFStringRef)CFArrayGetValueAtIndex(factoryIDStrArray, i); - curFactoryID = (CFGetTypeID(curFactoryIDStr) == CFStringGetTypeID()) ? CFUUIDCreateFromString(CFGetAllocator(bundle), curFactoryIDStr) : NULL; - if (!curFactoryID) curFactoryID = (CFUUIDRef)CFRetain(curFactoryIDStr); - CFPlugInRegisterPlugInType(curFactoryID, typeID); - if (curFactoryID) CFRelease(curFactoryID); - } - if (typeID) CFRelease(typeID); -} - -CF_PRIVATE void _CFBundleInitPlugIn(CFBundleRef bundle) { - CFArrayCallBacks _pluginFactoryArrayCallbacks = {0, NULL, NULL, NULL, NULL}; - Boolean doDynamicReg = false; - CFDictionaryRef infoDict; - CFDictionaryRef factoryDict; - CFDictionaryRef typeDict; - CFStringRef tempStr; - - infoDict = CFBundleGetInfoDictionary(bundle); - if (!infoDict) return; - - factoryDict = (CFDictionaryRef)CFDictionaryGetValue(infoDict, kCFPlugInFactoriesKey); - if (factoryDict && CFGetTypeID(factoryDict) != CFDictionaryGetTypeID()) factoryDict = NULL; - tempStr = (CFStringRef)CFDictionaryGetValue(infoDict, kCFPlugInDynamicRegistrationKey); - if (tempStr && CFGetTypeID(tempStr) == CFStringGetTypeID() && CFStringCompare(tempStr, CFSTR("YES"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) doDynamicReg = true; - if (!factoryDict && !doDynamicReg) return; // This is not a plug-in. - - if (__CFBundleGetPlugInData(bundle)->_registeredFactory) { - // We already registered - don't do it again - return; - } - - /* loadOnDemand is true by default if the plugIn does not do dynamic registration. It is false, by default if it does do dynamic registration. The dynamic register function can set this. */ - __CFBundleGetPlugInData(bundle)->_isPlugIn = true; - __CFBundleGetPlugInData(bundle)->_loadOnDemand = true; - __CFBundleGetPlugInData(bundle)->_isDoingDynamicRegistration = false; - __CFBundleGetPlugInData(bundle)->_instanceCount = 0; - __CFBundleGetPlugInData(bundle)->_registeredFactory = true; - - __CFBundleGetPlugInData(bundle)->_factories = CFArrayCreateMutable(CFGetAllocator(bundle), 0, &_pluginFactoryArrayCallbacks); - - /* Now do the registration */ - - /* First do static registrations, if any. */ - if (factoryDict) CFDictionaryApplyFunction(factoryDict, _registerFactory, bundle); - typeDict = (CFDictionaryRef)CFDictionaryGetValue(infoDict, kCFPlugInTypesKey); - if (typeDict && CFGetTypeID(typeDict) != CFDictionaryGetTypeID()) typeDict = NULL; - if (typeDict) CFDictionaryApplyFunction(typeDict, _registerType, bundle); - - /* Now set key for dynamic registration if necessary */ - if (doDynamicReg) { - CFDictionarySetValue((CFMutableDictionaryRef)infoDict, CFSTR("CFPlugInNeedsDynamicRegistration"), CFSTR("YES")); - if (CFBundleIsExecutableLoaded(bundle)) _CFBundlePlugInLoaded(bundle); - } -} - -CF_PRIVATE void _CFBundlePlugInLoaded(CFBundleRef bundle) { - CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle); - CFStringRef tempStr; - CFPlugInDynamicRegisterFunction func = NULL; - - if (!__CFBundleGetPlugInData(bundle)->_isPlugIn || __CFBundleGetPlugInData(bundle)->_isDoingDynamicRegistration || !infoDict || !CFBundleIsExecutableLoaded(bundle)) return; - - tempStr = (CFStringRef)CFDictionaryGetValue(infoDict, CFSTR("CFPlugInNeedsDynamicRegistration")); - if (tempStr && CFGetTypeID(tempStr) == CFStringGetTypeID() && CFStringCompare(tempStr, CFSTR("YES"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { - CFDictionaryRemoveValue((CFMutableDictionaryRef)infoDict, CFSTR("CFPlugInNeedsDynamicRegistration")); - tempStr = (CFStringRef)CFDictionaryGetValue(infoDict, kCFPlugInDynamicRegisterFunctionKey); - if (!tempStr || CFGetTypeID(tempStr) != CFStringGetTypeID() || CFStringGetLength(tempStr) <= 0) tempStr = CFSTR("CFPlugInDynamicRegister"); - __CFBundleGetPlugInData(bundle)->_loadOnDemand = false; - __CFBundleGetPlugInData(bundle)->_isDoingDynamicRegistration = true; - - /* Find the symbol and call it. */ - func = (CFPlugInDynamicRegisterFunction)CFBundleGetFunctionPointerForName(bundle, tempStr); - if (func) { - func(bundle); - // MF:!!! Unload function is never called. Need to deal with this! - } - - __CFBundleGetPlugInData(bundle)->_isDoingDynamicRegistration = false; - if (__CFBundleGetPlugInData(bundle)->_loadOnDemand && __CFBundleGetPlugInData(bundle)->_instanceCount == 0) CFBundleUnloadExecutable(bundle); // Unload now if we can/should. - } else { - CFDictionaryRemoveValue((CFMutableDictionaryRef)infoDict, CFSTR("CFPlugInNeedsDynamicRegistration")); - } -} - -CF_PRIVATE void _CFBundleDeallocatePlugIn(CFBundleRef bundle) { - if (__CFBundleGetPlugInData(bundle)->_isPlugIn) { - SInt32 c; - - /* Go through factories disabling them. Disabling these factories should cause them to dealloc since we wouldn't be deallocating if any of the factories had outstanding instances. So go backwards. */ - c = CFArrayGetCount(__CFBundleGetPlugInData(bundle)->_factories); - while (c-- > 0) _CFPFactoryDisable((_CFPFactoryRef)CFArrayGetValueAtIndex(__CFBundleGetPlugInData(bundle)->_factories, c)); - CFRelease(__CFBundleGetPlugInData(bundle)->_factories); - - __CFBundleGetPlugInData(bundle)->_isPlugIn = false; - } -} - -CFTypeID CFPlugInGetTypeID(void) { - return CFBundleGetTypeID(); -} - -CFPlugInRef CFPlugInCreate(CFAllocatorRef allocator, CFURLRef plugInURL) { - CFBundleRef bundle = CFBundleCreate(allocator, plugInURL); - return (CFPlugInRef)bundle; -} - -CFBundleRef CFPlugInGetBundle(CFPlugInRef plugIn) { - return (CFBundleRef)plugIn; -} - -void CFPlugInSetLoadOnDemand(CFPlugInRef plugIn, Boolean flag) { - if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) { - __CFBundleGetPlugInData(plugIn)->_loadOnDemand = flag; - if (__CFBundleGetPlugInData(plugIn)->_loadOnDemand && !__CFBundleGetPlugInData(plugIn)->_isDoingDynamicRegistration && __CFBundleGetPlugInData(plugIn)->_instanceCount == 0) { - /* Unload now if we can/should. */ - /* If we are doing dynamic registration currently, do not unload. The unloading will happen when dynamic registration is done, if necessary. */ - CFBundleUnloadExecutable(plugIn); - } else if (!__CFBundleGetPlugInData(plugIn)->_loadOnDemand) { - /* Make sure we're loaded now. */ - CFBundleLoadExecutable(plugIn); - } - } -} - -Boolean CFPlugInIsLoadOnDemand(CFPlugInRef plugIn) { - if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) { - return __CFBundleGetPlugInData(plugIn)->_loadOnDemand; - } else { - return false; - } -} - -CF_PRIVATE void _CFPlugInWillUnload(CFPlugInRef plugIn) { - if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) { - SInt32 c = CFArrayGetCount(__CFBundleGetPlugInData(plugIn)->_factories); - /* First, flush all the function pointers that may be cached by our factories. */ - while (c-- > 0) _CFPFactoryFlushFunctionCache((_CFPFactoryRef)CFArrayGetValueAtIndex(__CFBundleGetPlugInData(plugIn)->_factories, c)); - } -} - -CF_PRIVATE void _CFPlugInAddPlugInInstance(CFPlugInRef plugIn) { - if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) { - if (__CFBundleGetPlugInData(plugIn)->_instanceCount == 0 && __CFBundleGetPlugInData(plugIn)->_loadOnDemand) _CFBundleUnscheduleForUnloading(CFPlugInGetBundle(plugIn)); // Make sure we are not scheduled for unloading - __CFBundleGetPlugInData(plugIn)->_instanceCount++; - /* Instances also retain the CFBundle */ - CFRetain(plugIn); - } -} - -CF_PRIVATE void _CFPlugInRemovePlugInInstance(CFPlugInRef plugIn) { - if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) { - /* MF:!!! Assert that instanceCount > 0. */ - __CFBundleGetPlugInData(plugIn)->_instanceCount--; - if (__CFBundleGetPlugInData(plugIn)->_instanceCount == 0 && __CFBundleGetPlugInData(plugIn)->_loadOnDemand) { - // We unload the code lazily because the code that caused this function to be called is probably code from the plugin itself. If we unload now, we will hose things. - //CFBundleUnloadExecutable(plugIn); - _CFBundleScheduleForUnloading(CFPlugInGetBundle(plugIn)); - } - /* Instances also retain the CFPlugIn */ - /* MF:!!! This will cause immediate unloading if it was the last ref on the plugin. */ - CFRelease(plugIn); - } -} - -CF_PRIVATE void _CFPlugInAddFactory(CFPlugInRef plugIn, _CFPFactoryRef factory) { - if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) CFArrayAppendValue(__CFBundleGetPlugInData(plugIn)->_factories, factory); -} - -CF_PRIVATE void _CFPlugInRemoveFactory(CFPlugInRef plugIn, _CFPFactoryRef factory) { - if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) { - SInt32 idx = CFArrayGetFirstIndexOfValue(__CFBundleGetPlugInData(plugIn)->_factories, CFRangeMake(0, CFArrayGetCount(__CFBundleGetPlugInData(plugIn)->_factories)), factory); - if (idx >= 0) CFArrayRemoveValueAtIndex(__CFBundleGetPlugInData(plugIn)->_factories, idx); - } -} diff --git a/CoreFoundation/Preferences.subproj/CFApplicationPreferences.c b/CoreFoundation/Preferences.subproj/CFApplicationPreferences.c index 37c9964cd2..aac68d3775 100644 --- a/CoreFoundation/Preferences.subproj/CFApplicationPreferences.c +++ b/CoreFoundation/Preferences.subproj/CFApplicationPreferences.c @@ -1,7 +1,7 @@ /* CFApplicationPreferences.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Preferences.subproj/CFPreferences.c b/CoreFoundation/Preferences.subproj/CFPreferences.c index b7b92f2596..005cece4a9 100644 --- a/CoreFoundation/Preferences.subproj/CFPreferences.c +++ b/CoreFoundation/Preferences.subproj/CFPreferences.c @@ -1,7 +1,7 @@ /* CFPreferences.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -423,7 +423,7 @@ static CFStringRef _CFPreferencesStandardDomainCacheKey(CFStringRef domainName static CFURLRef _CFPreferencesURLForStandardDomainWithSafetyLevel(CFStringRef domainName, CFStringRef userName, CFStringRef hostName, unsigned long safeLevel) { CFURLRef theURL = NULL; CFAllocatorRef prefAlloc = __CFPreferencesAllocator(); -#if TARGET_OS_OSX || TARGET_OS_LINUX || TARGET_OS_WIN32 +#if TARGET_OS_OSX || TARGET_OS_WIN32 || TARGET_OS_LINUX CFURLRef prefDir = _preferencesDirectoryForUserHostSafetyLevel(userName, hostName, safeLevel); CFStringRef appName; CFStringRef fileName; diff --git a/CoreFoundation/Preferences.subproj/CFPreferences.h b/CoreFoundation/Preferences.subproj/CFPreferences.h index c37cf7c26b..9022da9fec 100644 --- a/CoreFoundation/Preferences.subproj/CFPreferences.h +++ b/CoreFoundation/Preferences.subproj/CFPreferences.h @@ -1,7 +1,7 @@ /* CFPreferences.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Preferences.subproj/CFXMLPreferencesDomain.c b/CoreFoundation/Preferences.subproj/CFXMLPreferencesDomain.c index f1a2bd0761..2c037657a4 100644 --- a/CoreFoundation/Preferences.subproj/CFXMLPreferencesDomain.c +++ b/CoreFoundation/Preferences.subproj/CFXMLPreferencesDomain.c @@ -1,7 +1,7 @@ /* CFXMLPreferencesDomain.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/RunLoop.subproj/CFMachPort.c b/CoreFoundation/RunLoop.subproj/CFMachPort.c index 33b8f74f18..c40afd8a2b 100644 --- a/CoreFoundation/RunLoop.subproj/CFMachPort.c +++ b/CoreFoundation/RunLoop.subproj/CFMachPort.c @@ -1,11 +1,11 @@ /* CFMachPort.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Christopher Kane + Responsibility: Michael LeHew */ #include @@ -115,9 +115,13 @@ static CFStringRef __CFMachPortCopyDescription(CFTypeRef cf) { // Only call with mp->_lock locked CF_INLINE void __CFMachPortInvalidateLocked(CFRunLoopSourceRef source, CFMachPortRef mp) { CFMachPortInvalidationCallBack cb = mp->_icallout; + void *const info = mp->_context.info; + void (*const release)(const void *info) = mp->release; + + mp->_context.info = NULL; if (cb) { __CFUnlock(&mp->_lock); - cb(mp, mp->_context.info); + cb(mp, info); __CFLock(&mp->_lock); } if (NULL != source) { @@ -126,10 +130,7 @@ CF_INLINE void __CFMachPortInvalidateLocked(CFRunLoopSourceRef source, CFMachPor CFRelease(source); __CFLock(&mp->_lock); } - void *info = mp->_context.info; - void (*release)(const void *info) = mp->release; - mp->_context.info = NULL; - if (release) { + if (release && info) { __CFUnlock(&mp->_lock); release(info); __CFLock(&mp->_lock); @@ -170,7 +171,7 @@ static void __CFMachPortDeallocate(CFTypeRef cf) { } // This lock protects __CFAllMachPorts. Take before any instance-specific lock. -static CFLock_t __CFAllMachPortsLock = CFLockInit; +static os_unfair_lock __CFAllMachPortsLock = OS_UNFAIR_LOCK_INIT; static CFMutableArrayRef __CFAllMachPorts = NULL; @@ -184,8 +185,8 @@ static Boolean __CFMachPortCheck(mach_port_t port) { // This function exists regardless of platform, but is only declared in headers for legacy clients. CF_EXPORT CFIndex CFGetRetainCount(CFTypeRef object); -static void __CFMachPortChecker(Boolean fromTimer) { - __CFLock(&__CFAllMachPortsLock); // take this lock first before any instance-specific lock +static void __CFMachPortChecker(void) { + os_unfair_lock_lock(&__CFAllMachPortsLock); // take this lock first before any instance-specific lock for (CFIndex idx = 0, cnt = __CFAllMachPorts ? CFArrayGetCount(__CFAllMachPorts) : 0; idx < cnt; idx++) { CFMachPortRef mp = (CFMachPortRef)CFArrayGetValueAtIndex(__CFAllMachPorts, idx); if (!mp) continue; @@ -209,7 +210,7 @@ static void __CFMachPortChecker(Boolean fromTimer) { } source = mp->_source; mp->_source = NULL; - CFRetain(mp); + CFRetain(mp); // matched below: __CFUnlock(&mp->_lock); dispatch_async(dispatch_get_main_queue(), ^{ // We can grab the mach port-specific spin lock here since we're no longer on the same thread as the one taking the all mach ports spin lock. @@ -217,7 +218,7 @@ static void __CFMachPortChecker(Boolean fromTimer) { __CFLock(&mp->_lock); __CFMachPortInvalidateLocked(source, mp); __CFUnlock(&mp->_lock); - CFRelease(mp); + CFRelease(mp); // matched above: }); } } @@ -226,7 +227,7 @@ static void __CFMachPortChecker(Boolean fromTimer) { cnt--; } } - __CFUnlock(&__CFAllMachPortsLock); + os_unfair_lock_unlock(&__CFAllMachPortsLock); }; @@ -250,7 +251,7 @@ CFTypeID CFMachPortGetTypeID(void) { * not be cleaned up by CFMachPort; it will increment and decrement * references on the port if the kernel ever allows that in the future, * but will not cleanup any references you got when you got the port. */ -CFMachPortRef _CFMachPortCreateWithPort2(CFAllocatorRef allocator, mach_port_t port, CFMachPortCallBack callout, CFMachPortContext *context, Boolean *shouldFreeInfo, Boolean deathWatch) { +CFMachPortRef _CFMachPortCreateWithPort2(CFAllocatorRef allocator, mach_port_t port, CFMachPortCallBack callout, CFMachPortContext *context, Boolean *shouldFreeInfo) { if (shouldFreeInfo) *shouldFreeInfo = true; CHECK_FOR_FORK_RET(NULL); @@ -264,33 +265,33 @@ CFMachPortRef _CFMachPortCreateWithPort2(CFAllocatorRef allocator, mach_port_t p } CFMachPortRef mp = NULL; - __CFLock(&__CFAllMachPortsLock); - for (CFIndex idx = 0, cnt = __CFAllMachPorts ? CFArrayGetCount(__CFAllMachPorts) : 0; idx < cnt; idx++) { - CFMachPortRef p = (CFMachPortRef)CFArrayGetValueAtIndex(__CFAllMachPorts, idx); - if (p && p->_port == port) { - CFRetain(p); - mp = p; - break; + os_unfair_lock_lock(&__CFAllMachPortsLock); + // First, do a scan for an existing CFMachPortRef for the specified port: + if (__CFAllMachPorts != NULL) { + CFIndex const nPorts = CFArrayGetCount(__CFAllMachPorts); + for (CFIndex idx = 0; idx < nPorts; idx++) { + CFMachPortRef const p = (CFMachPortRef)CFArrayGetValueAtIndex(__CFAllMachPorts, idx); + if (p && p->_port == port) { + CFRetain(p); + mp = p; // mp now has +2 retain count: 1: from set 2: from this local retain + break; + } } } - __CFUnlock(&__CFAllMachPortsLock); - if (!mp) { - CFIndex size = sizeof(struct __CFMachPort) - sizeof(CFRuntimeBase); - CFMachPortRef memory = (CFMachPortRef)_CFRuntimeCreateInstance(allocator, CFMachPortGetTypeID(), size, NULL); + if (mp) { + // We found a matching port, so we're done with the global lock + os_unfair_lock_unlock(&__CFAllMachPortsLock); + } else { + // We need to create a new CFMachPortRef. + // keep the global lock a bit longer, until we add it to the set of all ports. + CFIndex const size = sizeof(struct __CFMachPort) - sizeof(CFRuntimeBase); + CFMachPortRef const memory = (CFMachPortRef)_CFRuntimeCreateInstance(allocator, CFMachPortGetTypeID(), size, NULL); if (NULL == memory) { + os_unfair_lock_unlock(&__CFAllMachPortsLock); return NULL; } memory->_port = port; - memory->_dsrc = NULL; - memory->_icallout = NULL; - memory->_source = NULL; - memory->_context.info = NULL; - memory->_context.retain = NULL; - memory->_context.release = NULL; - memory->_context.copyDescription = NULL; - memory->retain = NULL; - memory->release = NULL; memory->_callout = callout; memory->_lock = CFLockInit; if (NULL != context) { @@ -302,12 +303,14 @@ CFMachPortRef _CFMachPortCreateWithPort2(CFAllocatorRef allocator, mach_port_t p memory->_context.release = (void *)0xAAAAAAAAAABBBAAA; } memory->_state = kCFMachPortStateReady; - __CFLock(&__CFAllMachPortsLock); - if (!__CFAllMachPorts) __CFAllMachPorts = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks); + if (!__CFAllMachPorts) { + // Create the set of all mach ports if it doesn't exist + __CFAllMachPorts = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks); + } CFArrayAppendValue(__CFAllMachPorts, memory); - __CFUnlock(&__CFAllMachPortsLock); - mp = memory; - if (shouldFreeInfo) *shouldFreeInfo = false; + os_unfair_lock_unlock(&__CFAllMachPortsLock); + mp = memory; // NOTE: at this point mp has +2 retain count, 1: from birth 2: from being added to the set + if (shouldFreeInfo) { *shouldFreeInfo = false; } if (type & MACH_PORT_TYPE_SEND_RIGHTS) { _cfmp_record_intent_to_invalidate(_CFMPLifetimeClientCFMachPort, port); @@ -317,7 +320,7 @@ CFMachPortRef _CFMachPortCreateWithPort2(CFAllocatorRef allocator, mach_port_t p _cfmp_source_invalidated(_CFMPLifetimeClientCFMachPort, port); dispatch_release(theSource); }); - dispatch_source_set_event_handler(theSource, ^{ __CFMachPortChecker(false); }); + dispatch_source_set_event_handler(theSource, ^{ __CFMachPortChecker(); }); memory->_dsrc = theSource; dispatch_resume(theSource); } @@ -325,14 +328,14 @@ CFMachPortRef _CFMachPortCreateWithPort2(CFAllocatorRef allocator, mach_port_t p } if (mp && !CFMachPortIsValid(mp)) { // must do this outside lock to avoid deadlock - CFRelease(mp); + CFRelease(mp); // NOTE: we release the extra +1 introduced in this function (or birth) so that the only potential refcount left for this frame is from the set of all ports. mp = NULL; } return mp; } CFMachPortRef CFMachPortCreateWithPort(CFAllocatorRef allocator, mach_port_t port, CFMachPortCallBack callout, CFMachPortContext *context, Boolean *shouldFreeInfo) { - return _CFMachPortCreateWithPort2(allocator, port, callout, context, shouldFreeInfo, true); + return _CFMachPortCreateWithPort2(allocator, port, callout, context, shouldFreeInfo); } CFMachPortRef CFMachPortCreate(CFAllocatorRef allocator, CFMachPortCallBack callout, CFMachPortContext *context, Boolean *shouldFreeInfo) { @@ -350,7 +353,7 @@ CFMachPortRef CFMachPortCreate(CFAllocatorRef allocator, CFMachPortCallBack call } return NULL; } - CFMachPortRef result = _CFMachPortCreateWithPort2(allocator, port, callout, context, shouldFreeInfo, true); + CFMachPortRef result = _CFMachPortCreateWithPort2(allocator, port, callout, context, shouldFreeInfo); if (NULL == result) { if (MACH_PORT_NULL != port) { // both receive and send succeeded above so decrement both @@ -368,10 +371,10 @@ void CFMachPortInvalidate(CFMachPortRef mp) { CHECK_FOR_FORK_RET(); CF_OBJC_FUNCDISPATCHV(CFMachPortGetTypeID(), void, (NSMachPort *)mp, invalidate); __CFGenericValidateType(mp, CFMachPortGetTypeID()); - CFRetain(mp); + CFRetain(mp); // matched below: CFRunLoopSourceRef source = NULL; Boolean wasReady = false; - __CFLock(&__CFAllMachPortsLock); // take this lock first + os_unfair_lock_lock(&__CFAllMachPortsLock); // take this lock first __CFLock(&mp->_lock); wasReady = (mp->_state == kCFMachPortStateReady); if (wasReady) { @@ -392,13 +395,13 @@ void CFMachPortInvalidate(CFMachPortRef mp) { mp->_source = NULL; } __CFUnlock(&mp->_lock); - __CFUnlock(&__CFAllMachPortsLock); // release this lock last + os_unfair_lock_unlock(&__CFAllMachPortsLock); // release this lock last if (wasReady) { __CFLock(&mp->_lock); __CFMachPortInvalidateLocked(source, mp); __CFUnlock(&mp->_lock); } - CFRelease(mp); + CFRelease(mp); // matched above: } mach_port_t CFMachPortGetPort(CFMachPortRef mp) { @@ -448,11 +451,12 @@ void CFMachPortSetInvalidationCallBack(CFMachPortRef mp, CFMachPortInvalidationC } } __CFLock(&mp->_lock); + void *const info = mp->_context.info; if (__CFMachPortIsValid(mp) || !callout) { mp->_icallout = callout; } else if (!mp->_icallout && callout) { __CFUnlock(&mp->_lock); - callout(mp, mp->_context.info); + callout(mp, info); __CFLock(&mp->_lock); } else { CFLog(kCFLogLevelWarning, CFSTR("CFMachPortSetInvalidationCallBack(): attempt to set invalidation callback (%p) on invalid CFMachPort (%p) thwarted"), callout, mp); @@ -497,7 +501,9 @@ CF_PRIVATE void *__CFMachPortPerform(void *msg, CFIndex size, CFAllocatorRef all if (context_release) { context_release(context_info); } - CHECK_FOR_FORK_RET(NULL); + if (HAS_FORKED()) { + return NULL; + } } return NULL; } @@ -536,26 +542,30 @@ CFRunLoopSourceRef CFMachPortCreateRunLoopSource(CFAllocatorRef allocator, CFMac } void __CFMachMessageCheckForAndDestroyUnsentMessage(kern_return_t const kr, mach_msg_header_t *const msg) { + // Account for the psuedo-receive of the local port described in [39359253] switch (kr) { - case MACH_SEND_TIMEOUT: + case MACH_SEND_TIMEOUT: // fallthrough case MACH_SEND_INTERRUPTED: { - // pseudo-receive mach_port_t const localPort = msg->msgh_local_port; if (MACH_PORT_VALID(localPort)) { - // handle pseudo-receive of local_port mach_msg_bits_t const mbits = MACH_MSGH_BITS_LOCAL(msg->msgh_bits); if (mbits == MACH_MSG_TYPE_MOVE_SEND || mbits == MACH_MSG_TYPE_MOVE_SEND_ONCE) { mach_port_deallocate(mach_task_self(), localPort); } msg->msgh_bits &= ~MACH_MSGH_BITS_LOCAL_MASK; } - } // fallthrough - case MACH_SEND_INVALID_HEADER: + break; + } + default: + break; + } + + // [53512422] It is only reasonable to destroy the msg for the following: + switch (kr) { + case MACH_SEND_TIMEOUT: // fallthrough case MACH_SEND_INVALID_DEST: - case MACH_SEND_INVALID_REPLY: - case MACH_SEND_INVALID_VOUCHER: - // destroy unsent message mach_msg_destroy(msg); + default: break; } } diff --git a/CoreFoundation/RunLoop.subproj/CFMachPort.h b/CoreFoundation/RunLoop.subproj/CFMachPort.h index f9371a7718..99c19e03a8 100644 --- a/CoreFoundation/RunLoop.subproj/CFMachPort.h +++ b/CoreFoundation/RunLoop.subproj/CFMachPort.h @@ -1,7 +1,7 @@ /* CFMachPort.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/RunLoop.subproj/CFMachPort_Internal.h b/CoreFoundation/RunLoop.subproj/CFMachPort_Internal.h index 2e33e76588..5756041bd3 100644 --- a/CoreFoundation/RunLoop.subproj/CFMachPort_Internal.h +++ b/CoreFoundation/RunLoop.subproj/CFMachPort_Internal.h @@ -1,7 +1,7 @@ /* CFMachPort_Internal.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/RunLoop.subproj/CFMachPort_Lifetime.c b/CoreFoundation/RunLoop.subproj/CFMachPort_Lifetime.c index f943a1acc8..f385e643fa 100644 --- a/CoreFoundation/RunLoop.subproj/CFMachPort_Lifetime.c +++ b/CoreFoundation/RunLoop.subproj/CFMachPort_Lifetime.c @@ -1,6 +1,6 @@ /* CFMachPort_Lifetime.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors All of the functions in this file exist to orchestrate the exact time/circumstances we decrement the port references. */ @@ -112,7 +112,7 @@ static void _cfmp_deallocation_record_release(CFAllocatorRef const allocator, vo if (!pr->inSet) { _cfmp_log_failure("Freeing a record not in the set", pr, pr->client, pr->port); } - free((_cfmp_deallocation_record *)value); + free(pr); } static CFStringRef _cfmp_copy_description(const void *value) { CFStringRef s = CFSTR("{null}"); @@ -161,8 +161,7 @@ CF_PRIVATE void _cfmp_cleanup(_cfmp_deallocation_record const R) { /// Records that a given mach_port has been deallocated. void _cfmp_record_deallocation(_CFMPLifetimeClient const client, mach_port_t const port, Boolean const doSend, Boolean const doReceive) { if (port == MACH_PORT_NULL) { return; } - if (doSend == false && doReceive == false) { return; } - + // now that we know we're not a no-op, look for an existing deallocation record CFMutableSetRef records = _cfmp_records(); @@ -208,8 +207,14 @@ void _cfmp_record_intent_to_invalidate(_CFMPLifetimeClient const client, mach_po CFMutableSetRef const records = _cfmp_records(); os_unfair_lock_lock(&_cfmp_records_lock); - CFSetAddValue(records, pr); - os_unfair_lock_unlock(&_cfmp_records_lock); + if (CFSetGetValue(records, pr) != NULL) { + // since we calloc before we insert; we check to make sure records doesn't already have an entry for this port + os_unfair_lock_unlock(&_cfmp_records_lock); + free(pr); + } else { + CFSetAddValue(records, pr); + os_unfair_lock_unlock(&_cfmp_records_lock); + } } void _cfmp_source_invalidated(_CFMPLifetimeClient const client, mach_port_t port) { diff --git a/CoreFoundation/RunLoop.subproj/CFMachPort_Lifetime.h b/CoreFoundation/RunLoop.subproj/CFMachPort_Lifetime.h index 9f652fece7..307e4e5f71 100644 --- a/CoreFoundation/RunLoop.subproj/CFMachPort_Lifetime.h +++ b/CoreFoundation/RunLoop.subproj/CFMachPort_Lifetime.h @@ -1,7 +1,7 @@ /* CFMachPort_Lifetime.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors Utilities for orchestrating the exact time/circumstances we decrement mach_port rights for CF types that make use of: deallocate, invalidate diff --git a/CoreFoundation/RunLoop.subproj/CFMessagePort.c b/CoreFoundation/RunLoop.subproj/CFMessagePort.c index ad30bfbc08..2df2c92678 100644 --- a/CoreFoundation/RunLoop.subproj/CFMessagePort.c +++ b/CoreFoundation/RunLoop.subproj/CFMessagePort.c @@ -1,11 +1,11 @@ /* CFMessagePort.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Christopher Kane + Responsibility: Michael LeHew */ #include @@ -54,7 +54,7 @@ extern pid_t getpid(void); #define __CFMessagePortMaxDataSize 0x60000000L -static CFLock_t __CFAllMessagePortsLock = CFLockInit; +static os_unfair_lock __CFAllMessagePortsLock = OS_UNFAIR_LOCK_INIT; static CFMutableDictionaryRef __CFAllLocalMessagePorts = NULL; static CFMutableDictionaryRef __CFAllRemoteMessagePorts = NULL; @@ -254,7 +254,7 @@ static void __CFMessagePortDeallocate(CFTypeRef cf) { // auto-invalidating; so we manually implement the 'auto-invalidation' here by // tickling each remote port to check its state after any message port is destroyed, // but most importantly after local message ports are destroyed. - __CFLock(&__CFAllMessagePortsLock); + os_unfair_lock_lock(&__CFAllMessagePortsLock); CFMessagePortRef *remotePorts = NULL; CFIndex cnt = 0; if (NULL != __CFAllRemoteMessagePorts) { @@ -265,7 +265,7 @@ static void __CFMessagePortDeallocate(CFTypeRef cf) { CFRetain(remotePorts[idx]); } } - __CFUnlock(&__CFAllMessagePortsLock); + os_unfair_lock_unlock(&__CFAllMessagePortsLock); if (remotePorts) { for (CFIndex idx = 0; idx < cnt; idx++) { // as a side-effect, this will auto-invalidate the CFMessagePort if the CFMachPort is invalid @@ -292,7 +292,7 @@ CFTypeID CFMessagePortGetTypeID(void) { return _kCFRuntimeIDCFMessagePort; } -static CFStringRef __CFMessagePortSanitizeStringName(CFStringRef name, uint8_t **utfnamep, CFIndex *utfnamelenp) CF_RETURNS_RETAINED { +static CFStringRef __CFMessagePortCreateSanitizedStringName(CFStringRef name, uint8_t **utfnamep, CFIndex *utfnamelenp) { uint8_t *utfname; CFIndex utflen; CFStringRef result = NULL; @@ -339,15 +339,15 @@ static CFMessagePortRef __CFMessagePortCreateLocal(CFAllocatorRef allocator, CFS CFStringRef name = NULL; if (inName != NULL) { - name = __CFMessagePortSanitizeStringName(inName, &utfname, NULL); + name = __CFMessagePortCreateSanitizedStringName(inName, &utfname, NULL); } - __CFLock(&__CFAllMessagePortsLock); + os_unfair_lock_lock(&__CFAllMessagePortsLock); if (!perPID && NULL != name) { CFMessagePortRef existing; if (NULL != __CFAllLocalMessagePorts && CFDictionaryGetValueIfPresent(__CFAllLocalMessagePorts, name, (const void **)&existing)) { CFRetain(existing); - __CFUnlock(&__CFAllMessagePortsLock); + os_unfair_lock_unlock(&__CFAllMessagePortsLock); CFRelease(name); CFAllocatorDeallocate(kCFAllocatorSystemDefault, utfname); if (!CFMessagePortIsValid(existing)) { // must do this outside lock to avoid deadlock @@ -357,7 +357,7 @@ static CFMessagePortRef __CFMessagePortCreateLocal(CFAllocatorRef allocator, CFS return (CFMessagePortRef)(existing); } } - __CFUnlock(&__CFAllMessagePortsLock); + os_unfair_lock_unlock(&__CFAllMessagePortsLock); CFIndex size = sizeof(struct __CFMessagePort) - sizeof(CFRuntimeBase); memory = (CFMessagePortRef)_CFRuntimeCreateInstance(allocator, CFMessagePortGetTypeID(), size, NULL); if (NULL == memory) { @@ -371,29 +371,18 @@ static CFMessagePortRef __CFMessagePortCreateLocal(CFAllocatorRef allocator, CFS __CFMessagePortUnsetExtraMachRef(memory); __CFMessagePortUnsetRemote(memory); memory->_lock = CFLockInit; - memory->_name = name; // memory takes ownership of name henceforth - memory->_port = NULL; - memory->_replies = NULL; - memory->_convCounter = 0; - memory->_perPID = perPID ? getpid() : 0; // actual value not terribly useful for local ports - memory->_replyPort = NULL; - memory->_source = NULL; - memory->_dispatchSource = NULL; - memory->_dispatchQ = NULL; - memory->_icallout = NULL; + memory->_name = name; + if (perPID) { + memory->_perPID = getpid(); // actual value not terribly useful for local ports + } memory->_callout = callout; memory->_calloutEx = calloutEx; - memory->_context.info = NULL; - memory->_context.retain = NULL; - memory->_context.release = NULL; - memory->_context.copyDescription = NULL; // sadly this is mostly a repeat of SetName function below sans locks... if (NULL != name) { CFMachPortRef native = NULL; kern_return_t ret; - mach_port_t bs, mp; - task_get_bootstrap_port(mach_task_self(), &bs); + mach_port_t mp; if (!perPID) { } if (!native) { @@ -417,12 +406,12 @@ static CFMessagePortRef __CFMessagePortCreateLocal(CFAllocatorRef allocator, CFS memmove(&memory->_context, context, sizeof(CFMessagePortContext)); memory->_context.info = context->retain ? (void *)context->retain(context->info) : context->info; } - __CFLock(&__CFAllMessagePortsLock); + os_unfair_lock_lock(&__CFAllMessagePortsLock); if (!perPID && NULL != name) { CFMessagePortRef existing; if (NULL != __CFAllLocalMessagePorts && CFDictionaryGetValueIfPresent(__CFAllLocalMessagePorts, name, (const void **)&existing)) { CFRetain(existing); - __CFUnlock(&__CFAllMessagePortsLock); + os_unfair_lock_unlock(&__CFAllMessagePortsLock); CFRelease(memory); return (CFMessagePortRef)(existing); } @@ -431,7 +420,7 @@ static CFMessagePortRef __CFMessagePortCreateLocal(CFAllocatorRef allocator, CFS } CFDictionaryAddValue(__CFAllLocalMessagePorts, name, memory); } - __CFUnlock(&__CFAllMessagePortsLock); + os_unfair_lock_unlock(&__CFAllMessagePortsLock); if (shouldFreeInfo) *shouldFreeInfo = false; return memory; } @@ -454,19 +443,19 @@ static CFMessagePortRef __CFMessagePortCreateRemote(CFAllocatorRef allocator, CF CFMachPortContext ctx; uint8_t *utfname = NULL; CFIndex size; - mach_port_t bp, port; + mach_port_t port; kern_return_t ret; - CFStringRef const name = __CFMessagePortSanitizeStringName(inName, &utfname, NULL); + CFStringRef const name = __CFMessagePortCreateSanitizedStringName(inName, &utfname, NULL); if (NULL == name) { return NULL; } - __CFLock(&__CFAllMessagePortsLock); + os_unfair_lock_lock(&__CFAllMessagePortsLock); if (!perPID && NULL != name) { CFMessagePortRef existing; if (NULL != __CFAllRemoteMessagePorts && CFDictionaryGetValueIfPresent(__CFAllRemoteMessagePorts, name, (const void **)&existing)) { CFRetain(existing); - __CFUnlock(&__CFAllMessagePortsLock); + os_unfair_lock_unlock(&__CFAllMessagePortsLock); CFRelease(name); CFAllocatorDeallocate(kCFAllocatorSystemDefault, utfname); if (!CFMessagePortIsValid(existing)) { // must do this outside lock to avoid deadlock @@ -476,7 +465,7 @@ static CFMessagePortRef __CFMessagePortCreateRemote(CFAllocatorRef allocator, CF return (CFMessagePortRef)(existing); } } - __CFUnlock(&__CFAllMessagePortsLock); + os_unfair_lock_unlock(&__CFAllMessagePortsLock); size = sizeof(struct __CFMessagePort) - sizeof(CFMessagePortContext) - sizeof(CFRuntimeBase); memory = (CFMessagePortRef)_CFRuntimeCreateInstance(allocator, CFMessagePortGetTypeID(), size, NULL); if (NULL == memory) { @@ -491,23 +480,15 @@ static CFMessagePortRef __CFMessagePortCreateRemote(CFAllocatorRef allocator, CF __CFMessagePortSetRemote(memory); memory->_lock = CFLockInit; memory->_name = name; - memory->_port = NULL; - memory->_replies = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, NULL); - memory->_convCounter = 0; - memory->_perPID = perPID ? pid : 0; - memory->_replyPort = NULL; - memory->_source = NULL; - memory->_dispatchSource = NULL; - memory->_dispatchQ = NULL; - memory->_icallout = NULL; - memory->_callout = NULL; - memory->_calloutEx = NULL; + memory->_replies = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks); + if (perPID) { + memory->_perPID = pid; + } ctx.version = 0; ctx.info = memory; ctx.retain = NULL; ctx.release = NULL; ctx.copyDescription = NULL; - task_get_bootstrap_port(mach_task_self(), &bp); native = (KERN_SUCCESS == ret) ? CFMachPortCreateWithPort(allocator, port, __CFMessagePortDummyCallback, &ctx, NULL) : NULL; CFAllocatorDeallocate(kCFAllocatorSystemDefault, utfname); if (NULL == native) { @@ -517,12 +498,12 @@ static CFMessagePortRef __CFMessagePortCreateRemote(CFAllocatorRef allocator, CF } memory->_port = native; __CFMessagePortSetValid(memory); - __CFLock(&__CFAllMessagePortsLock); + os_unfair_lock_lock(&__CFAllMessagePortsLock); if (!perPID && NULL != name) { CFMessagePortRef existing; if (NULL != __CFAllRemoteMessagePorts && CFDictionaryGetValueIfPresent(__CFAllRemoteMessagePorts, name, (const void **)&existing)) { CFRetain(existing); - __CFUnlock(&__CFAllMessagePortsLock); + os_unfair_lock_unlock(&__CFAllMessagePortsLock); CFRelease(memory); return (CFMessagePortRef)(existing); } @@ -532,7 +513,7 @@ static CFMessagePortRef __CFMessagePortCreateRemote(CFAllocatorRef allocator, CF CFDictionaryAddValue(__CFAllRemoteMessagePorts, name, memory); } CFRetain(native); - __CFUnlock(&__CFAllMessagePortsLock); + os_unfair_lock_unlock(&__CFAllMessagePortsLock); CFMachPortSetInvalidationCallBack(native, __CFMessagePortInvalidationCallBack); // that set-invalidation-callback might have called back into us // if the CFMachPort is already bad, but that was a no-op since @@ -571,22 +552,22 @@ Boolean CFMessagePortSetName(CFMessagePortRef ms, CFStringRef inName) { __CFGenericValidateType(ms, CFMessagePortGetTypeID()); if (ms->_perPID || __CFMessagePortIsRemote(ms)) return false; - CFStringRef const name = __CFMessagePortSanitizeStringName(inName, &utfname, NULL); + CFStringRef const name = __CFMessagePortCreateSanitizedStringName(inName, &utfname, NULL); if (NULL == name) { return false; } - __CFLock(&__CFAllMessagePortsLock); + os_unfair_lock_lock(&__CFAllMessagePortsLock); if (NULL != name) { CFMessagePortRef existing; if (NULL != __CFAllLocalMessagePorts && CFDictionaryGetValueIfPresent(__CFAllLocalMessagePorts, name, (const void **)&existing)) { - __CFUnlock(&__CFAllMessagePortsLock); + os_unfair_lock_unlock(&__CFAllMessagePortsLock); CFRelease(name); CFAllocatorDeallocate(kCFAllocatorSystemDefault, utfname); return false; } } - __CFUnlock(&__CFAllMessagePortsLock); + os_unfair_lock_unlock(&__CFAllMessagePortsLock); __CFMessagePortLock(ms); @@ -655,7 +636,7 @@ Boolean CFMessagePortSetName(CFMessagePortRef ms, CFStringRef inName) { CFMachPortInvalidate(oldPort); CFRelease(oldPort); } - __CFLock(&__CFAllMessagePortsLock); + os_unfair_lock_lock(&__CFAllMessagePortsLock); // This relocking without checking to see if something else has grabbed // that name in the cache is rather suspect, but what would that even // mean has happened? We'd expect the bootstrap_* calls above to have @@ -672,7 +653,7 @@ Boolean CFMessagePortSetName(CFMessagePortRef ms, CFStringRef inName) { } ms->_name = name; // consumes the +1 from sanitize above CFDictionaryAddValue(__CFAllLocalMessagePorts, name, ms); - __CFUnlock(&__CFAllMessagePortsLock); + os_unfair_lock_unlock(&__CFAllMessagePortsLock); } else if (name) { // if setting the same name on the message port, then avoid leak @@ -692,6 +673,9 @@ void CFMessagePortGetContext(CFMessagePortRef ms, CFMessagePortContext *context) void CFMessagePortInvalidate(CFMessagePortRef ms) { __CFGenericValidateType(ms, CFMessagePortGetTypeID()); + if (ms == NULL) { + return; + } if (!__CFMessagePortIsDeallocing(ms)) { CFRetain(ms); } @@ -720,11 +704,11 @@ void CFMessagePortInvalidate(CFMessagePortRef ms) { ms->_port = NULL; __CFMessagePortUnlock(ms); - __CFLock(&__CFAllMessagePortsLock); + os_unfair_lock_lock(&__CFAllMessagePortsLock); if (0 == ms->_perPID && NULL != name && NULL != (__CFMessagePortIsRemote(ms) ? __CFAllRemoteMessagePorts : __CFAllLocalMessagePorts)) { CFDictionaryRemoveValue(__CFMessagePortIsRemote(ms) ? __CFAllRemoteMessagePorts : __CFAllLocalMessagePorts, name); } - __CFUnlock(&__CFAllMessagePortsLock); + os_unfair_lock_unlock(&__CFAllMessagePortsLock); if (NULL != callout) { callout(ms, info); } @@ -818,6 +802,7 @@ static void __CFMessagePortReplyCallBack(CFMachPortRef port, void *msg, CFIndex invalidComplex = (msgp->header.msgh_bits & MACH_MSGH_BITS_COMPLEX) && ((1 != msgp->body.msgh_descriptor_count) || MSGP_GET(msgp, ool).type != MACH_MSG_OOL_DESCRIPTOR); wayTooBig = ((int32_t)MSGP_SIZE(msgp) + __CFMessagePortMaxInlineBytes) < msgp->header.msgh_size; // also less than a 32-bit signed int can hold } + Boolean wrongSize = false; if (!(invalidComplex || wayTooBig || wayTooSmall)) { byteslen = CFSwapInt32LittleToHost(MSGP_INFO(msgp, byteslen)); @@ -837,7 +822,7 @@ static void __CFMessagePortReplyCallBack(CFMachPortRef port, void *msg, CFIndex } if (CFDictionaryContainsKey(ms->_replies, (void *)(uintptr_t)MSGP_INFO(msgp, convid))) { - CFDataRef reply = NULL; + CFTypeRef reply = NULL; replymsg = (mach_msg_base_t *)msg; if (!(replymsg->header.msgh_bits & MACH_MSGH_BITS_COMPLEX)) { uintptr_t msgp_extent = (uintptr_t)((uint8_t *)msgp + msgp->header.msgh_size); @@ -845,15 +830,16 @@ static void __CFMessagePortReplyCallBack(CFMachPortRef port, void *msg, CFIndex if (byteslen < 0) byteslen = 0; // from here on, treat negative same as zero -- this is historical behavior: a NULL return from the callback on the other side results in empty data to the original requestor if (0 <= byteslen && data_extent <= msgp_extent) { reply = CFDataCreate(kCFAllocatorSystemDefault, MSGP_INFO(replymsg, bytes), byteslen); - } else { - reply = (void *)~0; // means NULL data - } - } else { -//#warning CF: should create a no-copy data here that has a custom VM-freeing allocator, and not vm_dealloc here + } else { + reply = CFRetain(kCFBooleanFalse); // means NULL data + } + } else { + //#warning CF: should create a no-copy data here that has a custom VM-freeing allocator, and not vm_dealloc here reply = CFDataCreate(kCFAllocatorSystemDefault, MSGP_GET(replymsg, ool).address, MSGP_GET(replymsg, ool).size); vm_deallocate(mach_task_self(), (vm_address_t)MSGP_GET(replymsg, ool).address, MSGP_GET(replymsg, ool).size); } - CFDictionarySetValue(ms->_replies, (void *)(uintptr_t)MSGP_INFO(msgp, convid), (void *)reply); + CFDictionarySetValue(ms->_replies, (void *)(uintptr_t)MSGP_INFO(msgp, convid), reply); + CFRelease(reply); } else { /* discard message */ if (msgp->header.msgh_bits & MACH_MSGH_BITS_COMPLEX) { vm_deallocate(mach_task_self(), (vm_address_t)MSGP_GET(msgp, ool).address, MSGP_GET(msgp, ool).size); @@ -866,7 +852,7 @@ SInt32 CFMessagePortSendRequest(CFMessagePortRef remote, SInt32 msgid, CFDataRef mach_msg_base_t *sendmsg; CFRunLoopRef currentRL = CFRunLoopGetCurrent(); CFRunLoopSourceRef source = NULL; - CFDataRef reply = NULL; + CFTypeRef reply = NULL; uint64_t termTSR; uint32_t sendOpts = 0, sendTimeOut = 0; int32_t desiredReply; @@ -903,7 +889,7 @@ SInt32 CFMessagePortSendRequest(CFMessagePortRef remote, SInt32 msgid, CFDataRef return kCFMessagePortTransportError; } if (replyMode != NULL) { - CFDictionarySetValue(remote->_replies, (void *)(uintptr_t)desiredReply, NULL); + CFDictionarySetValue(remote->_replies, (void *)(uintptr_t)desiredReply, kCFNull); source = CFMachPortCreateRunLoopSource(CFGetAllocator(remote), remote->_replyPort, -100); didRegister = !CFRunLoopContainsSource(currentRL, source, replyMode); if (didRegister) { @@ -915,14 +901,16 @@ SInt32 CFMessagePortSendRequest(CFMessagePortRef remote, SInt32 msgid, CFDataRef sendOpts = MACH_SEND_TIMEOUT; sendTimeout *= 1000.0; if (sendTimeout < 1.0) sendTimeout = 0.0; - sendTimeOut = floor(sendTimeout); + sendTimeOut = (uint32_t)floor(sendTimeout); } __CFMessagePortUnlock(remote); ret = mach_msg((mach_msg_header_t *)sendmsg, MACH_SEND_MSG|sendOpts, sendmsg->header.msgh_size, 0, MACH_PORT_NULL, sendTimeOut, MACH_PORT_NULL); __CFMessagePortLock(remote); if (KERN_SUCCESS != ret) { // need to deallocate the send-once right that might have been created - if (replyMode != NULL) { + if (replyMode != NULL && + (ret == MACH_SEND_INVALID_DEST || ret == MACH_SEND_TIMED_OUT) // [55207069] it is only valid to clean cleaup the local port for these two return values; to do otherwise is unsafe/undefined-behavior + ) { mach_port_deallocate(mach_task_self(), ((mach_msg_header_t *)sendmsg)->msgh_local_port); } if (didRegister) { @@ -946,7 +934,7 @@ SInt32 CFMessagePortSendRequest(CFMessagePortRef remote, SInt32 msgid, CFDataRef CFRunLoopRunInMode(replyMode, __CFTimeIntervalUntilTSR(termTSR), true); // warning: what, if anything, should be done if remote is now invalid? reply = CFDictionaryGetValue(remote->_replies, (void *)(uintptr_t)desiredReply); - if (NULL != reply || termTSR < mach_absolute_time()) { + if (!(NULL == reply || kCFNull == reply) || termTSR < mach_absolute_time()) { break; } if (!CFMessagePortIsValid(remote)) { @@ -959,15 +947,15 @@ SInt32 CFMessagePortSendRequest(CFMessagePortRef remote, SInt32 msgid, CFDataRef CFRunLoopRemoveSource(currentRL, source, replyMode); } if (source) CFRelease(source); - if (NULL == reply) { + // kCFNull is the placeholder for a reply mode + if (NULL == reply || kCFNull == reply) { CFDictionaryRemoveValue(remote->_replies, (void *)(uintptr_t)desiredReply); CFRelease(remote); return CFMessagePortIsValid(remote) ? kCFMessagePortReceiveTimeout : kCFMessagePortBecameInvalidError; } if (NULL != returnDatap) { - *returnDatap = ((void *)~0 == reply) ? NULL : reply; - } else if ((void *)~0 != reply) { - CFRelease(reply); + // kCFBooleanFalse is the placeholder for a null data + *returnDatap = (kCFBooleanFalse == reply) ? NULL : CFRetain((CFDataRef)reply); } CFDictionaryRemoveValue(remote->_replies, (void *)(uintptr_t)desiredReply); CFRelease(remote); diff --git a/CoreFoundation/RunLoop.subproj/CFMessagePort.h b/CoreFoundation/RunLoop.subproj/CFMessagePort.h index 221bd114e3..5ec1fc847b 100644 --- a/CoreFoundation/RunLoop.subproj/CFMessagePort.h +++ b/CoreFoundation/RunLoop.subproj/CFMessagePort.h @@ -1,7 +1,7 @@ /* CFMessagePort.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/RunLoop.subproj/CFRunLoop.c b/CoreFoundation/RunLoop.subproj/CFRunLoop.c index 163f9c3254..3855245c6c 100644 --- a/CoreFoundation/RunLoop.subproj/CFRunLoop.c +++ b/CoreFoundation/RunLoop.subproj/CFRunLoop.c @@ -1,7 +1,7 @@ /* CFRunLoop.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -33,40 +33,29 @@ extern void objc_terminate(void); -#if __has_include() -#include -#else -enum { - CHECKINT_NO_ERROR = 0, - CHECKINT_OVERFLOW_ERROR = (1 << 0), -}; - -CF_INLINE uint64_t check_uint64_add(uint64_t x, uint64_t y, int32_t* err) { - if((ULLONG_MAX - y) < x) - *err = *err | CHECKINT_OVERFLOW_ERROR; - return x + y; -}; -#endif +#include "CFOverflow.h" -#if TARGET_OS_MAC || TARGET_OS_WIN32 +#if TARGET_OS_MAC || TARGET_OS_WIN32 || !DEPLOYMENT_RUNTIME_OBJC #define USE_DISPATCH_SOURCE_FOR_TIMERS __HAS_DISPATCH__ -#define USE_MK_TIMER_TOO 1 #else #define USE_DISPATCH_SOURCE_FOR_TIMERS 0 -#define USE_MK_TIMER_TOO 1 #endif -#if __HAS_DISPATCH__ -#if __has_include() -#include -#else -extern dispatch_queue_t _dispatch_runloop_root_queue_create_4CF(const char *_Nullable label, unsigned long flags); #if USE_DISPATCH_SOURCE_FOR_TIMERS #if !TARGET_OS_MAC typedef uint32_t mach_port_t; +typedef uint32_t mach_port_name_t; +#endif #endif + +#if __HAS_DISPATCH__ && __has_include() +#include +#else +extern dispatch_queue_t _dispatch_runloop_root_queue_create_4CF(const char *_Nullable label, unsigned long flags); +#if TARGET_OS_MAC extern mach_port_t _dispatch_runloop_root_queue_get_port_4CF(dispatch_queue_t queue); #endif +#endif extern void _dispatch_source_set_runloop_timer_4CF(dispatch_source_t source, dispatch_time_t start, uint64_t interval, uint64_t leeway); extern bool _dispatch_runloop_root_queue_perform_4CF(dispatch_queue_t queue); @@ -78,10 +67,7 @@ typedef int dispatch_runloop_handle_t; typedef HANDLE dispatch_runloop_handle_t; #endif -#endif -#endif - -#if TARGET_OS_MAC || DEPLOYMENT_TARGET_SIMULATOR +#if TARGET_OS_MAC #include #include #include @@ -209,6 +195,11 @@ static _CFThreadRef const kNilPthreadT = (_CFThreadRef)0; #define CFRUNLOOP_WAKEUP_FOR_WAKEUP_ENABLED() (0) #endif +#define CFRUNLOOP_ARP_BEGIN +#define CFRUNLOOP_ARP_END + + + // NOTE: this is locally defined rather than in CFInternal.h as on Linux, // `linux/sysctl.h` defines `struct __sysctl_args` with an `__unused` member @@ -225,95 +216,7 @@ static _CFThreadRef const kNilPthreadT = (_CFThreadRef)0; // In order to reuse most of the code across Mach and Windows v1 RunLoopSources, we define a // simple abstraction layer spanning Mach ports and Windows HANDLES -#if TARGET_OS_MAC - -CF_PRIVATE uint32_t __CFGetProcessPortCount(void) { - ipc_info_space_t info; - ipc_info_name_array_t table = 0; - mach_msg_type_number_t tableCount = 0; - ipc_info_tree_name_array_t tree = 0; - mach_msg_type_number_t treeCount = 0; - - kern_return_t ret = mach_port_space_info(mach_task_self(), &info, &table, &tableCount, &tree, &treeCount); - if (ret != KERN_SUCCESS) { - return (uint32_t)0; - } - if (table != NULL) { - ret = vm_deallocate(mach_task_self(), (vm_address_t)table, tableCount * sizeof(*table)); - } - if (tree != NULL) { - ret = vm_deallocate(mach_task_self(), (vm_address_t)tree, treeCount * sizeof(*tree)); - } - return (uint32_t)tableCount; -} - -CF_PRIVATE CFArrayRef __CFStopAllThreads(void) { - CFMutableArrayRef suspended_list = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, NULL); - mach_port_t my_task = mach_task_self(); - mach_port_t my_thread = mach_thread_self(); - thread_act_array_t thr_list = 0; - mach_msg_type_number_t thr_cnt = 0; - - // really, should loop doing the stopping until no more threads get added to the list N times in a row - kern_return_t ret = task_threads(my_task, &thr_list, &thr_cnt); - if (ret == KERN_SUCCESS) { - for (CFIndex idx = 0; idx < thr_cnt; idx++) { - thread_act_t thread = thr_list[idx]; - if (thread == my_thread) continue; - if (CFArrayContainsValue(suspended_list, CFRangeMake(0, CFArrayGetCount(suspended_list)), (const void *)(uintptr_t)thread)) continue; - ret = thread_suspend(thread); - if (ret == KERN_SUCCESS) { - CFArrayAppendValue(suspended_list, (const void *)(uintptr_t)thread); - } else { - mach_port_deallocate(my_task, thread); - } - } - vm_deallocate(my_task, (vm_address_t)thr_list, sizeof(thread_t) * thr_cnt); - } - mach_port_deallocate(my_task, my_thread); - return suspended_list; -} - -CF_PRIVATE void __CFRestartAllThreads(CFArrayRef threads) { - for (CFIndex idx = 0; idx < CFArrayGetCount(threads); idx++) { - thread_act_t thread = (thread_act_t)(uintptr_t)CFArrayGetValueAtIndex(threads, idx); - kern_return_t ret = thread_resume(thread); - if (ret != KERN_SUCCESS) CRASH("*** Failure from thread_resume (%x) ***", ret); - mach_port_deallocate(mach_task_self(), thread); - } -} - -static uint32_t __CF_last_warned_port_count = 0; - -static void foo(void) __attribute__((unused)); -static void foo() { - uint32_t pcnt = __CFGetProcessPortCount(); - if (__CF_last_warned_port_count + 1000 < pcnt) { - CFArrayRef threads = __CFStopAllThreads(); - - -// do stuff here -CFOptionFlags responseFlags = 0; -SInt32 result = CFUserNotificationDisplayAlert(0.0, kCFUserNotificationCautionAlertLevel, NULL, NULL, NULL, CFSTR("High Mach Port Usage"), CFSTR("This application is using a lot of Mach ports."), CFSTR("Default"), CFSTR("Altern"), CFSTR("Other b"), &responseFlags); -if (0 != result) { - CFLog(3, CFSTR("ERROR")); -} else { - switch (responseFlags) { - case kCFUserNotificationDefaultResponse: CFLog(3, CFSTR("DefaultR")); break; - case kCFUserNotificationAlternateResponse: CFLog(3, CFSTR("AltR")); break; - case kCFUserNotificationOtherResponse: CFLog(3, CFSTR("OtherR")); break; - case kCFUserNotificationCancelResponse: CFLog(3, CFSTR("CancelR")); break; - } -} - - - __CFRestartAllThreads(threads); - CFRelease(threads); - __CF_last_warned_port_count = pcnt; - } -} - - +#if TARGET_OS_MAC typedef mach_port_t __CFPort; #define CFPORT_NULL MACH_PORT_NULL typedef mach_port_t __CFPortSet; @@ -501,6 +404,14 @@ typedef int __CFPort; typedef int __CFPortSet; #define CFPORTSET_NULL -1 +#ifndef __unused + #if __has_attribute(unused) + #define __unused __attribute__((unused)) + #else + #define __unused + #endif +#endif // !defined(__unused) + static __CFPort __CFPortAllocate(__unused uintptr_t guard) { return eventfd(0, EFD_CLOEXEC|EFD_NONBLOCK); } @@ -553,15 +464,10 @@ typedef UnsignedWide AbsoluteTime; #endif #if TARGET_OS_MAC - -#if USE_DISPATCH_SOURCE_FOR_TIMERS -#endif -#if USE_MK_TIMER_TOO extern mach_port_name_t mk_timer_create(void); extern kern_return_t mk_timer_destroy(mach_port_name_t name); extern kern_return_t mk_timer_cancel(mach_port_name_t name, AbsoluteTime *result_time); extern kern_return_t mk_timer_arm(mach_port_name_t name, uint64_t expire_time); -#endif static uint32_t __CFSendTrivialMachMessage(mach_port_t port, uint32_t msg_id, CFOptionFlags options, uint32_t timeout) { mach_msg_header_t header; @@ -683,10 +589,8 @@ struct __CFRunLoopMode { Boolean _timerFired; // set to true by the source when a timer has fired Boolean _dispatchTimerArmed; #endif -#if USE_MK_TIMER_TOO __CFPort _timerPort; Boolean _mkTimerArmed; -#endif #if TARGET_OS_WIN32 DWORD _msgQMask; void (*_msgPump)(void); @@ -726,9 +630,7 @@ static CFStringRef __CFRunLoopModeCopyDescription(CFTypeRef cf) { CFStringAppendFormat(result, NULL, CFSTR("queue = %p, "), rlm->_queue); CFStringAppendFormat(result, NULL, CFSTR("source = %p (%s), "), rlm->_timerSource, rlm->_timerFired ? "fired" : "not fired"); #endif -#if USE_MK_TIMER_TOO CFStringAppendFormat(result, NULL, CFSTR("timer port = 0x%x, "), rlm->_timerPort); -#endif #if TARGET_OS_WIN32 CFStringAppendFormat(result, NULL, CFSTR("MSGQ mask = %p, "), rlm->_msgQMask); #endif @@ -754,9 +656,7 @@ static void __CFRunLoopModeDeallocate(CFTypeRef cf) { dispatch_release(rlm->_queue); } #endif -#if USE_MK_TIMER_TOO if (MACH_PORT_NULL != rlm->_timerPort) mk_timer_destroy(rlm->_timerPort); -#endif _CFRecursiveMutexDestroy(&rlm->_lock); memset((char *)cf + sizeof(CFRuntimeBase), 0x7C, sizeof(struct __CFRunLoopMode) - sizeof(CFRuntimeBase)); } @@ -781,7 +681,6 @@ struct __CFRunLoop { CFRuntimeBase _base; _CFRecursiveMutex _lock; /* locked for accessing mode list */ __CFPort _wakeUpPort; // used for CFRunLoopWakeUp - Boolean _unused; volatile _per_run_data *_perRunData; // reset for runs of the run loop _CFThreadRef _pthread; uint32_t _winthread; @@ -912,18 +811,12 @@ static CFRunLoopModeRef __CFRunLoopFindMode(CFRunLoopRef rl, CFStringRef modeNam } _CFRecursiveMutexCreate(&rlm->_lock); rlm->_name = CFStringCreateCopy(kCFAllocatorSystemDefault, modeName); - rlm->_stopped = false; - rlm->_portToV1SourceMap = NULL; - rlm->_sources0 = NULL; - rlm->_sources1 = NULL; - rlm->_observers = NULL; - rlm->_timers = NULL; - rlm->_observerMask = 0; rlm->_portSet = __CFPortSetAllocate(); rlm->_timerSoftDeadline = UINT64_MAX; rlm->_timerHardDeadline = UINT64_MAX; kern_return_t ret = KERN_SUCCESS; +#if TARGET_OS_MAC #if USE_DISPATCH_SOURCE_FOR_TIMERS rlm->_timerFired = false; rlm->_queue = _dispatch_runloop_root_queue_create_4CF("Run Loop Mode Queue", 0); @@ -944,15 +837,14 @@ static CFRunLoopModeRef __CFRunLoopFindMode(CFRunLoopRef rl, CFStringRef modeNam if (KERN_SUCCESS != ret) CRASH("*** Unable to insert timer port into port set. (%d) ***", ret); #endif -#if USE_MK_TIMER_TOO +#endif rlm->_timerPort = mk_timer_create(); if (rlm->_timerPort == MACH_PORT_NULL) { CRASH("*** Unable to create timer Port (%d) ***", rlm->_timerPort); } ret = __CFPortSetInsert(rlm->_timerPort, rlm->_portSet); if (KERN_SUCCESS != ret) CRASH("*** Unable to insert timer port into port set. (%d) ***", ret); -#endif - + ret = __CFPortSetInsert(rl->_wakeUpPort, rlm->_portSet); if (KERN_SUCCESS != ret) CRASH("*** Unable to insert wake up port into port set. (%d) ***", ret); @@ -975,7 +867,7 @@ static Boolean __CFRunLoopModeIsEmpty(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFR if (0 != rlm->_msgQMask) return false; #endif #if __HAS_DISPATCH__ - Boolean libdispatchQSafe = pthread_main_np() && ((HANDLE_DISPATCH_ON_BASE_INVOCATION_ONLY && NULL == previousMode) || (!HANDLE_DISPATCH_ON_BASE_INVOCATION_ONLY && 0 == _CFGetTSD(__CFTSDKeyIsInGCDMainQ))); + Boolean libdispatchQSafe = pthread_main_np() == 1 && ((HANDLE_DISPATCH_ON_BASE_INVOCATION_ONLY && NULL == previousMode) || (!HANDLE_DISPATCH_ON_BASE_INVOCATION_ONLY && 0 == _CFGetTSD(__CFTSDKeyIsInGCDMainQ))); if (libdispatchQSafe && (CFRunLoopGetMain() == rl) && CFSetContainsValue(rl->_commonModes, rlm->_name)) return false; // represents the libdispatch main queue #endif if (NULL != rlm->_sources0 && 0 < CFSetGetCount(rlm->_sources0)) return false; @@ -986,7 +878,7 @@ static Boolean __CFRunLoopModeIsEmpty(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFR struct _block_item *curr = item; item = item->_next; Boolean doit = false; - if (CFStringGetTypeID() == CFGetTypeID(curr->_mode)) { + if (_kCFRuntimeIDCFString == CFGetTypeID(curr->_mode)) { doit = CFEqual(curr->_mode, rlm->_name) || (CFEqual(curr->_mode, kCFRunLoopCommonModes) && CFSetContainsValue(rl->_commonModes, rlm->_name)); } else { doit = CFSetContainsValue((CFSetRef)curr->_mode, rlm->_name) || (CFSetContainsValue((CFSetRef)curr->_mode, kCFRunLoopCommonModes) && CFSetContainsValue(rl->_commonModes, rlm->_name)); @@ -1089,24 +981,28 @@ struct __CFRunLoopSource { CFRuntimeBase _base; _CFRecursiveMutex _lock; CFIndex _order; /* immutable */ + _Atomic uint64_t _signaledTime; CFMutableBagRef _runLoops; union { CFRunLoopSourceContext version0; /* immutable, except invalidation */ CFRunLoopSourceContext1 version1; /* immutable, except invalidation */ } _context; - _Atomic(Boolean) _signaled; }; -CF_INLINE Boolean __CFRunLoopSourceIsSignaled(CFRunLoopSourceRef rls) { - return rls->_signaled; +static uint64_t __CFRunLoopSourceGetSignaledTime(CFRunLoopSourceRef rls) { + return atomic_load_explicit(&rls->_signaledTime, memory_order_acquire); +} + +static Boolean __CFRunLoopSourceIsSignaled(CFRunLoopSourceRef rls) { + return __CFRunLoopSourceGetSignaledTime(rls) != 0; } CF_INLINE void __CFRunLoopSourceSetSignaled(CFRunLoopSourceRef rls) { - rls->_signaled = true; + atomic_compare_exchange_strong_explicit(&rls->_signaledTime, &(uint64_t){0}, mach_absolute_time(), memory_order_acq_rel, memory_order_acq_rel); } CF_INLINE void __CFRunLoopSourceUnsetSignaled(CFRunLoopSourceRef rls) { - rls->_signaled = false; + atomic_store_explicit(&rls->_signaledTime, 0, memory_order_release); } CF_INLINE void __CFRunLoopSourceLock(CFRunLoopSourceRef rls) { @@ -1363,6 +1259,7 @@ static void __CFRunLoopDeallocateTimers(const void *value, void *context) { CF_EXPORT CFRunLoopRef _CFRunLoopGet0b(_CFThreadRef t); + static void __CFRunLoopDeallocate(CFTypeRef cf) { CFRunLoopRef rl = (CFRunLoopRef)cf; @@ -1370,6 +1267,8 @@ static void __CFRunLoopDeallocate(CFTypeRef cf) { CRSetCrashLogMessage("Attempting to deallocate CFRunLoop outside of thread destructor -- this is likely an over-release of the run loop"); HALT; } + + cf_trace(KDEBUG_EVENT_CFRL_LIFETIME|DBG_FUNC_END, rl, NULL, NULL, NULL); // unsetting this here to possibly try to catch multiple concurrent __CFRunLoopDeallocate calls (never seen wild) rl->_fromTSD = 0; @@ -1462,19 +1361,11 @@ static CFRunLoopRef __CFRunLoopCreate(_CFThreadRef t) { __CFRunLoopSetIgnoreWakeUps(loop); loop->_commonModes = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeSetCallBacks); CFSetAddValue(loop->_commonModes, kCFRunLoopDefaultMode); - loop->_commonModeItems = NULL; - loop->_currentMode = NULL; loop->_modes = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeSetCallBacks); - loop->_blocks_head = NULL; - loop->_blocks_tail = NULL; - loop->_counterpart = NULL; loop->_pthread = t; - loop->_fromTSD = 0; loop->_timerTSRLock = CFLockInit; #if TARGET_OS_WIN32 loop->_winthread = GetCurrentThreadId(); -#else - loop->_winthread = 0; #endif rlm = __CFRunLoopFindMode(loop, kCFRunLoopDefaultMode, true); if (NULL != rlm) __CFRunLoopModeUnlock(rlm); @@ -1508,7 +1399,7 @@ CF_PRIVATE CFRunLoopRef _CFRunLoopCacheLookup(_CFThreadRef t, const Boolean crea return loop; } -CF_PRIVATE CFRunLoopRef _CFRunLoopGetButDontCreateCurrent(void) { +CF_PRIVATE CFRunLoopRef _CFRunLoopGetButDontCreateCurrent(void) CF_RETURNS_NOT_RETAINED { CFRunLoopRef loop = (CFRunLoopRef)_CFGetTSDCreateIfNeeded(__CFTSDKeyRunLoop, false); if (loop == NULL) { loop = _CFRunLoopCacheLookup(pthread_self(), false); @@ -1546,6 +1437,8 @@ CF_EXPORT CFRunLoopRef _CFRunLoopGet0(_CFThreadRef t) { CFRunLoopRef loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t)); if (!loop) { newLoop = __CFRunLoopCreate(t); + + cf_trace(KDEBUG_EVENT_CFRL_LIFETIME|DBG_FUNC_START, newLoop, NULL, NULL, NULL); CFDictionarySetValue(__CFRunLoops, pthreadPointer(t), newLoop); loop = newLoop; } @@ -1596,7 +1489,7 @@ CF_PRIVATE void __CFFinalizeRunLoop(uintptr_t data) { } else { _CFSetTSD(__CFTSDKeyRunLoopCntr, (void *)(data - 1), (void (*)(void *))__CFFinalizeRunLoop); } - if (rl && CFRunLoopGetMain() != rl) { // protect against cooperative threads + if (rl && _CFRunLoopGet0b(pthread_main_thread_np()) != rl) { // protect against cooperative threads if (NULL != rl->_counterpart) { #if DEPLOYMENT_RUNTIME_SWIFT extern void swift_release(void *); @@ -1647,7 +1540,7 @@ CF_EXPORT CFTypeRef _CFRunLoopGet2b(CFRunLoopRef rl) { #if TARGET_OS_OSX void _CFRunLoopSetCurrent(CFRunLoopRef rl) { - if (pthread_main_np()) return; + if (pthread_main_np() == 1) return; CFRunLoopRef currentLoop = _CFRunLoopGetButDontCreateCurrent(); if (rl != currentLoop) { if (currentLoop) { @@ -1676,6 +1569,7 @@ CFRunLoopRef CFRunLoopGetMain(void) { return __main; } + CFRunLoopRef CFRunLoopGetCurrent(void) { CHECK_FOR_FORK(); CFRunLoopRef rl = (CFRunLoopRef)_CFGetTSD(__CFTSDKeyRunLoop); @@ -1714,11 +1608,12 @@ static void __CFRunLoopAddItemsToCommonMode(const void *value, void *ctx) { CFTypeRef item = (CFTypeRef)value; CFRunLoopRef rl = (CFRunLoopRef)(((CFTypeRef *)ctx)[0]); CFStringRef modeName = (CFStringRef)(((CFTypeRef *)ctx)[1]); - if (CFGetTypeID(item) == CFRunLoopSourceGetTypeID()) { + CFTypeID const itemID = CFGetTypeID(item); + if (itemID == CFRunLoopSourceGetTypeID()) { CFRunLoopAddSource(rl, (CFRunLoopSourceRef)item, modeName); - } else if (CFGetTypeID(item) == CFRunLoopObserverGetTypeID()) { + } else if (itemID == CFRunLoopObserverGetTypeID()) { CFRunLoopAddObserver(rl, (CFRunLoopObserverRef)item, modeName); - } else if (CFGetTypeID(item) == CFRunLoopTimerGetTypeID()) { + } else if (itemID == CFRunLoopTimerGetTypeID()) { CFRunLoopAddTimer(rl, (CFRunLoopTimerRef)item, modeName); } } @@ -1727,11 +1622,12 @@ static void __CFRunLoopAddItemToCommonModes(const void *value, void *ctx) { CFStringRef modeName = (CFStringRef)value; CFRunLoopRef rl = (CFRunLoopRef)(((CFTypeRef *)ctx)[0]); CFTypeRef item = (CFTypeRef)(((CFTypeRef *)ctx)[1]); - if (CFGetTypeID(item) == CFRunLoopSourceGetTypeID()) { + CFTypeID const itemID = CFGetTypeID(item); + if (itemID == CFRunLoopSourceGetTypeID()) { CFRunLoopAddSource(rl, (CFRunLoopSourceRef)item, modeName); - } else if (CFGetTypeID(item) == CFRunLoopObserverGetTypeID()) { + } else if (itemID == CFRunLoopObserverGetTypeID()) { CFRunLoopAddObserver(rl, (CFRunLoopObserverRef)item, modeName); - } else if (CFGetTypeID(item) == CFRunLoopTimerGetTypeID()) { + } else if (itemID == CFRunLoopTimerGetTypeID()) { CFRunLoopAddTimer(rl, (CFRunLoopTimerRef)item, modeName); } } @@ -1740,11 +1636,12 @@ static void __CFRunLoopRemoveItemFromCommonModes(const void *value, void *ctx) { CFStringRef modeName = (CFStringRef)value; CFRunLoopRef rl = (CFRunLoopRef)(((CFTypeRef *)ctx)[0]); CFTypeRef item = (CFTypeRef)(((CFTypeRef *)ctx)[1]); - if (CFGetTypeID(item) == CFRunLoopSourceGetTypeID()) { + CFTypeID const itemID = CFGetTypeID(item); + if (itemID == CFRunLoopSourceGetTypeID()) { CFRunLoopRemoveSource(rl, (CFRunLoopSourceRef)item, modeName); - } else if (CFGetTypeID(item) == CFRunLoopObserverGetTypeID()) { + } else if (itemID == CFRunLoopObserverGetTypeID()) { CFRunLoopRemoveObserver(rl, (CFRunLoopObserverRef)item, modeName); - } else if (CFGetTypeID(item) == CFRunLoopTimerGetTypeID()) { + } else if (itemID == CFRunLoopTimerGetTypeID()) { CFRunLoopRemoveTimer(rl, (CFRunLoopTimerRef)item, modeName); } } @@ -1829,7 +1726,7 @@ static Boolean __CFRunLoopDoBlocks(CFRunLoopRef rl, CFRunLoopModeRef rlm) { // C struct _block_item *curr = item; item = item->_next; Boolean doit = false; - if (CFStringGetTypeID() == CFGetTypeID(curr->_mode)) { + if (_kCFRuntimeIDCFString == CFGetTypeID(curr->_mode)) { doit = CFEqual(curr->_mode, curMode) || (CFEqual(curr->_mode, kCFRunLoopCommonModes) && CFSetContainsValue(commonModes, curMode)); } else { doit = CFSetContainsValue((CFSetRef)curr->_mode, curMode) || (CFSetContainsValue((CFSetRef)curr->_mode, kCFRunLoopCommonModes) && CFSetContainsValue(commonModes, curMode)); @@ -1853,7 +1750,7 @@ static Boolean __CFRunLoopDoBlocks(CFRunLoopRef rl, CFRunLoopModeRef rlm) { // C } __CFRunLoopLock(rl); __CFRunLoopModeLock(rlm); - if (head) { + if (head && tail) { tail->_next = rl->_blocks_head; rl->_blocks_head = head; if (!rl->_blocks_tail) rl->_blocks_tail = tail; @@ -1921,6 +1818,12 @@ static CFComparisonResult __CFRunLoopSourceComparator(const void *val1, const vo CFRunLoopSourceRef o2 = (CFRunLoopSourceRef)val2; if (o1->_order < o2->_order) return kCFCompareLessThan; if (o2->_order < o1->_order) return kCFCompareGreaterThan; + + const CFAbsoluteTime time1 = __CFRunLoopSourceGetSignaledTime(o1); + const CFAbsoluteTime time2 = __CFRunLoopSourceGetSignaledTime(o2); + + if (time1 < time2) return kCFCompareLessThan; + if (time1 > time2) return kCFCompareGreaterThan; return kCFCompareEqualTo; } @@ -2021,27 +1924,27 @@ static Boolean __CFRunLoopDoSources0(CFRunLoopRef rl, CFRunLoopModeRef rlm, Bool __CFRunLoopModeUnlock(rlm); __CFRunLoopUnlock(rl); // sources is either a single (retained) CFRunLoopSourceRef or an array of (retained) CFRunLoopSourceRef - if (CFGetTypeID(sources) == CFRunLoopSourceGetTypeID()) { - CFRunLoopSourceRef rls = (CFRunLoopSourceRef)sources; + if (CFGetTypeID(sources) == CFRunLoopSourceGetTypeID()) { + CFRunLoopSourceRef rls = (CFRunLoopSourceRef)sources; sourceHandled = __CFRunLoopDoSource0(rls); - } else { - CFIndex cnt = CFArrayGetCount((CFArrayRef)sources); - CFArraySortValues((CFMutableArrayRef)sources, CFRangeMake(0, cnt), (__CFRunLoopSourceComparator), NULL); - for (CFIndex idx = 0; idx < cnt; idx++) { - CFRunLoopSourceRef rls = (CFRunLoopSourceRef)CFArrayGetValueAtIndex((CFArrayRef)sources, idx); + } else { + CFIndex cnt = CFArrayGetCount((CFArrayRef)sources); + CFArraySortValues((CFMutableArrayRef)sources, CFRangeMake(0, cnt), (__CFRunLoopSourceComparator), NULL); + for (CFIndex idx = 0; idx < cnt; idx++) { + CFRunLoopSourceRef rls = (CFRunLoopSourceRef)CFArrayGetValueAtIndex((CFArrayRef)sources, idx); sourceHandled = __CFRunLoopDoSource0(rls); - if (stopAfterHandle && sourceHandled) { - break; - } + if (stopAfterHandle && sourceHandled) { + break; + } + } } - } - CFRelease(sources); - __CFRunLoopLock(rl); - __CFRunLoopModeLock(rlm); + CFRelease(sources); + __CFRunLoopLock(rl); + __CFRunLoopModeLock(rlm); } cf_trace(KDEBUG_EVENT_CFRL_IS_DOING_SOURCES0 | DBG_FUNC_END, rl, rlm, stopAfterHandle, 0); @@ -2053,11 +1956,12 @@ CF_INLINE void __CFRunLoopDebugInfoForRunLoopSource(CFRunLoopSourceRef rls) { } // msg, size and reply are unused on Windows -#if TARGET_OS_MAC -static Boolean __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopSourceRef rls, mach_msg_header_t *msg, CFIndex size, mach_msg_header_t **reply) __attribute__((noinline)); +#if TARGET_OS_MAC +static Boolean __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopSourceRef rls, mach_msg_header_t *msg, CFIndex size, mach_msg_header_t **reply) __attribute__((noinline)); static Boolean __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopSourceRef rls, mach_msg_header_t *msg, CFIndex size, mach_msg_header_t **reply) #else +static Boolean __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopSourceRef rls) __attribute__((noinline)); static Boolean __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopSourceRef rls) #endif @@ -2146,10 +2050,11 @@ static void __CFArmNextTimerInMode(CFRunLoopModeRef rlm, CFRunLoopRef rl) { // discount timers currently firing if (__CFRunLoopTimerIsFiring(t)) continue; - int32_t err = CHECKINT_NO_ERROR; + uint64_t oneTimerHardDeadline; uint64_t oneTimerSoftDeadline = t->_fireTSR; - uint64_t oneTimerHardDeadline = check_uint64_add(t->_fireTSR, __CFTimeIntervalToTSR(t->_tolerance), &err); - if (err != CHECKINT_NO_ERROR) oneTimerHardDeadline = UINT64_MAX; + if (os_add_overflow(t->_fireTSR, __CFTimeIntervalToTSR(t->_tolerance), &oneTimerHardDeadline)) { + oneTimerHardDeadline = UINT64_MAX; + } // We can stop searching if the soft deadline for this timer exceeds the current hard deadline. Otherwise, later timers with lower tolerance could still have earlier hard deadlines. if (oneTimerSoftDeadline > nextHardDeadline) { @@ -2175,7 +2080,6 @@ static void __CFArmNextTimerInMode(CFRunLoopModeRef rlm, CFRunLoopRef rl) { // We're going to hand off the range of allowable timer fire date to dispatch and let it fire when appropriate for the system. uint64_t leeway = __CFTSRToNanoseconds(nextHardDeadline - nextSoftDeadline); dispatch_time_t deadline = __CFTSRToDispatchTime(nextSoftDeadline); -#if USE_MK_TIMER_TOO if (leeway > 0) { // Only use the dispatch timer if we have any leeway // @@ -2204,9 +2108,6 @@ static void __CFArmNextTimerInMode(CFRunLoopModeRef rlm, CFRunLoopRef rl) { rlm->_mkTimerArmed = true; } } -#else - dispatch_source_set_timer(rlm->_timerSource, deadline, DISPATCH_TIME_FOREVER, leeway); -#endif #else if (rlm->_timerPort) { mk_timer_arm(rlm->_timerPort, nextSoftDeadline); @@ -2294,6 +2195,7 @@ static Boolean __CFRunLoopDoTimer(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLo __CFRunLoopModeUnlock(rlm); __CFRunLoopUnlock(rl); + CFRunLoopTimerCallBack callout = rlt->_callout; cf_trace(KDEBUG_EVENT_CFRL_IS_CALLING_TIMER | DBG_FUNC_START, callout, rlt, context_info, 0); __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__(callout, rlt, context_info); @@ -2306,6 +2208,7 @@ static Boolean __CFRunLoopDoTimer(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLo if (context_release) { context_release(context_info); } + __CFRunLoopLock(rl); __CFRunLoopModeLock(rlm); __CFRunLoopTimerLock(rlt); @@ -2419,15 +2322,19 @@ static Boolean __CFRunLoopDoTimers(CFRunLoopRef rl, CFRunLoopModeRef rlm, uint64 } } } + + CFRUNLOOP_ARP_BEGIN; for (CFIndex idx = 0, cnt = timers ? CFArrayGetCount(timers) : 0; idx < cnt; idx++) { CFRunLoopTimerRef rlt = (CFRunLoopTimerRef)CFArrayGetValueAtIndex(timers, idx); Boolean did = __CFRunLoopDoTimer(rl, rlm, rlt); timerHandled = timerHandled || did; } - - if (timers) CFRelease(timers); - + if (timers) CFRelease(timers); + + CFRUNLOOP_ARP_END; + + cf_trace(KDEBUG_EVENT_CFRL_IS_DOING_TIMERS | DBG_FUNC_END, rl, rlm, limitTSR, 0); return timerHandled; @@ -2454,7 +2361,7 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter #define TIMEOUT_INFINITY (~(mach_msg_timeout_t)0) -static Boolean __CFRunLoopServiceMachPort(mach_port_name_t port, mach_msg_header_t **buffer, size_t buffer_size, mach_port_t *livePort, mach_msg_timeout_t timeout, voucher_mach_msg_state_t *voucherState, voucher_t *voucherCopy, CFRunLoopRef rl, CFRunLoopModeRef rlm) { +static Boolean __CFRunLoopServiceMachPort(mach_port_name_t port, mach_msg_header_t **buffer, size_t buffer_size, mach_port_t *livePort, mach_msg_timeout_t timeout, voucher_mach_msg_state_t * _Nonnull voucherState, voucher_t *voucherCopy, CFRunLoopRef rl, CFRunLoopModeRef rlm) { Boolean originalBuffer = true; kern_return_t ret = KERN_SUCCESS; for (;;) { /* In that sleep of death what nightmares may come ... */ @@ -2473,7 +2380,7 @@ static Boolean __CFRunLoopServiceMachPort(mach_port_name_t port, mach_msg_header } cf_trace(KDEBUG_EVENT_CFRL_RUN | DBG_FUNC_END, rl, rlm, port, timeout); cf_trace(KDEBUG_EVENT_CFRL_IS_WAITING | DBG_FUNC_START, rl, rlm, port, timeout); - ret = mach_msg(msg, MACH_RCV_MSG|(voucherState ? MACH_RCV_VOUCHER : 0)|MACH_RCV_LARGE|((TIMEOUT_INFINITY != timeout) ? MACH_RCV_TIMEOUT : 0)|MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)|MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AV), 0, msg->msgh_size, port, timeout, MACH_PORT_NULL); + ret = mach_msg(msg, MACH_RCV_MSG|MACH_RCV_VOUCHER|MACH_RCV_LARGE|((TIMEOUT_INFINITY != timeout) ? MACH_RCV_TIMEOUT : 0)|MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)|MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AV), 0, msg->msgh_size, port, timeout, MACH_PORT_NULL); cf_trace(KDEBUG_EVENT_CFRL_IS_WAITING | DBG_FUNC_END, rl, rlm, port, timeout); cf_trace(KDEBUG_EVENT_CFRL_RUN | DBG_FUNC_START, rl, rlm, port, timeout); // Take care of all voucher-related work right after mach_msg. @@ -2488,7 +2395,7 @@ static Boolean __CFRunLoopServiceMachPort(mach_port_name_t port, mach_msg_header } CFRUNLOOP_WAKEUP(ret); - cf_trace(KDEBUG_EVENT_CFRL_WAKEUP, port, 0, 0, 0); + cf_trace(KDEBUG_EVENT_CFRL_DID_WAKEUP, port, 0, 0, 0); if (MACH_MSG_SUCCESS == ret) { *livePort = msg ? msg->msgh_local_port : MACH_PORT_NULL; return true; @@ -2677,7 +2584,7 @@ static void __CFRunLoopTimeout(void *arg) { context->termTSR = 0ULL; CFRUNLOOP_WAKEUP_FOR_TIMEOUT(); CFRunLoopRef rl = context->rl; - cf_trace(KDEBUG_EVENT_CFRL_WAKEUP_FOR_TIMEOUT, rl, 0, 0, 0); + cf_trace(KDEBUG_EVENT_CFRL_DID_WAKEUP_FOR_TIMEOUT, rl, 0, 0, 0); CFRunLoopWakeUp(rl); // The interval is DISPATCH_TIME_FOREVER, so this won't fire again } @@ -2696,10 +2603,11 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter #if __HAS_DISPATCH__ __CFPort dispatchPort = CFPORT_NULL; - Boolean libdispatchQSafe = pthread_main_np() && ((HANDLE_DISPATCH_ON_BASE_INVOCATION_ONLY && NULL == previousMode) || (!HANDLE_DISPATCH_ON_BASE_INVOCATION_ONLY && 0 == _CFGetTSD(__CFTSDKeyIsInGCDMainQ))); + Boolean libdispatchQSafe = (pthread_main_np() == 1) && ((HANDLE_DISPATCH_ON_BASE_INVOCATION_ONLY && NULL == previousMode) || (!HANDLE_DISPATCH_ON_BASE_INVOCATION_ONLY && 0 == _CFGetTSD(__CFTSDKeyIsInGCDMainQ))); if (libdispatchQSafe && (CFRunLoopGetMain() == rl) && CFSetContainsValue(rl->_commonModes, rlm->_name)) dispatchPort = _dispatch_get_main_queue_port_4CF(); #endif +#if TARGET_OS_MAC #if USE_DISPATCH_SOURCE_FOR_TIMERS mach_port_name_t modeQueuePort = MACH_PORT_NULL; if (rlm->_queue) { @@ -2709,6 +2617,7 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter } } #endif +#endif #if __HAS_DISPATCH__ dispatch_source_t timeout_timer = NULL; @@ -2719,7 +2628,7 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter timeout_context->termTSR = 0ULL; } else if (seconds <= TIMER_INTERVAL_LIMIT) { #if __HAS_DISPATCH__ - dispatch_queue_t queue = pthread_main_np() ? __CFDispatchQueueGetGenericMatchingMain() : __CFDispatchQueueGetGenericBackground(); + dispatch_queue_t queue = (pthread_main_np() == 1) ? __CFDispatchQueueGetGenericMatchingMain() : __CFDispatchQueueGetGenericBackground(); timeout_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); dispatch_retain(timeout_timer); timeout_context->ds = timeout_timer; @@ -2910,28 +2819,29 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter #endif if (MACH_PORT_NULL == livePort) { CFRUNLOOP_WAKEUP_FOR_NOTHING(); - cf_trace(KDEBUG_EVENT_CFRL_WAKEUP_FOR_NOTHING, rl, rlm, livePort, 0); + cf_trace(KDEBUG_EVENT_CFRL_DID_WAKEUP_FOR_NOTHING, rl, rlm, livePort, 0); // handle nothing } else if (livePort == rl->_wakeUpPort) { CFRUNLOOP_WAKEUP_FOR_WAKEUP(); - cf_trace(KDEBUG_EVENT_CFRL_WAKEUP_FOR_WAKEUP, rl, rlm, livePort, 0); + cf_trace(KDEBUG_EVENT_CFRL_DID_WAKEUP_FOR_WAKEUP, rl, rlm, livePort, 0); // do nothing on Mac OS #if TARGET_OS_WIN32 // Always reset the wake up port, or risk spinning forever ResetEvent(rl->_wakeUpPort); #endif } +#if TARGET_OS_MAC #if USE_DISPATCH_SOURCE_FOR_TIMERS else if (modeQueuePort != MACH_PORT_NULL && livePort == modeQueuePort) { CFRUNLOOP_WAKEUP_FOR_TIMER(); - cf_trace(KDEBUG_EVENT_CFRL_WAKEUP_FOR_TIMER, rl, rlm, livePort, 0); + cf_trace(KDEBUG_EVENT_CFRL_DID_WAKEUP_FOR_TIMER, rl, rlm, livePort, 0); if (!__CFRunLoopDoTimers(rl, rlm, mach_absolute_time())) { // Re-arm the next timer, because we apparently fired early __CFArmNextTimerInMode(rlm, rl); } } #endif -#if USE_MK_TIMER_TOO +#endif else if (rlm->_timerPort != MACH_PORT_NULL && livePort == rlm->_timerPort) { CFRUNLOOP_WAKEUP_FOR_TIMER(); // On Windows, we have observed an issue where the timer port is set before the time which we requested it to be set. For example, we set the fire time to be TSR 167646765860, but it is actually observed firing at TSR 167646764145, which is 1715 ticks early. The result is that, when __CFRunLoopDoTimers checks to see if any of the run loop timers should be firing, it appears to be 'too early' for the next timer, and no timers are handled. @@ -2948,23 +2858,28 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter __CFArmNextTimerInMode(rlm, rl); } } -#endif /* --- DISPATCHES --- */ #if __HAS_DISPATCH__ else if (livePort == dispatchPort) { CFRUNLOOP_WAKEUP_FOR_DISPATCH(); - cf_trace(KDEBUG_EVENT_CFRL_WAKEUP_FOR_DISPATCH, rl, rlm, livePort, 0); + cf_trace(KDEBUG_EVENT_CFRL_DID_WAKEUP_FOR_DISPATCH, rl, rlm, livePort, 0); __CFRunLoopModeUnlock(rlm); __CFRunLoopUnlock(rl); _CFSetTSD(__CFTSDKeyIsInGCDMainQ, (void *)6, NULL); + + CFRUNLOOP_ARP_BEGIN; + #if TARGET_OS_WIN32 || TARGET_OS_LINUX void *msg = 0; #endif cf_trace(KDEBUG_EVENT_CFRL_IS_CALLING_DISPATCH | DBG_FUNC_START, rl, rlm, msg, livePort); __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(msg); cf_trace(KDEBUG_EVENT_CFRL_IS_CALLING_DISPATCH | DBG_FUNC_END, rl, rlm, msg, livePort); + + CFRUNLOOP_ARP_END; + _CFSetTSD(__CFTSDKeyIsInGCDMainQ, (void *)0, NULL); __CFRunLoopLock(rl); __CFRunLoopModeLock(rlm); @@ -2977,7 +2892,7 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter else { CFRUNLOOP_WAKEUP_FOR_SOURCE(); - cf_trace(KDEBUG_EVENT_CFRL_WAKEUP_FOR_SOURCE, rl, rlm, 0, 0); + cf_trace(KDEBUG_EVENT_CFRL_DID_WAKEUP_FOR_SOURCE, rl, rlm, 0, 0); // Despite the name, this works for windows handles as well CFRunLoopSourceRef rls = __CFRunLoopModeFindSourceForMachPort(rl, rlm, livePort); if (rls) { @@ -3049,10 +2964,9 @@ SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterva __CFRunLoopLock(rl); CFRunLoopModeRef currentMode = __CFRunLoopFindMode(rl, modeName, false); if (NULL == currentMode || __CFRunLoopModeIsEmpty(rl, currentMode, rl->_currentMode)) { - Boolean did = false; - if (currentMode) __CFRunLoopModeUnlock(currentMode); + if (currentMode) { __CFRunLoopModeUnlock(currentMode); } __CFRunLoopUnlock(rl); - return did ? kCFRunLoopRunHandledSource : kCFRunLoopRunFinished; + return kCFRunLoopRunFinished; } volatile _per_run_data *previousPerRun = __CFRunLoopPushPerRunData(rl); CFRunLoopModeRef previousMode = rl->_currentMode; @@ -3121,6 +3035,9 @@ void CFRunLoopWakeUp(CFRunLoopRef rl) { __CFRunLoopUnlock(rl); return; } + + cf_trace(KDEBUG_EVENT_CFRL_WAKEUP | DBG_FUNC_START, rl, 0, 0, 0); + #if TARGET_OS_MAC kern_return_t ret; /* We unconditionally try to send the message, since we don't want @@ -3138,6 +3055,9 @@ void CFRunLoopWakeUp(CFRunLoopRef rl) { #elif TARGET_OS_WIN32 SetEvent(rl->_wakeUpPort); #endif + + cf_trace(KDEBUG_EVENT_CFRL_WAKEUP | DBG_FUNC_END, rl, 0, 0, 0); + __CFRunLoopUnlock(rl); } @@ -3183,7 +3103,7 @@ void CFRunLoopPerformBlock(CFRunLoopRef rl, CFTypeRef mode, void (^block)(void)) _CFRunLoopError_MainThreadHasExited(); return; } - if (CFStringGetTypeID() == CFGetTypeID(mode)) { + if (_kCFRuntimeIDCFString == CFGetTypeID(mode)) { mode = CFStringCreateCopy(kCFAllocatorSystemDefault, (CFStringRef)mode); __CFRunLoopLock(rl); // ensure mode exists @@ -3779,9 +3699,7 @@ CFRunLoopSourceRef CFRunLoopSourceCreate(CFAllocatorRef allocator, CFIndex order __CFSetValid(memory); __CFRunLoopSourceUnsetSignaled(memory); _CFRecursiveMutexCreate(&memory->_lock); - memory->_signaled = false; memory->_order = order; - memory->_runLoops = NULL; size = 0; switch (context->version) { case 0: @@ -3883,7 +3801,9 @@ void CFRunLoopSourceSignal(CFRunLoopSourceRef rls) { CHECK_FOR_FORK(); __CFRunLoopSourceLock(rls); if (__CFIsValid(rls)) { + cf_trace(KDEBUG_EVENT_CFRL_SOURCE0_SIGNAL | DBG_FUNC_START, rls, rls->_context.version0.perform, rls->_context.version0.info, 0); __CFRunLoopSourceSetSignaled(rls); + cf_trace(KDEBUG_EVENT_CFRL_SOURCE0_SIGNAL | DBG_FUNC_END, rls, rls->_context.version0.perform, rls->_context.version0.info, 0); } __CFRunLoopSourceUnlock(rls); } @@ -3986,11 +3906,6 @@ CFRunLoopObserverRef CFRunLoopObserverCreate(CFAllocatorRef allocator, CFOptionF memory->_context.retain = context->retain; memory->_context.release = context->release; memory->_context.copyDescription = context->copyDescription; - } else { - memory->_context.info = 0; - memory->_context.retain = 0; - memory->_context.release = 0; - memory->_context.copyDescription = 0; } return memory; } @@ -4170,7 +4085,6 @@ CFRunLoopTimerRef CFRunLoopTimerCreate(CFAllocatorRef allocator, CFAbsoluteTime memory->_tolerance = 0.0; if (TIMER_DATE_LIMIT < fireDate) fireDate = TIMER_DATE_LIMIT; memory->_nextFireDate = fireDate; - memory->_fireTSR = 0ULL; uint64_t now2 = mach_absolute_time(); CFAbsoluteTime now1 = CFAbsoluteTimeGetCurrent(); if (fireDate < now1) { @@ -4190,11 +4104,6 @@ CFRunLoopTimerRef CFRunLoopTimerCreate(CFAllocatorRef allocator, CFAbsoluteTime memory->_context.retain = context->retain; memory->_context.release = context->release; memory->_context.copyDescription = context->copyDescription; - } else { - memory->_context.info = 0; - memory->_context.retain = 0; - memory->_context.release = 0; - memory->_context.copyDescription = 0; } return memory; } diff --git a/CoreFoundation/RunLoop.subproj/CFRunLoop.h b/CoreFoundation/RunLoop.subproj/CFRunLoop.h index 1f11fa681b..9e012c3b6b 100644 --- a/CoreFoundation/RunLoop.subproj/CFRunLoop.h +++ b/CoreFoundation/RunLoop.subproj/CFRunLoop.h @@ -1,7 +1,7 @@ /* CFRunLoop.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -14,7 +14,7 @@ #include #include #include -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) +#if TARGET_OS_OSX || TARGET_OS_IPHONE #include #endif @@ -109,7 +109,7 @@ typedef struct { CFStringRef (*copyDescription)(const void *info); Boolean (*equal)(const void *info1, const void *info2); CFHashCode (*hash)(const void *info); -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) +#if TARGET_OS_OSX || TARGET_OS_IPHONE mach_port_t (*getPort)(void *info); void * (*perform)(void *msg, CFIndex size, CFAllocatorRef allocator, void *info); #else diff --git a/CoreFoundation/RunLoop.subproj/CFSocket.c b/CoreFoundation/RunLoop.subproj/CFSocket.c index 08b66b4b5c..cbd3b99653 100644 --- a/CoreFoundation/RunLoop.subproj/CFSocket.c +++ b/CoreFoundation/RunLoop.subproj/CFSocket.c @@ -1,938 +1,13 @@ /* CFSocket.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Christopher Kane + Responsibility: Michael LeHew */ -#define NEW_SOCKET 0 - -#if NEW_SOCKET -/* - -#include -#include "CFInternal.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -extern void _CFRunLoopSourceWakeUpRunLoops(CFRunLoopSourceRef rls); - -#define INVALID_SOCKET (CFSocketNativeHandle)(-1) -#define MAX_SOCKADDR_LEN 256 - - -DISPATCH_HELPER_FUNCTIONS(sock, CFSocket) - -static Boolean sockfd_is_readable(int fd) { - if (fd < 0 || 1048576 <= fd) HALT; - size_t sz = ((fd + CHAR_BIT) / CHAR_BIT) + 7; // generous - fd_set *fdset = malloc(sz); - int ret; - do { - memset(fdset, 0, sz); - FD_SET(fd, fdset); - struct timespec ts = {0, 1000UL}; // 1 us - ret = pselect(fd + 1, fdset, NULL, NULL, &ts, NULL); - } while (ret < 0 && (EINTR == errno || EAGAIN == errno)); - Boolean isSet = ((0 < ret) && FD_ISSET(fd, fdset)); - free(fdset); - return isSet; -} - -static Boolean sockfd_is_writeable(int fd) { - if (fd < 0 || 1048576 <= fd) HALT; - size_t sz = ((fd + CHAR_BIT) / CHAR_BIT) + 7; // generous - fd_set *fdset = malloc(sz); - int ret; - do { - memset(fdset, 0, sz); - FD_SET(fd, fdset); - struct timespec ts = {0, 1000UL}; // 1 us - ret = pselect(fd + 1, NULL, fdset, NULL, &ts, NULL); - } while (ret < 0 && (EINTR == errno || EAGAIN == errno)); - Boolean isSet = ((0 < ret) && FD_ISSET(fd, fdset)); - free(fdset); - return isSet; -} - - -enum { - kCFSocketStateReady = 0, - kCFSocketStateInvalidating = 1, - kCFSocketStateInvalid = 2, - kCFSocketStateDeallocating = 3 -}; - -struct __shared_blob { - dispatch_source_t _rdsrc; - dispatch_source_t _wrsrc; - CFRunLoopSourceRef _source; - CFSocketNativeHandle _socket; - uint8_t _closeFD; - uint8_t _refCnt; -}; - -struct __CFSocket { - CFRuntimeBase _base; - struct __shared_blob *_shared; // non-NULL when valid, NULL when invalid - - uint8_t _state:2; // mutable, not written safely - uint8_t _isSaneFD:1; // immutable - uint8_t _connOriented:1; // immutable - uint8_t _wantConnect:1; // immutable - uint8_t _wantWrite:1; // immutable - uint8_t _wantReadType:2; // immutable - - uint8_t _error; - - uint8_t _rsuspended:1; - uint8_t _wsuspended:1; - uint8_t _readable:1; - uint8_t _writeable:1; - uint8_t _unused:4; - - uint8_t _reenableRead:1; - uint8_t _readDisabled:1; - uint8_t _reenableWrite:1; - uint8_t _writeDisabled:1; - uint8_t _connectDisabled:1; - uint8_t _connected:1; - uint8_t _leaveErrors:1; - uint8_t _closeOnInvalidate:1; - - int32_t _runLoopCounter; - - CFDataRef _address; // immutable, once created - CFDataRef _peerAddress; // immutable, once created - CFSocketCallBack _callout; // immutable - CFSocketContext _context; // immutable -}; - - -CF_INLINE Boolean __CFSocketIsValid(CFSocketRef sock) { - return kCFSocketStateReady == sock->_state; -} - -static CFStringRef __CFSocketCopyDescription(CFTypeRef cf) { - CFSocketRef sock = (CFSocketRef)cf; - CFStringRef contextDesc = NULL; - if (NULL != sock->_context.info && NULL != sock->_context.copyDescription) { - contextDesc = sock->_context.copyDescription(sock->_context.info); - } - if (NULL == contextDesc) { - contextDesc = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR(""), sock->_context.info); - } - Dl_info info; - void *addr = sock->_callout; - const char *name = (dladdr(addr, &info) && info.dli_saddr == addr && info.dli_sname) ? info.dli_sname : "???"; - int avail = -1; - ioctlsocket(sock->_shared ? sock->_shared->_socket : -1, FIONREAD, &avail); - CFStringRef result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR( - "{valid = %s, socket = %d, " - "want connect = %s, connect disabled = %s, " - "want write = %s, reenable write = %s, write disabled = %s, " - "want read = %s, reenable read = %s, read disabled = %s, " - "leave errors = %s, close on invalidate = %s, connected = %s, " - "last error code = %d, bytes available for read = %d, " - "source = %p, callout = %s (%p), context = %@}"), - cf, CFGetAllocator(sock), __CFSocketIsValid(sock) ? "Yes" : "No", sock->_shared ? sock->_shared->_socket : -1, - sock->_wantConnect ? "Yes" : "No", sock->_connectDisabled ? "Yes" : "No", - sock->_wantWrite ? "Yes" : "No", sock->_reenableWrite ? "Yes" : "No", sock->_writeDisabled ? "Yes" : "No", - sock->_wantReadType ? "Yes" : "No", sock->_reenableRead ? "Yes" : "No", sock->_readDisabled? "Yes" : "No", - sock->_leaveErrors ? "Yes" : "No", sock->_closeOnInvalidate ? "Yes" : "No", sock->_connected ? "Yes" : "No", - sock->_error, avail, - sock->_shared ? sock->_shared->_source : NULL, name, addr, contextDesc); - if (NULL != contextDesc) { - CFRelease(contextDesc); - } - return result; -} - -static void __CFSocketDeallocate(CFTypeRef cf) { - CHECK_FOR_FORK_RET(); - CFSocketRef sock = (CFSocketRef)cf; - // Since CFSockets are cached, we can only get here sometime after being invalidated - sock->_state = kCFSocketStateDeallocating; - if (sock->_peerAddress) { - CFRelease(sock->_peerAddress); - sock->_peerAddress = NULL; - } - if (sock->_address) { - CFRelease(sock->_address); - sock->_address = NULL; - } -} - -static CFTypeID __kCFSocketTypeID = _kCFRuntimeNotATypeID; - -const CFRuntimeClass __CFSocketClass = { - 0, - "CFSocket", - NULL, // init - NULL, // copy - __CFSocketDeallocate, - NULL, // equal - NULL, // hash - NULL, // - __CFSocketCopyDescription -}; - -static CFMutableArrayRef __CFAllSockets = NULL; - -CFTypeID CFSocketGetTypeID(void) { - static dispatch_once_t initOnce; - dispatch_once(&initOnce, ^{ - __kCFSocketTypeID = _CFRuntimeRegisterClass(&__CFSocketClass); // initOnce covered - __CFAllSockets = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks); - struct rlimit lim1; - int ret1 = getrlimit(RLIMIT_NOFILE, &lim1); - int mib[] = {CTL_KERN, KERN_MAXFILESPERPROC}; - int maxfd = 0; - size_t len = sizeof(int); - int ret0 = sysctl(mib, 2, &maxfd, &len, NULL, 0); - if (0 == ret0 && 0 == ret1 && lim1.rlim_max < maxfd) maxfd = lim1.rlim_max; - if (0 == ret1 && lim1.rlim_cur < maxfd) { - struct rlimit lim2 = lim1; - lim2.rlim_cur += 2304; - if (maxfd < lim2.rlim_cur) lim2.rlim_cur = maxfd; - setrlimit(RLIMIT_NOFILE, &lim2); - // we try, but do not go to extraordinary measures - } - }); - return __kCFSocketTypeID; -} - -CFSocketRef CFSocketCreateWithNative(CFAllocatorRef allocator, CFSocketNativeHandle ufd, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context) { - CHECK_FOR_FORK_RET(NULL); - - CFSocketGetTypeID(); // cause initialization if necessary - - struct stat statbuf; - int ret = fstat(ufd, &statbuf); - if (ret < 0) ufd = INVALID_SOCKET; - - Boolean sane = false; - if (INVALID_SOCKET != ufd) { - uint32_t type = (statbuf.st_mode & S_IFMT); - sane = (S_IFSOCK == type) || (S_IFIFO == type) || (S_IFCHR == type); - if (1 && !sane) { - CFLog(kCFLogLevelWarning, CFSTR("*** CFSocketCreateWithNative(): creating CFSocket with silly fd type (%07o) -- may or may not work"), type); - } - } - - if (INVALID_SOCKET != ufd) { - Boolean canHandle = false; - int tmp_kq = kqueue(); - if (0 <= tmp_kq) { - struct kevent ev[2]; - EV_SET(&ev[0], ufd, EVFILT_READ, EV_ADD, 0, 0, 0); - EV_SET(&ev[1], ufd, EVFILT_WRITE, EV_ADD, 0, 0, 0); - int ret = kevent(tmp_kq, ev, 2, NULL, 0, NULL); - canHandle = (0 <= ret); // if kevent(ADD) succeeds, can handle - close(tmp_kq); - } - if (1 && !canHandle) { - CFLog(kCFLogLevelWarning, CFSTR("*** CFSocketCreateWithNative(): creating CFSocket with unsupported fd type -- may or may not work")); - } - } - - if (INVALID_SOCKET == ufd) { - // Historically, bad ufd was allowed, but gave an uncached and already-invalid CFSocketRef - SInt32 size = sizeof(struct __CFSocket) - sizeof(CFRuntimeBase); - CFSocketRef memory = (CFSocketRef)_CFRuntimeCreateInstance(allocator, CFSocketGetTypeID(), size, NULL); - if (NULL == memory) { - return NULL; - } - memory->_callout = callout; - memory->_state = kCFSocketStateInvalid; - return memory; - } - - __block CFSocketRef sock = NULL; - dispatch_sync(__sockQueue(), ^{ - for (CFIndex idx = 0, cnt = CFArrayGetCount(__CFAllSockets); idx < cnt; idx++) { - CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(__CFAllSockets, idx); - if (s->_shared->_socket == ufd) { - CFRetain(s); - sock = s; - return; - } - } - - SInt32 size = sizeof(struct __CFSocket) - sizeof(CFRuntimeBase); - CFSocketRef memory = (CFSocketRef)_CFRuntimeCreateInstance(allocator, CFSocketGetTypeID(), size, NULL); - if (NULL == memory) { - return; - } - - int socketType = 0; - if (INVALID_SOCKET != ufd) { - socklen_t typeSize = sizeof(socketType); - int ret = getsockopt(ufd, SOL_SOCKET, SO_TYPE, (void *)&socketType, (socklen_t *)&typeSize); - if (ret < 0) socketType = 0; - } - - memory->_rsuspended = true; - memory->_wsuspended = true; - memory->_readable = false; - memory->_writeable = false; - - memory->_isSaneFD = sane ? 1 : 0; - memory->_wantReadType = (callBackTypes & 0x3); - memory->_reenableRead = memory->_wantReadType ? true : false; - memory->_readDisabled = false; - memory->_wantWrite = (callBackTypes & kCFSocketWriteCallBack) ? true : false; - memory->_reenableWrite = false; - memory->_writeDisabled = false; - memory->_wantConnect = (callBackTypes & kCFSocketConnectCallBack) ? true : false; - memory->_connectDisabled = false; - memory->_leaveErrors = false; - memory->_closeOnInvalidate = true; - memory->_connOriented = (SOCK_STREAM == socketType); - memory->_connected = (memory->_wantReadType == kCFSocketAcceptCallBack || !memory->_connOriented) ? true : false; - - memory->_error = 0; - memory->_runLoopCounter = 0; - memory->_address = NULL; - memory->_peerAddress = NULL; - memory->_context.info = NULL; - memory->_context.retain = NULL; - memory->_context.release = NULL; - memory->_context.copyDescription = NULL; - memory->_callout = callout; - if (NULL != context) { - memmove(&memory->_context, context, sizeof(CFSocketContext)); - memory->_context.info = context->retain ? (void *)context->retain(context->info) : context->info; - } - - struct __shared_blob *shared = malloc(sizeof(struct __shared_blob)); - shared->_rdsrc = NULL; - shared->_wrsrc = NULL; - shared->_source = NULL; - shared->_socket = ufd; - shared->_closeFD = true; // copy of _closeOnInvalidate - shared->_refCnt = 1; // one for the CFSocket - memory->_shared = shared; - - if (memory->_wantReadType) { - dispatch_source_t dsrc = NULL; - if (sane) { - dsrc = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, ufd, 0, __sockQueue()); - } else { - dsrc = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, __sockQueue()); - dispatch_source_set_timer(dsrc, dispatch_time(DISPATCH_TIME_NOW, 0), NSEC_PER_SEC / 2, NSEC_PER_SEC); - } - dispatch_block_t event_block = ^{ - memory->_readable = true; - if (!memory->_rsuspended) { - dispatch_suspend(dsrc); -// CFLog(5, CFSTR("suspend %p due to read event block"), memory); - memory->_rsuspended = true; - } - if (shared->_source) { - CFRunLoopSourceSignal(shared->_source); - _CFRunLoopSourceWakeUpRunLoops(shared->_source); - } - }; - dispatch_block_t cancel_block = ^{ - shared->_rdsrc = NULL; - shared->_refCnt--; - if (0 == shared->_refCnt) { - if (shared->_closeFD) { - // thoroughly stop anything else from using the fd - (void)shutdown(shared->_socket, SHUT_RDWR); - int nullfd = open("/dev/null", O_RDONLY); - dup2(nullfd, shared->_socket); - close(nullfd); - close(shared->_socket); - } - free(shared); - } - dispatch_release(dsrc); - }; - dispatch_source_set_event_handler(dsrc, event_block); - dispatch_source_set_cancel_handler(dsrc, cancel_block); - shared->_rdsrc = dsrc; - } - if (memory->_wantWrite || memory->_wantConnect) { - dispatch_source_t dsrc = NULL; - if (sane) { - dsrc = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, ufd, 0, __sockQueue()); - } else { - dsrc = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, __sockQueue()); - dispatch_source_set_timer(dsrc, dispatch_time(DISPATCH_TIME_NOW, 0), NSEC_PER_SEC / 2, NSEC_PER_SEC); - } - dispatch_block_t event_block = ^{ - memory->_writeable = true; - if (!memory->_wsuspended) { - dispatch_suspend(dsrc); -// CFLog(5, CFSTR("suspend %p due to write event block"), memory); - memory->_wsuspended = true; - } - if (shared->_source) { - CFRunLoopSourceSignal(shared->_source); - _CFRunLoopSourceWakeUpRunLoops(shared->_source); - } - }; - dispatch_block_t cancel_block = ^{ - shared->_wrsrc = NULL; - shared->_refCnt--; - if (0 == shared->_refCnt) { - if (shared->_closeFD) { - // thoroughly stop anything else from using the fd - (void)shutdown(shared->_socket, SHUT_RDWR); - int nullfd = open("/dev/null", O_RDONLY); - dup2(nullfd, shared->_socket); - close(nullfd); - close(shared->_socket); - } - free(shared); - } - dispatch_release(dsrc); - }; - dispatch_source_set_event_handler(dsrc, event_block); - dispatch_source_set_cancel_handler(dsrc, cancel_block); - shared->_wrsrc = dsrc; - } - - if (shared->_rdsrc) { - shared->_refCnt++; - } - if (shared->_wrsrc) { - shared->_refCnt++; - } - - memory->_state = kCFSocketStateReady; - CFArrayAppendValue(__CFAllSockets, memory); - sock = memory; - }); -// CFLog(5, CFSTR("CFSocketCreateWithNative(): created socket %p with callbacks 0x%x"), sock, callBackTypes); - if (sock && !CFSocketIsValid(sock)) { // must do this outside lock to avoid deadlock - CFRelease(sock); - sock = NULL; - } - return sock; -} - -CFSocketNativeHandle CFSocketGetNative(CFSocketRef sock) { - CHECK_FOR_FORK_RET(INVALID_SOCKET); - __CFGenericValidateType(sock, CFSocketGetTypeID()); - return sock->_shared ? sock->_shared->_socket : INVALID_SOCKET; -} - -void CFSocketGetContext(CFSocketRef sock, CFSocketContext *context) { - __CFGenericValidateType(sock, CFSocketGetTypeID()); - CFAssert1(0 == context->version, __kCFLogAssertion, "%s(): context version not initialized to 0", __PRETTY_FUNCTION__); - memmove(context, &sock->_context, sizeof(CFSocketContext)); -} - -CFDataRef CFSocketCopyAddress(CFSocketRef sock) { - CHECK_FOR_FORK_RET(NULL); - __CFGenericValidateType(sock, CFSocketGetTypeID()); - __block CFDataRef result = NULL; - dispatch_sync(__sockQueue(), ^{ - if (!sock->_address) { - if (!__CFSocketIsValid(sock)) return; - uint8_t name[MAX_SOCKADDR_LEN]; - socklen_t namelen = sizeof(name); - int ret = getsockname(sock->_shared->_socket, (struct sockaddr *)name, (socklen_t *)&namelen); - if (0 == ret && 0 < namelen) { - sock->_address = CFDataCreate(CFGetAllocator(sock), name, namelen); - } - } - result = sock->_address ? (CFDataRef)CFRetain(sock->_address) : NULL; - }); - return result; -} - -CFDataRef CFSocketCopyPeerAddress(CFSocketRef sock) { - CHECK_FOR_FORK_RET(NULL); - __CFGenericValidateType(sock, CFSocketGetTypeID()); - __block CFDataRef result = NULL; - dispatch_sync(__sockQueue(), ^{ - if (!sock->_peerAddress) { - if (!__CFSocketIsValid(sock)) return; - uint8_t name[MAX_SOCKADDR_LEN]; - socklen_t namelen = sizeof(name); - int ret = getpeername(sock->_shared->_socket, (struct sockaddr *)name, (socklen_t *)&namelen); - if (0 == ret && 0 < namelen) { - sock->_peerAddress = CFDataCreate(CFGetAllocator(sock), name, namelen); - } - } - result = sock->_peerAddress ? (CFDataRef)CFRetain(sock->_peerAddress) : NULL; - }); - return result; -} - -CFOptionFlags CFSocketGetSocketFlags(CFSocketRef sock) { - CHECK_FOR_FORK(); - __CFGenericValidateType(sock, CFSocketGetTypeID()); - __block CFOptionFlags flags = 0; - dispatch_sync(__sockQueue(), ^{ - if (sock->_reenableRead) flags |= sock->_wantReadType; // flags are same as types here - if (sock->_reenableWrite) flags |= kCFSocketAutomaticallyReenableWriteCallBack; - if (sock->_leaveErrors) flags |= kCFSocketLeaveErrors; - if (sock->_closeOnInvalidate) flags |= kCFSocketCloseOnInvalidate; - }); - return flags; -} - -void CFSocketSetSocketFlags(CFSocketRef sock, CFOptionFlags flags) { - CHECK_FOR_FORK(); -// CFLog(5, CFSTR("CFSocketSetSocketFlags(%p, 0x%x) starting"), sock, flags); - __CFGenericValidateType(sock, CFSocketGetTypeID()); - dispatch_sync(__sockQueue(), ^{ - sock->_reenableRead = (sock->_wantReadType && ((flags & 0x3) == sock->_wantReadType)) ? true : false; - sock->_reenableWrite = (sock->_wantWrite && (flags & kCFSocketAutomaticallyReenableWriteCallBack)) ? true : false; - sock->_leaveErrors = (flags & kCFSocketLeaveErrors) ? true : false; - sock->_closeOnInvalidate = (flags & kCFSocketCloseOnInvalidate) ? true : false; - if (sock->_shared) sock->_shared->_closeFD = sock->_closeOnInvalidate; - }); -// CFLog(5, CFSTR("CFSocketSetSocketFlags(%p, 0x%x) done"), sock, flags); -} - -void CFSocketEnableCallBacks(CFSocketRef sock, CFOptionFlags callBackTypes) { - CHECK_FOR_FORK_RET(); - __CFGenericValidateType(sock, CFSocketGetTypeID()); -// CFLog(5, CFSTR("CFSocketEnableCallBacks(%p, 0x%x) starting"), sock, callBackTypes); - dispatch_sync(__sockQueue(), ^{ - if (!__CFSocketIsValid(sock)) return; - if (sock->_wantReadType && (callBackTypes & 0x3) == sock->_wantReadType) { - if (sockfd_is_readable(sock->_shared->_socket)) { - sock->_readable = true; -// CFLog(5, CFSTR("CFSocketEnableCallBacks(%p, 0x%x) socket is readable"), sock, callBackTypes); - if (!sock->_rsuspended) { - dispatch_suspend(sock->_shared->_rdsrc); - sock->_rsuspended = true; - } - // If the source exists, but is now invalid, this next stuff is relatively harmless. - if (sock->_shared->_source) { - CFRunLoopSourceSignal(sock->_shared->_source); - _CFRunLoopSourceWakeUpRunLoops(sock->_shared->_source); - } - } else if (sock->_rsuspended && sock->_shared->_rdsrc) { - sock->_rsuspended = false; - dispatch_resume(sock->_shared->_rdsrc); - } - sock->_readDisabled = false; - } - if (sock->_wantWrite && (callBackTypes & kCFSocketWriteCallBack)) { - if (sockfd_is_writeable(sock->_shared->_socket)) { - sock->_writeable = true; - if (!sock->_wsuspended) { - dispatch_suspend(sock->_shared->_wrsrc); - sock->_wsuspended = true; - } - // If the source exists, but is now invalid, this next stuff is relatively harmless. - if (sock->_shared->_source) { - CFRunLoopSourceSignal(sock->_shared->_source); - _CFRunLoopSourceWakeUpRunLoops(sock->_shared->_source); - } - } else if (sock->_wsuspended && sock->_shared->_wrsrc) { - sock->_wsuspended = false; - dispatch_resume(sock->_shared->_wrsrc); - } - sock->_writeDisabled = false; - } - if (sock->_wantConnect && !sock->_connected && (callBackTypes & kCFSocketConnectCallBack)) { - if (sockfd_is_writeable(sock->_shared->_socket)) { - sock->_writeable = true; - if (!sock->_wsuspended) { - dispatch_suspend(sock->_shared->_wrsrc); - sock->_wsuspended = true; - } - // If the source exists, but is now invalid, this next stuff is relatively harmless. - if (sock->_shared->_source) { - CFRunLoopSourceSignal(sock->_shared->_source); - _CFRunLoopSourceWakeUpRunLoops(sock->_shared->_source); - } - } else if (sock->_wsuspended && sock->_shared->_wrsrc) { - sock->_wsuspended = false; - dispatch_resume(sock->_shared->_wrsrc); - } - sock->_connectDisabled = false; - } - }); -// CFLog(5, CFSTR("CFSocketEnableCallBacks(%p, 0x%x) done"), sock, callBackTypes); -} - -void CFSocketDisableCallBacks(CFSocketRef sock, CFOptionFlags callBackTypes) { - CHECK_FOR_FORK_RET(); - __CFGenericValidateType(sock, CFSocketGetTypeID()); -// CFLog(5, CFSTR("CFSocketDisableCallBacks(%p, 0x%x) starting"), sock, callBackTypes); - dispatch_sync(__sockQueue(), ^{ - if (!__CFSocketIsValid(sock)) return; - if (sock->_wantReadType && (callBackTypes & 0x3) == sock->_wantReadType) { - if (!sock->_rsuspended && sock->_shared->_rdsrc) { - dispatch_suspend(sock->_shared->_rdsrc); - sock->_rsuspended = true; - } - sock->_readDisabled = true; - } - if (sock->_wantWrite && (callBackTypes & kCFSocketWriteCallBack)) { - if (!sock->_wsuspended && sock->_shared->_wrsrc) { - dispatch_suspend(sock->_shared->_wrsrc); - sock->_wsuspended = true; - } - sock->_writeDisabled = true; - } - if (sock->_wantConnect && !sock->_connected && (callBackTypes & kCFSocketConnectCallBack)) { - if (!sock->_wsuspended && sock->_shared->_wrsrc) { - dispatch_suspend(sock->_shared->_wrsrc); - sock->_wsuspended = true; - } - sock->_connectDisabled = true; - } - }); -// CFLog(5, CFSTR("CFSocketDisableCallBacks(%p, 0x%x) done"), sock, callBackTypes); -} - -void CFSocketInvalidate(CFSocketRef sock) { - CHECK_FOR_FORK_RET(); - __CFGenericValidateType(sock, CFSocketGetTypeID()); - CFRetain(sock); -// CFLog(5, CFSTR("CFSocketInvalidate(%p) starting"), sock); - __block CFRunLoopSourceRef source = NULL; - __block Boolean wasReady = false; - dispatch_sync(__sockQueue(), ^{ - wasReady = (sock->_state == kCFSocketStateReady); - if (wasReady) { - sock->_state = kCFSocketStateInvalidating; - OSMemoryBarrier(); - for (CFIndex idx = 0, cnt = CFArrayGetCount(__CFAllSockets); idx < cnt; idx++) { - CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(__CFAllSockets, idx); - if (s == sock) { - CFArrayRemoveValueAtIndex(__CFAllSockets, idx); - break; - } - } - if (sock->_shared->_rdsrc) { - dispatch_source_cancel(sock->_shared->_rdsrc); - if (sock->_rsuspended) { - sock->_rsuspended = false; - dispatch_resume(sock->_shared->_rdsrc); - } - } - if (sock->_shared->_wrsrc) { - dispatch_source_cancel(sock->_shared->_wrsrc); - if (sock->_wsuspended) { - sock->_wsuspended = false; - dispatch_resume(sock->_shared->_wrsrc); - } - } - source = sock->_shared->_source; - sock->_shared->_source = NULL; - sock->_shared->_refCnt--; - if (0 == sock->_shared->_refCnt) { - if (sock->_shared->_closeFD) { - // thoroughly stop anything else from using the fd - (void)shutdown(sock->_shared->_socket, SHUT_RDWR); - int nullfd = open("/dev/null", O_RDONLY); - dup2(nullfd, sock->_shared->_socket); - close(nullfd); - close(sock->_shared->_socket); - } - free(sock->_shared); - } - sock->_shared = NULL; - } - }); - if (wasReady) { - if (NULL != source) { - CFRunLoopSourceInvalidate(source); - CFRelease(source); - } - void *info = sock->_context.info; - sock->_context.info = NULL; - if (sock->_context.release) { - sock->_context.release(info); - } - sock->_state = kCFSocketStateInvalid; - OSMemoryBarrier(); - } -// CFLog(5, CFSTR("CFSocketInvalidate(%p) done%s"), sock, wasReady ? " -- done on this thread" : ""); - CFRelease(sock); -} - -Boolean CFSocketIsValid(CFSocketRef sock) { - __CFGenericValidateType(sock, CFSocketGetTypeID()); - if (!__CFSocketIsValid(sock)) return false; - struct stat statbuf; - int ret = sock->_shared ? fstat(sock->_shared->_socket, &statbuf) : -1; - if (ret < 0) { - CFSocketInvalidate(sock); - return false; - } - return true; -} - - -static void __CFSocketPerform(void *info) { // CFRunLoop should only call this on one thread at a time - CHECK_FOR_FORK_RET(); - CFSocketRef sock = (CFSocketRef)info; - -// CFLog(5, CFSTR("__CFSocketPerform(%p) starting '%@'"), sock, sock); - __block Boolean doRead = false, doWrite = false, doConnect = false, isValid = false; - __block int fd = INVALID_SOCKET; - __block SInt32 errorCode = 0; - __block int new_fd = INVALID_SOCKET; - __block CFDataRef address = NULL; - __block CFMutableDataRef data = NULL; - __block void *context_info = NULL; - __block void (*context_release)(const void *) = NULL; - dispatch_sync(__sockQueue(), ^{ - isValid = __CFSocketIsValid(sock); - if (!isValid) return; - fd = sock->_shared->_socket; - doRead = sock->_readable && sock->_wantReadType && !sock->_readDisabled; - if (doRead) { - sock->_readable = false; - doRead = sockfd_is_readable(fd); -// if (!doRead) CFLog(5, CFSTR("__CFSocketPerform(%p) socket is not actually readable"), sock); - } - doWrite = sock->_writeable && sock->_wantWrite && !sock->_writeDisabled; - doConnect = sock->_writeable && sock->_wantConnect && !sock->_connectDisabled && !sock->_connected; - if (doWrite || doConnect) { - sock->_writeable = false; - if (doWrite) doWrite = sockfd_is_writeable(fd); - if (doConnect) doConnect = sockfd_is_writeable(fd); - } - if (!sock->_leaveErrors && (doWrite || doConnect)) { // not on read, for whatever reason - int errorSize = sizeof(errorCode); - int ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&errorCode, (socklen_t *)&errorSize); - if (0 != ret) errorCode = 0; - sock->_error = errorCode; - } - sock->_connected = true; -// CFLog(5, CFSTR("__CFSocketPerform(%p) doing %d %d %d"), sock, doRead, doWrite, doConnect); - if (doRead) { - switch (sock->_wantReadType) { - case kCFSocketReadCallBack: - break; - case kCFSocketAcceptCallBack: { - uint8_t name[MAX_SOCKADDR_LEN]; - socklen_t namelen = sizeof(name); - new_fd = accept(fd, (struct sockaddr *)name, (socklen_t *)&namelen); - if (INVALID_SOCKET != new_fd) { - address = CFDataCreate(CFGetAllocator(sock), name, namelen); - } - break; - } - case kCFSocketDataCallBack: { - uint8_t name[MAX_SOCKADDR_LEN]; - socklen_t namelen = sizeof(name); - int avail = 0; - int ret = ioctlsocket(fd, FIONREAD, &avail); - if (ret < 0 || avail < 256) avail = 256; - if ((1 << 20) < avail) avail = (1 << 20); - data = CFDataCreateMutable(CFGetAllocator(sock), 0); - CFDataSetLength(data, avail); - ssize_t len = recvfrom(fd, CFDataGetMutableBytePtr(data), avail, 0, (struct sockaddr *)name, (socklen_t *)&namelen); - CFIndex datalen = (len < 0) ? 0 : len; - CFDataSetLength(data, datalen); - if (0 < namelen) { - address = CFDataCreate(CFGetAllocator(sock), name, namelen); - } else if (sock->_connOriented) { - // cannot call CFSocketCopyPeerAddress(), or deadlock - if (!sock->_peerAddress) { - uint8_t name[MAX_SOCKADDR_LEN]; - socklen_t namelen = sizeof(name); - int ret = getpeername(sock->_shared->_socket, (struct sockaddr *)name, (socklen_t *)&namelen); - if (0 == ret && 0 < namelen) { - sock->_peerAddress = CFDataCreate(CFGetAllocator(sock), name, namelen); - } - } - address = sock->_peerAddress ? (CFDataRef)CFRetain(sock->_peerAddress) : NULL; - } - if (NULL == address) { - address = CFDataCreate(CFGetAllocator(sock), NULL, 0); - } - break; - } - } - } - if (sock->_reenableRead) { -// CFLog(5, CFSTR("__CFSocketPerform(%p) reenabling read %d %p"), sock, sock->_rsuspended, sock->_shared->_rdsrc); - if (sock->_rsuspended && sock->_shared->_rdsrc) { - sock->_rsuspended = false; - dispatch_resume(sock->_shared->_rdsrc); - } - } - if (sock->_reenableWrite) { - if (sock->_wsuspended && sock->_shared->_wrsrc) { - sock->_wsuspended = false; - dispatch_resume(sock->_shared->_wrsrc); - } - } - if (sock->_context.retain && (doConnect || doRead || doWrite)) { - context_info = (void *)sock->_context.retain(sock->_context.info); - context_release = sock->_context.release; - } else { - context_info = sock->_context.info; - } - }); -// CFLog(5, CFSTR("__CFSocketPerform(%p) isValid:%d, doRead:%d, doWrite:%d, doConnect:%d error:%d"), sock, isValid, doRead, doWrite, doConnect, errorCode); - if (!isValid || !(doConnect || doRead || doWrite)) return; - - Boolean calledOut = false; - if (doConnect) { - if (sock->_callout) sock->_callout(sock, kCFSocketConnectCallBack, NULL, (0 != errorCode) ? &errorCode : NULL, context_info); - calledOut = true; - } - if (doRead && (!calledOut || __CFSocketIsValid(sock))) { - switch (sock->_wantReadType) { - case kCFSocketReadCallBack: - if (sock->_callout) sock->_callout(sock, kCFSocketReadCallBack, NULL, NULL, context_info); - calledOut = true; - break; - case kCFSocketAcceptCallBack: - if (INVALID_SOCKET != new_fd) { - if (sock->_callout) sock->_callout(sock, kCFSocketAcceptCallBack, address, &new_fd, context_info); - calledOut = true; - } - break; - case kCFSocketDataCallBack: - if (sock->_callout) sock->_callout(sock, kCFSocketDataCallBack, address, data, context_info); - calledOut = true; - break; - } - } - if (doWrite && (!calledOut || __CFSocketIsValid(sock))) { - if (0 == errorCode) { - if (sock->_callout) sock->_callout(sock, kCFSocketWriteCallBack, NULL, NULL, context_info); - calledOut = true; - } - } - - if (data && 0 == CFDataGetLength(data)) CFSocketInvalidate(sock); - if (address) CFRelease(address); - if (data) CFRelease(data); - if (context_release) { - context_release(context_info); - } - - CHECK_FOR_FORK_RET(); -// CFLog(5, CFSTR("__CFSocketPerform(%p) done"), sock); -} - -static void __CFSocketSchedule(void *info, CFRunLoopRef rl, CFStringRef mode) { - CFSocketRef sock = (CFSocketRef)info; - int32_t newVal = OSAtomicIncrement32Barrier(&sock->_runLoopCounter); - if (1 == newVal) { // on a transition from 0->1, the old code forced all desired callbacks enabled - CFOptionFlags types = sock->_wantReadType | (sock->_wantWrite ? kCFSocketWriteCallBack : 0) | (sock->_wantConnect ? kCFSocketConnectCallBack : 0); - CFSocketEnableCallBacks(sock, types); - } - CFRunLoopWakeUp(rl); -} - -static void __CFSocketCancel(void *info, CFRunLoopRef rl, CFStringRef mode) { - CFSocketRef sock = (CFSocketRef)info; - OSAtomicDecrement32Barrier(&sock->_runLoopCounter); - CFRunLoopWakeUp(rl); -} - -CFRunLoopSourceRef CFSocketCreateRunLoopSource(CFAllocatorRef allocator, CFSocketRef sock, CFIndex order) { - CHECK_FOR_FORK_RET(NULL); - __CFGenericValidateType(sock, CFSocketGetTypeID()); - if (!CFSocketIsValid(sock)) return NULL; - __block CFRunLoopSourceRef result = NULL; - dispatch_sync(__sockQueue(), ^{ - if (!__CFSocketIsValid(sock)) return; - if (NULL != sock->_shared->_source && !CFRunLoopSourceIsValid(sock->_shared->_source)) { - CFRelease(sock->_shared->_source); - sock->_shared->_source = NULL; - } - if (NULL == sock->_shared->_source) { - CFRunLoopSourceContext context; - context.version = 0; - context.info = (void *)sock; - context.retain = (const void *(*)(const void *))CFRetain; - context.release = (void (*)(const void *))CFRelease; - context.copyDescription = (CFStringRef (*)(const void *))__CFSocketCopyDescription; - context.equal = NULL; - context.hash = NULL; - context.schedule = __CFSocketSchedule; - context.cancel = __CFSocketCancel; - context.perform = __CFSocketPerform; - sock->_shared->_source = CFRunLoopSourceCreate(allocator, order, (CFRunLoopSourceContext *)&context); - if (sock->_shared->_source) { - if (sock->_wantReadType) { - if (sockfd_is_readable(sock->_shared->_socket)) { - sock->_readable = true; - if (!sock->_rsuspended) { - dispatch_suspend(sock->_shared->_rdsrc); - sock->_rsuspended = true; - } - if (sock->_shared->_source) { - CFRunLoopSourceSignal(sock->_shared->_source); - _CFRunLoopSourceWakeUpRunLoops(sock->_shared->_source); - } - } else if (sock->_rsuspended && sock->_shared->_rdsrc) { - sock->_rsuspended = false; - dispatch_resume(sock->_shared->_rdsrc); - } - } - if (sock->_wantWrite || (sock->_wantConnect && !sock->_connected)) { - if (sockfd_is_writeable(sock->_shared->_socket)) { - sock->_writeable = true; - if (!sock->_wsuspended) { - dispatch_suspend(sock->_shared->_wrsrc); - sock->_wsuspended = true; - } - if (sock->_shared->_source) { - CFRunLoopSourceSignal(sock->_shared->_source); - _CFRunLoopSourceWakeUpRunLoops(sock->_shared->_source); - } - } else if (sock->_wsuspended && sock->_shared->_wrsrc) { - sock->_wsuspended = false; - dispatch_resume(sock->_shared->_wrsrc); - } - } - } - } - result = sock->_shared->_source ? (CFRunLoopSourceRef)CFRetain(sock->_shared->_source) : NULL; - }); -// CFLog(5, CFSTR("CFSocketCreateRunLoopSource(%p) => %p"), sock, result); - return result; -} - - -void __CFSocketSetSocketReadBufferAttrs(CFSocketRef s, CFTimeInterval timeout, CFIndex length) { -} - -CFIndex __CFSocketRead(CFSocketRef s, UInt8* buffer, CFIndex length, int* error) { - *error = 0; - int ret = read(CFSocketGetNative(s), buffer, length); - if (ret < 0) { - *error = errno; - } - return ret; -} - -Boolean __CFSocketGetBytesAvailable(CFSocketRef s, CFIndex* ctBytesAvailable) { - int bytesAvailable; - int ret = ioctlsocket(CFSocketGetNative(s), FIONREAD, &bytesAvailable); - if (ret < 0) return false; - *ctBytesAvailable = (CFIndex)bytesAvailable; - return true; -} - -*/ -#else /* not NEW_SOCKET */ - - #include #include #include @@ -942,6 +17,9 @@ Boolean __CFSocketGetBytesAvailable(CFSocketRef s, CFIndex* ctBytesAvailable) { #include #include #include +#if TARGET_OS_CYGWIN +#include +#endif #endif #if TARGET_OS_CYGWIN || TARGET_OS_BSD #include @@ -1676,7 +754,7 @@ static void __CFSocketHandleRead(CFSocketRef s, Boolean causedByTimeout) if (0 >= recvlen) { //??? should return error if <0 - /* zero-length data is the signal for perform to invalidate */ + /* zero-length data is the signal for perform to invalidate if socket is connection oriented */ data = (CFDataRef)CFRetain(zeroLengthData); } else { data = CFDataCreate(CFGetAllocator(s), buffer, recvlen); @@ -2194,7 +1272,7 @@ static void *__CFSocketManager(void * arg) struct timeval tv; struct timeval* pTimeout = NULL; - struct timeval timeBeforeSelect; + struct timeval timeBeforeSelect = {0, 0}; for (;;) { __CFLock(&__CFActiveSocketsLock); @@ -2577,41 +1655,18 @@ static CFSocketRef _CFSocketCreateWithNative(CFAllocatorRef allocator, CFSocketN __CFSocketUnsetWriteSignalled(memory); __CFSocketUnsetReadSignalled(memory); memory->_f.client = ((callBackTypes & (~kCFSocketConnectCallBack)) & (~kCFSocketWriteCallBack)) | kCFSocketCloseOnInvalidate; - memory->_f.disabled = 0; - memory->_f.connected = FALSE; - memory->_f.writableHint = FALSE; - memory->_f.closeSignaled = FALSE; memory->_lock = CFLockInit; memory->_writeLock = CFLockInit; memory->_socket = sock; if (INVALID_SOCKET == sock || 0 != getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *)&(memory->_socketType), (socklen_t *)&typeSize)) memory->_socketType = 0; // cast for WinSock bad API - memory->_errorCode = 0; - memory->_address = NULL; - memory->_peerAddress = NULL; - memory->_socketSetCount = 0; - memory->_source0 = NULL; if (INVALID_SOCKET != sock) { - memory->_runLoops = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, NULL); - } else { - memory->_runLoops = NULL; + CFArrayCallBacks retainingCallbacks = kCFTypeArrayCallBacks; + retainingCallbacks.copyDescription = NULL; + memory->_runLoops = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &retainingCallbacks); } memory->_callout = callout; - memory->_dataQueue = NULL; - memory->_addressQueue = NULL; - memory->_context.info = 0; - memory->_context.retain = 0; - memory->_context.release = 0; - memory->_context.copyDescription = 0; timerclear(&memory->_readBufferTimeout); timerclear(&memory->_readBufferTimeoutNotificationTime); - memory->_hitTheTimeout = false; - memory->_readBuffer = NULL; - memory->_bytesToBuffer = 0; - memory->_bytesToBufferPos = 0; - memory->_bytesToBufferReadPos = 0; - memory->_atEOF = false; - memory->_bufferedReadError = 0; - memory->_leftoverBytes = NULL; if (INVALID_SOCKET != sock) CFDictionaryAddValue(__CFAllSockets, (void *)(uintptr_t)sock, memory); if (NULL == __CFSocketManagerThread) { @@ -3019,7 +2074,7 @@ static void __CFSocketDoCallback(CFSocketRef s, CFDataRef data, CFDataRef addres __CFSOCKETLOG_WS(s, "perform calling out data of length %ld", (long)datalen); if (callout) callout(s, kCFSocketDataCallBack, address, data, contextInfo); calledOut = true; - if (0 == datalen) CFSocketInvalidate(s); + if (0 == datalen && __CFSocketIsConnectionOriented(s)) CFSocketInvalidate(s); } } else if (kCFSocketAcceptCallBack == readCallBackType) { if (INVALID_SOCKET != sock && (!calledOut || CFSocketIsValid(s))) { @@ -3167,8 +2222,6 @@ CFRunLoopSourceRef CFSocketCreateRunLoopSource(CFAllocatorRef allocator, CFSocke return result; } -#endif /* NEW_SOCKET */ - static uint16_t __CFSocketDefaultNameRegistryPortNumber = 2454; @@ -3182,47 +2235,17 @@ CONST_STRING_DECL(kCFSocketRegisterCommand, "Register") CONST_STRING_DECL(kCFSocketRetrieveCommand, "Retrieve") CONST_STRING_DECL(__kCFSocketRegistryRequestRunLoopMode, "CFSocketRegistryRequest") -static CFLock_t __CFSocketWriteLock_ = CFLockInit; +static os_unfair_lock __CFSocketWriteLock_ = OS_UNFAIR_LOCK_INIT; //#warning can only send on one socket at a time now CF_INLINE void __CFSocketWriteLock(CFSocketRef s) { - __CFLock(& __CFSocketWriteLock_); + os_unfair_lock_lock(& __CFSocketWriteLock_); } CF_INLINE void __CFSocketWriteUnlock(CFSocketRef s) { - __CFUnlock(& __CFSocketWriteLock_); -} - -#if NEW_SOCKET - -CF_INLINE CFIndex __CFSocketFdGetSize(CFDataRef fdSet) { - return NBBY * CFDataGetLength(fdSet); + os_unfair_lock_unlock(& __CFSocketWriteLock_); } -CF_INLINE Boolean __CFSocketFdSet(CFSocketNativeHandle sock, CFMutableDataRef fdSet) { - /* returns true if a change occurred, false otherwise */ - Boolean retval = false; - if (INVALID_SOCKET != sock && 0 <= sock) { - CFIndex numFds = NBBY * CFDataGetLength(fdSet); - fd_mask *fds_bits; - if (sock >= numFds) { - CFIndex oldSize = numFds / NFDBITS, newSize = (sock + NFDBITS) / NFDBITS, changeInBytes = (newSize - oldSize) * sizeof(fd_mask); - CFDataIncreaseLength(fdSet, changeInBytes); - fds_bits = (fd_mask *)CFDataGetMutableBytePtr(fdSet); - memset(fds_bits + oldSize, 0, changeInBytes); - } else { - fds_bits = (fd_mask *)CFDataGetMutableBytePtr(fdSet); - } - if (!FD_ISSET(sock, (fd_set *)fds_bits)) { - retval = true; - FD_SET(sock, (fd_set *)fds_bits); - } - } - return retval; -} - -#endif - //??? need timeout, error handling, retries CFSocketError CFSocketSendData(CFSocketRef s, CFDataRef address, CFDataRef data, CFTimeInterval timeout) { CHECK_FOR_FORK(); @@ -3564,7 +2587,7 @@ CFSocketError CFSocketRegisterSocketSignature(const CFSocketSignature *nameServe retval = CFSocketRegisterValue(nameServerSignature, timeout, name, data); CFRelease(data); } - CFRelease(validatedSignature.address); + if (validatedSignature.address) CFRelease(validatedSignature.address); } return retval; } diff --git a/CoreFoundation/RunLoop.subproj/CFSocket.h b/CoreFoundation/RunLoop.subproj/CFSocket.h index ee6897dcf2..5ffba978e7 100644 --- a/CoreFoundation/RunLoop.subproj/CFSocket.h +++ b/CoreFoundation/RunLoop.subproj/CFSocket.h @@ -1,7 +1,7 @@ /* CFSocket.h - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Stream.subproj/CFConcreteStreams.c b/CoreFoundation/Stream.subproj/CFConcreteStreams.c index 6301cff34a..338c9dae82 100644 --- a/CoreFoundation/Stream.subproj/CFConcreteStreams.c +++ b/CoreFoundation/Stream.subproj/CFConcreteStreams.c @@ -1,7 +1,7 @@ /* CFConcreteStreams.c - Copyright (c) 2000-2018, Apple Inc. and the Swift project authors + Copyright (c) 2000-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Stream.subproj/CFSocketStream.c b/CoreFoundation/Stream.subproj/CFSocketStream.c index 0c8e02eb53..74a792d08a 100644 --- a/CoreFoundation/Stream.subproj/CFSocketStream.c +++ b/CoreFoundation/Stream.subproj/CFSocketStream.c @@ -1,7 +1,7 @@ /* CFSocketStream.c - Copyright (c) 2000-2018, Apple Inc. and the Swift project authors + Copyright (c) 2000-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -217,7 +217,7 @@ CF_PRIVATE CFStreamError _CFStreamErrorFromError(CFErrorRef error) { return result; } -CF_PRIVATE CFErrorRef _CFErrorFromStreamError(CFAllocatorRef alloc, CFStreamError *streamError) { +CF_PRIVATE CFErrorRef _CFStreamCreateErrorFromStreamError(CFAllocatorRef alloc, CFStreamError *streamError) { CFErrorRef result; Boolean canUpCall; diff --git a/CoreFoundation/Stream.subproj/CFStream.c b/CoreFoundation/Stream.subproj/CFStream.c index 163ea1b26b..1a8bacc0db 100644 --- a/CoreFoundation/Stream.subproj/CFStream.c +++ b/CoreFoundation/Stream.subproj/CFStream.c @@ -1,7 +1,7 @@ /* CFStream.c - Copyright (c) 2000-2018, Apple Inc. and the Swift project authors + Copyright (c) 2000-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -12,7 +12,6 @@ #include #include #include "CFStreamInternal.h" -#include "CFInternal.h" #include "CFRuntime_Internal.h" #include #if TARGET_OS_WIN32 @@ -24,23 +23,6 @@ #endif -struct _CFStream { - CFRuntimeBase _cfBase; - CFOptionFlags flags; - CFErrorRef error; // if callBacks->version < 2, this is actually a pointer to a CFStreamError - struct _CFStreamClient *client; - void *info; /* callBacks info */ - const struct _CFStreamCallBacks *callBacks; // This will not exist (will not be allocated) if the callbacks are from our known, "blessed" set. - - CFLock_t streamLock; - CFArrayRef previousRunloopsAndModes; -#if __HAS_DISPATCH__ - dispatch_queue_t queue; -#endif - Boolean pendingEventsToDeliver; -}; - - enum { MIN_STATUS_CODE_BIT = 0, // ..status bits... @@ -287,7 +269,7 @@ static void __CFStreamDeallocate(CFTypeRef cf) { CFAllocatorDeallocate(alloc, stream->client); stream->client = NULL; // Just in case finalize, below, calls back in to us } - if (cb->finalize) { + if (cb && cb->finalize) { if (cb->version == 0) { ((void(*)(void *))cb->finalize)(_CFStreamGetInfoPointer(stream)); } else { @@ -295,7 +277,7 @@ static void __CFStreamDeallocate(CFTypeRef cf) { } } if (stream->error) { - if (cb->version < 2) { + if (cb && cb->version < 2) { CFAllocatorDeallocate(alloc, (void *)stream->error); } else { CFRelease(stream->error); @@ -355,22 +337,10 @@ CF_EXPORT CFTypeID CFWriteStreamGetTypeID(void) { } static struct _CFStream *_CFStreamCreate(CFAllocatorRef allocator, Boolean isReadStream) { - struct _CFStream *newStream = (struct _CFStream *)_CFRuntimeCreateInstance(allocator, isReadStream ? _kCFRuntimeIDCFReadStream : _kCFRuntimeIDCFWriteStream, sizeof(struct _CFStream) - sizeof(CFRuntimeBase), NULL); + struct _CFStream *newStream = (struct _CFStream *)_CFRuntimeCreateInstance(allocator, isReadStream ? _kCFRuntimeIDCFReadStream : _kCFRuntimeIDCFWriteStream, _CFSTREAM_SIZE, NULL); if (newStream) { -// numStreamInstances ++; - newStream->flags = 0; _CFStreamSetStatusCode(newStream, kCFStreamStatusNotOpen); - newStream->error = NULL; - newStream->client = NULL; - newStream->info = NULL; - newStream->callBacks = NULL; - newStream->streamLock = CFLockInit; - newStream->previousRunloopsAndModes = NULL; -#if __HAS_DISPATCH__ - newStream->queue = NULL; -#endif - newStream->pendingEventsToDeliver = false; } return newStream; } @@ -928,7 +898,7 @@ static CFErrorRef _CFStreamCopyError(struct _CFStream *stream) { if (!stream->error) { return NULL; } else if (_CFStreamGetCallBackPtr(stream)->version < 2) { - return _CFErrorFromStreamError(CFGetAllocator(stream), (CFStreamError *)(stream->error)); + return _CFStreamCreateErrorFromStreamError(CFGetAllocator(stream), (CFStreamError *)(stream->error)); } else { CFRetain(stream->error); return stream->error; @@ -936,13 +906,13 @@ static CFErrorRef _CFStreamCopyError(struct _CFStream *stream) { } CF_EXPORT CFErrorRef CFReadStreamCopyError(CFReadStreamRef stream) { - CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFReadStream, CFErrorRef, (NSInputStream *)stream, streamError); + CF_OBJC_RETAINED_FUNCDISPATCHV(_kCFRuntimeIDCFReadStream, CFErrorRef, (NSInputStream *)stream, streamError); return _CFStreamCopyError((struct _CFStream *)stream); } CF_EXPORT CFErrorRef CFWriteStreamCopyError(CFWriteStreamRef stream) { + CF_OBJC_RETAINED_FUNCDISPATCHV(_kCFRuntimeIDCFWriteStream, CFErrorRef, (NSOutputStream *)stream, streamError); return _CFStreamCopyError((struct _CFStream *)stream); - CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFWriteStream, CFErrorRef, (NSOutputStream *)stream, streamError); } CF_PRIVATE Boolean _CFStreamOpen(struct _CFStream *stream) { @@ -1229,12 +1199,12 @@ CF_PRIVATE CFTypeRef _CFStreamCopyProperty(struct _CFStream *stream, CFStringRef } CF_EXPORT CFTypeRef CFReadStreamCopyProperty(CFReadStreamRef stream, CFStringRef propertyName) { - CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFReadStream, CFTypeRef, (NSInputStream *)stream, propertyForKey:(NSString *)propertyName); + CF_OBJC_RETAINED_FUNCDISPATCHV(_kCFRuntimeIDCFReadStream, CFTypeRef, (NSInputStream *)stream, propertyForKey:(NSString *)propertyName); return _CFStreamCopyProperty((struct _CFStream *)stream, propertyName); } CF_EXPORT CFTypeRef CFWriteStreamCopyProperty(CFWriteStreamRef stream, CFStringRef propertyName) { - CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFWriteStream, CFTypeRef, (NSOutputStream *)stream, propertyForKey:(NSString *)propertyName); + CF_OBJC_RETAINED_FUNCDISPATCHV(_kCFRuntimeIDCFWriteStream, CFTypeRef, (NSOutputStream *)stream, propertyForKey:(NSString *)propertyName); return _CFStreamCopyProperty((struct _CFStream *)stream, propertyName); } @@ -1264,8 +1234,6 @@ Boolean CFWriteStreamSetProperty(CFWriteStreamRef stream, CFStringRef propertyNa } static void _initializeClient(struct _CFStream *stream) { - const struct _CFStreamCallBacks *cb = _CFStreamGetCallBackPtr(stream); - if (!cb->schedule) return; // Do we wish to allow this? stream->client = (struct _CFStreamClient *)CFAllocatorAllocate(CFGetAllocator(stream), sizeof(struct _CFStreamClient), 0); memset(stream->client, 0, sizeof(struct _CFStreamClient)); } @@ -1317,6 +1285,28 @@ CF_PRIVATE Boolean _CFStreamSetClient(struct _CFStream *stream, CFOptionFlags st return TRUE; } +CF_EXPORT void _CFReadStreamInitialize(CFReadStreamRef readStream) { + struct _CFStream *stream = (struct _CFStream *)readStream; + if (stream) { + stream->streamLock = CFLockInit; + } +} + +CF_EXPORT void _CFWriteStreamInitialize(CFWriteStreamRef writeStream) { + struct _CFStream *stream = (struct _CFStream *)writeStream; + if (stream) { + stream->streamLock = CFLockInit; + } +} + +CF_EXPORT void _CFReadStreamDeallocate(CFReadStreamRef readStream) { + __CFStreamDeallocate(readStream); +} + +CF_EXPORT void _CFWriteStreamDeallocate(CFWriteStreamRef writeStream) { + __CFStreamDeallocate(writeStream); +} + CF_EXPORT Boolean CFReadStreamSetClient(CFReadStreamRef readStream, CFOptionFlags streamEvents, CFReadStreamClientCallBack clientCB, CFStreamClientContext *clientContext) { #if defined(CFSTREAM_SUPPORTS_BRIDGING) if (CF_IS_OBJC(_kCFRuntimeIDCFReadStream, (const void *)(NSInputStream *)readStream)) { @@ -1517,7 +1507,7 @@ CF_PRIVATE void _CFStreamScheduleWithRunLoop(struct _CFStream *stream, CFRunLoop checkRLMArray(stream->client->runLoopsAndModes); _CFStreamUnlock(stream); - if (cb->schedule) { + if (cb && cb->schedule) { __CFBitSet(stream->flags, CALLING_CLIENT); cb->schedule(stream, runLoop, runLoopMode, _CFStreamGetInfoPointer(stream)); __CFBitClear(stream->flags, CALLING_CLIENT); @@ -1618,7 +1608,7 @@ CF_PRIVATE void _CFStreamUnscheduleFromRunLoop(struct _CFStream *stream, CFRunLo checkRLMArray(stream->client->runLoopsAndModes); _CFStreamUnlock(stream); - if (cb->unschedule) { + if (cb && cb->unschedule) { cb->unschedule(stream, runLoop, runLoopMode, _CFStreamGetInfoPointer(stream)); } } @@ -1655,10 +1645,32 @@ void CFWriteStreamUnscheduleFromRunLoop(CFWriteStreamRef stream, CFRunLoopRef ru #if __HAS_DISPATCH__ +#if !DEPLOYMENT_RUNTIME_OBJC +typedef _Atomic(int64_t) _OSAtomic_int64_t; + +#if __has_extension(c_alignof) && __has_attribute(aligned) +typedef int64_t __attribute__((__aligned__(_Alignof(_OSAtomic_int64_t)))) + OSAtomic_int64_aligned64_t; +#elif __has_attribute(aligned) +typedef int64_t __attribute__((__aligned__((sizeof(_OSAtomic_int64_t))))) + OSAtomic_int64_aligned64_t; +#else +typedef int64_t OSAtomic_int64_aligned64_t; +#endif +#endif + static CFRunLoopRef sLegacyRL = NULL; +#if TARGET_OS_MAC +static volatile OSAtomic_int64_aligned64_t sPerformCount = 0; +#endif + +extern _CFThreadRef _CFMainPThread; static void _perform(void* info) { +#if TARGET_OS_MAC + OSAtomicAdd64(1, &sPerformCount); +#endif } static void* _legacyStreamRunLoop_workThread(void* arg) @@ -1754,7 +1766,7 @@ static CFRunLoopRef _legacyStreamRunLoop() dispatch_release(sem); } }); - + return sLegacyRL; } @@ -1905,7 +1917,7 @@ static Boolean _CFStreamRemoveRunLoopAndModeFromArray(CFMutableArrayRef runLoops // Used by NSStream to properly allocate the bridged objects CF_EXPORT CFIndex _CFStreamInstanceSize(void) { - return sizeof(struct _CFStream); + return _CFSTREAM_SIZE; } #if TARGET_OS_WIN32 diff --git a/CoreFoundation/Stream.subproj/CFStream.h b/CoreFoundation/Stream.subproj/CFStream.h index 1f59e232e6..4a80ff90a0 100644 --- a/CoreFoundation/Stream.subproj/CFStream.h +++ b/CoreFoundation/Stream.subproj/CFStream.h @@ -1,7 +1,7 @@ /* CFStream.h - Copyright (c) 2000-2018, Apple Inc. and the Swift project authors + Copyright (c) 2000-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Stream.subproj/CFStreamAbstract.h b/CoreFoundation/Stream.subproj/CFStreamAbstract.h index cda9622a3f..458dc401c4 100644 --- a/CoreFoundation/Stream.subproj/CFStreamAbstract.h +++ b/CoreFoundation/Stream.subproj/CFStreamAbstract.h @@ -1,7 +1,7 @@ /* CFStreamAbstract.h - Copyright (c) 2000-2018, Apple Inc.and the Swift project authors + Copyright (c) 2000-2019, Apple Inc.and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Stream.subproj/CFStreamInternal.h b/CoreFoundation/Stream.subproj/CFStreamInternal.h index 4706088289..693b081f0d 100644 --- a/CoreFoundation/Stream.subproj/CFStreamInternal.h +++ b/CoreFoundation/Stream.subproj/CFStreamInternal.h @@ -1,7 +1,7 @@ /* CFStreamInternal.h - Copyright (c) 2000-2018, Apple Inc. and the Swift project authors + Copyright (c) 2000-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -12,10 +12,30 @@ #include #include #include +#include #include CF_EXTERN_C_BEGIN +struct _CFStream { + CFRuntimeBase _cfBase; + CFOptionFlags flags; + CFErrorRef error; // if callBacks->version < 2, this is actually a pointer to a CFStreamError + struct _CFStreamClient *client; + void *info; /* callBacks info */ + const struct _CFStreamCallBacks *callBacks; // This will not exist (will not be allocated) if the callbacks are from our known, "blessed" set. + + CFLock_t streamLock; + CFArrayRef previousRunloopsAndModes; +#if __HAS_DISPATCH__ + dispatch_queue_t queue; +#endif + Boolean pendingEventsToDeliver; +}; + +#ifndef _CFSTREAM_SIZE +#define _CFSTREAM_SIZE (sizeof(struct _CFStream) - sizeof(CFRuntimeBase)) +#endif // Older versions of the callbacks; v0 callbacks match v1 callbacks, except that create, finalize, and copyDescription are missing. typedef Boolean (*_CFStreamCBOpenV1)(struct _CFStream *stream, CFStreamError *error, Boolean *openComplete, void *info); @@ -49,7 +69,7 @@ struct _CFStreamCallBacksV1 { }; // These two are defined in CFSocketStream.c because that's where the glue for CFNetwork is. -CF_PRIVATE CFErrorRef _CFErrorFromStreamError(CFAllocatorRef alloc, CFStreamError *err); +CF_PRIVATE CFErrorRef _CFStreamCreateErrorFromStreamError(CFAllocatorRef alloc, CFStreamError *err); CF_PRIVATE CFStreamError _CFStreamErrorFromError(CFErrorRef error); CF_EXTERN_C_END diff --git a/CoreFoundation/Stream.subproj/CFStreamPriv.h b/CoreFoundation/Stream.subproj/CFStreamPriv.h index 1e57262637..e2a6c8ce64 100644 --- a/CoreFoundation/Stream.subproj/CFStreamPriv.h +++ b/CoreFoundation/Stream.subproj/CFStreamPriv.h @@ -1,7 +1,7 @@ /* CFStreamPriv.h - Copyright (c) 2000-2018, Apple Inc. and the Swift project authors + Copyright (c) 2000-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -82,7 +82,7 @@ CFWriteStreamRef _CFWriteStreamCreateFromFileDescriptor(CFAllocatorRef alloc, in #define SECURITY_SSLv32 (3) #define SECURITY_TLS (4) -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) +#if TARGET_OS_OSX || TARGET_OS_IPHONE // This symbol is exported from CFNetwork (see CFSocketStream.i). Only __MACH__ systems will // get this symbol from CoreFoundation. extern const int kCFStreamErrorDomainSSL; diff --git a/CoreFoundation/String.subproj/CFAttributedString.c b/CoreFoundation/String.subproj/CFAttributedString.c index 3fb9a611dc..d27aa35211 100644 --- a/CoreFoundation/String.subproj/CFAttributedString.c +++ b/CoreFoundation/String.subproj/CFAttributedString.c @@ -1,7 +1,7 @@ /* CFAttributedString.c - Copyright (c) 2004-2018, Apple Inc. All rights reserved. + Copyright (c) 2004-2019, Apple Inc. All rights reserved. - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -19,7 +19,7 @@ #if (TARGET_OS_MAC || TARGET_OS_WIN32) && DEPLOYMENT_RUNTIME_OBJC #import @interface NSAttributedString (NSPrivate) -- (NSAttributedString *)_createAttributedSubstringWithRange:(NSRange)range; +- (NSAttributedString *)_createAttributedSubstringWithRange:(NSRange)range NS_RETURNS_RETAINED; @end #endif @@ -87,7 +87,8 @@ static CFHashCode __CFAttributedStringHash(CFTypeRef cf) { #define createLocalArray(array, count) \ CFTypeRef array ## Buf[localArrayStackSize]; \ - CFTypeRef *array = (count <= localArrayStackSize) ? (array ## Buf) : ((count < LONG_MAX / sizeof(CFTypeRef)) ? malloc(count * sizeof(CFTypeRef)) : NULL); + if (!(count < LONG_MAX / sizeof(CFTypeRef))) { CRSetCrashLogMessage("Ridiculous size count"); HALT; } \ + CFTypeRef *array = (count <= localArrayStackSize) ? (array ## Buf) : malloc(count * sizeof(CFTypeRef)); #define freeLocalArray(array) \ if (array != array ## Buf) free(array); diff --git a/CoreFoundation/String.subproj/CFAttributedString.h b/CoreFoundation/String.subproj/CFAttributedString.h index 25d3493abf..9eafdcbb02 100644 --- a/CoreFoundation/String.subproj/CFAttributedString.h +++ b/CoreFoundation/String.subproj/CFAttributedString.h @@ -8,7 +8,7 @@ // /* CFAttributedString.h - Copyright (c) 2004-2018, Apple Inc. All rights reserved. + Copyright (c) 2004-2019, Apple Inc. All rights reserved. */ /*! @header CFAttributedString diff --git a/CoreFoundation/String.subproj/CFAttributedStringPriv.h b/CoreFoundation/String.subproj/CFAttributedStringPriv.h index dd9c66823e..6f2e0ef7f6 100644 --- a/CoreFoundation/String.subproj/CFAttributedStringPriv.h +++ b/CoreFoundation/String.subproj/CFAttributedStringPriv.h @@ -1,5 +1,5 @@ /* CFAttributedStringPriv.h - Copyright (c) 2004-2018, Apple Inc. All rights reserved. + Copyright (c) 2004-2019, Apple Inc. All rights reserved. */ #if !defined(__COREFOUNDATION_CFATTRIBUTEDSTRINGPRIV__) diff --git a/CoreFoundation/String.subproj/CFBurstTrie.c b/CoreFoundation/String.subproj/CFBurstTrie.c index 7950c2c0ff..0c83659e31 100644 --- a/CoreFoundation/String.subproj/CFBurstTrie.c +++ b/CoreFoundation/String.subproj/CFBurstTrie.c @@ -1,7 +1,7 @@ /* CFBurstTrie.c - Copyright (c) 2008-2018, Apple Inc. and the Swift project authors + Copyright (c) 2008-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -844,6 +844,10 @@ static void addCFBurstTrieBurstLevel(CFBurstTrieRef trie, TrieLevelRef root, con next = (uintptr_t) newNode; NextTrie_SetKind(next, ListKind); root->slots[*key] = next; +#ifdef __clang_analyzer__ + // The analyzer doesn't understand mangled pointers. + free(newNode); +#endif } else { // ** Handle payload. root->weight = weight; @@ -862,8 +866,10 @@ static TrieLevelRef burstCFBurstTrieLevel(CFBurstTrieRef trie, ListNodeRef list, return newLevel; } -static CFBTInsertCode addCFBurstTrieListNode(CFBurstTrieRef trie, ListNodeRef list, const uint8_t *key, uint32_t keylen, uint32_t weight, uint32_t payload, uint32_t *listCount) +static CFBTInsertCode addCFBurstTrieListNode(CFBurstTrieRef trie, ListNodeRef _Nonnull list, const uint8_t *key, uint32_t keylen, uint32_t weight, uint32_t payload, uint32_t *listCount) { + if (!list) HALT_MSG("list is NULL"); + CFBTInsertCode code = FailedInsert; uint32_t count = 1; @@ -904,14 +910,24 @@ static CFBTInsertCode addCFBurstTrieLevel(CFBurstTrieRef trie, TrieLevelRef root ListNodeRef listNode = (ListNodeRef) NextTrie_GetPtr(next); code = addCFBurstTrieListNode(trie, listNode, key+1, keylen-1, weight, payload, &listCount); if (listCount > trie->containerSize) { - next = (uintptr_t) burstCFBurstTrieLevel(trie, listNode, listCount); + TrieLevelRef newLevel = burstCFBurstTrieLevel(trie, listNode, listCount); + next = (uintptr_t)newLevel; NextTrie_SetKind(next, TrieKind); +#ifdef __clang_analyzer__ + // The analyzer doesn't understand mangled pointers. + free(newLevel); +#endif } } else { // ** Make a new list node - next = (uintptr_t) makeCFBurstTrieListNode(key+1, keylen-1, weight, payload); + ListNodeRef newNode = makeCFBurstTrieListNode(key+1, keylen-1, weight, payload); + next = (intptr_t)newNode; NextTrie_SetKind(next, ListKind); code = NewTerm; +#ifdef __clang_analyzer__ + // The analyzer doesn't understand mangled pointers. + free(newNode); +#endif } root->slots[*key] = next; } diff --git a/CoreFoundation/String.subproj/CFBurstTrie.h b/CoreFoundation/String.subproj/CFBurstTrie.h index fd86e0cc90..58cc53ef41 100644 --- a/CoreFoundation/String.subproj/CFBurstTrie.h +++ b/CoreFoundation/String.subproj/CFBurstTrie.h @@ -1,7 +1,7 @@ /* CFBurstTrie.h - Copyright (c) 2008-2018, Apple Inc. and the Swift project authors + Copyright (c) 2008-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/String.subproj/CFCharacterSet.c b/CoreFoundation/String.subproj/CFCharacterSet.c index 06901caaa0..cfba7a5994 100644 --- a/CoreFoundation/String.subproj/CFCharacterSet.c +++ b/CoreFoundation/String.subproj/CFCharacterSet.c @@ -1,7 +1,7 @@ /* CFCharacterSet.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -375,7 +375,7 @@ CF_INLINE void __CFCSetBitmapRemoveCharactersInRange(uint8_t *bitmap, UniChar fi #define __CFCSetAnnexBitmapClearPlane(bitmap,plane) ((bitmap) &= (~(1 << (plane)))) #define __CFCSetAnnexBitmapGetPlane(bitmap,plane) ((bitmap) & (1 << (plane))) -CF_INLINE void __CFCSetAllocateAnnexForPlane(CFCharacterSetRef cset, int plane) { +CF_INLINE void __CFCSetAllocateAnnexForPlane(CFCharacterSetRef cset, unsigned char plane) { if (cset->_annex == NULL) { ((CFMutableCharacterSetRef)cset)->_annex = (CFCharSetAnnexStruct *)CFAllocatorAllocate(CFGetAllocator(cset), sizeof(CFCharSetAnnexStruct), 0); cset->_annex->_numOfAllocEntries = plane; @@ -397,10 +397,13 @@ CF_INLINE void __CFCSetAnnexSetIsInverted(CFCharacterSetRef cset, Boolean flag) if (cset->_annex) ((CFMutableCharacterSetRef)cset)->_annex->_isAnnexInverted = flag; } -CF_INLINE void __CFCSetPutCharacterSetToAnnexPlane(CFCharacterSetRef cset, CFCharacterSetRef annexCSet, int plane) { +CF_INLINE void __CFCSetPutCharacterSetToAnnexPlane(CFCharacterSetRef cset, CFCharacterSetRef annexCSet, unsigned char plane) { if (plane < 1) { HALT; } __CFCSetAllocateAnnexForPlane(cset, plane); - if (__CFCSetAnnexBitmapGetPlane(cset->_annex->_validEntriesBitmap, plane)) CFRelease(cset->_annex->_nonBMPPlanes[plane - 1]); + if (__CFCSetAnnexBitmapGetPlane(cset->_annex->_validEntriesBitmap, plane)) { + _CLANG_ANALYZER_ASSERT(cset->_annex->_nonBMPPlanes[plane - 1] != NULL); + CFRelease(cset->_annex->_nonBMPPlanes[plane - 1]); + } if (annexCSet) { cset->_annex->_nonBMPPlanes[plane - 1] = (CFCharacterSetRef)CFRetain(annexCSet); __CFCSetAnnexBitmapSetPlane(cset->_annex->_validEntriesBitmap, plane); @@ -409,8 +412,9 @@ CF_INLINE void __CFCSetPutCharacterSetToAnnexPlane(CFCharacterSetRef cset, CFCha } } -CF_INLINE CFCharacterSetRef __CFCSetGetAnnexPlaneCharacterSet(CFCharacterSetRef cset, int plane) { +CF_INLINE CFCharacterSetRef __CFCSetGetAnnexPlaneCharacterSet(CFCharacterSetRef cset, unsigned char plane) { if (plane < 1) { HALT; } + if (plane > MAX_ANNEX_PLANE) { return NULL; } __CFCSetAllocateAnnexForPlane(cset, plane); if (!__CFCSetAnnexBitmapGetPlane(cset->_annex->_validEntriesBitmap, plane)) { cset->_annex->_nonBMPPlanes[plane - 1] = (CFCharacterSetRef)CFCharacterSetCreateMutable(CFGetAllocator(cset)); @@ -419,9 +423,17 @@ CF_INLINE CFCharacterSetRef __CFCSetGetAnnexPlaneCharacterSet(CFCharacterSetRef return cset->_annex->_nonBMPPlanes[plane - 1]; } -CF_INLINE CFCharacterSetRef __CFCSetGetAnnexPlaneCharacterSetNoAlloc(CFCharacterSetRef cset, int plane) { +CF_INLINE CFCharacterSetRef __CFCSetGetAnnexPlaneCharacterSetNoAlloc(CFCharacterSetRef cset, unsigned char plane) { if (plane < 1) { HALT; } - return (cset->_annex && __CFCSetAnnexBitmapGetPlane(cset->_annex->_validEntriesBitmap, plane) ? cset->_annex->_nonBMPPlanes[plane - 1] : NULL); + if (plane > MAX_ANNEX_PLANE) { return NULL; } + if (cset->_annex) { + if (__CFCSetAnnexBitmapGetPlane(cset->_annex->_validEntriesBitmap, plane)) { + if (plane <= cset->_annex->_numOfAllocEntries) { + return cset->_annex->_nonBMPPlanes[plane - 1]; + } + } + } + return NULL; } CF_INLINE void __CFCSetDeallocateAnnexPlane(CFCharacterSetRef cset) { @@ -719,25 +731,41 @@ static void __CFCSetAddNonBMPPlanesInRange(CFMutableCharacterSetRef cset, CFRang int firstChar = (range.location & 0xFFFF); int maxChar = range.location + range.length; int idx = range.location >> 16; // first plane - int maxPlane = (maxChar - 1) >> 16; // last plane + int maxPlane = MIN((maxChar - 1) >> 16, MAX_ANNEX_PLANE); // last plane CFRange planeRange; CFMutableCharacterSetRef annexPlane; maxChar &= 0xFFFF; + if (idx > MAX_ANNEX_PLANE) { + // no point going further, we're not going to be able to store any part of this range + return; + } + + Boolean const annex_inverted = __CFCSetAnnexIsInverted(cset); + for (idx = (idx ? idx : 1);idx <= maxPlane;idx++) { planeRange.location = __CFMax(firstChar, 0); planeRange.length = (idx == maxPlane && maxChar ? maxChar : 0x10000) - planeRange.location; - if (__CFCSetAnnexIsInverted(cset)) { + if (annex_inverted) { if ((annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(cset, idx))) { CFCharacterSetRemoveCharactersInRange(annexPlane, planeRange); if (__CFCSetIsEmpty(annexPlane) && !__CFCSetIsInverted(annexPlane)) { CFRelease(annexPlane); __CFCSetAnnexBitmapClearPlane(cset->_annex->_validEntriesBitmap, idx); } + } else { + CFAllocatorRef const allocator = CFGetAllocator(cset); + annexPlane = CFCharacterSetCreateMutable(allocator); + CFCharacterSetAddCharactersInRange(annexPlane, planeRange); + __CFCSetPutCharacterSetToAnnexPlane(cset, annexPlane, idx); + CFRelease(annexPlane); } } else { - CFCharacterSetAddCharactersInRange((CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(cset, idx), planeRange); + annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(cset, idx); + if (annexPlane) { + CFCharacterSetAddCharactersInRange(annexPlane, planeRange); + } } } if (!__CFCSetHasNonBMPPlane(cset) && !__CFCSetAnnexIsInverted(cset)) __CFCSetDeallocateAnnexPlane(cset); @@ -747,17 +775,25 @@ static void __CFCSetRemoveNonBMPPlanesInRange(CFMutableCharacterSetRef cset, CFR int firstChar = (range.location & 0xFFFF); int maxChar = range.location + range.length; int idx = range.location >> 16; // first plane - int maxPlane = (maxChar - 1) >> 16; // last plane + int maxPlane = MIN((maxChar - 1) >> 16, MAX_ANNEX_PLANE); // last plane CFRange planeRange; CFMutableCharacterSetRef annexPlane; + if (idx > MAX_ANNEX_PLANE) { + // no point going further, we're not going to be able to store any part of this range + return; + } + maxChar &= 0xFFFF; for (idx = (idx ? idx : 1);idx <= maxPlane;idx++) { planeRange.location = __CFMax(firstChar, 0); planeRange.length = (idx == maxPlane && maxChar ? maxChar : 0x10000) - planeRange.location; if (__CFCSetAnnexIsInverted(cset)) { - CFCharacterSetAddCharactersInRange((CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(cset, idx), planeRange); + annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(cset, idx); + if (annexPlane) { + CFCharacterSetAddCharactersInRange(annexPlane, planeRange); + } } else { if ((annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(cset, idx))) { CFCharacterSetRemoveCharactersInRange(annexPlane, planeRange); @@ -799,10 +835,12 @@ static void __CFCSetMakeBitmap(CFMutableCharacterSetRef cset) { while (bitmapLength-- > 0) *(bytes++) = (uint8_t)0xFF; } annexSet = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(cset, idx); - __CFCSetPutClassType(annexSet, __kCFCharSetClassBitmap); - __CFCSetPutBitmapBits(annexSet, annexBitmap); - __CFCSetPutIsInverted(annexSet, false); - __CFCSetPutHasHashValue(annexSet, false); + if (annexSet) { + __CFCSetPutClassType(annexSet, __kCFCharSetClassBitmap); + __CFCSetPutBitmapBits(annexSet, annexBitmap); + __CFCSetPutIsInverted(annexSet, false); + __CFCSetPutHasHashValue(annexSet, false); + } annexBitmap = NULL; } if (annexBitmap) CFAllocatorDeallocate(allocator, annexBitmap); @@ -896,7 +934,7 @@ CF_INLINE Boolean __CFCSetBsearchUniChar(const UniChar *theTable, CFIndex length /* Array of instantiated builtin set. Note builtin set ID starts with 1 so the array index is ID - 1 */ -static CFCharacterSetRef __CFBuiltinSets[sizeof(CFCharacterSetRef) * __kCFLastBuiltinSetID] = {0}; +static CFCharacterSetRef __CFBuiltinSets[__kCFLastBuiltinSetID] = {0}; /* Global lock for character set */ @@ -1304,7 +1342,7 @@ static bool __CFCheckForExapendedSet = false; CF_PRIVATE void __CFCharacterSetInitialize(void) { static dispatch_once_t initOnce; dispatch_once(&initOnce, ^{ - const char *checkForExpandedSet = __CFgetenv("__CF_DEBUG_EXPANDED_SET"); + const char *checkForExpandedSet = getenv("__CF_DEBUG_EXPANDED_SET"); if (checkForExpandedSet && (*checkForExpandedSet == 'Y')) __CFCheckForExapendedSet = true; }); } @@ -1588,7 +1626,7 @@ CFCharacterSetRef CFCharacterSetCreateWithBitmapRepresentation(CFAllocatorRef al CFCharacterSetRef CFCharacterSetCreateInvertedSet(CFAllocatorRef alloc, CFCharacterSetRef theSet) { CFMutableCharacterSetRef cset; - CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFCharacterSet, CFCharacterSetRef , (NSCharacterSet *)theSet, invertedSet); + CF_OBJC_RETAINED_FUNCDISPATCHV(_kCFRuntimeIDCFCharacterSet, CFCharacterSetRef , (NSCharacterSet *)theSet, invertedSet); cset = CFCharacterSetCreateMutableCopy(alloc, theSet); CFCharacterSetInvert(cset); @@ -1774,7 +1812,7 @@ Boolean CFCharacterSetIsCharacterMember(CFCharacterSetRef theSet, UniChar theCha CF_CROSS_PLATFORM_EXPORT Boolean _CFCharacterSetIsLongCharacterMember(CFCharacterSetRef theSet, UTF32Char theChar) { CFIndex length; - UInt32 plane = (theChar >> 16); + unsigned char plane = (theChar >> 16); Boolean isAnnexInverted = false; Boolean isInverted; Boolean result = false; @@ -1950,6 +1988,9 @@ Boolean CFCharacterSetIsSupersetOfSet(CFCharacterSetRef theSet, CFCharacterSetRe Boolean CFCharacterSetHasMemberInPlane(CFCharacterSetRef theSet, CFIndex thePlane) { Boolean isInverted = __CFCSetIsInverted(theSet); + if (thePlane < 0 || thePlane > MAX_ANNEX_PLANE) { + return FALSE; + } CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFCharacterSet, Boolean, (NSCharacterSet *)theSet, hasMemberInPlane:(uint8_t)thePlane); @@ -2029,34 +2070,92 @@ Boolean CFCharacterSetHasMemberInPlane(CFCharacterSetRef theSet, CFIndex thePlan CFDataRef CFCharacterSetCreateBitmapRepresentation(CFAllocatorRef alloc, CFCharacterSetRef theSet) { - CFMutableDataRef data; - int numNonBMPPlanes = 0; - int planeIndices[MAX_ANNEX_PLANE]; - int idx; - int length; - bool isAnnexInverted; - CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFCharacterSet, CFDataRef , (NSCharacterSet *)theSet, _retainedBitmapRepresentation); __CFGenericValidateType(theSet, _kCFRuntimeIDCFCharacterSet); - isAnnexInverted = (__CFCSetAnnexIsInverted(theSet) != 0); + bool isAnnexInverted = (__CFCSetAnnexIsInverted(theSet) != 0); if (__CFCSetHasNonBMPPlane(theSet)) { - for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) { + int numNonBMPPlanes = 0; + unsigned char planeIndices[MAX_ANNEX_PLANE]; + + for (unsigned char idx = 1;idx <= MAX_ANNEX_PLANE;idx++) { if (isAnnexInverted || __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, idx)) { planeIndices[numNonBMPPlanes++] = idx; } } + + const int length = __kCFBitmapSize + ((__kCFBitmapSize + 1) * numNonBMPPlanes); + CFMutableDataRef data = CFDataCreateMutable(alloc, length); + CFDataSetLength(data, length); + __CFCSetGetBitmap(theSet, CFDataGetMutableBytePtr(data)); + + if (numNonBMPPlanes > 0) { + uint8_t *bytes = CFDataGetMutableBytePtr(data) + __kCFBitmapSize; + + if (__CFCSetHasNonBMPPlane(theSet)) { + CFCharacterSetRef subset; + + for (int idx = 0;idx < numNonBMPPlanes; idx++) { + *(bytes++) = planeIndices[idx]; + if ((subset = __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, planeIndices[idx])) == NULL) { + __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, (isAnnexInverted ? 0xFF : 0)); + } else { + __CFCSetGetBitmap(subset, bytes); + if (isAnnexInverted) { + uint32_t count = __kCFBitmapSize / sizeof(uint32_t); + uint32_t *bits = (uint32_t *)bytes; + + while (count-- > 0) { + *bits = ~(*bits); + ++bits; + } + } + } + bytes += __kCFBitmapSize; + } + } + } + + return data; } else if (__CFCSetIsBuiltin(theSet)) { - numNonBMPPlanes = (__CFCSetIsInverted(theSet) ? MAX_ANNEX_PLANE : CFUniCharGetNumberOfPlanes(__CFCSetBuiltinType(theSet)) - 1); + int numNonBMPPlanes = (__CFCSetIsInverted(theSet) ? MAX_ANNEX_PLANE : CFUniCharGetNumberOfPlanes(__CFCSetBuiltinType(theSet)) - 1); + + const int length = __kCFBitmapSize + ((__kCFBitmapSize + 1) * numNonBMPPlanes); + CFMutableDataRef data = CFDataCreateMutable(alloc, length); + CFDataSetLength(data, length); + __CFCSetGetBitmap(theSet, CFDataGetMutableBytePtr(data)); + + if (numNonBMPPlanes > 0) { + uint8_t *bytes = CFDataGetMutableBytePtr(data) + __kCFBitmapSize; + UInt8 result; + CFIndex delta; + Boolean isInverted = __CFCSetIsInverted(theSet); + + for (int idx = 0;idx < numNonBMPPlanes;idx++) { + if ((result = CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(theSet), idx + 1, bytes + 1, (isInverted != 0))) == kCFUniCharBitmapEmpty) continue; + *(bytes++) = idx + 1; + if (result == kCFUniCharBitmapAll) { + CFIndex bitmapLength = __kCFBitmapSize; + while (bitmapLength-- > 0) *(bytes++) = (uint8_t)0xFF; + } else { + bytes += __kCFBitmapSize; + } + } + delta = bytes - (const uint8_t *)CFDataGetBytePtr(data); + if (delta < length) CFDataSetLength(data, delta); + } + + return data; } else if (__CFCSetIsRange(theSet)) { + int numNonBMPPlanes = 0; UInt32 firstChar = __CFCSetRangeFirstChar(theSet); UInt32 lastChar = __CFCSetRangeFirstChar(theSet) + __CFCSetRangeLength(theSet) - 1; int firstPlane = (firstChar >> 16); int lastPlane = (lastChar >> 16); bool isInverted = (__CFCSetIsInverted(theSet) != 0); - + if (lastPlane > 0) { if (firstPlane == 0) { firstPlane = 1; @@ -2075,62 +2174,19 @@ CFDataRef CFCharacterSetCreateBitmapRepresentation(CFAllocatorRef alloc, CFChara } else if (isInverted) { numNonBMPPlanes = MAX_ANNEX_PLANE; } - } else if (isAnnexInverted) { - numNonBMPPlanes = MAX_ANNEX_PLANE; - } - - length = __kCFBitmapSize + ((__kCFBitmapSize + 1) * numNonBMPPlanes); - data = CFDataCreateMutable(alloc, length); - CFDataSetLength(data, length); - __CFCSetGetBitmap(theSet, CFDataGetMutableBytePtr(data)); - - if (numNonBMPPlanes > 0) { - uint8_t *bytes = CFDataGetMutableBytePtr(data) + __kCFBitmapSize; - - if (__CFCSetHasNonBMPPlane(theSet)) { - CFCharacterSetRef subset; - - for (idx = 0;idx < numNonBMPPlanes;idx++) { - *(bytes++) = planeIndices[idx]; - if ((subset = __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, planeIndices[idx])) == NULL) { - __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, (isAnnexInverted ? 0xFF : 0)); - } else { - __CFCSetGetBitmap(subset, bytes); - if (isAnnexInverted) { - uint32_t count = __kCFBitmapSize / sizeof(uint32_t); - uint32_t *bits = (uint32_t *)bytes; - - while (count-- > 0) { - *bits = ~(*bits); - ++bits; - } - } - } - bytes += __kCFBitmapSize; - } - } else if (__CFCSetIsBuiltin(theSet)) { - UInt8 result; - CFIndex delta; - Boolean isInverted = __CFCSetIsInverted(theSet); - - for (idx = 0;idx < numNonBMPPlanes;idx++) { - if ((result = CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(theSet), idx + 1, bytes + 1, (isInverted != 0))) == kCFUniCharBitmapEmpty) continue; - *(bytes++) = idx + 1; - if (result == kCFUniCharBitmapAll) { - CFIndex bitmapLength = __kCFBitmapSize; - while (bitmapLength-- > 0) *(bytes++) = (uint8_t)0xFF; - } else { - bytes += __kCFBitmapSize; - } - } - delta = bytes - (const uint8_t *)CFDataGetBytePtr(data); - if (delta < length) CFDataSetLength(data, delta); - } else if (__CFCSetIsRange(theSet)) { + + const int length = __kCFBitmapSize + ((__kCFBitmapSize + 1) * numNonBMPPlanes); + CFMutableDataRef data = CFDataCreateMutable(alloc, length); + CFDataSetLength(data, length); + __CFCSetGetBitmap(theSet, CFDataGetMutableBytePtr(data)); + + if (numNonBMPPlanes > 0) { + uint8_t *bytes = CFDataGetMutableBytePtr(data) + __kCFBitmapSize; UInt32 firstChar = __CFCSetRangeFirstChar(theSet); UInt32 lastChar = __CFCSetRangeFirstChar(theSet) + __CFCSetRangeLength(theSet) - 1; int firstPlane = (firstChar >> 16); int lastPlane = (lastChar >> 16); - + if (firstPlane == 0) { firstPlane = 1; firstChar = 0x10000; @@ -2139,7 +2195,9 @@ CFDataRef CFCharacterSetCreateBitmapRepresentation(CFAllocatorRef alloc, CFChara // Mask out the plane byte firstChar &= 0xFFFF; lastChar &= 0xFFFF; - + + // n.b. idx is used outside the loop here + int idx; for (idx = 1;idx < firstPlane;idx++) { // Fill up until the first plane *(bytes++) = idx; __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, 0xFF); @@ -2148,46 +2206,66 @@ CFDataRef CFCharacterSetCreateBitmapRepresentation(CFAllocatorRef alloc, CFChara if (firstPlane == lastPlane) { if ((firstChar > 0) || (lastChar < 0xFFFF)) { *(bytes++) = idx; - __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, 0xFF); + __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, 0xFF); __CFCSetBitmapRemoveCharactersInRange(bytes, firstChar, lastChar); bytes += __kCFBitmapSize; } } else if (firstPlane < lastPlane) { if (firstChar > 0) { *(bytes++) = idx; - __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, 0); + __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, 0); __CFCSetBitmapAddCharactersInRange(bytes, 0, firstChar - 1); bytes += __kCFBitmapSize; } if (lastChar < 0xFFFF) { *(bytes++) = idx; - __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, 0); + __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, 0); __CFCSetBitmapAddCharactersInRange(bytes, lastChar, 0xFFFF); bytes += __kCFBitmapSize; } } - for (idx = lastPlane + 1;idx <= MAX_ANNEX_PLANE;idx++) { + for (int idx = lastPlane + 1;idx <= MAX_ANNEX_PLANE;idx++) { *(bytes++) = idx; __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, 0xFF); bytes += __kCFBitmapSize; } } else { - for (idx = firstPlane;idx <= lastPlane;idx++) { + for (int idx = firstPlane;idx <= lastPlane;idx++) { *(bytes++) = idx; __CFCSetBitmapAddCharactersInRange(bytes, (idx == firstPlane ? firstChar : 0), (idx == lastPlane ? lastChar : 0xFFFF)); - bytes += __kCFBitmapSize; + bytes += __kCFBitmapSize; } } - } else if (isAnnexInverted) { - for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) { + } + + return data; + } else if (isAnnexInverted) { + int numNonBMPPlanes = MAX_ANNEX_PLANE; + + const int length = __kCFBitmapSize + ((__kCFBitmapSize + 1) * numNonBMPPlanes); + CFMutableDataRef data = CFDataCreateMutable(alloc, length); + CFDataSetLength(data, length); + __CFCSetGetBitmap(theSet, CFDataGetMutableBytePtr(data)); + + if (numNonBMPPlanes > 0) { + uint8_t *bytes = CFDataGetMutableBytePtr(data) + __kCFBitmapSize; + + for (int idx = 1;idx <= MAX_ANNEX_PLANE;idx++) { *(bytes++) = idx; __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, 0xFF); bytes += __kCFBitmapSize; } } + + return data; + } else { + const int length = __kCFBitmapSize; + CFMutableDataRef data = CFDataCreateMutable(alloc, length); + CFDataSetLength(data, length); + __CFCSetGetBitmap(theSet, CFDataGetMutableBytePtr(data)); + + return data; } - - return data; } /*** MutableCharacterSet functions ***/ @@ -2589,10 +2667,16 @@ void CFCharacterSetUnion(CFMutableCharacterSetRef theSet, CFCharacterSetRef theO if (__CFCSetHasNonBMPPlane(theOtherSet)) { CFMutableCharacterSetRef otherSetPlane; int idx; + + Boolean const otherSet_annexInverted = __CFCSetAnnexIsInverted(theOtherSet); for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) { if ((otherSetPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theOtherSet, idx))) { - CFCharacterSetUnion((CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(theSet, idx), otherSetPlane); + if (otherSet_annexInverted) { + CFCharacterSetIntersect((CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(theSet, idx), otherSetPlane); + } else { + CFCharacterSetUnion((CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(theSet, idx), otherSetPlane); + } } } } else if (__CFCSetAnnexIsInverted(theOtherSet)) { @@ -2602,7 +2686,7 @@ void CFCharacterSetUnion(CFMutableCharacterSetRef theSet, CFCharacterSetRef theO CFMutableCharacterSetRef annexPlane; uint8_t bitmapBuffer[__kCFBitmapSize]; uint8_t result; - int planeIndex; + unsigned char planeIndex; Boolean isOtherAnnexPlaneInverted = __CFCSetAnnexIsInverted(theOtherSet); UInt32 *bitmap1; UInt32 *bitmap2; @@ -2782,7 +2866,7 @@ void CFCharacterSetIntersect(CFMutableCharacterSetRef theSet, CFCharacterSetRef CFMutableCharacterSetRef annexPlane; uint8_t bitmapBuffer[__kCFBitmapSize]; uint8_t result; - int planeIndex; + unsigned char planeIndex; UInt32 *bitmap1; UInt32 *bitmap2; CFIndex length; @@ -2818,29 +2902,48 @@ void CFCharacterSetIntersect(CFMutableCharacterSetRef theSet, CFCharacterSetRef __CFCSetAddNonBMPPlanesInRange(tempOtherSet, CFRangeMake(__CFCSetRangeFirstChar(theOtherSet), __CFCSetRangeLength(theOtherSet))); + Boolean const theSet_annexInverted = __CFCSetAnnexIsInverted(theSet); + Boolean const otherSet_annexInverted = __CFCSetAnnexIsInverted(tempOtherSet); + for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) { - if ((otherSetPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(tempOtherSet, idx))) { + + otherSetPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(tempOtherSet, idx); + if (otherSetPlane) { annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(theSet, idx); - if (__CFCSetAnnexIsInverted(tempOtherSet)) CFCharacterSetInvert(otherSetPlane); - if (__CFCSetAnnexIsInverted(theSet)) CFCharacterSetInvert(annexPlane); + + if (otherSet_annexInverted) { + CFCharacterSetInvert(otherSetPlane); + } + if (theSet_annexInverted) { + CFCharacterSetInvert(annexPlane); + } + CFCharacterSetIntersect(annexPlane, otherSetPlane); - if (__CFCSetAnnexIsInverted(theSet)) CFCharacterSetInvert(annexPlane); - if (__CFCSetAnnexIsInverted(tempOtherSet)) CFCharacterSetInvert(otherSetPlane); - if (__CFCSetIsEmpty(annexPlane) && !__CFCSetIsInverted(annexPlane)) __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, idx); + + if (theSet_annexInverted) { + CFCharacterSetInvert(annexPlane); + } + if (otherSet_annexInverted) { + CFCharacterSetInvert(otherSetPlane); + } + + if (__CFCSetIsEmpty(annexPlane) && !__CFCSetIsInverted(annexPlane)) { + __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, idx); + } } else if ((annexPlane = (CFMutableCharacterSetRef) __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, idx))) { - if (__CFCSetAnnexIsInverted(theSet)) { + if (theSet_annexInverted) { CFCharacterSetInvert(annexPlane); CFCharacterSetIntersect(annexPlane, emptySet); CFCharacterSetInvert(annexPlane); } else { __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, idx); } - } else if ((__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, idx) == NULL) && __CFCSetAnnexIsInverted(theSet)) { + } else if ((__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, idx) == NULL) && theSet_annexInverted) { // the set has no such annex plane and the annex plane is inverted, it means the set contains everything in the annex plane annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(theSet, idx); - if (__CFCSetAnnexIsInverted(theSet)) CFCharacterSetInvert(annexPlane); + if (theSet_annexInverted) CFCharacterSetInvert(annexPlane); CFCharacterSetIntersect(annexPlane, emptySet); - if (__CFCSetAnnexIsInverted(theSet)) CFCharacterSetInvert(annexPlane); + if (theSet_annexInverted) CFCharacterSetInvert(annexPlane); } } if (!__CFCSetHasNonBMPPlane(theSet)) __CFCSetDeallocateAnnexPlane(theSet); @@ -2921,7 +3024,7 @@ void CFCharacterSetInvert(CFMutableCharacterSetRef theSet) { __CFCSetAnnexSetIsInverted(theSet, !__CFCSetAnnexIsInverted(theSet)); } -void CFCharacterSetCompact(CFMutableCharacterSetRef theSet) { +void _CFCharacterSetCompact(CFMutableCharacterSetRef theSet) { if (__CFCSetIsBitmap(theSet) && __CFCSetBitmapBits(theSet)) __CFCSetMakeCompact(theSet); if (__CFCSetHasNonBMPPlane(theSet)) { CFMutableCharacterSetRef annex; @@ -2935,7 +3038,7 @@ void CFCharacterSetCompact(CFMutableCharacterSetRef theSet) { } } -void CFCharacterSetFast(CFMutableCharacterSetRef theSet) { +void _CFCharacterSetFast(CFMutableCharacterSetRef theSet) { if (__CFCSetIsCompactBitmap(theSet) && __CFCSetCompactBitmapBits(theSet)) __CFCSetMakeBitmap(theSet); if (__CFCSetHasNonBMPPlane(theSet)) { CFMutableCharacterSetRef annex; diff --git a/CoreFoundation/String.subproj/CFCharacterSet.h b/CoreFoundation/String.subproj/CFCharacterSet.h index 2b26369a1b..789c590edc 100644 --- a/CoreFoundation/String.subproj/CFCharacterSet.h +++ b/CoreFoundation/String.subproj/CFCharacterSet.h @@ -1,7 +1,7 @@ /* CFCharacterSet.h - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/String.subproj/CFCharacterSetPriv.h b/CoreFoundation/String.subproj/CFCharacterSetPriv.h index 1803f47796..90a6ab9689 100644 --- a/CoreFoundation/String.subproj/CFCharacterSetPriv.h +++ b/CoreFoundation/String.subproj/CFCharacterSetPriv.h @@ -1,7 +1,7 @@ /* CFCharacterSetPriv.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -67,6 +67,11 @@ CF_EXPORT CFStringRef _CFCharacterSetCreateKeyedCodingString(CFCharacterSetRef c CF_EXPORT bool _CFCharacterSetIsInverted(CFCharacterSetRef cset); CF_EXPORT void _CFCharacterSetSetIsInverted(CFCharacterSetRef cset, bool flag); +/* For use ONLY by CoreText, contact the Foundation team before using. +*/ +CF_EXPORT void _CFCharacterSetCompact(CFMutableCharacterSetRef cset); +CF_EXPORT void _CFCharacterSetFast(CFMutableCharacterSetRef cset); + CF_EXTERN_C_END #endif /* ! __COREFOUNDATION_CFCHARACTERSETPRIV__ */ diff --git a/CoreFoundation/String.subproj/CFRunArray.c b/CoreFoundation/String.subproj/CFRunArray.c index 981083c57b..07bb1e32e6 100644 --- a/CoreFoundation/String.subproj/CFRunArray.c +++ b/CoreFoundation/String.subproj/CFRunArray.c @@ -9,7 +9,7 @@ /* CFRunArray.c - Copyright (c) 2004-2018, Apple Inc. All rights reserved. + Copyright (c) 2004-2019, Apple Inc. All rights reserved. */ #include "CFRunArray.h" diff --git a/CoreFoundation/String.subproj/CFRunArray.h b/CoreFoundation/String.subproj/CFRunArray.h index ee987b685a..4148116606 100644 --- a/CoreFoundation/String.subproj/CFRunArray.h +++ b/CoreFoundation/String.subproj/CFRunArray.h @@ -9,7 +9,7 @@ /* CFRunArray.h - Copyright (c) 2004-2018, Apple Inc. All rights reserved. + Copyright (c) 2004-2019, Apple Inc. All rights reserved. Contains CFRunArray */ diff --git a/CoreFoundation/String.subproj/CFString.c b/CoreFoundation/String.subproj/CFString.c index 6dac4d8a38..57f0b3c2b2 100644 --- a/CoreFoundation/String.subproj/CFString.c +++ b/CoreFoundation/String.subproj/CFString.c @@ -1,7 +1,7 @@ /* CFString.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -27,6 +27,7 @@ #include "CFString_Internal.h" #include "CFRuntime_Internal.h" #include +#include #if TARGET_OS_MAC || TARGET_OS_WIN32 || TARGET_OS_LINUX #include "CFLocaleInternal.h" #include "CFStringLocalizedFormattingInternal.h" @@ -112,6 +113,15 @@ CF_PRIVATE uint32_t CFUniCharGetConditionalCaseMappingFlags(UTF32Char theChar, U static Boolean __CFStringAppendFormatCore(CFMutableStringRef outputString, CFStringRef (*copyDescFunc)(void *, const void *), CFStringRef (*contextDescFunc)(void *, const void *, const void *, bool, bool *), CFDictionaryRef formatOptions, CFDictionaryRef stringsDictConfig, CFStringRef validFormatSpecifiers, CFStringRef formatString, CFIndex initialArgPosition, const void *origValues, CFIndex originalValuesSize, va_list args, CFErrorRef *errorPtr); +static inline const char * _CFStringGetCStringPtrInternal(CFStringRef str, CFStringEncoding encoding, Boolean requiresNullTermination, Boolean requiresBridgingCheck); + +CF_INLINE void _CFStringInitInlineBufferInternal(CFStringRef str, CFStringInlineBuffer *buf, CFRange range, Boolean requiresBridgingCheck) { + buf->theString = str; + buf->rangeToBuffer = range; + buf->directCStringBuffer = (buf->directUniCharBuffer = CFStringGetCharactersPtr(str)) ? NULL : _CFStringGetCStringPtrInternal(str, kCFStringEncodingASCII, false, requiresBridgingCheck); + buf->bufferedRangeStart = buf->bufferedRangeEnd = 0; +} + #if defined(DEBUG) // We put this into C & Pascal strings if we can't convert @@ -272,7 +282,7 @@ CF_INLINE SInt32 __CFStrSkipAnyLengthByte(CFStringRef str) {return __CF /* Returns ptr to the buffer (which might include the length byte). */ -CF_INLINE const void *__CFStrContents(CFStringRef str) { +CF_INLINE const void * _Nullable __CFStrContents(CFStringRef str) { if (__CFStrIsInline(str)) { return (const void *)(((uintptr_t)&(str->variants)) + (__CFStrHasExplicitLength(str) ? sizeof(CFIndex) : 0)); } else { // Not inline; pointer is always word 2 @@ -476,6 +486,8 @@ CFIndex CFStringGetMaximumSizeForEncoding(CFIndex length, CFStringEncoding encod case kCFStringEncodingISOLatin1: case kCFStringEncodingNextStepLatin: case kCFStringEncodingASCII: + return length / sizeof(uint8_t); + default: return length / sizeof(uint8_t); } @@ -547,45 +559,49 @@ CF_INLINE Boolean __CFBytesInASCII(const uint8_t *bytes, CFIndex len) { #if TARGET_RT_64_BIT /* A bit of unrolling; go by 32s, 16s, and 8s first */ - while (len >= 32) { - uint64_t val = *(const uint64_t *)bytes; + while (len >= 4 * sizeof(uint64_t)) { + uint64_t val; + memcpy(&val, bytes, sizeof(uint64_t)); uint64_t hiBits = (val & 0x8080808080808080ULL); // More efficient to collect this rather than do a conditional at every step - bytes += 8; - val = *(const uint64_t *)bytes; + bytes += sizeof(uint64_t); + memcpy(&val, bytes, sizeof(uint64_t)); hiBits |= (val & 0x8080808080808080ULL); - bytes += 8; - val = *(const uint64_t *)bytes; + bytes += sizeof(uint64_t); + memcpy(&val, bytes, sizeof(uint64_t)); hiBits |= (val & 0x8080808080808080ULL); - bytes += 8; - val = *(const uint64_t *)bytes; + bytes += sizeof(uint64_t); + memcpy(&val, bytes, sizeof(uint64_t)); if (hiBits | (val & 0x8080808080808080ULL)) return false; - bytes += 8; - len -= 32; + bytes += sizeof(uint64_t); + len -= 4 * sizeof(uint64_t); } - while (len >= 16) { - uint64_t val = *(const uint64_t *)bytes; + while (len >= 2 * sizeof(uint64_t)) { + uint64_t val; + memcpy(&val, bytes, sizeof(uint64_t)); uint64_t hiBits = (val & 0x8080808080808080ULL); - bytes += 8; - val = *(const uint64_t *)bytes; + bytes += sizeof(uint64_t); + memcpy(&val, bytes, sizeof(uint64_t)); if (hiBits | (val & 0x8080808080808080ULL)) return false; - bytes += 8; - len -= 16; + bytes += sizeof(uint64_t); + len -= 2 * sizeof(uint64_t); } - while (len >= 8) { - uint64_t val = *(const uint64_t *)bytes; + while (len >= sizeof(uint64_t)) { + uint64_t val; + memcpy(&val, bytes, sizeof(uint64_t)); if (val & 0x8080808080808080ULL) return false; - bytes += 8; - len -= 8; + bytes += sizeof(uint64_t); + len -= sizeof(uint64_t); } #endif /* Go by 4s */ - while (len >= 4) { - uint32_t val = *(const uint32_t *)bytes; + while (len >= sizeof(uint32_t)) { + uint32_t val; + memcpy(&val, bytes, sizeof(uint32_t)); if (val & 0x80808080U) return false; - bytes += 4; - len -= 4; + bytes += sizeof(uint32_t); + len -= sizeof(uint32_t); } /* Handle the rest one byte at a time */ while (len--) { @@ -814,11 +830,9 @@ static void copyBlocks( /* Call the callback; if it doesn't exist or returns false, then log */ -static void __CFStringHandleOutOfMemory(CFTypeRef obj) { +__attribute__((cold)) +void __CFStringHandleOutOfMemory(CFTypeRef _Nullable obj) CLANG_ANALYZER_NORETURN { CFStringRef msg = CFSTR("Out of memory. We suggest restarting the application. If you have an unsaved document, create a backup copy in Finder, then try to save."); - { - CFLog(kCFLogLevelCritical, CFSTR("%@"), msg); - } } /* Reallocates the backing store of the string to accomodate the new length. Space is reserved or characters are deleted as indicated by insertLength and the ranges in deleteRanges. The length is updated to reflect the new state. Will also maintain a length byte and a null byte in 8-bit strings. If length cannot fit in length byte, the space will still be reserved, but will be 0. (Hence the reason the length byte should never be looked at as length unless there is no explicit length.) @@ -859,7 +873,8 @@ static void __CFStringChangeSizeMultiple(CFMutableStringRef str, const CFRange * } else { if (!__CFStrIsExternalMutable(str)) { __CFStrSetUnicode(str, false); - if (curCapacity >= (int)(sizeof(uint8_t) * 2)) { // If there's room + if (curCapacity >= (int)(sizeof(uint8_t) * 2)) { // If there's room + if (!curContents) { CRSetCrashLogMessage("String had a capacity but NULL buffer pointer"); HALT; } __CFStrSetHasLengthAndNullBytes(str); ((uint8_t *)curContents)[0] = ((uint8_t *)curContents)[1] = 0; } else { @@ -878,7 +893,7 @@ static void __CFStringChangeSizeMultiple(CFMutableStringRef str, const CFRange * if (newLength > (LONG_MAX - numExtraBytes) / newCharSize) __CFStringHandleOutOfMemory(str); // Does not return CFIndex newCapacity = __CFStrNewCapacity(str, newLength * newCharSize + numExtraBytes, curCapacity, true, newCharSize); if (newCapacity == -1) __CFStringHandleOutOfMemory(str); // Does not return - Boolean allocNewBuffer = (newCapacity != curCapacity) || (curLength > 0 && !oldIsUnicode && newIsUnicode); /* We alloc new buffer if oldIsUnicode != newIsUnicode because the contents have to be copied */ + Boolean allocNewBuffer = (curContents == NULL) || (newCapacity != curCapacity) || (curLength > 0 && !oldIsUnicode && newIsUnicode); /* We alloc new buffer if oldIsUnicode != newIsUnicode because the contents have to be copied */ uint8_t *newContents; if (allocNewBuffer) { newContents = (uint8_t *)__CFStrAllocateMutableContents(str, newCapacity); @@ -1004,7 +1019,7 @@ static Boolean __CFStringEqual(CFTypeRef cf1, CFTypeRef cf2) { CFStringInlineBuffer buf; CFIndex buf_idx = 0; - CFStringInitInlineBuffer(str1, &buf, CFRangeMake(0, len1)); + _CFStringInitInlineBufferInternal(str1, &buf, CFRangeMake(0, len1), false); for (buf_idx = 0; buf_idx < len1; buf_idx++) { if (__CFStringGetCharacterFromInlineBufferQuick(&buf, buf_idx) != ((UniChar *)contents2)[buf_idx]) return false; } @@ -1012,7 +1027,7 @@ static Boolean __CFStringEqual(CFTypeRef cf1, CFTypeRef cf2) { CFStringInlineBuffer buf; CFIndex buf_idx = 0; - CFStringInitInlineBuffer(str2, &buf, CFRangeMake(0, len1)); + _CFStringInitInlineBufferInternal(str2, &buf, CFRangeMake(0, len1), false); for (buf_idx = 0; buf_idx < len1; buf_idx++) { if (__CFStringGetCharacterFromInlineBufferQuick(&buf, buf_idx) != ((UniChar *)contents1)[buf_idx]) return false; } @@ -1052,10 +1067,10 @@ Hash function was changed between Panther and Tiger, and Tiger and Leopard. #define HashEverythingLimit 96 #define HashNextFourUniChars(accessStart, accessEnd, pointer) \ - {result = result * 67503105 + (((accessStart 0 accessEnd) * 257 + (accessStart 1 accessEnd)) * 257 + (accessStart 2 accessEnd)) * 257 + (accessStart 3 accessEnd); pointer += 4;} + {result = result * 67503105U + (((accessStart 0 accessEnd) * 257U + (accessStart 1 accessEnd)) * 257U + (accessStart 2 accessEnd)) * 257U + (accessStart 3 accessEnd); pointer += 4;} #define HashNextUniChar(accessStart, accessEnd, pointer) \ - {result = result * 257 + (accessStart 0 accessEnd); pointer++;} + {result = result * 257U + (accessStart 0 accessEnd); pointer++;} /* In this function, actualLen is the length of the original string; but len is the number of characters in buffer. The buffer is expected to contain the parts of the string relevant to hashing. @@ -1213,13 +1228,14 @@ static CFStringRef __CFStringCopyFormattingDescription(CFTypeRef cf, CFDictionar return (CFStringRef)CFStringCreateCopy(__CFGetAllocator(cf), (CFStringRef)cf); } +CF_PRIVATE CFStringRef _CFNonObjCStringCreateCopy(CFAllocatorRef alloc, CFStringRef str); typedef CFTypeRef (*CF_STRING_CREATE_COPY)(CFAllocatorRef alloc, CFTypeRef theString); const CFRuntimeClass __CFStringClass = { _kCFRuntimeScannedObject, "CFString", NULL, // init - (CF_STRING_CREATE_COPY)CFStringCreateCopy, + (CF_STRING_CREATE_COPY)_CFNonObjCStringCreateCopy, __CFStringDeallocate, __CFStringEqual, __CFStringHash, @@ -1439,7 +1455,7 @@ CF_PRIVATE CFStringRef __CFStringCreateImmutableFunnel3( if (stringSupportsROM) { // Disable the string ROM if necessary static char sDisableStringROM = -1; - if (sDisableStringROM == -1) sDisableStringROM = !! __CFgetenv("CFStringDisableROM"); + if (sDisableStringROM == -1) sDisableStringROM = !! getenv("CFStringDisableROM"); if (sDisableStringROM == 0) romResult = __CFSearchStringROM((const char *)realBytes, realNumBytes); } @@ -1454,7 +1470,7 @@ CF_PRIVATE CFStringRef __CFStringCreateImmutableFunnel3( bytes = NULL; /* set our result to the ROM result which is not really mutable, of course, but that's OK because we don't try to modify it. */ - str = (CFMutableStringRef)romResult; + str = (CFMutableStringRef)CFRetain(romResult); #if INSTRUMENT_TAGGED_POINTER_STRINGS _CFTaggedPointerStringStats.stringROMCount++; @@ -1689,7 +1705,7 @@ CFStringRef CFStringCreateWithSubstring(CFAllocatorRef alloc, CFStringRef str, C __CFAssertRangeIsInStringBounds(str, range.location, range.length); if ((range.location == 0) && (range.length == __CFStrLength(str))) { /* The substring is the whole string... */ - return (CFStringRef)CFStringCreateCopy(alloc, str); + return (CFStringRef)_CFNonObjCStringCreateCopy(alloc, str); } else if (__CFStrIsEightBit(str)) { const uint8_t *contents = (const uint8_t *)__CFStrContents(str); return __CFStringCreateImmutableFunnel3(alloc, contents + range.location + __CFStrSkipAnyLengthByte(str), range.length, __CFStringGetEightBitStringEncoding(), false, false, false, false, false, ALLOCATORSFREEFUNC, 0); @@ -1700,40 +1716,47 @@ CFStringRef CFStringCreateWithSubstring(CFAllocatorRef alloc, CFStringRef str, C } static CFStringRef _CFStringSlowPathCopyBundleUnloadingProtectedString(CFStringRef str) { - CFStringEncoding fastestEncoding = CFStringGetFastestEncoding(str); - const char *cStr = CFStringGetCStringPtr(str, fastestEncoding); - CFIndex len = CFStringGetLength(str); + CFIndex const len = CFStringGetLength(str); + if (len == 0) { + // Check this first to both avoid an allocation, and avoid potentially stack-allocating a zero-length buffer below. + return CFSTR(""); + } + + CFStringEncoding const fastestEncoding = CFStringGetFastestEncoding(str); + const char * const cStr = _CFStringGetCStringPtrInternal(str, fastestEncoding, false, true); if (cStr) { return CFStringCreateWithBytes(kCFAllocatorSystemDefault, (const uint8_t *)cStr, len, fastestEncoding, false); } - const UniChar *charsPtr = CFStringGetCharactersPtr(str); + + const UniChar * const charsPtr = CFStringGetCharactersPtr(str); if (charsPtr) { return CFStringCreateWithCharacters(kCFAllocatorSystemDefault, charsPtr, len); } - CFIndex maxByteCount = CFStringGetMaximumSizeForEncoding(len, fastestEncoding); - STACK_BUFFER_DECL(uint8_t, buffer, maxByteCount); + + CFIndex const maxByteCount = CFStringGetMaximumSizeForEncoding(len, fastestEncoding); CFIndex byteCount = 0; + CFStringRef result = NULL; + SAFE_STACK_BUFFER_DECL(uint8_t, buffer, maxByteCount, 256 /* malloc for buffers longer than 256 bytes */); // `str` here is currently only ever a bundle ID. Bundle IDs are rarely this long. if (CFStringGetBytes(str, CFRangeMake(0, len), fastestEncoding, 0, false, buffer, maxByteCount, &byteCount)) { - return CFStringCreateWithBytes(kCFAllocatorSystemDefault, buffer, byteCount, fastestEncoding, false); + result = CFStringCreateWithBytes(kCFAllocatorSystemDefault, buffer, byteCount, fastestEncoding, false); + } else { + result = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, str); } - return CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, str); + + SAFE_STACK_BUFFER_CLEANUP(buffer); + return result; } CF_PRIVATE CFStringRef _CFStringCopyBundleUnloadingProtectedString(CFStringRef str) { return _CFStringSlowPathCopyBundleUnloadingProtectedString(str); } - -CFStringRef CFStringCreateCopy(CFAllocatorRef alloc, CFStringRef str) { - CF_SWIFT_FUNCDISPATCHV(_kCFRuntimeIDCFString, CFStringRef, (CFSwiftRef)str, NSString.copy); -// CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFString, CFStringRef, (NSString *)str, copy); - +CF_PRIVATE CFStringRef _CFNonObjCStringCreateCopy(CFAllocatorRef alloc, CFStringRef str) { __CFAssertIsString(str); - if (!__CFStrIsMutable((CFStringRef)str) && // If the string is not mutable - ((alloc ? alloc : __CFGetDefaultAllocator()) == __CFGetAllocator(str)) && // and it has the same allocator as the one we're using - (__CFStrIsInline((CFStringRef)str) || __CFStrFreeContentsWhenDone((CFStringRef)str) || __CFStrIsConstant((CFStringRef)str))) { // and the characters are inline, or are owned by the string, or the string is constant - CFRetain(str); // Then just retain instead of making a true copy - return str; + if (!__CFStrIsMutable((CFStringRef)str) && // If the string is not mutable + ((alloc ? alloc : __CFGetDefaultAllocator()) == __CFGetAllocator(str)) && // and it has the same allocator as the one we're using + (__CFStrIsInline((CFStringRef)str) || __CFStrFreeContentsWhenDone((CFStringRef)str) || __CFStrIsConstant((CFStringRef)str))) { // and the characters are inline, or are owned by the string, or the string is constant + return _CFNonObjCRetain(str); // Then just retain instead of making a true copy } if (__CFStrIsEightBit((CFStringRef)str)) { const uint8_t *contents = (const uint8_t *)__CFStrContents((CFStringRef)str); @@ -1744,6 +1767,13 @@ CFStringRef CFStringCreateCopy(CFAllocatorRef alloc, CFStringRef str) { } } +CFStringRef CFStringCreateCopy(CFAllocatorRef alloc, CFStringRef str) { + CF_SWIFT_FUNCDISPATCHV(_kCFRuntimeIDCFString, CFStringRef, (CFSwiftRef)str, NSString.copy); +// CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFString, CFStringRef, (NSString *)str, copy); + + return _CFNonObjCStringCreateCopy(alloc, str); +} + /*** Constant string stuff... ***/ @@ -1943,7 +1973,9 @@ CF_INLINE void __CFStringReplace(CFMutableStringRef str, CFRange range, CFString if (__CFStrIsUnicode(str)) { UniChar *contents = (UniChar *)__CFStrContents(str); - CFStringGetCharacters(replacement, CFRangeMake(0, replacementLength), contents + range.location); + if (contents) { + CFStringGetCharacters(replacement, CFRangeMake(0, replacementLength), contents + range.location); + } } else { uint8_t *contents = (uint8_t *)__CFStrContents(str); CFStringGetBytes(replacement, CFRangeMake(0, replacementLength), __CFStringGetEightBitStringEncoding(), 0, false, contents + range.location + __CFStrSkipAnyLengthByte(str), replacementLength, NULL); @@ -1992,6 +2024,10 @@ CFMutableStringRef CFStringCreateMutableWithExternalCharactersNoCopy(CFAllocator if (__CFStrHasContentsAllocator(string)) { CFAllocatorRef allocator = __CFStrContentsAllocator((CFMutableStringRef)string); CFRelease(allocator); + + // If externalCharactersAllocator == NULL, contentsAllocationBits is set to __kCFNotInlineContentsDefaultFree, which gives the string a default (non-custom) contents allocator. + // In that case, __CFStrHasContentsAllocator() returns FALSE, and we don't fall into here. + _CLANG_ANALYZER_ASSERT(externalCharactersAllocator != NULL); __CFStrSetContentsAllocator(string, externalCharactersAllocator); } CFStringSetExternalCharactersNoCopy(string, chars, numChars, capacity); @@ -2072,7 +2108,7 @@ UniChar CFStringGetCharacterAtIndex(CFStringRef str, CFIndex idx) { */ int _CFStringCheckAndGetCharacterAtIndex(CFStringRef str, CFIndex idx, UniChar *ch) { const uint8_t *contents = (const uint8_t *)__CFStrContents(str); - if (idx >= __CFStrLength2(str, contents) && __CFStringNoteErrors()) return _CFStringErrBounds; + if (idx < 0 || idx >= __CFStrLength2(str, contents)) { return _CFStringErrBounds; } *ch = __CFStringGetCharacterAtIndexGuts(str, idx, contents); return _CFStringErrNone; } @@ -2104,15 +2140,15 @@ void CFStringGetCharacters(CFStringRef str, CFRange range, UniChar *buffer) { */ int _CFStringCheckAndGetCharacters(CFStringRef str, CFRange range, UniChar *buffer) { const uint8_t *contents = (const uint8_t *)__CFStrContents(str); - if (range.location + range.length > __CFStrLength2(str, contents) && __CFStringNoteErrors()) return _CFStringErrBounds; + if (range.location + range.length > __CFStrLength2(str, contents)) return _CFStringErrBounds; __CFStringGetCharactersGuts(str, range, buffer, contents); return _CFStringErrNone; } -CFIndex CFStringGetBytes(CFStringRef str, CFRange range, CFStringEncoding encoding, uint8_t lossByte, Boolean isExternalRepresentation, uint8_t *buffer, CFIndex maxBufLen, CFIndex *usedBufLen) { +CFIndex CFStringGetBytes(CFStringRef str, CFRange range, CFStringEncoding encoding, uint8_t lossByte, Boolean isExternalRepresentation, uint8_t * _Nullable buffer, CFIndex maxBufLen, CFIndex *usedBufLen) { #if DEPLOYMENT_RUNTIME_SWIFT - if (CF_IS_SWIFT(CFStringGetTypeID(), str) && __CFSwiftBridge.NSString.__getBytes != NULL) { + if (CF_IS_SWIFT(_kCFRuntimeIDCFString, str) && __CFSwiftBridge.NSString.__getBytes != NULL) { return __CFSwiftBridge.NSString.__getBytes(str, encoding, range, buffer, maxBufLen, usedBufLen); } #endif @@ -2154,27 +2190,35 @@ ConstStringPtr CFStringGetPascalStringPtr (CFStringRef str, CFStringEncoding enc return NULL; } - -const char * CFStringGetCStringPtr(CFStringRef str, CFStringEncoding encoding) { - +static inline const char * _CFStringGetCStringPtrInternal(CFStringRef str, CFStringEncoding encoding, Boolean requiresNullTermination, Boolean requiresBridgingCheck) { if (encoding != __CFStringGetEightBitStringEncoding() && (kCFStringEncodingASCII != __CFStringGetEightBitStringEncoding() || !__CFStringEncodingIsSupersetOfASCII(encoding))) return NULL; // ??? Also check for encoding = SystemEncoding and perhaps bytes are all ASCII? - + if (str == NULL) return NULL; // Should really just crash, but for compatibility... see - CF_SWIFT_FUNCDISPATCHV(_kCFRuntimeIDCFString, const char *, (CFSwiftRef)str, NSString._fastCStringContents, true); - CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFString, const char *, (NSString *)str, _fastCStringContents:true); - + if (requiresBridgingCheck) { + CF_SWIFT_FUNCDISPATCHV(_kCFRuntimeIDCFString, const char *, (CFSwiftRef)str, NSString._fastCStringContents, requiresNullTermination); + CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFString, const char *, (NSString *)str, _fastCStringContents:requiresNullTermination); + } + __CFAssertIsString(str); - - if (__CFStrHasNullByte(str)) { + + if ((!requiresNullTermination && __CFStrIsEightBit(str)) || __CFStrHasNullByte(str)) { // Note: this is called a lot, 27000 times to open a small xcode project with one file open. // Of these uses about 1500 are for cStrings/utf8strings. - return (const char *)__CFStrContents(str) + __CFStrSkipAnyLengthByte(str); + return (const char *)__CFStrContents(str) + __CFStrSkipAnyLengthByte(str); } else { - return NULL; + return NULL; } } + +const char * _CFNonObjCStringGetCStringPtr(CFStringRef str, CFStringEncoding encoding, Boolean requiresNullTermination) { + return _CFStringGetCStringPtrInternal(str, encoding, requiresNullTermination, false); +} + +const char * CFStringGetCStringPtr(CFStringRef str, CFStringEncoding encoding) { + return _CFStringGetCStringPtrInternal(str, encoding, true, true); +} const UniChar *CFStringGetCharactersPtr(CFStringRef str) { @@ -2619,8 +2663,8 @@ CFComparisonResult CFStringCompareWithOptionsAndLocale(CFStringRef string, CFStr if ((NULL == locale) && (NULL == ignoredChars) && !numerically) { // could do binary comp (be careful when adding new flags) CFStringEncoding eightBitEncoding = __CFStringGetEightBitStringEncoding(); - const uint8_t *str1Bytes = (const uint8_t *)CFStringGetCStringPtr(string, eightBitEncoding); - const uint8_t *str2Bytes = (const uint8_t *)CFStringGetCStringPtr(string2, eightBitEncoding); + const uint8_t *str1Bytes = (const uint8_t *)_CFStringGetCStringPtrInternal(string, eightBitEncoding, false, true); + const uint8_t *str2Bytes = (const uint8_t *)_CFStringGetCStringPtrInternal(string2, eightBitEncoding, false, true); CFIndex factor = sizeof(uint8_t); if ((NULL != str1Bytes) && (NULL != str2Bytes)) { @@ -2698,8 +2742,8 @@ CFComparisonResult CFStringCompareWithOptionsAndLocale(CFStringRef string, CFStr const uint8_t *graphemeBMP = CFUniCharGetBitmapPtrForPlane(kCFUniCharGraphemeExtendCharacterSet, 0); - CFStringInitInlineBuffer(string, &inlineBuf1, rangeToCompare); - CFStringInitInlineBuffer(string2, &inlineBuf2, CFRangeMake(0, str2Len)); + _CFStringInitInlineBufferInternal(string, &inlineBuf1, rangeToCompare, true); + _CFStringInitInlineBufferInternal(string2, &inlineBuf2, CFRangeMake(0, str2Len), true); if (NULL != locale) { str1LocalizedIndex = str1Index; @@ -2956,8 +3000,8 @@ Boolean CFStringFindWithOptionsAndLocale(CFStringRef string, CFStringRef stringT CFStringInlineBuffer inlineBuf1, inlineBuf2; UTF32Char str1Char = 0, str2Char = 0; CFStringEncoding eightBitEncoding = __CFStringGetEightBitStringEncoding(); - const uint8_t *str1Bytes = (const uint8_t *)CFStringGetCStringPtr(string, eightBitEncoding); - const uint8_t *str2Bytes = (const uint8_t *)CFStringGetCStringPtr(stringToFind, eightBitEncoding); + const uint8_t *str1Bytes = (const uint8_t *)_CFStringGetCStringPtrInternal(string, eightBitEncoding, false, true); + const uint8_t *str2Bytes = (const uint8_t *)_CFStringGetCStringPtrInternal(stringToFind, eightBitEncoding, false, true); const UTF32Char *characters, *charactersLimit; const uint8_t *langCode = NULL; CFIndex fromLoc, toLoc; @@ -2980,8 +3024,8 @@ Boolean CFStringFindWithOptionsAndLocale(CFStringRef string, CFStringRef stringT langCode = (const uint8_t *)_CFStrGetLanguageIdentifierForLocale(locale, true); } - CFStringInitInlineBuffer(string, &inlineBuf1, CFRangeMake(0, rangeToSearch.location + rangeToSearch.length)); - CFStringInitInlineBuffer(stringToFind, &inlineBuf2, CFRangeMake(0, findStrLen)); + _CFStringInitInlineBufferInternal(string, &inlineBuf1, CFRangeMake(0, rangeToSearch.location + rangeToSearch.length), true); + _CFStringInitInlineBufferInternal(stringToFind, &inlineBuf2, CFRangeMake(0, findStrLen), true); if (compareOptions & kCFCompareBackwards) { fromLoc = rangeToSearch.location + rangeToSearch.length - (lengthVariants ? 1 : findStrLen); @@ -3272,10 +3316,10 @@ Boolean CFStringFindWithOptionsAndLocale(CFStringRef string, CFStringRef stringT if (diacriticsInsensitive) { if (str1Char < 0x10000) { CFIndex index = str1Index; - do { str1Char = CFStringGetCharacterFromInlineBuffer(&inlineBuf1, --index); - } while (CFUniCharIsMemberOfBitmap(str1Char, graphemeBMP), (rangeToSearch.location < index)); + // Possible lost optimization in CFString + } while (/* CFUniCharIsMemberOfBitmap(str1Char, graphemeBMP), */(rangeToSearch.location < index)); if (str1Char < 0x0510) { while (++str1Index < maxStr1Index) if (!CFUniCharIsMemberOfBitmap(CFStringGetCharacterFromInlineBuffer(&inlineBuf1, str1Index), graphemeBMP)) break; @@ -3463,359 +3507,517 @@ enum { kCFStringHangulStateLVT, kCFStringHangulStateBreak }; - -#pragma mark FitzPatrick (skin tone) Modifier Functions - -static const CFCharacterSetInlineBuffer *__CFStringGetFitzpatrickModifierBaseCharacterSet(void) { - static CFCharacterSetInlineBuffer buffer; - static dispatch_once_t initOnce; - dispatch_once(&initOnce, ^{ // based on UTR#51 1.0 (draft 7) for Unicode 8.0 - /* - 8.0 - U+261D WHITE UP POINTING INDEX - U+2639 WHITE FROWNING FACE…U+263A WHITE SMILING FACE - U+270A RAISED FIST…U+270D WRITING HAND - U+1F385 FATHER CHRISTMAS - U+1F3C2 SNOWBOARDER…U+1F3C4 SURFER - U+1F3C7 HORSE RACING - U+1F3CA SWIMMER - U+1F3CC GOLFER - U+1F442 EAR…U+1F443 NOSE - U+1F446 WHITE UP POINTING BACKHAND INDEX…U+1F450 OPEN HANDS SIGN - U+1F466 BOY…U+1F469 WOMAN - U+1F46A FAMILY…U+1F46F WOMAN WITH BUNNY EARS - U+1F470 BRIDE WITH VEIL…U+1F478 PRINCESS - U+1F47C BABY ANGEL - U+1F47F IMP - U+1F481 INFORMATION DESK PERSON…U+1F482 GUARDSMAN - U+1F483 DANCER - U+1F485 NAIL POLISH - U+1F486 FACE MASSAGE…U+1F487 HAIRCUT - U+1F4AA FLEXED BICEPS - U+1F574 MAN IN BUSINESS SUIT LEVITATING - U+1F575 SLEUTH OR SPY - U+1F590 RAISED HAND WITH FINGERS SPLAYED - U+1F595 REVERSED HAND WITH MIDDLE FINGER EXTENDED…U+1F596 RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS - U+1F600 GRINNING FACE…U+1F637 FACE WITH MEDICAL MASK - U+1F641 SLIGHTLY FROWNING FACE…U+1F647 PERSON BOWING DEEPLY - U+1F64B HAPPY PERSON RAISING ONE HAND - U+1F64C PERSON RAISING BOTH HANDS IN CELEBRATION - U+1F64D PERSON FROWNING…U+1F64E PERSON WITH POUTING FACE - U+1F64F PERSON WITH FOLDED HANDS - U+1F6A3 ROWBOAT - U+1F6B4 BICYCLIST…U+1F6B6 PEDESTRIAN - U+1F6C0 BATH - U+1F6CC SLEEPING ACCOMMODATION - U+1F910 ZIPPER-MOUTH FACE…U+1F915 FACE WITH HEAD-BANDAGE - U+1F917 HUGGING FACE…U+1F918 SIGN OF THE HORNS - - 9.0 - U+26F9 PERSON WITH BALL - U+1F3CB WEIGHT LIFTER - U+1F57A MAN DANCING - U+1F919 CALL ME HAND - U+1F91A RAISED BACK OF HAND - U+1F91B LEFT-FACING FIST - U+1F91C RIGHT-FACING FIST - U+1F91D HANDSHAKE - U+1F91E HAND WITH INDEX AND MIDDLE FINGERS CROSSED - U+1F926 FACE PALM - U+1F930 PREGNANT WOMAN - U+1F933 SELFIE - U+1F934 PRINCE - U+1F935 MAN IN TUXEDO - U+1F936 MOTHER CHRISTMAS - U+1F937 SHRUG - U+1F938 PERSON DOING CARTWHEEL - U+1F939 JUGGLING - U+1F93C WRESTLERS - U+1F93D WATER POLO - U+1F93E HANDBALL - - 10.0 - U+1F91F LOVE-YOU GESTURE - U+1F931 BREAST-FEEDING - U+1F932 PALMS UP TOGETHER - U+1F9D1 ADULT - U+1F9D2 CHILD - U+1F9D3 OLDER ADULT - U+1F9D4 BEARDED PERSON - U+1F9D5 PERSON WITH HEADSCARF [WOMAN WITH HEADSCARF] - U+1F9D6 PERSON IN STEAMY ROOM - U+1F9D7 PERSON CLIMBING - U+1F9D8 PERSON IN LOTUS POSITION - U+1F9D9 MAGE - U+1F9DA FAIRY - U+1F9DB VAMPIRE - U+1F9DC MERPERSON - U+1F9DD ELF - */ - CFMutableCharacterSetRef cset = CFCharacterSetCreateMutable(NULL); - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x261D, 1)); // WHITE UP POINTING INDEX - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x2639, 2)); // WHITE FROWNING FACE ~ WHITE SMILING FACE - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x270A, 4)); // RAISED FIST ~ WRITING HAND - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F385, 1)); // FATHER CHRISTMAS - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3C2, 3)); // SNOWBOARDER ~ SURFER - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3C7, 1)); // HORSE RACING - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3CA, 1)); // SWIMMER - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3CC, 1)); // GOLFER - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F442, 2)); // EAR ~ NOSE - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F446, 0x1F451 - 0x1F446)); // WHITE UP POINTING BACKHAND INDEX ~ OPEN HANDS SIGN - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F466, 4)); // BOY ~ WOMAN - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F46A, 6)); // FAMILY…U+1F46F WOMAN WITH BUNNY EARS - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F470, 0x1F479 - 0x1F470)); // BRIDE WITH VEIL ~ PRINCESS - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F47C, 1)); // BABY ANGEL - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F47F, 1)); // IMP - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F481, 3)); // INFORMATION DESK PERSON ~ DANCER - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F485, 3)); // NAIL POLISH ~ HAIRCUT - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F4AA, 1)); // FLEXED BICEPS - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F574, 1)); // MAN IN BUSINESS SUIT LEVITATING - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F575, 1)); // SLEUTH OR SPY - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F57A, 1)); // MAN DANCING - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F590, 1)); // RAISED HAND WITH FINGERS SPLAYED - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F595, 2)); // REVERSED HAND WITH MIDDLE FINGER EXTENDED ~ RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F600, 0x1F638 - 0x1F600)); // GRINNING FACE ~ FACE WITH MEDICAL MASK - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F641, 0x1F648 - 0x1F641)); // SLIGHTLY FROWNING FACE ~ PERSON BOWING DEEPLY - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F64B, 0x1F650 - 0x1F64B)); // HAPPY PERSON RAISING ONE HAND ~ PERSON WITH FOLDED HANDS - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F6A3, 1)); // ROWBOAT - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F6B4, 0x1F6B7 - 0x1F6B4)); // BICYCLIST ~ PEDESTRIAN - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F6C0, 1)); // BATH - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F6CC, 1)); // SLEEPING ACCOMMODATION - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F910, 0x1F916 - 0x1F910)); // U+1F910 ZIPPER-MOUTH FACE…U+1F915 FACE WITH HEAD-BANDAGE - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F917, 8)); // U+1F917 HUGGING FACE…U+1F91E HAND WITH INDEX AND MIDDLE FINGERS CROSSED - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F91F, 1)); // LOVE-YOU GESTURE - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F926, 1)); // FACE PALM - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F930, 3)); // PREGNANT WOMAN ~ PALMS UP TOGETHER - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F933, 4)); // SELFIE ~ MOTHER CHRISTMAS - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F937, 3)); // SHRUG ~ JUGGLING - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F93C, 3)); // WRESTLERS ~ HANDBALL - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F9D1, 13)); // ADULT ~ ELF - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x26F9, 1)); // U+26F9 PERSON WITH BALL - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3CB, 1)); // U+1F3CB WEIGHT LIFTER - CFCharacterSetCompact(cset); - CFCharacterSetInitInlineBuffer(cset, &buffer); - }); - - return (const CFCharacterSetInlineBuffer *)&buffer; -} - -static inline bool __CFStringIsFitzpatrickModifiers(UTF32Char character) { return ((character >= 0x1F3FB) && (character <= 0x1F3FF) ? true : false); } -static inline bool __CFStringIsBaseForFitzpatrickModifiers(UTF32Char character) { - if (((character >= 0x2600) && (character < 0x3000)) || ((character >= 0x1F300) && (character < 0x1FA00))) { // Misc symbols, dingbats, & emoticons - return (CFCharacterSetInlineBufferIsLongCharacterMember(__CFStringGetFitzpatrickModifierBaseCharacterSet(), character) ? true : false); + +#pragma mark Pictographic Sequences +/* The following few functions serve to identify ranges of pictographic sequences (AKA emoji sequences with forwards and backwards extension) in a string around a given index. */ + +// Reads a character from the given inline buffer at the given index. +// If the character is a non-BMP character, this reads the matching surrogate pair character as well, and returns the effective read range through an out parameter. +static inline UTF32Char __CFStringGetLongCharacterFromInlineBuffer(CFStringInlineBuffer *buffer, CFIndex length, CFIndex idx, CFRange *readRange) { + if (idx < 0 || idx >= length) { + // Matches CFStringGetCharacterFromInlineBuffer. + if (readRange) *readRange = CFRangeMake(kCFNotFound, 0); + return 0; } - - return false; + + CFRange range = CFRangeMake(idx, 1); + UTF32Char character = CFStringGetCharacterFromInlineBuffer(buffer, idx); + if (CFUniCharIsSurrogateHighCharacter(character) && idx < length - 1) { + // We need to read ahead if possible to get the low surrogate and combine. + UTF16Char surrogateLow = CFStringGetCharacterFromInlineBuffer(buffer, idx + 1); + if (CFUniCharIsSurrogateLowCharacter(surrogateLow)) { + range.length++; + character = CFUniCharGetLongCharacterForSurrogatePair(character, surrogateLow); + } + } else if (CFUniCharIsSurrogateLowCharacter(character) && idx > 0) { + // We need to read behind if possible to get the low surrogate and combine. + UTF16Char surrogateHigh = CFStringGetCharacterFromInlineBuffer(buffer, idx - 1); + if (CFUniCharIsSurrogateHighCharacter(surrogateHigh)) { + range.location--; + range.length++; + character = CFUniCharGetLongCharacterForSurrogatePair(surrogateHigh, character); + } + } + + if (readRange) *readRange = range; + return character; } -static inline bool __CFStringIsTagSequence(UTF32Char character) { return ((character >= 0xE0020) && (character <= 0xE007F) ? true : false); } -#pragma mark Gender Modifier Functions - -static const CFCharacterSetInlineBuffer *__CFStringGetGenderModifierBaseCharacterSet(void) { - static CFCharacterSetInlineBuffer buffer; - static dispatch_once_t initOnce; - dispatch_once(&initOnce, ^{ - /* - Unicode 8.0 - ⛹U+26F9 PERSON WITH BALL // 0x26F9 - 🏃U+1F3C3 RUNNER // 0xD83C 0xDFC3 - 🏄U+1F3C4 SURFER // 0xD83C 0xDFC4 - 🏊U+1F3CA SWIMMER // 0xD83C 0xDFCA - 🏋U+1F3CB WEIGHT LIFTER // 0xD83C 0xDFCB - 🏌U+1F3CC GOLFER // 0xD83C 0xDFCC - 👮U+1F46E POLICE OFFICER // 0xD83D 0xDC6E - 👯U+1F46F TWO WOMEN DANCING // 0xD83D 0xDC6F - 👱U+1F471 PERSON WITH BLOND HAIR // 0xD83D 0xDC71 - 👳U+1F473 MAN WITH TURBAN // 0xD83D 0xDC73 - 👷U+1F477 CONSTRUCTION WORKER // 0xD83D 0xDC77 - 💁U+1F481 INFORMATION DESK PERSON // 0xD83D 0xDC81 - 💂U+1F482 GUARDSMAN // 0xD83D 0xDC82 - 💆U+1F486 FACE MASSAGE // 0xD83D 0xDC86 - 💇U+1F487 HAIRCUT // 0xD83D 0xDC87 - 🕵U+1F575 SLEUTH OR SPY // 0xD83D 0xDD75 - 🙅U+1F645 FACE WITH NO GOOD GESTURE // 0xD83D 0xDE45 - 🙆U+1F646 FACE WITH OK GESTURE // 0xD83D 0xDE46 - 🙇U+1F647 PERSON BOWING DEEPLY // 0xD83D 0xDE47 - 🙋U+1F64B HAPPY PERSON RAISING ONE HAND // 0xD83D 0xDE4B - 🙍U+1F64D PERSON FROWNING // 0xD83D 0xDE4D - 🙎U+1F64E PERSON WITH POUTING FACE // 0xD83D 0xDE4E - 🚣U+1F6A3 ROWBOAT // 0xD83D 0xDEA3 - 🚴U+1F6B4 BICYCLIST // 0xD83D 0xDEB4 - 🚵U+1F6B5 MOUNTAIN BICYCLIST // 0xD83D 0xDEB5 - 🚶U+1F6B6 PEDESTRIAN // 0xD83D 0xDEB6 - - Unicode 9.0 - U+1F926 FACE PALM - U+1F937 SHRUG - U+1F938 PERSON DOING CARTWHEEL - U+1F939 JUGGLING - U+1F93C WRESTLERS - U+1F93D WATER POLO - U+1F93E HANDBALL - - Unicode 10.0 - U+1F9D6 PERSON IN STEAMY ROOM - U+1F9D7 PERSON CLIMBING - U+1F9D8 PERSON IN LOTUS POSITION - U+1F9D9 MAGE - U+1F9DA FAIRY - U+1F9DB VAMPIRE - U+1F9DC MERPERSON - U+1F9DD ELF - U+1F9DE GENIE - U+1F9DF ZOMBIE - */ - CFMutableCharacterSetRef cset = CFCharacterSetCreateMutable(NULL); - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x26F9, 1)); // PERSON WITH BALL - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3C3, 1)); // RUNNER - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3C4, 1)); // SURFER - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3CA, 1)); // SWIMMER - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3CB, 1)); // WEIGHT LIFTER - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3CC, 1)); // GOLFER - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F46E, 1)); // POLICE OFFICER - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F46F, 1)); // TWO WOMEN DANCING - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F471, 1)); // PERSON WITH BLOND HAIR - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F473, 1)); // MAN WITH TURBAN - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F477, 1)); // CONSTRUCTION WORKER - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F481, 1)); // INFORMATION DESK PERSON - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F482, 1)); // GUARDSMAN - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F486, 1)); // FACE MASSAGE - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F487, 1)); // HAIRCUT - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F575, 1)); // SLEUTH OR SPY - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F645, 1)); // FACE WITH NO GOOD GESTURE - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F646, 1)); // FACE WITH OK GESTURE - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F647, 1)); // PERSON BOWING DEEPLY - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F64B, 1)); // HAPPY PERSON RAISING ONE HAND - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F64D, 1)); // PERSON FROWNING - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F64E, 1)); // PERSON WITH POUTING FACE - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F6A3, 1)); // ROWBOAT - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F6B4, 1)); // BICYCLIST - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F6B5, 1)); // MOUNTAIN BICYCLIST - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F6B6, 1)); // PEDESTRIAN - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F926, 1)); // FACE PALM - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F937, 3)); // SHRUG ~ JUGGLING - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F93C, 3)); // WRESTLERS ~ HANDBALL - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F9D6, 10)); // PERSON IN STEAMY ROOM ~ ZOMBIE - CFCharacterSetCompact(cset); - CFCharacterSetInitInlineBuffer(cset, &buffer); - }); - return (const CFCharacterSetInlineBuffer *)&buffer; +static inline bool __CFStringIsValidExtendCharacterForPictographicSequence(UTF32Char character) { + // From https://www.unicode.org/reports/tr29/#Extend: + // + // Grapheme_Extend = Yes, or + // Emoji_Modifier=Yes in emoji-data.txt + // + return u_hasBinaryProperty(character, UCHAR_GRAPHEME_EXTEND) || u_hasBinaryProperty(character, UCHAR_EMOJI_MODIFIER); } -static inline bool __CFStringIsGenderModifier(UTF32Char character) { return ((character == 0x2640) || (character == 0x2642)); } +static inline bool __CFStringIsValidExtendedPictographicCharacterForPictographicSequence(UTF32Char character) { + return u_hasBinaryProperty(character, UCHAR_EXTENDED_PICTOGRAPHIC); +} -static inline bool __CFStringIsBaseForGenderModifier(UTF32Char character) { - if (((character >= 0x2600) && (character < 0x3000)) || ((character >= 0x1F300) && (character < 0x1FA00))) { // Misc symbols, dingbats, & emoticons - return CFCharacterSetInlineBufferIsLongCharacterMember(__CFStringGetGenderModifierBaseCharacterSet(), character); - } - return false; +static inline bool __CFStringIsValidPrecoreCharacterForPictographicSequence(UTF32Char character) { + // From https://www.unicode.org/reports/tr29/#Regex_Definitions: + // + // precore := Prepend + // + // We can look up the grapheme cluster break class and use it directly. + bool isValid = (UGraphemeClusterBreak)u_getIntPropertyValue(character, UCHAR_GRAPHEME_CLUSTER_BREAK) == U_GCB_PREPEND; + return isValid; } -static inline bool __CFStringIsGenderModifierBaseCluster(CFStringInlineBuffer *buffer, CFRange range) { - UTF16Char character = CFStringGetCharacterFromInlineBuffer(buffer, range.location); - UTF32Char baseCharacter = character; - if (range.length > 1) { - if (CFUniCharIsSurrogateHighCharacter(character)) { - UTF16Char otherCharacter = CFStringGetCharacterFromInlineBuffer(buffer, range.location + 1); - if (CFUniCharIsSurrogateLowCharacter(otherCharacter)) { - baseCharacter = CFUniCharGetLongCharacterForSurrogatePair(character, otherCharacter); +static inline bool __CFStringIsValidPostcoreCharacterForPictographicSequence(UTF32Char character) { + // From https://www.unicode.org/reports/tr29/#Regex_Definitions: + // + // postcore := [Extend ZWJ SpacingMark] + // + // We already have an expression to match Extend characters (and ZWJ is trivial); we can look up the grapheme cluster break class and use it directly to determine spacing mark characters. + bool isValid = character == ZERO_WIDTH_JOINER || __CFStringIsValidExtendCharacterForPictographicSequence(character) || (UGraphemeClusterBreak)u_getIntPropertyValue(character, UCHAR_GRAPHEME_CLUSTER_BREAK) == U_GCB_SPACING_MARK; + return isValid; +} + +// Represents the match information for a single component in a pictographic sequence below. +// See __CFStringGetExtendedPictographicSequenceComponent and __CFStringGetExtendedPictographicSequence for usage information. +typedef struct { + CFRange range; + CFIndex firstExtendIndex; + CFIndex zwjIndex; + CFIndex pictographIndex; +} __CFStringPictographicSequenceComponent; + +// Given an index, attempts to return the range of the containing element of Grapheme Cluster Boundary Rule GB11: +// +// \p{Extended_Pictographic} (Extend* ZWJ \p{Extended_Pictographic})* +// +// Specifically, this will attempt to match either the lone starting \p{Extended_Pictographic} if the index corresponds to it, or a singular instance of (Extend* ZWJ \p{Extended_Pictographic}) which contains the `index`. +// For instance, the string @"stuff...👩‍❤️‍💋‍👨stuff..." is segmented this way as: +// +// 👩 ❤ Var_Sel 💋 👨 +// ┌──────────┐│┌───────┐┌─────┐┌──────┐┌──────┐┌─────┐┌───────┐┌─────┐┌───────┐│┌──────────┐ +// │ stuff... │ │ 1F469 ││ ZWJ ││ 2764 ││ FE0F ││ ZWJ ││ 1F48B ││ ZWJ ││ 1F468 │ │ stuff... │ +// └──────────┘│└───────┘└─────┘└──────┘└──────┘└─────┘└───────┘└─────┘└───────┘│└──────────┘ +// ──r0─── ─────r1────── ─────────r2─────────── ──────r3────── +// +// Each of ranges r0-r3 is one "component" of this sequence that we're looking to match. Given any index which falls in one of these ranges, we should return the same match information. +// Here, r0 is matched as a \p{Extended_Pictographic}, while each of r1-r3 are matched as (Extend* ZWJ \p{Extended_Pictographic}). +// +// If a match is found for the given index, the match information is returned through the `outComponent` parameter. +static inline bool __CFStringGetExtendedPictographicSequenceComponent(CFStringInlineBuffer *buffer, CFIndex length, CFIndex index, __CFStringPictographicSequenceComponent *outComponent) { + if (index < 0 || index >= length) { + // This is relied upon in __CFStringGetExtendedPictographicSequence to prevent reading invalid components without additional checking. + return false; + } + + __CFStringPictographicSequenceComponent match = {{kCFNotFound, 0}, -1, -1, -1}; + + // The given index can point to any part of any component in a sequence as above. + // Start by rewinding backwards as far as we can to see if we we're in the type of component which has a ZWJ or not. + CFRange currentRange = CFRangeMake(index, 0); + while (currentRange.location >= 0) { + // This adjusts currentRange to match the actual range of a long character, if necessary. + UTF32Char character = __CFStringGetLongCharacterFromInlineBuffer(buffer, length, currentRange.location, ¤tRange); + + if (__CFStringIsValidExtendCharacterForPictographicSequence(character)) { + // This is an extend character; we're at the beginning of the cluster. + match.firstExtendIndex = currentRange.location; + } else if (character == ZERO_WIDTH_JOINER) { + if (match.firstExtendIndex != -1 || match.zwjIndex != -1) { + // A ZWJ isn't valid here — we've already previously seen a ZWJ or Extend characters (i.e. this ZWJ is not part of this component). + // For example, we've extended backwards and hit another ZWJ: + // + // ┌───────────────────────┐ ┌─────┐ ┌────────┐ ┌─────┐ ┌───────────────────────┐ + // │ Extended_Pictographic │ │ ZWJ │ │ Extend │ │ ZWJ │ │ Extended_Pictographic │ + // └───────────────────────┘ └─────┘ └────────┘ └─────┘ └───────────────────────┘ + // ▲ │ + // └───────────────────────────────────┘ + // + // Note that this sequence is not valid (and we will reject it one level up), but we'll stop here. + break; + } + + match.zwjIndex = currentRange.location; + } else if (__CFStringIsValidExtendedPictographicCharacterForPictographicSequence(character)) { + if (match.pictographIndex != -1 || match.zwjIndex != -1 || match.firstExtendIndex != -1) { + // We've already either seen a pictograph before, or we've seen other characters which come before a pictograph. + // For example, we've extended far enough backwards to find the previous pictograph: + // + // ┌───────────────────────┐ ┌────────┐ ┌─────┐ ┌───────────────────────┐ + // │ Extended_Pictographic │ │ Extend │ │ ZWJ │ │ Extended_Pictographic │ + // └───────────────────────┘ └────────┘ └─────┘ └───────────────────────┘ + // ▲ │ + // └────────────────────────────────────────────┘ + break; } + + match.pictographIndex = currentRange.location; + } else { + // This isn't a character which is valid to include in this pictograph sequence. + break; } + + match.range.location = currentRange.location; + match.range.length += currentRange.length; + currentRange.location--; } - return __CFStringIsBaseForGenderModifier(baseCharacter); -} - -static inline bool __CFStringIsGenderModifierCluster(CFStringInlineBuffer *buffer, CFRange range) { - if ((range.length < 1) || (range.length > 2)) return false; - UTF16Char character = CFStringGetCharacterFromInlineBuffer(buffer, range.location); - return (__CFStringIsGenderModifier(character) && ((range.length == 1) || (0xFE0F == CFStringGetCharacterFromInlineBuffer(buffer, range.location + 1)))); // Either modifier is alone or is followed by FEOF -} - -#pragma mark Profession Modifier Functions - -static inline bool __CFStringIsBaseForManOrWomanCluster(UTF16Char character) { - return ((character == 0xDC68) || (character == 0xDC69)); // Low surrogate chars representing MAN (U+1F468) and WOMAN (U+1F469) respectively -} + + // We've advanced as far back as we can go. At this point, we should either have matched + // + // ┌───────────────────────┐ + // │ Extended_Pictographic │ + // └───────────────────────┘ + // + // or at least some subset of + // + // ┌─────────┐ ┌──────┐ ┌────────────────────────┐ + // │ Extend* │ │ ZWJ* │ │ Extended_Pictographic* │ + // └─────────┘ └──────┘ └────────────────────────┘ + // + // If we didn't match _anything_ then we're not looking at a valid component. + if (match.pictographIndex == -1) { + // No pictograph yet... + if (match.zwjIndex == -1 && match.firstExtendIndex == -1) { + // ... nor anything else. Advancing forward won't be any use here; this isn't a pictographic sequence component. + return false; + } -static inline bool __CFStringIsProfessionBaseCluster(CFStringInlineBuffer *buffer, CFRange range) { - // The code here in this method follows the same structure as __CFStringIsGenderModifierBaseCluster() above in that it separates the high and low surrogate chars and passes the low surrogate char to __CFStringIsBaseForManOrWomanCluster(). - if (range.length > 1) { - UTF16Char character = CFStringGetCharacterFromInlineBuffer(buffer, range.location); - if (CFUniCharIsSurrogateHighCharacter(character)) { - UTF16Char otherCharacter = CFStringGetCharacterFromInlineBuffer(buffer, range.location + 1); - if (CFUniCharIsSurrogateLowCharacter(otherCharacter)) { - return __CFStringIsBaseForManOrWomanCluster(otherCharacter); + // We've matched the start of a component here; continue below. + } else { + // We've got a pictograph, so there's nothing left to find by searching forward. + // Possible options for what we've matched: + // + // 1. + // 2. + // 3. + // 4. + // + // Of these, options 1, 2, and 4 are valid, since we either need a ZWJ or don't. + if (match.firstExtendIndex != -1 && match.zwjIndex == -1) { + // This is option 3 above. It's likely that we're matching the FE0F (or similar) from a preceding cluster. + // For example, we may have extended backwards from the start of 👨‍👦 to the end of 👱‍♀️ in the string @"👱‍♀️👨‍👦" with no ZWJ in between: + // + // + // 👱 ZWJ ♀ Var_Sel 👨 ZWJ 👦 + // ┌───────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ ┌───────┐ ┌──────┐ ┌───────┐ + // │ 1F471 │ │ 200D │ │ 2640 │ │ FE0F │ │ 1F468 │ │ 200D │ │ 1F466 │ + // └───────┘ └──────┘ └──────┘ └──────┘ │ └───────┘ └──────┘ └───────┘ + // ▲ │ + // └──────────┘ + // + // FE0F is a variant selector (a valid extend character) and we matched it with no intervening ZWJ. + // In this case, simply ignore the extend characters we've found and return the base pictograph itself as the start of a new sequence looking forward. + match.range.location = match.pictographIndex; + match.range.length -= (match.pictographIndex - match.firstExtendIndex); + } + + if (outComponent) *outComponent = match; + return true; + } + + // We don't have a full component yet — we might have some Extend characters and/or a ZWJ, but no pictograph yet. + // Extend forward as far as we can. + currentRange.location = match.range.location + match.range.length; + currentRange.length = 0; + while (match.pictographIndex == -1 && currentRange.location < length) { + // This adjusts currentRange to match the actual range of a long character, if necessary. + UTF32Char character = __CFStringGetLongCharacterFromInlineBuffer(buffer, length, currentRange.location, ¤tRange); + + if (__CFStringIsValidExtendCharacterForPictographicSequence(character)) { + if (match.zwjIndex != -1) { + // We've already seen a ZWJ, so further * characters are not valid here. + // For example: + // + // ┌───────────────────────┐ ┌─────┐ ┌────────┐ ┌─────┐ ┌───────────────────────┐ + // │ Extended_Pictographic │ │ ZWJ │ │ Extend │ │ ZWJ │ │ Extended_Pictographic │ + // └───────────────────────┘ └─────┘ └────────┘ └─────┘ └───────────────────────┘ + // │ ▲ + // └────────┘ + // + // Note that this sequence is not valid (and we will reject all trailing characters as part of the sequence), but we'll stop here. + break; + } + + // When extending backwards, we updated component.firstExtendIndex; here we don't update it because we're extending forward. + } else if (character == ZERO_WIDTH_JOINER) { + if (match.zwjIndex != -1) { + // We've already seen a ZWJ, so another ZWJ is not valid here. + // For example: + // + // ┌───────────────────────┐ ┌─────┐ ┌─────┐ ┌───────────────────────┐ + // │ Extended_Pictographic │ │ ZWJ │ │ ZWJ │ │ Extended_Pictographic │ + // └───────────────────────┘ └─────┘ └─────┘ └───────────────────────┘ + // │ ▲ + // └───────┘ + // + // Note that this sequence is not valid (and we will reject all trailing characters as part of the sequence), but we'll stop here. + break; } + + match.zwjIndex = currentRange.location; + } else if (__CFStringIsValidExtendedPictographicCharacterForPictographicSequence(character)) { + // We're matching the pictograph we've been looking for, e.g. + // + // ┌───────────────────────┐ ┌─────┐ ┌───────────────────────┐ + // │ Extended_Pictographic │ │ ZWJ │ │ Extended_Pictographic │ + // └───────────────────────┘ └─────┘ └───────────────────────┘ + // │ ▲ + // └────────────────┘ + // + // The loop condition means we'll break out after matching this. + match.pictographIndex = currentRange.location; + } else { + // This isn't a character which is valid to include in this pictograph sequence. + break; } + + match.range.length += currentRange.length; + currentRange.location += currentRange.length; + currentRange.length = 0; } - return false; -} - -static const CFCharacterSetInlineBuffer *__CFStringGetProfessionModifierBaseCharacterSet(void) { - static CFCharacterSetInlineBuffer buffer; - static dispatch_once_t initOnce; - dispatch_once(&initOnce, ^{ - /* Unicode 9.0 - Supported profession modifiers */ - CFMutableCharacterSetRef cset = CFCharacterSetCreateMutable(NULL); - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x2695, 1)); // ⚕U+2695 STAFF OF AESCULAPIUS // Health Worker - 0x2695 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F33E, 1)); // 🌾U+1F33E EAR OF RICE // Farmer - 0xD83C 0xDF3E - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F373, 1)); // 🍳U+1F373 COOKING // Cook - 0xD83C 0xDF73 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F393, 1)); // 🎓U+1F393 GRADUATION CAP // Student - 0xD83C 0xDF93 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3A4, 1)); // 🎤U+1F3A4 MICROPHONE // Singer - 0xD83C 0xDFA4 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3EB, 1)); // 🏫U+1F3EB SCHOOL // Teacher - 0xD83C 0xDFEB - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3ED, 1)); // 🏭U+1F3ED FACTORY // Factory Worker - 0xD83C 0XDFED - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F4BB, 1)); // 💻U+1F4BB PERSONAL COMPUTER // Technologist - 0xD83D 0xDCBB - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F4BC, 1)); // 💼U+1F4BC BRIEFCASE // Office Worker - 0xD83D 0xDCBC - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F527, 1)); // 🔧U+1F527 WRENCH // Mechanic - 0xD83D 0xDD27 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F52C, 1)); // 🔬U+1F52C MICROSCOPE // Scientist - 0xD83D 0xDD2C - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3A8, 1)); // 🎨U+1F3A8 ARTIST PALETTE // Artist - 0xD83C 0xDFA8 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F692, 1)); // 🚒U+1F692 FIRE ENGINE // Firefighter - 0xD83D 0xDE92 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x2708, 1)); // ✈️U+2708 AIRPLANE // Pilot - 0x2708 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F680, 1)); // 🚀U+1F680 ROCKET // Astronaut - 0xD83D 0xDE80 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x2696, 1)); // ⚖️U+2696 SCALES // Judge - 0x2696 - CFCharacterSetCompact(cset); - CFCharacterSetInitInlineBuffer(cset, &buffer); - }); - return (const CFCharacterSetInlineBuffer *)&buffer; -} - -static inline bool __CFStringIsBaseForProfessionModifier(UTF32Char character) { - if (((character >= 0x2600) && (character < 0x3000)) || ((character >= 0x1F300) && (character < 0x1FA00))) { // Misc symbols, dingbats, & emoticons - return CFCharacterSetInlineBufferIsLongCharacterMember(__CFStringGetProfessionModifierBaseCharacterSet(), character); + + if (match.pictographIndex == -1) { + // Still no pictograph. We're done. + return false; + } else { + // At this point we should have everything. + if (outComponent) *outComponent = match; + return true; } - return false; } -static inline bool __CFStringIsProfessionModifierCluster(CFStringInlineBuffer *buffer, CFRange range) { - UTF16Char character = CFStringGetCharacterFromInlineBuffer(buffer, range.location); - UTF32Char baseCharacter = character; - if (range.length > 1) { - if (CFUniCharIsSurrogateHighCharacter(character)) { - UTF16Char otherCharacter = CFStringGetCharacterFromInlineBuffer(buffer, range.location + 1); - if (CFUniCharIsSurrogateLowCharacter(otherCharacter)) { - baseCharacter = CFUniCharGetLongCharacterForSurrogatePair(character, otherCharacter); +// Given an index into a buffer, attempts to match an extended pictographic sequence containing the character at that index. +// Specifically, we're looking to match an instance of the extended grapheme cluster grammar in Table 1b. of UAX#29 (http://unicode.org/reports/tr29/) as it concerns pictographic sequences: +// +// precore* core postcore* +// +// where in our case, we care about +// +// precore := Prepend +// core := \p{Extended_Pictographic} (Extend* ZWJ \p{Extended_Pictographic})* +// postcore := [Extend ZWJ SpacingMark] +// +// In the future, we can extend core to match the full definition of +// +// core := hangul-syllable | ri-sequence | xpicto-sequence | [^Control CR LF] +// +// to more generalize the implementation of CFStringGetRangeOfCharacterClusterAtIndex. +// +// To do this, we look to match instances of precore, core, and postcore characters around `index`. +// __CFStringGetExtendedPictographicSequenceComponent above will be used to match instances of `core`, and the general strategy involved tries to extend backwards to the start of the sequence, then forwards to figure out where/what we're matching. +// +// For instance, a string like @"stuff...👩🏿‍✈️stuff..." is segmented as +// +// 👩 🏿 ✈ Var_Sel +// ┌──────────┐│┌───────┐┌───────┐┌─────┐┌──────┐┌──────┐│┌──────────┐ +// │ stuff... │ │ 1F469 ││ 1F3FF ││ ZWJ ││ 2708 ││ FE0F │ │ stuff... │ +// └──────────┘│└───────┘└───────┘└─────┘└──────┘└──────┘│└──────────┘ +// ──r0─── ──────────r1────────── ──r2── +// +// Given any index which falls within ranges r0-r2, we're looking to return the full match from the beginning of r0 to the end of r2 in `outRange`. +// In this case, +// +// * r0 is the base \p{Extended_Pictographic} matched from `core`, +// * r1 is the extension (Extend* ZWJ \p{Extended_Pictographic}) matched from `core`, +// * and r2 is a `postcore` extend character +// +// `core` characters are matched using __CFStringGetExtendedPictographicSequenceComponent, and we extend with `precore` and `postcore` here. +static inline bool __CFStringGetExtendedPictographicSequence(CFStringInlineBuffer *buffer, CFIndex length, CFIndex index, CFRange *outRange) { + if (index < 0 || index >= length) { + return false; + } + + // We want to find the base character here of the whole cluster, so let's rewind backwards. + // We may be at the end of the cluster, so let's start rewinding backwards until we hit a boundary. + CFRange currentRange; + UTF32Char currentCharacter = __CFStringGetLongCharacterFromInlineBuffer(buffer, length, index, ¤tRange); + + // We'll start by matching postcore characters. One difficulty here is that allowable postcore characters are also present in the middle of core matches (like Extend and ZWJs). + // This means that if we match some characters here, they may actually fall in the middle of a core match: + // + // ┌───────────────────────┐ ┌─────┐ ┌───────────────────────┐ + // │ Extended_Pictographic │ │ ZWJ │ │ Extended_Pictographic │ + // └───────────────────────┘ └─────┘ └───────────────────────┘ + // ▲ + // └─── could be postcore or could be core (in this case, it's core, but we don't know it yet) + // + // We can reconcile this later; for now, we'll keep track of this range until we've concluded whether or not these are really postcore characters. + CFRange postcoreRange = CFRangeMake(currentRange.length, 0); + while (__CFStringIsValidPostcoreCharacterForPictographicSequence(currentCharacter)) { + postcoreRange.location = currentRange.location; + postcoreRange.length += currentRange.length; + + if (postcoreRange.location == 0) { + // We've managed to only match postcore characters and can't extend further; there's no pictographic sequence here, so no point in continuing to look. + return false; + } + + // This adjusts currentRange to match the actual range of a long character, if necessary. + currentCharacter = __CFStringGetLongCharacterFromInlineBuffer(buffer, length, postcoreRange.location - 1, ¤tRange); + } + + // We may or may not have matched any postcore characters, but either way, now try to match a pictographic sequence if we can, extending backwards. + __CFStringPictographicSequenceComponent currentComponent = {{kCFNotFound, 0}, -1, -1, -1}; + CFRange coreRange = CFRangeMake(currentRange.location, 0); + while (__CFStringGetExtendedPictographicSequenceComponent(buffer, length, currentRange.location, ¤tComponent)) { + coreRange.location = currentComponent.range.location; + coreRange.length += currentComponent.range.length; + + currentRange.location = currentComponent.range.location - 1; + currentRange.length = 0; + + if (currentComponent.zwjIndex == -1) { + // This component is the start of the sequence; stop trying to look for more. + break; + } + } + + bool shouldLookForPrecoreCharacters = true; + if (currentComponent.firstExtendIndex != -1 || currentComponent.zwjIndex != -1) { + // The last component we found had characters preceding the pictograph, but we stopped looking. + // This can either be because we've hit the beginning of the string (i.e. there's no preceding component to find), or the character preceding those would not form a valid component itself, e.g.: + // + // │ ┌─────┐ ┌───────┐ ┌─────┐ + // │ ZWJ │ │ 1F469 │ │ ... │ + // │ └─────┘ └───────┘ └─────┘ + // ▲ │ + // └────────┘ + // + // OR + // + // ┌────────────┐ ┌────────┐ ┌─────┐ ┌───────┐ ┌─────┐ + // │ Garbage... │ | Extend | │ ZWJ │ │ 1F469 │ │ ... │ + // └────────────┘ └────────┘ └─────┘ └───────┘ └─────┘ + // ▲ │ + // └──────────────────┘ + // + // or similar. + // In this case, we'll ignore these preceding characters and use the pictograph as the start of the sequence looking forward. + coreRange.location = currentComponent.pictographIndex; + coreRange.length -= currentComponent.pictographIndex - currentComponent.range.location; + currentRange.location = currentComponent.pictographIndex + 1; + + // There's also no point in further looking for precore characters because Extend and ZWJ are not valid precore chars. + shouldLookForPrecoreCharacters = false; + } + + if (postcoreRange.length > 0 && coreRange.length == 0) { + // We matched some postcore characters but no pictographic sequence components. + // There's no point in looking for precore characters, or looking forwards afterwards. + return false; + } + + // We've now extended backwards to the start of the emoji sequence, if one exists. We can now try to match precore if there are any to be found. + CFRange precoreRange = CFRangeMake(currentRange.location, 0); + if (shouldLookForPrecoreCharacters) { + // Extend backwards as far as possible. + if (currentRange.location >= 0) { + // This adjusts currentRange to match the actual range of a long character, if necessary. + currentCharacter = __CFStringGetLongCharacterFromInlineBuffer(buffer, length, currentRange.location, ¤tRange); + while (__CFStringIsValidPrecoreCharacterForPictographicSequence(currentCharacter)) { + precoreRange.location = currentRange.location; + precoreRange.length += currentRange.length; + + if (precoreRange.location == 0) { + break; + } + + currentCharacter = __CFStringGetLongCharacterFromInlineBuffer(buffer, length, precoreRange.location - 1, ¤tRange); + } + } + + // Then forwards... + currentRange = CFRangeMake(precoreRange.location + precoreRange.length, 0); + while (currentRange.location < length) { + // This adjusts currentRange to match the actual range of a long character, if necessary. + currentCharacter = __CFStringGetLongCharacterFromInlineBuffer(buffer, length, currentRange.location, ¤tRange); + if (__CFStringIsValidPrecoreCharacterForPictographicSequence(currentCharacter)) { + precoreRange.length += currentRange.length; + currentRange.location += currentRange.length; + } else { + break; } } } - return __CFStringIsBaseForProfessionModifier(baseCharacter); -} - -#pragma mark Family Cluster Functions - -static inline bool __CFStringIsFamilySequenceBaseCharacterHigh(UTF16Char character) { return (character == 0xD83D) ? true : false; } -static inline bool __CFStringIsFamilySequenceBaseCharacterLow(UTF16Char character) { return (((character >= 0xDC66) && (character <= 0xDC69)) || (character == 0xDC8B) || (character == 0xDC41) || (character == 0xDDE8) ? true : false); } -static inline bool __CFStringIsFamilySequenceCluster(CFStringInlineBuffer *buffer, CFRange range) { - UTF16Char character = CFStringGetCharacterFromInlineBuffer(buffer, range.location); - - if (character == 0x2764) { // HEART - return true; - } else if (range.length > 1) { - if (__CFStringIsFamilySequenceBaseCharacterHigh(character) && __CFStringIsFamilySequenceBaseCharacterLow(CFStringGetCharacterFromInlineBuffer(buffer, range.location + 1))) return true; + + // We've now extended backwards as far as we can go... + if (precoreRange.length == 0 && coreRange.length == 0) { + // ... and haven't matched anything meaningful that we could get to by searching forward from here (i.e. we can't match precore/core characters after any postcore ones). + return false; } - return false; + + // We can now extend forwards to increase our match. + // If we found no core characters, we'll look for them right past any precore characters we've found. If we have found core characters, we'll continue extending them forward. + if (coreRange.length == 0) { + coreRange = CFRangeMake(precoreRange.location + precoreRange.length, 0); + currentRange = coreRange; + } else { + currentRange = CFRangeMake(coreRange.location + coreRange.length, 0); + } + + while (__CFStringGetExtendedPictographicSequenceComponent(buffer, length, currentRange.location, ¤tComponent)) { + if (coreRange.length > 0 && currentComponent.zwjIndex == -1) { + // This component had no ZWJ; it's the start of the next sequence, and we shouldn't include it. + break; + } + + coreRange.length += currentComponent.range.length; + currentRange.location += currentComponent.range.length; + } + + // Now before looking for more postcore characters, we should evaluate whether the ones we've already seen are actual postcore characters or not. + // It's entirely possible we matched something like a ZWJ up-front that's really part of the core match. + if (postcoreRange.length > 0) { + CFIndex onePastCore = coreRange.location + coreRange.length; + CFIndex onePastPostcore = postcoreRange.location + postcoreRange.length; + if (onePastCore >= onePastPostcore) { + // We've subsumed the entire postcore range, e.g., our initial example: + // + // ┌───────────────────────┐ ┌─────┐ ┌───────────────────────┐ ┌─────┐ + // │ Extended_Pictographic │ │ ZWJ │ │ Extended_Pictographic │ | ... | + // └───────────────────────┘ └─────┘ └───────────────────────┘ └─────┘ + // ▲ ▲ + // │ └─ coreRange ends here + // └─── appeared to be postcore but is part of coreRange + // + // We can look for more postcore characters past the whole of the currently matched range. + postcoreRange = CFRangeMake(onePastCore, 0); + } + + currentRange = CFRangeMake(postcoreRange.location + postcoreRange.length, 0); + } else { + // We didn't find any postcore characters; currentRange points just past the end of coreRange, so advance to there and if we find any characters, we'll append them to this range. + postcoreRange = currentRange; + } + + if (currentRange.location < length) { + // There may be further trailing post-core characters. + // This adjusts currentRange to match the actual range of a long character, if necessary. + currentCharacter = __CFStringGetLongCharacterFromInlineBuffer(buffer, length, currentRange.location, ¤tRange); + while (__CFStringIsValidPostcoreCharacterForPictographicSequence(currentCharacter)) { + postcoreRange.length += currentRange.length; + currentRange.location += currentRange.length; + currentCharacter = __CFStringGetLongCharacterFromInlineBuffer(buffer, length, currentRange.location, ¤tRange); + } + } + + // We're only willing to return full matches, which necessitate finding a core character -- otherwise this is not an eligible xpicto-sequence. + bool const haveMatch = coreRange.length > 0; + if (haveMatch && outRange) { + // At this point, the union of {precoreRange, coreRange, postcoreRange} gives us the full range of the match. + *outRange = coreRange; + if (precoreRange.length > 0) { + outRange->location = precoreRange.location; + outRange->length += precoreRange.length; + } + + if (postcoreRange.length > 0) { + outRange->length += postcoreRange.length; + } + } + + return haveMatch; } - -#pragma mark Regional Indicator Functions + +#pragma mark Composed Character Sequences #define RI_SURROGATE_HI (0xD83C) static inline bool __CFStringIsRegionalIndicatorSurrogateLow(UTF16Char character) { return (character >= 0xDDE6) && (character <= 0xDDFF) ? true : false; } @@ -3824,14 +4026,8 @@ static inline bool __CFStringIsRegionalIndicatorAtIndex(CFStringInlineBuffer *bu return ((CFStringGetCharacterFromInlineBuffer(buffer, index) == RI_SURROGATE_HI) && __CFStringIsRegionalIndicatorSurrogateLow(CFStringGetCharacterFromInlineBuffer(buffer, index + 1))) ? true : false; } -#pragma mark White/Rainbow Flag Functions -static inline bool __CFStringIsWavingWhiteFlagCluster(CFStringInlineBuffer *buffer, CFRange range) { - return ((CFStringGetCharacterFromInlineBuffer(buffer, range.location) == RI_SURROGATE_HI) && (CFStringGetCharacterFromInlineBuffer(buffer, range.location + 1) == 0xDFF3)); -} - -static inline bool __CFStringIsRainbowCluster(CFStringInlineBuffer *buffer, CFRange range) { - return ((CFStringGetCharacterFromInlineBuffer(buffer, range.location) == RI_SURROGATE_HI) && (CFStringGetCharacterFromInlineBuffer(buffer, range.location + 1) == 0xDF08)); -} +static inline bool __CFStringIsFitzpatrickModifiers(UTF32Char character) { return ((character >= 0x1F3FB) && (character <= 0x1F3FF) ? true : false); } +static inline bool __CFStringIsTagSequence(UTF32Char character) { return ((character >= 0xE0020) && (character <= 0xE007F) ? true : false); } static CFRange _CFStringInlineBufferGetComposedRange(CFStringInlineBuffer *buffer, CFIndex start, CFStringCharacterClusterType type, const uint8_t *bmpBitmap, CFIndex csetType) { CFIndex end = start + 1; @@ -3865,18 +4061,13 @@ static CFRange _CFStringInlineBufferGetComposedRange(CFStringInlineBuffer *buffe } } - if (__CFStringIsFitzpatrickModifiers(character) && (start > 0)) { - UTF32Char baseCharacter = CFStringGetCharacterFromInlineBuffer(buffer, start - 1); - - if (CFUniCharIsSurrogateLowCharacter(baseCharacter) && ((start - 1) > 0)) { - UTF16Char otherCharacter = CFStringGetCharacterFromInlineBuffer(buffer, start - 2); - - if (CFUniCharIsSurrogateHighCharacter(otherCharacter)) baseCharacter = CFUniCharGetLongCharacterForSurrogatePair(otherCharacter, baseCharacter); - } - - if (!__CFStringIsBaseForFitzpatrickModifiers(baseCharacter)) break; - } else { - if (!CFUniCharIsMemberOfBitmap(character, bitmap) && !__CFStringIsTagSequence(character) && (character != 0xFF9E) && (character != 0xFF9F) && ((character & 0x1FFFF0) != 0xF870)) break; + Boolean isRelevantFitzpatrickModifier = (start > 0 && __CFStringIsFitzpatrickModifiers(character)); + Boolean isInBitmap = CFUniCharIsMemberOfBitmap(character, bitmap); + Boolean isTagSequence = __CFStringIsTagSequence(character); + Boolean behavesLikeCombiningMark = (character == 0xFF9E) || (character == 0xFF9F) || ((character & 0x1FFFF0) == 0xF870 /* variant tag */); + if (!isRelevantFitzpatrickModifier && !isInBitmap && ! isTagSequence && !behavesLikeCombiningMark) { + // Nothing to extend backward for. + break; } --start; @@ -3969,8 +4160,6 @@ static CFRange _CFStringInlineBufferGetComposedRange(CFStringInlineBuffer *buffe } } - bool prevIsFitzpatrickBase = __CFStringIsBaseForFitzpatrickModifiers(character); - // Extend forward while ((character = CFStringGetCharacterFromInlineBuffer(buffer, end)) > 0) { if ((type == kCFStringBackwardDeletionCluster) && (character >= 0x0530) && (character < 0x1950)) break; @@ -3984,9 +4173,14 @@ static CFRange _CFStringInlineBufferGetComposedRange(CFStringInlineBuffer *buffe step = 1; } - if ((!prevIsFitzpatrickBase || !__CFStringIsFitzpatrickModifiers(character)) && !CFUniCharIsMemberOfBitmap(character, bitmap) && !__CFStringIsTagSequence(character) && (character != 0xFF9E) && (character != 0xFF9F) && ((character & 0x1FFFF0) != 0xF870)) break; - - prevIsFitzpatrickBase = __CFStringIsBaseForFitzpatrickModifiers(character); + Boolean isRelevantFitzpatrickModifier = __CFStringIsFitzpatrickModifiers(character); + Boolean isInBitmap = CFUniCharIsMemberOfBitmap(character, bitmap); + Boolean isTagSequence = __CFStringIsTagSequence(character); + Boolean behavesLikeCombiningMark = (character == 0xFF9E) || (character == 0xFF9F) || ((character & 0x1FFFF0) == 0xF870 /* variant tag */); + if (!isRelevantFitzpatrickModifier && !isInBitmap && ! isTagSequence && !behavesLikeCombiningMark) { + // Nothing to extend backward for. + break; + } end += step; } @@ -4143,171 +4337,42 @@ CFRange CFStringGetRangeOfCharacterClusterAtIndex(CFStringRef string, CFIndex ch } } - // Rainbow flag sequence & Gender modifier sequence - CFRange aCluster; - - if (__CFStringIsWavingWhiteFlagCluster(&stringBuffer, range)) { - CFIndex end = range.location + range.length - 1; - if ((end + 1) < length) { - UTF32Char endCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, end); - if (endCharacter != ZERO_WIDTH_JOINER) { - end++; - endCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, end); - } - if (endCharacter == ZERO_WIDTH_JOINER) { - aCluster = _CFStringInlineBufferGetComposedRange(&stringBuffer, end + 1, type, bmpBitmap, csetType); - if (__CFStringIsRainbowCluster(&stringBuffer, aCluster)) { - currentIndex = aCluster.location + aCluster.length; - if ((aCluster.length > 1) && (ZERO_WIDTH_JOINER == CFStringGetCharacterFromInlineBuffer(&stringBuffer, currentIndex - 1))) --currentIndex; - } - if (currentIndex > (range.location + range.length)) range.length = currentIndex - range.location; - } - } - } else if (__CFStringIsRainbowCluster(&stringBuffer, range)) { - if (range.location > 1) { - CFIndex prev = range.location - 1; - UTF32Char prevCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, prev); - if (prevCharacter == ZERO_WIDTH_JOINER) { - aCluster = _CFStringInlineBufferGetComposedRange(&stringBuffer, prev - 1, type, bmpBitmap, csetType); - if (__CFStringIsWavingWhiteFlagCluster(&stringBuffer, aCluster)) { - currentIndex = aCluster.location; - } - if (currentIndex < range.location) { - range.length += range.location - currentIndex; - range.location = currentIndex; - } - } - } - } else if (__CFStringIsGenderModifierBaseCluster(&stringBuffer, range)) { - CFIndex end = range.location + range.length - 1; - if ((end + 1) < length) { - UTF32Char endCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, end); - if (endCharacter != ZERO_WIDTH_JOINER) { - end++; - endCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, end); - } - if (endCharacter == ZERO_WIDTH_JOINER) { - aCluster = _CFStringInlineBufferGetComposedRange(&stringBuffer, end + 1, type, bmpBitmap, csetType); - if (__CFStringIsGenderModifierCluster(&stringBuffer, aCluster)) { - currentIndex = aCluster.location + aCluster.length; - if ((aCluster.length > 1) && (ZERO_WIDTH_JOINER == CFStringGetCharacterFromInlineBuffer(&stringBuffer, currentIndex - 1))) --currentIndex; - } - if (currentIndex > (range.location + range.length)) range.length = currentIndex - range.location; - } - } - } else if (__CFStringIsGenderModifierCluster(&stringBuffer, range)) { - if (range.location > 1) { - CFIndex prev = range.location - 1; - UTF32Char prevCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, prev); - if (prevCharacter == ZERO_WIDTH_JOINER) { - aCluster = _CFStringInlineBufferGetComposedRange(&stringBuffer, prev - 1, type, bmpBitmap, csetType); - if (__CFStringIsGenderModifierBaseCluster(&stringBuffer, aCluster)) { - currentIndex = aCluster.location; - } - if (currentIndex < range.location) { - range.length += range.location - currentIndex; - range.location = currentIndex; - } - } - } - } else if (__CFStringIsProfessionBaseCluster(&stringBuffer, range)) { - CFIndex end = range.location + range.length - 1; - if ((end + 1) < length) { - UTF32Char endCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, end); - if (endCharacter != ZERO_WIDTH_JOINER) { - end++; - endCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, end); - } - if (endCharacter == ZERO_WIDTH_JOINER) { - aCluster = _CFStringInlineBufferGetComposedRange(&stringBuffer, end + 1, type, bmpBitmap, csetType); - if (__CFStringIsProfessionModifierCluster(&stringBuffer, aCluster)) { - currentIndex = aCluster.location + aCluster.length; - if ((aCluster.length > 1) && (ZERO_WIDTH_JOINER == CFStringGetCharacterFromInlineBuffer(&stringBuffer, currentIndex - 1))) --currentIndex; - } - if (currentIndex > (range.location + range.length)) range.length = currentIndex - range.location; - } - } - } else if (__CFStringIsProfessionModifierCluster(&stringBuffer, range)) { - if (range.location > 1) { - CFIndex prev = range.location - 1; - UTF32Char prevCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, prev); - if (prevCharacter == ZERO_WIDTH_JOINER) { - aCluster = _CFStringInlineBufferGetComposedRange(&stringBuffer, prev - 1, type, bmpBitmap, csetType); - if (__CFStringIsProfessionBaseCluster(&stringBuffer, aCluster)) { - currentIndex = aCluster.location; - } - if (currentIndex < range.location) { - range.length += range.location - currentIndex; - range.location = currentIndex; - } - } - } - } else { - // range is zwj - CFIndex end = range.location + range.length - 1; - UTF32Char endCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, end); - if (((end + 1) < length) && ((endCharacter == ZERO_WIDTH_JOINER) || (endCharacter == WHITE_SPACE_CHARACTER))) { - // Get cluster before and after zwj. Range length of zwj cluster is always 1. - CFRange rangeBeforeZWJ = _CFStringInlineBufferGetComposedRange(&stringBuffer, end - 1, type, bmpBitmap, csetType); - aCluster = _CFStringInlineBufferGetComposedRange(&stringBuffer, end + 1, type, bmpBitmap, csetType); - - if (((__CFStringIsWavingWhiteFlagCluster(&stringBuffer, rangeBeforeZWJ)) && (__CFStringIsRainbowCluster(&stringBuffer, aCluster))) - || ((__CFStringIsGenderModifierBaseCluster(&stringBuffer, rangeBeforeZWJ)) && (__CFStringIsGenderModifierCluster(&stringBuffer, aCluster))) - || ((__CFStringIsProfessionBaseCluster(&stringBuffer, rangeBeforeZWJ)) && (__CFStringIsProfessionModifierCluster(&stringBuffer, aCluster)))) { - range.location = rangeBeforeZWJ.location; - range.length += rangeBeforeZWJ.length + aCluster.length; - } - } - } - - // Family face sequence - if (range.location > 1) { // there are more than 2 chars - character = CFStringGetCharacterFromInlineBuffer(&stringBuffer, range.location); - - if (__CFStringIsFamilySequenceCluster(&stringBuffer, range) || (character == ZERO_WIDTH_JOINER)) { // extend backward - currentIndex = (character == ZERO_WIDTH_JOINER) ? range.location + 1 : range.location; - - while ((currentIndex > 1) && (ZERO_WIDTH_JOINER == CFStringGetCharacterFromInlineBuffer(&stringBuffer, currentIndex - 1))) { - aCluster = _CFStringInlineBufferGetComposedRange(&stringBuffer, currentIndex - 2, type, bmpBitmap, csetType); - - if (aCluster.location < range.location) { - if (__CFStringIsFamilySequenceCluster(&stringBuffer, aCluster)) { - currentIndex = aCluster.location; - } else { - break; - } - } - } + // Attempt to expand to match pictographic sequences (Emoji and otherwise). + CFRange cluster; + if (__CFStringGetExtendedPictographicSequence(&stringBuffer, length, range.location, &cluster)) { + // We've found a pictographic cluster by the definition given in https://www.unicode.org/reports/tr29/#Regex_Definitions + // However, we have to be careful -- if we are trying to match a composed character sequence, we might end up with `cluster` not aligning with `range`. + // + // For instance, + // + // \U0001F498\u108F\u103D ≡ [HEART WITH ARROW, MYANMAR SIGN RUMAI PALAUNG TONE-5, MYANMAR CONSONANT SIGN MEDIAL WA] + // + // is in its entirety a valid composed character sequence (1F498 is a Symbol; 108F and 103D are both Marks). + // + // However, it does not form a pictographic sequence -- 1F498 is a valid Extended_Pictographic character, but 108F is specifically excluded from the SpacingMark property. + // + // So, `range` here might be {0, 4}, while `cluster` can be `{0, 2}`. We should only allow `cluster` to _extend_ `range`, not shrink it. + CFIndex const rangeEnd = range.location + range.length; + CFIndex const clusterEnd = cluster.location + cluster.length; + + /* We want cluster to exclusively extend range, not just intersect it. Cases: + 1. range: [ ] range.location == cluster.location && rangeEnd == clusterEnd + cluster: [ ] + 2. range: [ ] range.location == cluster.location && rangeEnd < clusterEnd + cluster: [ ] + 3. range: [ ] range.location > cluster.location && rangeEnd == clusterEnd + cluster: [ ] + 4. range: [ ] range.location > cluster.location && rangeEnd < clusterEnd + cluster: [ ] + */ + Boolean const clusterContainsRange = (range.location >= cluster.location && rangeEnd <= clusterEnd); - if (currentIndex < range.location) { - range.length += range.location - currentIndex; - range.location = currentIndex; - } + // If the above is not true, the match we've found here is not useful for the semantics we're applying, and we'll ignore it. + if (clusterContainsRange) { + range = cluster; } } - - // Extend forward - if (range.location + range.length < length) { - currentIndex = range.location + range.length - 1; - character = CFStringGetCharacterFromInlineBuffer(&stringBuffer, currentIndex); - - if ((ZERO_WIDTH_JOINER == character) || __CFStringIsFamilySequenceCluster(&stringBuffer, _CFStringInlineBufferGetComposedRange(&stringBuffer, currentIndex, type, bmpBitmap, csetType))) { - - if (ZERO_WIDTH_JOINER != character) ++currentIndex; // move to the end of cluster - - while (((currentIndex + 1) < length) && (ZERO_WIDTH_JOINER == CFStringGetCharacterFromInlineBuffer(&stringBuffer, currentIndex))) { - aCluster = _CFStringInlineBufferGetComposedRange(&stringBuffer, currentIndex + 1, type, bmpBitmap, csetType); - if ((__CFStringIsFamilySequenceCluster(&stringBuffer, aCluster))) { - currentIndex = aCluster.location + aCluster.length; - if ((aCluster.length > 1) && (ZERO_WIDTH_JOINER == CFStringGetCharacterFromInlineBuffer(&stringBuffer, currentIndex - 1))) --currentIndex; - } else { - break; - } - } - if (currentIndex > (range.location + range.length)) range.length = currentIndex - range.location; - } - } - + // Gather the final grapheme extends CFRange finalCluster; @@ -4390,7 +4455,7 @@ CF_EXPORT Boolean CFStringFindCharacterFromSet(CFStringRef theString, CFCharacte step = (fromLoc <= toLoc) ? 1 : -1; cnt = fromLoc; - CFStringInitInlineBuffer(theString, &stringBuffer, rangeToSearch); + _CFStringInitInlineBufferInternal(theString, &stringBuffer, rangeToSearch, true); CFCharacterSetInitInlineBuffer(theSet, &csetBuffer); do { @@ -4461,7 +4526,7 @@ static void __CFStringGetLineOrParagraphBounds(CFStringRef string, CFRange range if (range.location == 0) { start = 0; } else { - CFStringInitInlineBuffer(string, &buf, CFRangeMake(0, len)); + _CFStringInitInlineBufferInternal(string, &buf, CFRangeMake(0, len), false); CFIndex buf_idx = range.location; /* Take care of the special case where start happens to fall right between \r and \n */ @@ -4488,7 +4553,7 @@ static void __CFStringGetLineOrParagraphBounds(CFStringRef string, CFRange range /* Now find the ending point */ if (lineEndIndex || contentsEndIndex) { CFIndex endOfContents, lineSeparatorLength = 1; /* 1 by default */ - CFStringInitInlineBuffer(string, &buf, CFRangeMake(0, len)); + _CFStringInitInlineBufferInternal(string, &buf, CFRangeMake(0, len), false); CFIndex buf_idx = range.location + range.length - (range.length ? 1 : 0); /* First look at the last char in the range (if the range is zero length, the char after the range) to see if we're already on or within a end of line sequence... */ ch = __CFStringGetCharacterFromInlineBufferAux(&buf, buf_idx); @@ -4564,6 +4629,12 @@ CFStringRef CFStringCreateByCombiningStrings(CFAllocatorRef alloc, CFArrayRef ar buffer = (uint8_t *)CFAllocatorAllocate(alloc, canBeEightbit ? ((numChars + 1) * sizeof(uint8_t)) : (numChars * sizeof(UniChar)), 0); bufPtr = (uint8_t *)buffer; + + // check that bufPtr actually got allocated + if (!bufPtr) { + __CFStringHandleOutOfMemory(NULL); + } + if (__CFOASafe) __CFSetLastAllocationEventName(buffer, "CFString (store)"); separatorNumByte = CFStringGetLength(separatorString) * (canBeEightbit ? sizeof(uint8_t) : sizeof(UniChar)); @@ -4732,7 +4803,7 @@ SInt32 CFStringGetIntValue(CFStringRef str) { SInt32 result; SInt32 idx = 0; CFStringInlineBuffer buf; - CFStringInitInlineBuffer(str, &buf, CFRangeMake(0, CFStringGetLength(str))); + _CFStringInitInlineBufferInternal(str, &buf, CFRangeMake(0, CFStringGetLength(str)), true); success = __CFStringScanInteger(&buf, NULL, &idx, false, &result); return success ? result : 0; } @@ -4743,7 +4814,7 @@ double CFStringGetDoubleValue(CFStringRef str) { double result; SInt32 idx = 0; CFStringInlineBuffer buf; - CFStringInitInlineBuffer(str, &buf, CFRangeMake(0, CFStringGetLength(str))); + _CFStringInitInlineBufferInternal(str, &buf, CFRangeMake(0, CFStringGetLength(str)), true); success = __CFStringScanDouble(&buf, NULL, &idx, &result); return success ? result : 0.0; } @@ -4879,13 +4950,17 @@ void __CFStringAppendBytes(CFMutableStringRef str, const char *cStr, CFIndex app } else { CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFString, void, (NSMutableString *)str, appendCharacters:(const unichar *)cStr length:(NSUInteger)appendedLength); } - } else if (CF_IS_SWIFT(_kCFRuntimeIDCFString, str)) { + } +#if DEPLOYMENT_RUNTIME_SWIFT + else if (CF_IS_SWIFT(_kCFRuntimeIDCFString, str)) { if (!appendedIsUnicode && !demoteAppendedUnicode) { CF_SWIFT_FUNCDISPATCHV(_kCFRuntimeIDCFString, void, (CFSwiftRef)str, NSMutableString._cfAppendCString,(const char *)cStr, appendedLength); } else { CF_SWIFT_FUNCDISPATCHV(_kCFRuntimeIDCFString, void, (CFSwiftRef)str, NSMutableString.appendCharacters, (const UniChar *)cStr, appendedLength); } - } else { + } +#endif + else { CFIndex strLength; __CFAssertIsStringAndMutable(str); strLength = __CFStrLength(str); @@ -4994,10 +5069,10 @@ CFIndex CFStringFindAndReplace(CFMutableStringRef string, CFStringRef stringToFi int __CFStringCheckAndReplace(CFMutableStringRef str, CFRange range, CFStringRef replacement) { if (!__CFStrIsMutable(str)) return _CFStringErrNotMutable; // These three ifs are always here, for NSString usage - if (!replacement && __CFStringNoteErrors()) return _CFStringErrNilArg; + if (!replacement) return _CFStringErrNilArg; // This attempts to catch bad ranges including those described in 3375535 (-1,1) unsigned long endOfRange = (unsigned long)(range.location) + (unsigned long)(range.length); // NSRange uses unsigned quantities, hence the casting - if (((endOfRange > (unsigned long)__CFStrLength(str)) || (endOfRange < (unsigned long)(range.location))) && __CFStringNoteErrors()) return _CFStringErrBounds; + if ((endOfRange > (unsigned long)__CFStrLength(str)) || (endOfRange < (unsigned long)(range.location))) return _CFStringErrBounds; __CFAssertIsStringAndMutable(str); __CFAssertRangeIsInStringBounds(str, range.location, range.length); @@ -5112,7 +5187,7 @@ void CFStringTrimWhitespace(CFMutableStringRef string) { newStartIndex = 0; length = __CFStrLength(string); - CFStringInitInlineBuffer(string, &buffer, CFRangeMake(0, length)); + _CFStringInitInlineBufferInternal(string, &buffer, CFRangeMake(0, length), false /* already did CF_OBJC_FUNCDISPATCHV above */); CFIndex buffer_idx = 0; while (buffer_idx < length && CFUniCharIsMemberOf(__CFStringGetCharacterFromInlineBufferQuick(&buffer, buffer_idx), kCFUniCharWhitespaceAndNewlineCharacterSet)) @@ -5788,11 +5863,11 @@ void CFStringFold(CFMutableStringRef theString, CFStringCompareFlags theFlags, C langCode = ((NULL == theLocale) ? NULL : (const uint8_t *)_CFStrGetLanguageIdentifierForLocale(theLocale, true)); eightBitEncoding = __CFStringGetEightBitStringEncoding(); - cString = (const uint8_t *)CFStringGetCStringPtr(theString, eightBitEncoding); + cString = (const uint8_t *)_CFStringGetCStringPtrInternal(theString, eightBitEncoding, false, isObjcOrSwift); if ((NULL != cString) && !caseInsensitive && (kCFStringEncodingASCII == eightBitEncoding)) goto bail; // All ASCII - CFStringInitInlineBuffer(theString, &stringBuffer, CFRangeMake(0, length)); + _CFStringInitInlineBufferInternal(theString, &stringBuffer, CFRangeMake(0, length), isObjcOrSwift); if ((NULL != cString) && (theFlags & (kCFCompareCaseInsensitive|kCFCompareDiacriticInsensitive))) { const uint8_t *cStringPtr = cString; @@ -5849,7 +5924,7 @@ void CFStringFold(CFMutableStringRef theString, CFStringCompareFlags theFlags, C if (bufferLength > 0) { __CFStringChangeSize(theString, CFRangeMake(currentIndex + 1, 0), bufferLength - 1, true); length = __CFStrLength(theString); - CFStringInitInlineBuffer(theString, &stringBuffer, CFRangeMake(0, length)); + _CFStringInitInlineBufferInternal(theString, &stringBuffer, CFRangeMake(0, length), isObjcOrSwift); contents = (UTF16Char *)__CFStrContents(theString) + currentIndex; characters = buffer; @@ -5899,7 +5974,7 @@ void CFStringFold(CFMutableStringRef theString, CFStringCompareFlags theFlags, C } __CFStringChangeSize(theString, range, insertLength, true); length = __CFStrLength(theString); - CFStringInitInlineBuffer(theString, &stringBuffer, CFRangeMake(0, length)); + _CFStringInitInlineBufferInternal(theString, &stringBuffer, CFRangeMake(0, length), isObjcOrSwift); } (void)CFUniCharFromUTF32(buffer, bufferLength, (UTF16Char *)__CFStrContents(theString) + currentIndex, true, __CF_BIG_ENDIAN__); @@ -6081,6 +6156,10 @@ static Boolean __CFStringFormatLocalizedNumber(CFMutableStringRef output, CFLoca } formatter = gFormatter; break; + default: + // HALT, or else CFNumberGetFormat below will be called on uninitialized memory + CRSetCrashLogMessage("Unexpected formatter style"); + HALT; } CFStringRef origFormat = CFStringCreateCopy(NULL, CFNumberFormatterGetFormat(formatter)); // Need to hang on to this in case the format changes while we are setting properties below @@ -6178,16 +6257,12 @@ static Boolean __CFStringFormatLocalizedNumber(CFMutableStringRef output, CFLoca CFNumberGetValue(tmp, kCFNumberSInt32Type, &minDigits); // Ensure we're padding up to the minimum number of digits - // NOTE: MinIntegerDigits doesn't take punctuation (plus/minus sign, grouping separators, radix, etc) into account but printf normally does. if (padZero && (minDigits > 0) && p) { - if (spec->type == CFFormatDoubleType) { - if (width > precision) { - CFRelease(tmp); - SInt32 minIntDigits = width - precision; - tmp = CFNumberCreate(NULL, kCFNumberSInt32Type, &minIntDigits); - } + // For floating-point values, the previously set `kCFNumberFormatterFormatWidthKey` value is sufficient to calculate the minimum integer digits needed, accounting for plus/minus sign, grouping separators, radix, etc. + // We need this to force padding for integer values (e.g., 42 -> "%04d" => "0,042", or 234 -> "%10.5d" => " 00,234"). + if (spec->type != CFFormatDoubleType) { + CFNumberFormatterSetProperty(formatter, kCFNumberFormatterMinIntegerDigitsKey, tmp); } - CFNumberFormatterSetProperty(formatter, kCFNumberFormatterMinIntegerDigitsKey, tmp); } CFRelease(tmp); @@ -6420,7 +6495,7 @@ reswtch:switch (ch) { if (spec->size != CFFormatSize16) spec->size = CFFormatSize8; return true; case 'n': /* %n is not handled correctly; for Leopard or newer apps, we disable it further */ - spec->type = 1 ? CFFormatDummyPointerType : CFFormatPointerType; + spec->type = CFFormatDummyPointerType; spec->size = CFFormatSizePointer; // 4 or 8 depending on LP64 return true; case 'p': @@ -6614,20 +6689,20 @@ SInt32 __CFStringFindFormatSpecifiersInString(const uint8_t *cformat, const UniC SInt32 cidx, idx, loc; loc = specs[curSpec].loc; if (cformat) { - for (idx = 0, cidx = 0; cidx < specs[curSpec].len; idx++, cidx++) { + for (idx = 0, cidx = 0; cidx < specs[curSpec].len && idx < 128; idx++, cidx++) { if ('$' == cformat[loc + cidx]) { if (idx > -1) { - for (idx--; '0' <= formatBuffer[idx] && formatBuffer[idx] <= '9'; idx--); + for (idx--; idx >= 0 && '0' <= formatBuffer[idx] && formatBuffer[idx] <= '9'; idx--); } } else { formatBuffer[idx] = cformat[loc + cidx]; } } } else { - for (idx = 0, cidx = 0; cidx < specs[curSpec].len; idx++, cidx++) { + for (idx = 0, cidx = 0; cidx < specs[curSpec].len && idx < 128; idx++, cidx++) { if ('$' == uformat[loc + cidx]) { if (idx > -1) { - for (idx--; '0' <= formatBuffer[idx] && formatBuffer[idx] <= '9'; idx--); + for (idx--; idx >= 0 && '0' <= formatBuffer[idx] && formatBuffer[idx] <= '9'; idx--); } } else { formatBuffer[idx] = (int8_t)uformat[loc + cidx]; @@ -6967,7 +7042,6 @@ static Boolean __CFStringAppendFormatCore(CFMutableStringRef outputString, CFStr } else { specs[curSpec].len = newFmtIdx - formatIdx; } - if (NULL != configKey) CFRelease(configKey); } formatIdx = newFmtIdx; @@ -7091,7 +7165,10 @@ static Boolean __CFStringAppendFormatCore(CFMutableStringRef outputString, CFStr } SInt32 numSpecsContext = 0; - CFFormatSpec *specsContext = (CFFormatSpec *)calloc(numSpecs, sizeof(CFFormatSpec)); + CFFormatSpec *specsContext = NULL; + if (numSpecs > 0) { + specsContext = (CFFormatSpec *)calloc(numSpecs, sizeof(CFFormatSpec)); + } const CFStringRef replacement = CFSTR("%@NSCONTEXT"); for (curSpec = 0; curSpec < numSpecs; curSpec++) { diff --git a/CoreFoundation/String.subproj/CFString.h b/CoreFoundation/String.subproj/CFString.h index 59735ff900..058a02b924 100644 --- a/CoreFoundation/String.subproj/CFString.h +++ b/CoreFoundation/String.subproj/CFString.h @@ -1,7 +1,7 @@ /* CFString.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -196,7 +196,7 @@ struct __CFConstStr { #endif -#if defined(__GNUC__) && (__GNUC__*10+__GNUC_MINOR__ >= 42) && defined(__APPLE_CC__) && (__APPLE_CC__ > 1) && !defined(__INTEL_COMPILER) && (TARGET_OS_MAC || TARGET_OS_EMBEDDED) +#if defined(__GNUC__) && (__GNUC__*10+__GNUC_MINOR__ >= 42) && defined(__APPLE_CC__) && (__APPLE_CC__ > 1) && !defined(__INTEL_COMPILER) && TARGET_OS_MAC #define CF_FORMAT_FUNCTION(F,A) __attribute__((format(CFString, F, A))) #define CF_FORMAT_ARGUMENT(A) __attribute__((format_arg(A))) #else diff --git a/CoreFoundation/String.subproj/CFStringDefaultEncoding.h b/CoreFoundation/String.subproj/CFStringDefaultEncoding.h index 7caf12e744..5d1804f451 100644 --- a/CoreFoundation/String.subproj/CFStringDefaultEncoding.h +++ b/CoreFoundation/String.subproj/CFStringDefaultEncoding.h @@ -1,7 +1,7 @@ /* CFStringDefaultEncoding.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -12,7 +12,7 @@ #include -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) +#if TARGET_OS_OSX || TARGET_OS_IPHONE #include #include #include diff --git a/CoreFoundation/String.subproj/CFStringEncodingExt.h b/CoreFoundation/String.subproj/CFStringEncodingExt.h index d368b8678a..7e404fdd47 100644 --- a/CoreFoundation/String.subproj/CFStringEncodingExt.h +++ b/CoreFoundation/String.subproj/CFStringEncodingExt.h @@ -1,7 +1,7 @@ /* CFStringEncodingExt.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/String.subproj/CFStringEncodings.c b/CoreFoundation/String.subproj/CFStringEncodings.c index bcece3eb9b..42e288c56e 100644 --- a/CoreFoundation/String.subproj/CFStringEncodings.c +++ b/CoreFoundation/String.subproj/CFStringEncodings.c @@ -1,7 +1,7 @@ /* CFStringEncodings.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -9,6 +9,7 @@ */ #include "CFInternal.h" +#include "CFRuntime_Internal.h" #include "CFString_Internal.h" #include #include @@ -18,7 +19,7 @@ #include "CFStringEncodingConverterPriv.h" #include #include -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) +#if TARGET_OS_OSX || TARGET_OS_IPHONE #include #include #include @@ -128,6 +129,15 @@ Boolean __CFStringDecodeByteStream3(const uint8_t *bytes, CFIndex len, CFStringE if ((encoding == kCFStringEncodingUTF16) || (encoding == kCFStringEncodingUTF16BE) || (encoding == kCFStringEncodingUTF16LE)) { // UTF-16 const UTF16Char *src = (const UTF16Char *)bytes; const UTF16Char *limit = src + (len / sizeof(UTF16Char)); // avoiding odd len issue + if (src == limit) { + // There weren't enough bytes to make a single UTF16Char, i.e., the encoding we were given is invalid. + // We've already checked `0 == len` above, so the buffer is not empty. + // + // NOTE: Because of the check for 7854378 above, we'll only effectively hit this if len == 1. + // The division ensures that `limit` is a multiple of `sizeof(UTF16Char)` (2), so we'll ignore any odd bytes past the end. The issue lies in lopping off the odd byte in the first "character". + goto memoryErrorExit; + } + bool swap = false; if (kCFStringEncodingUTF16 == encoding) { @@ -208,6 +218,15 @@ Boolean __CFStringDecodeByteStream3(const uint8_t *bytes, CFIndex len, CFStringE } else if ((encoding == kCFStringEncodingUTF32) || (encoding == kCFStringEncodingUTF32BE) || (encoding == kCFStringEncodingUTF32LE)) { const UTF32Char *src = (const UTF32Char *)bytes; const UTF32Char *limit = src + (len / sizeof(UTF32Char)); // avoiding odd len issue + if (src == limit) { + // There weren't enough bytes to make a single UTF32Char, i.e., the encoding we were given is invalid. + // We've already checked `0 == len` above, so the buffer is not empty. + // + // NOTE: Because of the check for 7854378 above, we'll only effectively hit this if `1 <= len <= 3`. + // The division ensures that `limit` is a multiple of `sizeof(UTF32Char)` (4), so we'll ignore any bytes past the end. The issue lies in lopping off the extra bytes in the first "character". + goto memoryErrorExit; + } + bool swap = false; static bool strictUTF32 = (bool)-1; @@ -626,7 +645,7 @@ CFIndex __CFStringEncodeByteStream(CFStringRef string, CFIndex rangeLoc, CFIndex if (!CFStringEncodingIsValidEncoding(encoding)) return 0; - if (!CF_IS_OBJC(CFStringGetTypeID(), string) && isASCIISuperset) { // Checking for NSString to avoid infinite recursion + if (!CF_IS_OBJC(_kCFRuntimeIDCFString, string) && isASCIISuperset) { // Checking for NSString to avoid infinite recursion const unsigned char *ptr; if ((cString = (const unsigned char *)CFStringGetCStringPtr(string, __CFStringGetEightBitStringEncoding()))) { ptr = (cString += rangeLoc); @@ -904,7 +923,7 @@ Boolean _CFStringGetFileSystemRepresentation(CFStringRef string, uint8_t *buffer } -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) +#if TARGET_OS_OSX || TARGET_OS_IPHONE /* This function is used to obtain users' default script/region code. The function first looks at environment variable __kCFUserEncodingEnvVariableName, then, reads the configuration file in user's home directory. diff --git a/CoreFoundation/String.subproj/CFStringScanner.c b/CoreFoundation/String.subproj/CFStringScanner.c index 897b4095db..673a113a4e 100644 --- a/CoreFoundation/String.subproj/CFStringScanner.c +++ b/CoreFoundation/String.subproj/CFStringScanner.c @@ -1,7 +1,7 @@ /* CFStringScanner.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/String.subproj/CFStringUtilities.c b/CoreFoundation/String.subproj/CFStringUtilities.c index 00fb9cd9ff..1edae9d16e 100644 --- a/CoreFoundation/String.subproj/CFStringUtilities.c +++ b/CoreFoundation/String.subproj/CFStringUtilities.c @@ -1,7 +1,7 @@ /* CFStringUtilities.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -15,6 +15,7 @@ #include "CFStringEncodingConverterPriv.h" #include "CFStringEncodingDatabase.h" #include "CFICUConverters.h" +#include "CFString_Internal.h" #include #include #if TARGET_OS_MAC || TARGET_OS_WIN32 || TARGET_OS_LINUX @@ -43,7 +44,6 @@ Boolean CFStringIsEncodingAvailable(CFStringEncoding theEncoding) { case kCFStringEncodingUTF32BE: case kCFStringEncodingUTF32LE: return true; - default: return CFStringEncodingIsValidEncoding(theEncoding); } @@ -178,16 +178,19 @@ enum { #define NSENCODING_MASK (1 << 31) unsigned long CFStringConvertEncodingToNSStringEncoding(CFStringEncoding theEncoding) { + //These two are frequently used in situations that are otherwise very fast (e.g. tagged strings), so check them first + if (theEncoding == kCFStringEncodingUTF8) return NSUTF8StringEncoding; + if (theEncoding == kCFStringEncodingASCII) return NSASCIIStringEncoding; switch (theEncoding & 0xFFF) { case kCFStringEncodingUnicode: if (theEncoding == kCFStringEncodingUTF16) return NSUnicodeStringEncoding; - else if (theEncoding == kCFStringEncodingUTF8) return NSUTF8StringEncoding; + //UTF8 handled above break; case kCFStringEncodingWindowsLatin1: return NSWindowsCP1252StringEncoding; case kCFStringEncodingMacRoman: return NSMacOSRomanStringEncoding; - case kCFStringEncodingASCII: return NSASCIIStringEncoding; + //ASCII handled above case kCFStringEncodingDOSJapanese: return NSShiftJISStringEncoding; case kCFStringEncodingWindowsCyrillic: return NSWindowsCP1251StringEncoding; @@ -432,7 +435,10 @@ static void __collatorFinalize(UCollator *collator) { } __CFUnlock(&__CFDefaultCollatorLock); if (NULL != collator) ucol_close(collator); +#ifndef __clang_analyzer__ + // This release is unbalanced from perspective of analyzer, but it is retained when __CFTSDKeyCollatorLocale is set if (locale) CFRelease(locale); +#endif } #endif @@ -659,6 +665,9 @@ CF_PRIVATE CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer * bufferSize = range1.length + (kCFStringCompareAllocationIncrement - (range1.length % kCFStringCompareAllocationIncrement)); if (0 == buffer1Len) { buffer1 = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UTF16Char) * bufferSize, 0); + if (!buffer1) { + __CFStringHandleOutOfMemory(NULL); + } } else if (buffer1Len < range1.length) { buffer1 = __CFSafelyReallocateWithAllocator(kCFAllocatorSystemDefault, buffer1, sizeof(UTF16Char) * bufferSize, 0, NULL); } @@ -684,6 +693,9 @@ CF_PRIVATE CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer * bufferSize = range2.length + (kCFStringCompareAllocationIncrement - (range2.length % kCFStringCompareAllocationIncrement)); if (0 == buffer2Len) { buffer2 = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UTF16Char) * bufferSize, 0); + if (!buffer2) { + __CFStringHandleOutOfMemory(NULL); + } } else if (buffer2Len < range2.length) { buffer2 = __CFSafelyReallocateWithAllocator(kCFAllocatorSystemDefault, buffer2, sizeof(UTF16Char) * bufferSize, 0, NULL); } @@ -706,7 +718,14 @@ CF_PRIVATE CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer * } } else #endif - { + if ((NULL == characters1) || (NULL == characters2)) { + // We've reached here by producing invalid ranges for either string. + // + // If either range1 or range2 initially doesn't cover a valid portion of the corresponding characters buffer, CFStringGetCharactersPtrFromInlineBuffer will return NULL and we fall into this loop. + // Then, if either str1Range.location >= str1Max or str2Range.location >= str2Max (i.e. we got faulty input), then the matching range can't be advanced, and we won't attempt to allocate a new buffer. + // We'll then arrive here, and cannot reasonably perform the direct memcmp below. + HALT_MSG("Invalid string range produced for character buffer in _CFCompareStringsWithLocale."); + } else { order = memcmp(characters1, characters2, sizeof(UTF16Char) * ((range1.length < range2.length) ? range1.length : range2.length)); if (0 == order) { if (range1.length < range2.length) { @@ -742,7 +761,10 @@ CF_PRIVATE CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer * if (threadLocale) __collatorFinalize((UCollator *)_CFGetTSD(__CFTSDKeyCollatorUCollator)); // need to dealloc collators _CFSetTSD(__CFTSDKeyCollatorUCollator, collator, (void *)__collatorFinalize); +#ifndef __clang_analyzer__ + // This retain is unbalanced from perspective of analyzer, but it is released in __collatorFinalize _CFSetTSD(__CFTSDKeyCollatorLocale, (void *)CFRetain(compareLocale), NULL); +#endif } #endif diff --git a/CoreFoundation/String.subproj/CFString_Internal.h b/CoreFoundation/String.subproj/CFString_Internal.h index 9496b8ac4d..54778bf90c 100644 --- a/CoreFoundation/String.subproj/CFString_Internal.h +++ b/CoreFoundation/String.subproj/CFString_Internal.h @@ -1,7 +1,7 @@ /* CFString_Internal.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -10,12 +10,15 @@ #include #include #include +#include "CFInternal.h" CF_ASSUME_NONNULL_BEGIN CF_PRIVATE void __CFSetCharToUniCharFunc(CFStringEncodingCheapEightBitToUnicodeProc _Nullable func); CF_PRIVATE UniChar __CFCharToUniCharTable[256]; CF_PRIVATE CFIndex CFUniCharCompatibilityDecompose(UTF32Char *convertedChars, CFIndex length, CFIndex maxBufferLength); +__attribute__((cold)) +CF_PRIVATE void __CFStringHandleOutOfMemory(CFTypeRef _Nullable obj) CLANG_ANALYZER_NORETURN; CF_ASSUME_NONNULL_END diff --git a/CoreFoundation/StringEncodings.subproj/CFBuiltinConverters.c b/CoreFoundation/StringEncodings.subproj/CFBuiltinConverters.c index e0a9f52908..b551ecb658 100644 --- a/CoreFoundation/StringEncodings.subproj/CFBuiltinConverters.c +++ b/CoreFoundation/StringEncodings.subproj/CFBuiltinConverters.c @@ -1,7 +1,7 @@ /* CFBuiltinConverters.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFICUConverters.c b/CoreFoundation/StringEncodings.subproj/CFICUConverters.c index 12f78d3746..e59f668936 100644 --- a/CoreFoundation/StringEncodings.subproj/CFICUConverters.c +++ b/CoreFoundation/StringEncodings.subproj/CFICUConverters.c @@ -1,7 +1,7 @@ /* CFICUConverters.c - Copyright (c) 2004-2018, Apple Inc. and the Swift project authors + Copyright (c) 2004-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFICUConverters.h b/CoreFoundation/StringEncodings.subproj/CFICUConverters.h index 4827b29b5f..d6ab35467d 100644 --- a/CoreFoundation/StringEncodings.subproj/CFICUConverters.h +++ b/CoreFoundation/StringEncodings.subproj/CFICUConverters.h @@ -2,9 +2,9 @@ CFICUConverters.h CoreFoundation - Copyright (c) 2007-2018, Apple Inc. and the Swift project authors + Copyright (c) 2007-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFPlatformConverters.c b/CoreFoundation/StringEncodings.subproj/CFPlatformConverters.c index e9a0f525fe..177e03757a 100644 --- a/CoreFoundation/StringEncodings.subproj/CFPlatformConverters.c +++ b/CoreFoundation/StringEncodings.subproj/CFPlatformConverters.c @@ -1,7 +1,7 @@ /* CFPlatformConverters.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverter.c b/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverter.c index d2c615a005..6fb1cadb22 100644 --- a/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverter.c +++ b/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverter.c @@ -1,7 +1,7 @@ /* CFStringEncodingConverter.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -607,6 +607,7 @@ static const _CFEncodingConverter *__CFGetConverter(uint32_t encoding) { #warning This case must match __defaultEncoding value defined in CFString.c case kCFStringEncodingISOLatin1: commonConverterSlot = (const _CFEncodingConverter **)(&(commonConverters[1])); break; #endif + case kCFStringEncodingInvalidId: return NULL; default: if (CFStringGetSystemEncoding() == encoding) commonConverterSlot = (const _CFEncodingConverter **)&(commonConverters[2]); break; } diff --git a/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverter.h b/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverter.h index 3cdea7d2ba..2daf3fc185 100644 --- a/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverter.h +++ b/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverter.h @@ -1,7 +1,7 @@ /* CFStringEncodingConverter.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverterExt.h b/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverterExt.h index 41aefd3412..c990c3f637 100644 --- a/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverterExt.h +++ b/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverterExt.h @@ -1,7 +1,7 @@ /* CFStringEncodingConverterExt.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverterPriv.h b/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverterPriv.h index 6e03a01e29..0c5a867f9a 100644 --- a/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverterPriv.h +++ b/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverterPriv.h @@ -1,7 +1,7 @@ /* CFStringEncodingConverterPriv.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFStringEncodingDatabase.c b/CoreFoundation/StringEncodings.subproj/CFStringEncodingDatabase.c index 7ea1db96dd..edb70db6ed 100644 --- a/CoreFoundation/StringEncodings.subproj/CFStringEncodingDatabase.c +++ b/CoreFoundation/StringEncodings.subproj/CFStringEncodingDatabase.c @@ -1,7 +1,7 @@ /* CFStringEncodingDatabase.c - Copyright (c) 2005-2018, Apple Inc. and the Swift project authors + Copyright (c) 2005-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFStringEncodingDatabase.h b/CoreFoundation/StringEncodings.subproj/CFStringEncodingDatabase.h index e4ae4f486d..d9d8c07f23 100644 --- a/CoreFoundation/StringEncodings.subproj/CFStringEncodingDatabase.h +++ b/CoreFoundation/StringEncodings.subproj/CFStringEncodingDatabase.h @@ -2,9 +2,9 @@ CFStringEncodingDatabase.h CoreFoundation - Copyright (c) 2007-2018, Apple Inc. and the Swift project authors + Copyright (c) 2007-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFUniChar.c b/CoreFoundation/StringEncodings.subproj/CFUniChar.c index 7601a0e50a..2d7dd8b903 100644 --- a/CoreFoundation/StringEncodings.subproj/CFUniChar.c +++ b/CoreFoundation/StringEncodings.subproj/CFUniChar.c @@ -1,7 +1,7 @@ /* CFUniChar.c - Copyright (c) 2001-2018, Apple Inc. and the Swift project authors + Copyright (c) 2001-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -114,7 +114,9 @@ CF_INLINE void __CFUniCharCharacterSetPath(wchar_t *wpath) { #else #error Unknown or unspecified DEPLOYMENT_TARGET #endif -#if TARGET_OS_MAC || TARGET_OS_LINUX || TARGET_OS_BSD +#if TARGET_OS_MAC + strlcpy(cpath, __kCFCharacterSetDir, MAXPATHLEN); +#elif TARGET_OS_LINUX || TARGET_OS_BSD strlcpy(cpath, __kCFCharacterSetDir, MAXPATHLEN); #elif TARGET_OS_WIN32 wchar_t frameworkPath[MAXPATHLEN]; @@ -430,7 +432,7 @@ static char __CFUniCharUnicodeVersionString[8] = {0, 0, 0, 0, 0, 0, 0, 0}; static uint32_t __CFUniCharNumberOfBitmaps = 0; static __CFUniCharBitmapData *__CFUniCharBitmapDataArray = NULL; -static CFLock_t __CFUniCharBitmapLock = CFLockInit; +static os_unfair_lock __CFUniCharBitmapLock = OS_UNFAIR_LOCK_INIT; static bool __CFUniCharLoadBitmapData(void) { __CFUniCharBitmapData *array; @@ -444,10 +446,10 @@ static bool __CFUniCharLoadBitmapData(void) { int idx, bitmapIndex; int64_t fileSize; - __CFLock(&__CFUniCharBitmapLock); + os_unfair_lock_lock(&__CFUniCharBitmapLock); if (__CFUniCharBitmapDataArray || !__CFUniCharLoadFile(CF_UNICHAR_BITMAP_FILE, &bytes, &fileSize) || !__CFSimpleFileSizeVerification(bytes, fileSize)) { - __CFUnlock(&__CFUniCharBitmapLock); + os_unfair_lock_unlock(&__CFUniCharBitmapLock); return false; } @@ -495,7 +497,7 @@ static bool __CFUniCharLoadBitmapData(void) { __CFUniCharBitmapDataArray = array; - __CFUnlock(&__CFUniCharBitmapLock); + os_unfair_lock_unlock(&__CFUniCharBitmapLock); return true; } @@ -719,27 +721,27 @@ CF_PRIVATE uint32_t CFUniCharGetNumberOfPlanes(uint32_t charset) { // Mapping data loading static const void **__CFUniCharMappingTables = NULL; -static CFLock_t __CFUniCharMappingTableLock = CFLockInit; +static os_unfair_lock __CFUniCharMappingTableLock = OS_UNFAIR_LOCK_INIT; CF_PRIVATE const void *CFUniCharGetMappingData(uint32_t type) { - __CFLock(&__CFUniCharMappingTableLock); + os_unfair_lock_lock(&__CFUniCharMappingTableLock); if (NULL == __CFUniCharMappingTables) { const void *bytes; const void *bodyBase; - int headerSize; - int idx, count; + int32_t headerSize; + size_t idx, count; int64_t fileSize; if (!__CFUniCharLoadFile(MAPPING_TABLE_FILE, &bytes, &fileSize) || !__CFSimpleFileSizeVerification(bytes, fileSize)) { - __CFUnlock(&__CFUniCharMappingTableLock); + os_unfair_lock_unlock(&__CFUniCharMappingTableLock); return NULL; } #if defined (__cplusplus) - bytes = (uint8_t *)bytes + 4; // Skip Unicode version - headerSize = *((uint8_t *)bytes); bytes = (uint8_t *)bytes + sizeof(uint32_t); + bytes = (uint8_t *)bytes + 4; // Skip Unicode version + headerSize = *((uint8_t *)bytes); bytes = (uint8_t *)bytes + sizeof(uint32_t); #else bytes += 4; // Skip Unicode version headerSize = unaligned_load32(bytes); @@ -754,7 +756,7 @@ CF_PRIVATE const void *CFUniCharGetMappingData(uint32_t type) { for (idx = 0;idx < count;idx++) { #if defined (__cplusplus) - __CFUniCharMappingTables[idx] = (char *)bodyBase + *((uint32_t *)bytes); bytes = (uint8_t *)bytes + sizeof(uint32_t); + __CFUniCharMappingTables[idx] = (char *)bodyBase + *((uint32_t *)bytes); bytes = (uint8_t *)bytes + sizeof(uint32_t); #else __CFUniCharMappingTables[idx] = (char *)bodyBase + unaligned_load32(bytes); bytes += sizeof(uint32_t); @@ -762,7 +764,7 @@ CF_PRIVATE const void *CFUniCharGetMappingData(uint32_t type) { } } - __CFUnlock(&__CFUniCharMappingTableLock); + os_unfair_lock_unlock(&__CFUniCharMappingTableLock); return __CFUniCharMappingTables[type]; } @@ -812,10 +814,10 @@ static bool __CFUniCharLoadCaseMappingTable(void) { if (NULL == __CFUniCharMappingTables) (void)CFUniCharGetMappingData(kCFUniCharToLowercase); if (NULL == __CFUniCharMappingTables) return false; - __CFLock(&__CFUniCharMappingTableLock); + os_unfair_lock_lock(&__CFUniCharMappingTableLock); if (__CFUniCharCaseMappingTableCounts) { - __CFUnlock(&__CFUniCharMappingTableLock); + os_unfair_lock_unlock(&__CFUniCharMappingTableLock); return true; } @@ -831,7 +833,7 @@ static bool __CFUniCharLoadCaseMappingTable(void) { __CFUniCharCaseMappingTableCounts = countArray; - __CFUnlock(&__CFUniCharMappingTableLock); + os_unfair_lock_unlock(&__CFUniCharMappingTableLock); return true; } diff --git a/CoreFoundation/StringEncodings.subproj/CFUniChar.h b/CoreFoundation/StringEncodings.subproj/CFUniChar.h index e01ec6f53c..7da8d52ce6 100644 --- a/CoreFoundation/StringEncodings.subproj/CFUniChar.h +++ b/CoreFoundation/StringEncodings.subproj/CFUniChar.h @@ -1,7 +1,7 @@ /* CFUniChar.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFUniCharPriv.h b/CoreFoundation/StringEncodings.subproj/CFUniCharPriv.h index 66abedf924..d22b2279e5 100644 --- a/CoreFoundation/StringEncodings.subproj/CFUniCharPriv.h +++ b/CoreFoundation/StringEncodings.subproj/CFUniCharPriv.h @@ -1,7 +1,7 @@ /* CFUniCharPriv.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFUnicodeDecomposition.c b/CoreFoundation/StringEncodings.subproj/CFUnicodeDecomposition.c index 316a1bc28f..832a328831 100644 --- a/CoreFoundation/StringEncodings.subproj/CFUnicodeDecomposition.c +++ b/CoreFoundation/StringEncodings.subproj/CFUnicodeDecomposition.c @@ -1,7 +1,7 @@ /* CFUnicodeDecomposition.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -24,20 +24,20 @@ static UTF32Char *__CFUniCharMultipleDecompositionTable = NULL; static const uint8_t *__CFUniCharDecomposableBitmapForBMP = NULL; static const uint8_t *__CFUniCharHFSPlusDecomposableBitmapForBMP = NULL; -static CFLock_t __CFUniCharDecompositionTableLock = CFLockInit; +static os_unfair_lock __CFUniCharDecompositionTableLock = OS_UNFAIR_LOCK_INIT; static const uint8_t **__CFUniCharCombiningPriorityTable = NULL; static uint8_t __CFUniCharCombiningPriorityTableNumPlane = 0; static void __CFUniCharLoadDecompositionTable(void) { - __CFLock(&__CFUniCharDecompositionTableLock); + os_unfair_lock_lock(&__CFUniCharDecompositionTableLock); if (NULL == __CFUniCharDecompositionTable) { const uint32_t *bytes = (uint32_t *)CFUniCharGetMappingData(kCFUniCharCanonicalDecompMapping); if (NULL == bytes) { - __CFUnlock(&__CFUniCharDecompositionTableLock); + os_unfair_lock_unlock(&__CFUniCharDecompositionTableLock); return; } @@ -56,7 +56,7 @@ static void __CFUniCharLoadDecompositionTable(void) { for (idx = 0;idx < __CFUniCharCombiningPriorityTableNumPlane;idx++) __CFUniCharCombiningPriorityTable[idx] = (const uint8_t *)CFUniCharGetUnicodePropertyDataForPlane(kCFUniCharCombiningProperty, idx); } - __CFUnlock(&__CFUniCharDecompositionTableLock); + os_unfair_lock_unlock(&__CFUniCharDecompositionTableLock); } static CFLock_t __CFUniCharCompatibilityDecompositionTableLock = CFLockInit; diff --git a/CoreFoundation/StringEncodings.subproj/CFUnicodeDecomposition.h b/CoreFoundation/StringEncodings.subproj/CFUnicodeDecomposition.h index 10396d2dc8..ebe37e99be 100644 --- a/CoreFoundation/StringEncodings.subproj/CFUnicodeDecomposition.h +++ b/CoreFoundation/StringEncodings.subproj/CFUnicodeDecomposition.h @@ -3,9 +3,9 @@ CoreFoundation Created by aki on Wed Oct 03 2001. - Copyright (c) 2001-2018, Apple Inc. and the Swift project authors + Copyright (c) 2001-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFUnicodePrecomposition.c b/CoreFoundation/StringEncodings.subproj/CFUnicodePrecomposition.c index 6051edf9e5..88776c45ef 100644 --- a/CoreFoundation/StringEncodings.subproj/CFUnicodePrecomposition.c +++ b/CoreFoundation/StringEncodings.subproj/CFUnicodePrecomposition.c @@ -1,7 +1,7 @@ /* CFUnicodePrecomposition.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFUnicodePrecomposition.h b/CoreFoundation/StringEncodings.subproj/CFUnicodePrecomposition.h index cb00434039..3fc32c9c43 100644 --- a/CoreFoundation/StringEncodings.subproj/CFUnicodePrecomposition.h +++ b/CoreFoundation/StringEncodings.subproj/CFUnicodePrecomposition.h @@ -3,9 +3,9 @@ CoreFoundation Created by aki on Wed Oct 03 2001. - Copyright (c) 2001-2018, Apple Inc. and the Swift project authors + Copyright (c) 2001-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/URL.subproj/CFURL.c b/CoreFoundation/URL.subproj/CFURL.c index bc4ebfbc29..f7c934ecbd 100644 --- a/CoreFoundation/URL.subproj/CFURL.c +++ b/CoreFoundation/URL.subproj/CFURL.c @@ -1,7 +1,7 @@ /* CFURL.c - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -14,7 +14,9 @@ #include #include "CFInternal.h" #include "CFRuntime_Internal.h" +#include #include +#include #include #include #include @@ -181,7 +183,7 @@ struct __CFURL { CFRuntimeBase _cfBase; UInt32 _flags; CFStringEncoding _encoding; // The encoding to use when asked to remove percent escapes - CFStringRef _string; // Never NULL + _Atomic(CFStringRef) _string; // Never NULL CFURLRef _base; struct _CFURLAdditionalData* _extra; _Atomic(void *)_resourceInfo; // For use by CoreServicesInternal to cache property values. Retained and released by CFURL. @@ -525,10 +527,6 @@ CF_INLINE Boolean _translateBytes(UniChar ch1, UniChar ch2, uint8_t *result) { return true; } -CF_INLINE Boolean _haveTestedOriginalString(CFURLRef url) { - return ((url->_flags & ORIGINAL_AND_URL_STRINGS_MATCH) != 0) || (_getSanitizedString(url) != NULL); -} - enum { IS_PCHAR = 0x01, }; @@ -1160,6 +1158,7 @@ CFStringRef CFURLCreateStringByReplacingPercentEscapes(CFAllocatorRef alloc, CF } else { numBytesExpected = 4; } + _CLANG_ANALYZER_IGNORE_UNINITIALIZED_BUFFER(bytes, numBytesExpected * sizeof(char)); // The static analyzer doesn't understand _translateBytes. if (numBytesExpected == 1) { // one byte sequence (most common case); handle this specially escapedChar = bytes[0]; @@ -1644,8 +1643,7 @@ static void __CFURLDeallocate(CFTypeRef cf) { if (url->_string) CFRelease(url->_string); ((struct __CFURL *)url)->_string = (void *)0xdeadbeef; // 28124664: catch anyone using URL after it was released if (url->_base) CFRelease(url->_base); - CFStringRef sanitizedString = _getSanitizedString(url); - if (sanitizedString) CFRelease(sanitizedString); + if (url->_extra && url->_extra->_sanitizedString) CFRelease(url->_extra->_sanitizedString); if ( url->_extra != NULL ) CFAllocatorDeallocate( alloc, url->_extra ); void *resourceInfo = _getResourceInfo(url); #if DEPLOYMENT_RUNTIME_SWIFT @@ -1919,12 +1917,7 @@ static struct __CFURL * _CFURLAlloc(CFAllocatorRef allocator, uint8_t numberOfRa CFIndex extraBytes = offsetof(struct __CFURL, _ranges[numberOfRanges]) - sizeof(CFRuntimeBase); url = (struct __CFURL *)_CFRuntimeCreateInstance(allocator, CFURLGetTypeID(), extraBytes, NULL); if (url) { - url->_flags = 0; url->_encoding = kCFStringEncodingUTF8; - url->_string = NULL; - url->_base = NULL; - url->_extra = NULL; - atomic_store(&url->_resourceInfo, NULL); } return url; } @@ -2084,6 +2077,10 @@ static CFURLRef _CFURLCreateWithURLString(CFAllocatorRef allocator, CFStringRef #endif } } + // call computeSanitizedString now so it doesn't cause thread safety problems later + if ( result ) { + computeSanitizedString(result); + } #if DEBUG_URL_INITIALIZER_LOGGING CFLog(kCFLogLevelError, CFSTR("_CFURLCreateWithURLString (in) string '%@', checkForLegalCharacters %@, baseURL %@\n\t_CFURLCreateWithURLString (out) result %@, resultBaseURL %@"), input_string, input_checkForLegalCharacters ? CFSTR("YES") : CFSTR("NO"), input_baseURL, result ? CFURLGetString(result) : CFSTR("(null)"), result ? (result->_base ? CFURLGetString(result->_base) : CFSTR("(null)")) : CFSTR("(null)") ); if ( input_string ) { @@ -2522,8 +2519,8 @@ CFURLRef CFURLCreateAbsoluteURLWithBytes(CFAllocatorRef alloc, const UInt8 *rela if ( CFStringGetLength(relativeString) > 0 ) { ch = CFStringGetCharacterAtIndex(relativeString, 0); } - if (ch == '?' || ch == ';' || ch == '#') { - // Nothing but parameter + query + fragment; append to the baseURL string + if ( (ch == '?') || (ch == '#') // Nothing but query + fragment; append to the baseURL string + ) { CFStringRef baseString; if (CF_IS_OBJC(CFURLGetTypeID(), baseURL)) { baseString = CFURLGetString(baseURL); @@ -2664,7 +2661,7 @@ static CFStringRef _resolvedPath(UniChar *pathStr, UniChar *end, UniChar pathDel } } } else if (stripLeadingDotDots) { - if (idx + 3 != end) { + if (idx + 3 < end) { unsigned numCharsToMove = end - (idx + 3) + 1; memmove(idx, idx+3, numCharsToMove * sizeof(UniChar)); end -= 3; @@ -2735,15 +2732,21 @@ static CFMutableStringRef resolveAbsoluteURLStringBuffer(CFAllocatorRef alloc, C } else { // FIXME: Get rid of this allocation UniChar *newPathBuf = (UniChar *)CFAllocatorAllocate(alloc, sizeof(UniChar) * (relPathRg.length + basePathRg.length + 1), 0); - UniChar *idx, *end; - CFStringGetCharacters(baseString, basePathRg, newPathBuf); - idx = newPathBuf + basePathRg.length - 1; - while (idx != newPathBuf && *idx != '/') idx --; - if (*idx == '/') idx ++; - CFStringGetCharacters(relString, relPathRg, idx); - end = idx + relPathRg.length; - *end = 0; - newPath = _resolvedPath(newPathBuf, end, '/', false, false, alloc); + if ( newPathBuf ) { + UniChar *idx, *end; + CFStringGetCharacters(baseString, basePathRg, newPathBuf); + idx = newPathBuf + basePathRg.length - 1; + while (idx != newPathBuf && *idx != '/') idx --; + if (*idx == '/') idx ++; + CFStringGetCharacters(relString, relPathRg, idx); + end = idx + relPathRg.length; + *end = 0; + newPath = _resolvedPath(newPathBuf, end, '/', false, false, alloc); + } + else { + CFStringReleaseAppendBuffer(&appendBuffer); + return NULL; + } } /* Under Win32 absolute path can begin with letter * so we have to add one '/' to the newString @@ -2939,9 +2942,6 @@ Boolean CFURLCanBeDecomposed(CFURLRef anURL) { CFStringRef CFURLGetString(CFURLRef url) { CF_OBJC_FUNCDISPATCHV(CFURLGetTypeID(), CFStringRef, (NSURL *)url, relativeString); - if (!_haveTestedOriginalString(url)) { - computeSanitizedString(url); - } if (url->_flags & ORIGINAL_AND_URL_STRINGS_MATCH) { return url->_string; } else { @@ -3032,9 +3032,6 @@ static CFStringRef _retainedComponentString(CFURLRef url, UInt32 compFlag, Boole } if (comp && !fromOriginalString) { - if (!_haveTestedOriginalString(url)) { - computeSanitizedString(url); - } if (!(url->_flags & ORIGINAL_AND_URL_STRINGS_MATCH) && (_getAdditionalDataFlags(url) & compFlag)) { CFStringRef newComp = correctedComponent(comp, compFlag, url->_encoding); CFRelease(comp); @@ -3133,9 +3130,6 @@ CFStringRef CFURLCopyNetLocation(CFURLRef anURL) { // We provide the net location CFRange netRg = _netLocationRange(anURL->_flags, anURL->_ranges); CFStringRef netLoc; - if (!_haveTestedOriginalString(anURL)) { - computeSanitizedString(anURL); - } if (!(anURL->_flags & ORIGINAL_AND_URL_STRINGS_MATCH) && (_getAdditionalDataFlags(anURL) & (USER_DIFFERS | PASSWORD_DIFFERS | HOST_DIFFERS | PORT_DIFFERS))) { // Only thing that can come before the net location is the scheme. It's impossible for the scheme to contain percent escapes. Therefore, we can use the location of netRg in _sanitizedString, just not the length. CFRange netLocEnd; @@ -3215,9 +3209,6 @@ CFStringRef CFURLCopyResourceSpecifier(CFURLRef anURL) { if (!(anURL->_flags & IS_DECOMPOSABLE)) { CFRange schemeRg = _rangeForComponent(anURL->_flags, anURL->_ranges, HAS_SCHEME); CFIndex base = schemeRg.location + schemeRg.length + 1; - if (!_haveTestedOriginalString(anURL)) { - computeSanitizedString(anURL); - } CFStringRef sanitizedString = _getSanitizedString(anURL); @@ -3234,9 +3225,6 @@ CFStringRef CFURLCopyResourceSpecifier(CFURLRef anURL) { Boolean canUseOriginalString = true; Boolean canUseSanitizedString = true; CFAllocatorRef alloc = CFGetAllocator(anURL); - if (!_haveTestedOriginalString(anURL)) { - computeSanitizedString(anURL); - } UInt32 additionalDataFlags = _getAdditionalDataFlags(anURL); CFStringRef sanitizedString = _getSanitizedString(anURL); @@ -3294,6 +3282,7 @@ CFStringRef CFURLCopyResourceSpecifier(CFURLRef anURL) { // For the next four methods, it is important to realize that, if a URL supplies any part of the net location (host, user, port, or password), it must supply all of the net location (i.e. none of it comes from its base URL). Also, it is impossible for a URL to be relative, supply none of the net location, and still have its (empty) net location take precedence over its base URL (because there's nothing that precedes the net location except the scheme, and if the URL supplied the scheme, it would be absolute, and there would be no base). CFStringRef CFURLCopyHostName(CFURLRef anURL) { + assert(anURL); CFStringRef tmp; if (CF_IS_OBJC(CFURLGetTypeID(), anURL)) { tmp = (CFStringRef) CF_OBJC_CALLV((NSURL *)anURL, host); @@ -3320,6 +3309,7 @@ CFStringRef CFURLCopyHostName(CFURLRef anURL) { // Return -1 to indicate no port is specified SInt32 CFURLGetPortNumber(CFURLRef anURL) { + assert(anURL); CFStringRef port; if (CF_IS_OBJC(CFURLGetTypeID(), anURL)) { CFNumberRef cfPort = (CFNumberRef) CF_OBJC_CALLV((NSURL *)anURL, port); @@ -3347,6 +3337,7 @@ SInt32 CFURLGetPortNumber(CFURLRef anURL) { } CFStringRef CFURLCopyUserName(CFURLRef anURL) { + assert(anURL); CFStringRef user; if (CF_IS_OBJC(CFURLGetTypeID(), anURL)) { user = (CFStringRef) CF_OBJC_CALLV((NSURL *)anURL, user); @@ -3365,6 +3356,7 @@ CFStringRef CFURLCopyUserName(CFURLRef anURL) { } CFStringRef CFURLCopyPassword(CFURLRef anURL) { + assert(anURL); CFStringRef passwd; if (CF_IS_OBJC(CFURLGetTypeID(), anURL)) { passwd = (CFStringRef) CF_OBJC_CALLV((NSURL *)anURL, password); @@ -3384,43 +3376,16 @@ CFStringRef CFURLCopyPassword(CFURLRef anURL) { // The NSURL methods do not deal with escaping escape characters at all; therefore, in order to properly bridge NSURL methods, and still provide the escaping behavior that we want, we need to create functions that match the ObjC behavior exactly, and have the public CFURL... functions call these. -- REW, 10/29/98 -static CFStringRef _unescapedParameterString(CFURLRef anURL) CF_RETURNS_RETAINED { - CFStringRef str; - if (CF_IS_OBJC(CFURLGetTypeID(), anURL)) { - str = (CFStringRef) CF_OBJC_CALLV((NSURL *)anURL, parameterString); - if (str) CFRetain(str); - return str; - } - __CFGenericValidateType(anURL, CFURLGetTypeID()); - str = _retainedComponentString(anURL, HAS_PARAMETERS, false, false); - if (str) return str; - if (!(anURL->_flags & IS_DECOMPOSABLE)) return NULL; - if (!anURL->_base || (anURL->_flags & (NET_LOCATION_MASK | HAS_PATH | HAS_SCHEME))) { - return NULL; - // Parameter string definitely coming from the relative portion of the URL - } - return _unescapedParameterString( anURL->_base); -} - CFStringRef CFURLCopyParameterString(CFURLRef anURL, CFStringRef charactersToLeaveEscaped) { - CFStringRef param = _unescapedParameterString(anURL); - if (param) { - CFStringRef result; - if (anURL->_encoding == kCFStringEncodingUTF8) { - result = CFURLCreateStringByReplacingPercentEscapes(CFGetAllocator(anURL), param, charactersToLeaveEscaped); - } else { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - result = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(CFGetAllocator(anURL), param, charactersToLeaveEscaped, anURL->_encoding); -#pragma GCC diagnostic pop - } - CFRelease(param); - return result; - } + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + os_log_debug(_CFOSLog(), "CFURLCopyParameterString is deprecated and now always returns NULL. The path component now includes the part of the URL string which CFURLCopyParameterString used to return.\nURL = %{private}@", anURL); + }); return NULL; } static CFStringRef _unescapedQueryString(CFURLRef anURL) CF_RETURNS_RETAINED { + assert(anURL); CFStringRef str; if (CF_IS_OBJC(CFURLGetTypeID(), anURL)) { str = (CFStringRef) CF_OBJC_CALLV((NSURL *)anURL, query); @@ -3431,7 +3396,8 @@ static CFStringRef _unescapedQueryString(CFURLRef anURL) CF_RETURNS_RETAINED { str = _retainedComponentString(anURL, HAS_QUERY, false, false); if (str) return str; if (!(anURL->_flags & IS_DECOMPOSABLE)) return NULL; - if (!anURL->_base || (anURL->_flags & (HAS_SCHEME | NET_LOCATION_MASK | HAS_PATH | HAS_PARAMETERS))) { + UInt32 flagsToCheck = (HAS_SCHEME | NET_LOCATION_MASK | HAS_PATH); + if (!anURL->_base || (anURL->_flags & flagsToCheck)) { return NULL; } return _unescapedQueryString(anURL->_base); @@ -3552,7 +3518,7 @@ static CFRange _CFURLGetCharRangeForMask(CFURLRef url, CFOptionFlags mask, CFRan } static CFRange _getCharRangeInDecomposableURL(CFURLRef url, CFURLComponentType component, CFRange *rangeIncludingSeparators) { - CFOptionFlags mask; + CFOptionFlags mask = 0; switch (component) { case kCFURLComponentScheme: mask = HAS_SCHEME; @@ -3581,9 +3547,6 @@ static CFRange _getCharRangeInDecomposableURL(CFURLRef url, CFURLComponentType c case kCFURLComponentPort: mask = HAS_PORT; break; - case kCFURLComponentParameterString: - mask = HAS_PARAMETERS; - break; case kCFURLComponentQuery: mask = HAS_QUERY; break; @@ -3725,10 +3688,6 @@ static CFURLRef composeFromNonHierarchical(CFAllocatorRef alloc, const CFURLComp static Boolean decomposeToRFC1808(CFURLRef url, CFURLComponentsRFC1808 *components) { CFAllocatorRef alloc = CFGetAllocator(url); - static CFStringRef emptyStr = NULL; - if (!emptyStr) { - emptyStr = CFSTR(""); - } if (!CFURLCanBeDecomposed(url)) { return false; @@ -3756,7 +3715,7 @@ static Boolean decomposeToRFC1808(CFURLRef url, CFURLComponentsRFC1808 *componen } else { components->port = kCFNotFound; } - components->parameterString = _retainedComponentString(url, HAS_PARAMETERS, false, false); + components->parameterString = NULL; components->query = _retainedComponentString(url, HAS_QUERY, false, false); components->fragment = _retainedComponentString(url, HAS_FRAGMENT, false, false); return true; @@ -4224,7 +4183,7 @@ static Boolean CanonicalFileURLStringToFileSystemRepresentation(CFStringRef str, extern CFStringRef CFCreateWindowsDrivePathFromVolumeName(CFStringRef volNameStr); #endif -static CFStringRef URLPathToWindowsPath(CFStringRef path, CFAllocatorRef allocator, CFStringEncoding encoding) { +static CFStringRef URLPathToWindowsPath(CFStringRef path, CFAllocatorRef allocator, CFStringEncoding encoding) CF_RETURNS_RETAINED { // Check for a drive letter, then flip all the slashes CFStringRef result; CFArrayRef tmp = CFStringCreateArrayBySeparatingStrings(allocator, path, CFSTR("/")); @@ -4349,6 +4308,7 @@ CFURLRef CFURLCreateWithFileSystemPath(CFAllocatorRef allocator, CFStringRef fil return ( result ); } + CF_EXPORT CFURLRef CFURLCreateWithFileSystemPathRelativeToBase(CFAllocatorRef allocator, CFStringRef filePath, CFURLPathStyle fsType, Boolean isDirectory, CFURLRef baseURL) { CFURLRef result; @@ -5122,7 +5082,7 @@ CFURLRef _CFURLCreateFromPropertyListRepresentation(CFAllocatorRef alloc, CFProp CFDictionaryRef dict = (CFDictionaryRef)pListRepresentation; // Start by getting all the pieces and verifying they're of the correct type. - if (CFGetTypeID(pListRepresentation) != CFDictionaryGetTypeID()) { + if (CFGetTypeID(pListRepresentation) != _kCFRuntimeIDCFDictionary) { return NULL; } string = (CFStringRef)CFDictionaryGetValue(dict, CFSTR("_CFURLString")); diff --git a/CoreFoundation/URL.subproj/CFURL.h b/CoreFoundation/URL.subproj/CFURL.h index 169ca8b4e7..e0390929f7 100644 --- a/CoreFoundation/URL.subproj/CFURL.h +++ b/CoreFoundation/URL.subproj/CFURL.h @@ -1,7 +1,7 @@ /* CFURL.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -254,8 +254,7 @@ CFStringRef CFURLCopyPassword(CFURLRef anURL); /* corresponding characters. If charactersToLeaveEscaped is NULL, */ /* then no escape sequences are removed at all */ CF_EXPORT -CFStringRef CFURLCopyParameterString(CFURLRef anURL, CFStringRef charactersToLeaveEscaped); - +CFStringRef CFURLCopyParameterString(CFURLRef anURL, CFStringRef charactersToLeaveEscaped) API_DEPRECATED("The CFURLCopyParameterString function is deprecated. Post deprecation for applications linked with or after the macOS 10.15, and for all iOS, watchOS, and tvOS applications, CFURLCopyParameterString will always return NULL, and the CFURLCopyPath(), CFURLCopyStrictPath(), and CFURLCopyFileSystemPath() functions will return the complete path including the semicolon separator and params component if the URL string contains them.", macosx(10.2,10.15), ios(2.0,13.0), watchos(2.0,6.0), tvos(9.0,13.0)); CF_EXPORT CFStringRef CFURLCopyQueryString(CFURLRef anURL, CFStringRef charactersToLeaveEscaped); @@ -403,7 +402,7 @@ CF_EXPORT CFStringRef CFURLCreateStringByAddingPercentEscapes(CFAllocatorRef allocator, CFStringRef originalString, CFStringRef charactersToLeaveUnescaped, CFStringRef legalURLCharactersToBeEscaped, CFStringEncoding encoding) API_DEPRECATED("Use [NSString stringByAddingPercentEncodingWithAllowedCharacters:] instead, which always uses the recommended UTF-8 encoding, and which encodes for a specific URL component or subcomponent (since each URL component or subcomponent has different rules for what characters are valid).", macos(10.0,10.11), ios(2.0,9.0), watchos(2.0,2.0), tvos(9.0,9.0)); -#if (TARGET_OS_MAC || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) || CF_BUILDING_CF || NSBUILDINGFOUNDATION +#if TARGET_OS_MAC || CF_BUILDING_CF || NSBUILDINGFOUNDATION CF_IMPLICIT_BRIDGING_DISABLED /* @@ -470,7 +469,7 @@ CF_IMPLICIT_BRIDGING_ENABLED -#if (TARGET_OS_MAC || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) || CF_BUILDING_CF || NSBUILDINGFOUNDATION || DEPLOYMENT_RUNTIME_SWIFT +#if TARGET_OS_MAC || CF_BUILDING_CF || NSBUILDINGFOUNDATION || DEPLOYMENT_RUNTIME_SWIFT CF_IMPLICIT_BRIDGING_DISABLED /* Resource access @@ -837,7 +836,7 @@ const CFStringRef kCFURLDocumentIdentifierKey API_AVAILABLE(macos(10.10), ios(8. CF_EXPORT const CFStringRef kCFURLAddedToDirectoryDateKey API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); - /* The date the resource was created, or renamed into or within its parent directory. Note that inconsistent behavior may be observed when this attribute is requested on hard-linked items. This property is not supported by all volumes. (Read-only, value type CFDate) */ + /* The date the resource was created, or renamed into or within its parent directory. Note that inconsistent behavior may be observed when this attribute is requested on hard-linked items. This property is not supported by all volumes. (Read-only before macOS 10.15, iOS 13.0, watchOS 6.0, and tvOS 13.0; Read-write after, value type CFDate) */ CF_EXPORT const CFStringRef kCFURLQuarantinePropertiesKey API_AVAILABLE(macos(10.10)) API_UNAVAILABLE(ios, watchos, tvos); @@ -1143,17 +1142,18 @@ const CFStringRef kCFURLUbiquitousItemDownloadingStatusCurrent API_AVAILABLE(mac typedef CF_OPTIONS(CFOptionFlags, CFURLBookmarkCreationOptions) { kCFURLBookmarkCreationMinimalBookmarkMask = ( 1UL << 9 ), // creates bookmark data with "less" information, which may be smaller but still be able to resolve in certain ways kCFURLBookmarkCreationSuitableForBookmarkFile = ( 1UL << 10 ), // include the properties required by CFURLWriteBookmarkDataToFile() in the bookmark data created - kCFURLBookmarkCreationWithSecurityScope CF_ENUM_AVAILABLE(10_7, NA) = ( 1UL << 11 ), // Mac OS X 10.7.3 and later, include information in the bookmark data which allows the same sandboxed process to access the resource after being relaunched - kCFURLBookmarkCreationSecurityScopeAllowOnlyReadAccess CF_ENUM_AVAILABLE(10_7, NA) = ( 1UL << 12 ), // Mac OS X 10.7.3 and later, if used with kCFURLBookmarkCreationWithSecurityScope, at resolution time only read access to the resource will be granted + kCFURLBookmarkCreationWithSecurityScope API_AVAILABLE(macos(10.7)) API_UNAVAILABLE(ios, watchos, tvos) = ( 1UL << 11 ), // Mac OS X 10.7.3 and later, include information in the bookmark data which allows the same sandboxed process to access the resource after being relaunched + kCFURLBookmarkCreationSecurityScopeAllowOnlyReadAccess API_AVAILABLE(macos(10.7)) API_UNAVAILABLE(ios, watchos, tvos) = ( 1UL << 12 ), // Mac OS X 10.7.3 and later, if used with kCFURLBookmarkCreationWithSecurityScope, at resolution time only read access to the resource will be granted // deprecated - kCFURLBookmarkCreationPreferFileIDResolutionMask CF_ENUM_DEPRECATED(10_6, 10_9, 4_0, 7_0, "kCFURLBookmarkCreationPreferFileIDResolutionMask does nothing and has no effect on bookmark resolution" ) = ( 1UL << 8 ), + kCFURLBookmarkCreationPreferFileIDResolutionMask + API_DEPRECATED("kCFURLBookmarkCreationPreferFileIDResolutionMask does nothing and has no effect on bookmark resolution", macos(10.6,10.9), ios(4.0,7.0)) = ( 1UL << 8 ), } API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); typedef CF_OPTIONS(CFOptionFlags, CFURLBookmarkResolutionOptions) { kCFURLBookmarkResolutionWithoutUIMask = ( 1UL << 8 ), // don't perform any user interaction during bookmark resolution kCFURLBookmarkResolutionWithoutMountingMask = ( 1UL << 9 ), // don't mount a volume during bookmark resolution - kCFURLBookmarkResolutionWithSecurityScope CF_ENUM_AVAILABLE(10_7, NA) = ( 1UL << 10 ), // Mac OS X 10.7.3 and later, use the secure information included at creation time to provide the ability to access the resource in a sandboxed process. + kCFURLBookmarkResolutionWithSecurityScope API_AVAILABLE(macos(10.7)) API_UNAVAILABLE(ios, watchos, tvos) = ( 1UL << 10 ), // Mac OS X 10.7.3 and later, use the secure information included at creation time to provide the ability to access the resource in a sandboxed process. kCFBookmarkResolutionWithoutUIMask = kCFURLBookmarkResolutionWithoutUIMask, kCFBookmarkResolutionWithoutMountingMask = kCFURLBookmarkResolutionWithoutMountingMask, @@ -1211,7 +1211,7 @@ CF_EXPORT void CFURLStopAccessingSecurityScopedResource(CFURLRef url) API_AVAILABLE(macos(10.7), ios(8.0), watchos(2.0), tvos(9.0)); // On OSX, available in MacOS X 10.7.3 and later #endif /* !DEPLOYMENT_TARGET_SWIFT */ -#endif /* TARGET_OS_MAC || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || DEPLOYMENT_TARGET_SWIFT */ +#endif /* TARGET_OS_MAC || CF_BUILDING_CF || NSBUILDINGFOUNDATION || DEPLOYMENT_RUNTIME_SWIFT */ CF_EXTERN_C_END CF_IMPLICIT_BRIDGING_DISABLED diff --git a/CoreFoundation/URL.subproj/CFURL.inc.h b/CoreFoundation/URL.subproj/CFURL.inc.h index 490d1f1b9c..cee0c97c88 100644 --- a/CoreFoundation/URL.subproj/CFURL.inc.h +++ b/CoreFoundation/URL.subproj/CFURL.inc.h @@ -1,7 +1,7 @@ /* CFURL.inc.h - Copyright (c) 2012-2018, Apple Inc. and the Swift project authors + Copyright (c) 2012-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -65,42 +65,47 @@ } } // 2: parse the scheme - for (idx = base_idx; idx < string_length; idx++) { - UniChar ch = characterArray[idx]; - if (':' == ch) { - flags |= HAS_SCHEME; - unpackedRanges[scheme_index].location = base_idx; - unpackedRanges[scheme_index].length = idx; - numRanges ++; - base_idx = idx + 1; - // optimization for ftp urls - if (idx == 3 && characterArray[0] == 'f' && characterArray[1] == 't' && characterArray[2] == 'p') { - _setSchemeTypeInFlags(&flags, kHasFtpScheme); - } - else if (idx == 4) { - // optimization for http urls - if (characterArray[0] == 'h' && characterArray[1] == 't' && characterArray[2] == 't' && characterArray[3] == 'p') { - _setSchemeTypeInFlags(&flags, kHasHttpScheme); + // Make sure the first character is an ALPHA character (schemes must start with ALPHA character), + // or the first character is a colon (this non-compliant parser has always returned "" for the scheme if the URL string starts with a colon) + UniChar firstCh = (string_length > 0) ? characterArray[base_idx] : 0; + if ( (scheme_valid(firstCh) && (firstCh >= 'A')) || (firstCh == ':') ) { + for (idx = base_idx; idx < string_length; idx++) { + UniChar ch = characterArray[idx]; + if (':' == ch) { + flags |= HAS_SCHEME; + unpackedRanges[scheme_index].location = base_idx; + unpackedRanges[scheme_index].length = idx; + numRanges ++; + base_idx = idx + 1; + // optimization for ftp urls + if (idx == 3 && characterArray[0] == 'f' && characterArray[1] == 't' && characterArray[2] == 'p') { + _setSchemeTypeInFlags(&flags, kHasFtpScheme); } - // optimization for file urls - if (characterArray[0] == 'f' && characterArray[1] == 'i' && characterArray[2] == 'l' && characterArray[3] == 'e') { - _setSchemeTypeInFlags(&flags, kHasFileScheme); + else if (idx == 4) { + // optimization for http urls + if (characterArray[0] == 'h' && characterArray[1] == 't' && characterArray[2] == 't' && characterArray[3] == 'p') { + _setSchemeTypeInFlags(&flags, kHasHttpScheme); + } + // optimization for file urls + if (characterArray[0] == 'f' && characterArray[1] == 'i' && characterArray[2] == 'l' && characterArray[3] == 'e') { + _setSchemeTypeInFlags(&flags, kHasFileScheme); + } + // optimization for data urls + if (characterArray[0] == 'd' && characterArray[1] == 'a' && characterArray[2] == 't' && characterArray[3] == 'a') { + _setSchemeTypeInFlags(&flags, kHasDataScheme); + } } - // optimization for data urls - if (characterArray[0] == 'd' && characterArray[1] == 'a' && characterArray[2] == 't' && characterArray[3] == 'a') { - _setSchemeTypeInFlags(&flags, kHasDataScheme); + // optimization for https urls + else if (idx == 5 && characterArray[0] == 'h' && characterArray[1] == 't' && characterArray[2] == 't' && characterArray[3] == 'p' && characterArray[4] == 's') { + _setSchemeTypeInFlags(&flags, kHasHttpsScheme); } + break; + } else if (!scheme_valid(ch)) { + break; // invalid scheme character -- no scheme } - // optimization for https urls - else if (idx == 5 && characterArray[0] == 'h' && characterArray[1] == 't' && characterArray[2] == 't' && characterArray[3] == 'p' && characterArray[4] == 's') { - _setSchemeTypeInFlags(&flags, kHasHttpsScheme); - } - break; - } else if (!scheme_valid(ch)) { - break; // invalid scheme character -- no scheme } } - + // Make sure we have an RFC-1808 compliant URL - that's either something without a scheme, or scheme:/(stuff) or scheme://(stuff) // Strictly speaking, RFC 1808 & 2396 bar "scheme:" (with nothing following the colon); however, common usage // expects this to be treated identically to "scheme://" - REW, 12/08/03 @@ -212,17 +217,8 @@ } // 5: parse the parameters; remainder after left-most ";" is parameters - for (idx = base_idx; idx < string_length; idx++) { - if (';' == characterArray[idx]) { - flags |= HAS_PARAMETERS; - numRanges ++; - unpackedRanges[parameters_index].location = idx + 1; - unpackedRanges[parameters_index].length = string_length - (idx+1); - string_length = idx; // remove parameters from parse string - break; - } - } - + // parameters are deprecated and obsolete. What used to be parameter is part of the path. + // 6: parse the path; it's whatever's left between string_length & base_idx if (string_length - base_idx != 0 || (flags & NET_LOCATION_MASK)) { diff --git a/CoreFoundation/URL.subproj/CFURLAccess.c b/CoreFoundation/URL.subproj/CFURLAccess.c index 2cb4189f1b..e2b04f915f 100644 --- a/CoreFoundation/URL.subproj/CFURLAccess.c +++ b/CoreFoundation/URL.subproj/CFURLAccess.c @@ -1,7 +1,7 @@ /* CFURLAccess.c - Copyright (c) 1999-2018, Apple Inc. and the Swift project authors + Copyright (c) 1999-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -318,7 +318,7 @@ const CFStringRef kCFDataURLTextEncodingName; /* kCFDataURLTextEncodingName is a CFString. */ /* REMINDSMZ: From CFURLResponse.c */ -static CFStringRef mimeTypeFromContentTypeComponent(CFStringRef component) { +static CFStringRef createMimeTypeFromContentTypeComponent(CFStringRef component) { CFIndex compLen = CFStringGetLength(component); CFStringInlineBuffer buf; CFIndex idx; @@ -354,7 +354,7 @@ static CFStringRef mimeTypeFromContentTypeComponent(CFStringRef component) { } /* REMINDSMZ: From CFURLResponse.c */ -static CFStringRef charsetFromContentTypeHeader(CFStringRef contentType) { +static CFStringRef createCharsetFromContentTypeHeader(CFStringRef contentType) { // FIXME: Should this use KeyValuePair parsing to handle quoting properly? CFRange range; CFIndex compLen = CFStringGetLength(contentType); @@ -484,7 +484,7 @@ static UInt8 base64DigitValue(char c) } } -static CFDataRef base64DecodeData(CFAllocatorRef alloc, CFDataRef data) +static CFDataRef _createBase64DecodedData(CFAllocatorRef alloc, CFDataRef data) { const UInt8 *srcBuffer = CFDataGetBytePtr(data); CFIndex length = CFDataGetLength(data); @@ -535,7 +535,7 @@ static CFDataRef base64DecodeData(CFAllocatorRef alloc, CFDataRef data) return result; } -static inline CFStringRef percentExpandAndTrimContentType(CFAllocatorRef alloc, CFStringRef str, CFRange range) +static inline CFStringRef createPercentExpandAndTrimContentType(CFAllocatorRef alloc, CFStringRef str, CFRange range) { CFMutableStringRef contentTypeHeader = NULL; CFStringRef contentTypeUnexpanded = CFStringCreateWithSubstring(alloc, str, range); @@ -562,9 +562,9 @@ static Boolean parseDataRequestURL(CFURLRef url, CFDataRef* outData, CFStringRef CFRange commaRange = CFStringFind(str, CFSTR(","), 0); if (commaRange.location != kCFNotFound) { - CFStringRef contentTypeHeader = percentExpandAndTrimContentType(alloc, str, CFRangeMake(0, commaRange.location)); - CFStringRef mimeType = mimeTypeFromContentTypeComponent(contentTypeHeader); - CFStringRef textEncodingName = charsetFromContentTypeHeader(contentTypeHeader); + CFStringRef contentTypeHeader = createPercentExpandAndTrimContentType(alloc, str, CFRangeMake(0, commaRange.location)); + CFStringRef mimeType = createMimeTypeFromContentTypeComponent(contentTypeHeader); + CFStringRef textEncodingName = createCharsetFromContentTypeHeader(contentTypeHeader); Boolean base64 = CFStringFind(contentTypeHeader, CFSTR(";base64"), kCFCompareCaseInsensitive).location != kCFNotFound; @@ -591,7 +591,7 @@ static Boolean parseDataRequestURL(CFURLRef url, CFDataRef* outData, CFStringRef } else { CFDataRef unescapedAndStripped = percentEscapeDecodeBuffer(alloc, srcBuffer, dataRange, true); if (unescapedAndStripped) { - dataRef = base64DecodeData(alloc, unescapedAndStripped); + dataRef = _createBase64DecodedData(alloc, unescapedAndStripped); CFRelease(unescapedAndStripped); } } @@ -629,7 +629,9 @@ static Boolean _CFDataURLCreateDataAndPropertiesFromResource(CFAllocatorRef allo if (! parseDataRequestURL(url, &data, &mimeType, &textEncodingName)) { if (errorCode) *errorCode = kCFURLUnknownError; - *fetchedData = NULL; + if (fetchedData) { + *fetchedData = NULL; + } success = false; } else { if (fetchedData) { @@ -728,7 +730,7 @@ Boolean CFURLCreateDataAndPropertiesFromResource(CFAllocatorRef alloc, CFURLRef CFTypeRef CFURLCreatePropertyFromResource(CFAllocatorRef alloc, CFURLRef url, CFStringRef property, SInt32 *errorCode) { CFArrayRef array = CFArrayCreate(alloc, (const void **)&property, 1, &kCFTypeArrayCallBacks); - CFDictionaryRef dict; + CFDictionaryRef dict = NULL; if (CFURLCreateDataAndPropertiesFromResource(alloc, url, NULL, &dict, array, errorCode)) { CFTypeRef result = CFDictionaryGetValue(dict, property); diff --git a/CoreFoundation/URL.subproj/CFURLAccess.h b/CoreFoundation/URL.subproj/CFURLAccess.h index e0de85fc62..fddcefd3fa 100644 --- a/CoreFoundation/URL.subproj/CFURLAccess.h +++ b/CoreFoundation/URL.subproj/CFURLAccess.h @@ -1,7 +1,7 @@ /* CFURLAccess.h - Copyright (c) 1998-2018, Apple Inc. and the Swift project authors + Copyright (c) 1998-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/URL.subproj/CFURLComponents.c b/CoreFoundation/URL.subproj/CFURLComponents.c index 17ce894042..a44933947c 100644 --- a/CoreFoundation/URL.subproj/CFURLComponents.c +++ b/CoreFoundation/URL.subproj/CFURLComponents.c @@ -1,7 +1,7 @@ /* CFURLComponents.c - Copyright (c) 2015-2018, Apple Inc. All rights reserved. + Copyright (c) 2015-2019, Apple Inc. All rights reserved. - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -119,7 +119,6 @@ CF_EXPORT CFURLComponentsRef _CFURLComponentsCreate(CFAllocatorRef alloc) { memory->_lock = CFLockInit; - memory->_urlString = NULL; memory->_schemeComponentValid = true; memory->_userComponentValid = true; memory->_passwordComponentValid = true; @@ -128,16 +127,7 @@ CF_EXPORT CFURLComponentsRef _CFURLComponentsCreate(CFAllocatorRef alloc) { memory->_pathComponentValid = true; memory->_queryComponentValid = true; memory->_fragmentComponentValid = true; - - memory->_schemeComponent = NULL; - memory->_userComponent = NULL; - memory->_passwordComponent = NULL; - memory->_hostComponent = NULL; - memory->_portComponent = NULL; - memory->_pathComponent = NULL; - memory->_queryComponent = NULL; - memory->_fragmentComponent = NULL; - + return memory; } @@ -156,49 +146,32 @@ CF_EXPORT CFURLComponentsRef _CFURLComponentsCreateWithURL(CFAllocatorRef alloc, } CF_EXPORT CFURLComponentsRef _CFURLComponentsCreateWithString(CFAllocatorRef alloc, CFStringRef string) { - CFIndex size = sizeof(struct __CFURLComponents) - sizeof(CFRuntimeBase); - CFURLComponentsRef memory = (CFURLComponentsRef)_CFRuntimeCreateInstance(alloc, _CFURLComponentsGetTypeID(), size, NULL); - if (NULL == memory) { - return NULL; - } - - _CFURIParserParseURIReference(string, &memory->_parseInfo); - if (!_CFURIParserURLStringIsValid(string, &memory->_parseInfo)) { - CFAllocatorDeallocate(alloc, memory); - return NULL; - } - - memory->_lock = CFLockInit; - - memory->_urlString = CFStringCreateCopy(alloc, string); - memory->_schemeComponentValid = false; - memory->_userComponentValid = false; - memory->_passwordComponentValid = false; - memory->_hostComponentValid = false; - memory->_portComponentValid = false; - memory->_pathComponentValid = false; - memory->_queryComponentValid = false; - memory->_fragmentComponentValid = false; - - memory->_schemeComponent = NULL; - memory->_userComponent = NULL; - memory->_passwordComponent = NULL; - memory->_hostComponent = NULL; - memory->_portComponent = NULL; - memory->_pathComponent = NULL; - memory->_queryComponent = NULL; - memory->_fragmentComponent = NULL; - - // if paramExists, there's a semi-colon in the path - if (memory->_parseInfo.paramExists) { - CFStringRef path = _CFURLComponentsCopyPath(memory); - _CFURLComponentsSetPath(memory, path); - if ( path ) { - CFRelease(path); + CFURLComponentsRef result = NULL; + struct _URIParseInfo parseInfo; + _CFURIParserParseURIReference(string, &parseInfo); + if ( _CFURIParserURLStringIsValid(string, &parseInfo) ) { + CFIndex size = sizeof(struct __CFURLComponents) - sizeof(CFRuntimeBase); + result = (CFURLComponentsRef)_CFRuntimeCreateInstance(alloc, _CFURLComponentsGetTypeID(), size, NULL); + if ( result) { + // copy the _URIParseInfo into the result + memcpy(&result->_parseInfo, &parseInfo, sizeof(parseInfo)); + + result->_lock = CFLockInit; + + result->_urlString = CFStringCreateCopy(alloc, string); + + // if there's a semi-colon in the path (what used to delimit the deprecated param component) + if (result->_parseInfo.semicolonInPathExists) { + // this will percent-encode it + CFStringRef path = _CFURLComponentsCopyPath(result); + _CFURLComponentsSetPath(result, path); + if ( path ) { + CFRelease(path); + } + } } } - - return memory; + return ( result ); } CF_EXPORT CFURLComponentsRef _CFURLComponentsCreateCopy(CFAllocatorRef alloc, CFURLComponentsRef components) { @@ -222,21 +195,32 @@ CF_EXPORT CFURLComponentsRef _CFURLComponentsCreateCopy(CFAllocatorRef alloc, CF memory->_queryComponentValid = components->_queryComponentValid; memory->_fragmentComponentValid = components->_fragmentComponentValid; - memory->_schemeComponent = components->_schemeComponent ? CFStringCreateCopy(alloc, components->_schemeComponent) : NULL; - memory->_userComponent = components->_userComponent ? CFStringCreateCopy(alloc, components->_userComponent) : NULL;; - memory->_passwordComponent = components->_passwordComponent ? CFStringCreateCopy(alloc, components->_passwordComponent) : NULL;; - memory->_hostComponent = components->_hostComponent ? CFStringCreateCopy(alloc, components->_hostComponent) : NULL;; + if (components->_schemeComponent) { + memory->_schemeComponent = CFStringCreateCopy(alloc, components->_schemeComponent); + } + if (components->_userComponent) { + memory->_userComponent = CFStringCreateCopy(alloc, components->_userComponent); + } + if (components->_passwordComponent) { + memory->_passwordComponent = CFStringCreateCopy(alloc, components->_passwordComponent); + } + if (components->_hostComponent) { + memory->_hostComponent = CFStringCreateCopy(alloc, components->_hostComponent); + } if (components->_portComponent) { long long port = 0; CFNumberGetValue(components->_portComponent, kCFNumberLongLongType, &port); memory->_portComponent = CFNumberCreate(alloc, kCFNumberLongLongType, &port); - } else { - memory->_portComponent = NULL; } - memory->_pathComponent = components->_pathComponent ? CFStringCreateCopy(alloc, components->_pathComponent) : NULL;; - memory->_queryComponent = components->_queryComponent ? CFStringCreateCopy(alloc, components->_queryComponent) : NULL;; - memory->_fragmentComponent = components->_fragmentComponent ? CFStringCreateCopy(alloc, components->_fragmentComponent) : NULL;; - + if (components->_pathComponent) { + memory->_pathComponent = CFStringCreateCopy(alloc, components->_pathComponent); + } + if (components->_queryComponent) { + memory->_queryComponent = CFStringCreateCopy(alloc, components->_queryComponent); + } + if (components->_fragmentComponent) { + memory->_fragmentComponent = CFStringCreateCopy(alloc, components->_fragmentComponent); + } __CFUnlock(&components->_lock); return memory; @@ -664,7 +648,7 @@ CF_EXPORT CFStringRef _CFURLComponentsCopyPath(CFURLComponentsRef components) { __CFLock(&components->_lock); if ( !components->_pathComponentValid ) { - components->_pathComponent = CreateComponentWithURLStringRange(components->_urlString, _CFURIParserGetPathRange(&components->_parseInfo, false, false)); + components->_pathComponent = CreateComponentWithURLStringRange(components->_urlString, _CFURIParserGetPathRange(&components->_parseInfo, false)); components->_pathComponentValid = true; } if (!components->_pathComponent) { @@ -708,25 +692,38 @@ CF_EXPORT CFStringRef _CFURLComponentsCopyFragment(CFURLComponentsRef components return ( result ); } -CF_EXPORT Boolean _CFURLComponentsSetScheme(CFURLComponentsRef components, CFStringRef scheme) { +CF_EXPORT Boolean _CFURLComponentsSchemeIsValid(CFStringRef scheme) { + Boolean valid = false; if ( scheme ) { - Boolean valid = false; CFIndex length = CFStringGetLength(scheme); if ( length != 0 ) { UniChar ch = CFStringGetCharacterAtIndex(scheme, 0); valid = (ch <= 127) && _CFURIParserAlphaAllowed(ch) && _CFURIParserValidateComponent(scheme, CFRangeMake(1, length - 1), kURLSchemeAllowed, false); } - if ( !valid ) { - // invalid characters in scheme - return false; + } + else { + // NULL is valid because it can be passed to _CFURLComponentsSetScheme to clear the scheme component + valid = true; + } + return ( valid ); +} + +CF_EXPORT Boolean _CFURLComponentsSetScheme(CFURLComponentsRef components, CFStringRef scheme) { + Boolean result; + if ( _CFURLComponentsSchemeIsValid(scheme) ) { + __CFLock(&components->_lock); + if (components->_schemeComponent) { + CFRelease(components->_schemeComponent); } + components->_schemeComponent = scheme ? CFStringCreateCopy(kCFAllocatorSystemDefault, scheme) : NULL; + components->_schemeComponentValid = true; + __CFUnlock(&components->_lock); + result = true; } - __CFLock(&components->_lock); - if (components->_schemeComponent) CFRelease(components->_schemeComponent); - components->_schemeComponent = scheme ? CFStringCreateCopy(kCFAllocatorSystemDefault, scheme) : NULL; - components->_schemeComponentValid = true; - __CFUnlock(&components->_lock); - return true; + else { + result = false; + } + return ( result ); } CF_EXPORT Boolean _CFURLComponentsSetUser(CFURLComponentsRef components, CFStringRef user) { @@ -905,7 +902,7 @@ CF_EXPORT CFStringRef _CFURLComponentsCopyPercentEncodedPath(CFURLComponentsRef __CFLock(&components->_lock); if ( !components->_pathComponentValid ) { - components->_pathComponent = CreateComponentWithURLStringRange(components->_urlString, _CFURIParserGetPathRange(&components->_parseInfo, false, false)); + components->_pathComponent = CreateComponentWithURLStringRange(components->_urlString, _CFURIParserGetPathRange(&components->_parseInfo, false)); components->_pathComponentValid = true; } result = components->_pathComponent ? CFRetain(components->_pathComponent) : NULL; @@ -1147,7 +1144,7 @@ CF_EXPORT CFRange _CFURLComponentsGetRangeOfPath(CFURLComponentsRef components) _CFURIParserParseURIReference(str, theParseInfo); CFRelease(str); } - return ( _CFURIParserGetPathRange(theParseInfo, false, false) ); + return ( _CFURIParserGetPathRange(theParseInfo, false) ); } CF_EXPORT CFRange _CFURLComponentsGetRangeOfQuery(CFURLComponentsRef components) { @@ -1409,6 +1406,9 @@ static Boolean _CFURLComponentsSetQueryItemsInternal(CFURLComponentsRef componen if ( name && name != kCFNull ) { if ( addPercentEncoding ) { CFStringRef stringWithPercentEncoding = _CFStringCreateByAddingPercentEncodingWithAllowedCharacters(kCFAllocatorSystemDefault, name, queryNameValueAllowed); + if ( !stringWithPercentEncoding ) { + stringWithPercentEncoding = (CFStringRef)CFRetain(CFSTR("")); + } CFStringAppendStringToAppendBuffer(&buf, stringWithPercentEncoding); CFRelease(stringWithPercentEncoding); } @@ -1426,6 +1426,9 @@ static Boolean _CFURLComponentsSetQueryItemsInternal(CFURLComponentsRef componen CFStringAppendCharactersToAppendBuffer(&buf, chars, 1); if ( addPercentEncoding ) { CFStringRef stringWithPercentEncoding = _CFStringCreateByAddingPercentEncodingWithAllowedCharacters(kCFAllocatorSystemDefault, value, queryNameValueAllowed); + if ( !stringWithPercentEncoding ) { + stringWithPercentEncoding = (CFStringRef)CFRetain(CFSTR("")); + } CFStringAppendStringToAppendBuffer(&buf, stringWithPercentEncoding); CFRelease(stringWithPercentEncoding); } diff --git a/CoreFoundation/URL.subproj/CFURLComponents.h b/CoreFoundation/URL.subproj/CFURLComponents.h index 51e05529a8..8eb23ffc15 100644 --- a/CoreFoundation/URL.subproj/CFURLComponents.h +++ b/CoreFoundation/URL.subproj/CFURLComponents.h @@ -1,7 +1,7 @@ /* CFURLComponents.h - Copyright (c) 2015-2018, Apple Inc. All rights reserved. + Copyright (c) 2015-2019, Apple Inc. All rights reserved. - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -23,86 +23,89 @@ CF_ASSUME_NONNULL_BEGIN typedef struct CF_BRIDGED_TYPE(id) __CFURLComponents *CFURLComponentsRef; -CF_EXPORT CFTypeID _CFURLComponentsGetTypeID(void); +CF_EXPORT CFTypeID _CFURLComponentsGetTypeID(void) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); // URLComponents are always mutable. -CF_EXPORT _Nullable CFURLComponentsRef _CFURLComponentsCreate(CFAllocatorRef alloc); +CF_EXPORT _Nullable CFURLComponentsRef _CFURLComponentsCreate(CFAllocatorRef alloc) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); -CF_EXPORT _Nullable CFURLComponentsRef _CFURLComponentsCreateWithURL(CFAllocatorRef alloc, CFURLRef url, Boolean resolveAgainstBaseURL); +CF_EXPORT _Nullable CFURLComponentsRef _CFURLComponentsCreateWithURL(CFAllocatorRef alloc, CFURLRef url, Boolean resolveAgainstBaseURL) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); -CF_EXPORT _Nullable CFURLComponentsRef _CFURLComponentsCreateWithString(CFAllocatorRef alloc, CFStringRef string); +CF_EXPORT _Nullable CFURLComponentsRef _CFURLComponentsCreateWithString(CFAllocatorRef alloc, CFStringRef string) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); -CF_EXPORT _Nullable CFURLComponentsRef _CFURLComponentsCreateCopy(CFAllocatorRef alloc, CFURLComponentsRef components); +CF_EXPORT _Nullable CFURLComponentsRef _CFURLComponentsCreateCopy(CFAllocatorRef alloc, CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); -CF_EXPORT _Nullable CFURLRef _CFURLComponentsCopyURL(CFURLComponentsRef components); +CF_EXPORT _Nullable CFURLRef _CFURLComponentsCopyURL(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); -CF_EXPORT _Nullable CFURLRef _CFURLComponentsCopyURLRelativeToURL(CFURLComponentsRef components, _Nullable CFURLRef relativeToURL); +CF_EXPORT _Nullable CFURLRef _CFURLComponentsCopyURLRelativeToURL(CFURLComponentsRef components, _Nullable CFURLRef relativeToURL) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); -CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyString(CFURLComponentsRef components); +CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyString(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); -CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyScheme(CFURLComponentsRef components); -CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyUser(CFURLComponentsRef components); -CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyPassword(CFURLComponentsRef components); -CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyHost(CFURLComponentsRef components); -CF_EXPORT _Nullable CFNumberRef _CFURLComponentsCopyPort(CFURLComponentsRef components); -CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyPath(CFURLComponentsRef components); -CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyQuery(CFURLComponentsRef components); -CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyFragment(CFURLComponentsRef components); +CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyScheme(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyUser(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyPassword(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyHost(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT _Nullable CFNumberRef _CFURLComponentsCopyPort(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyPath(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyQuery(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyFragment(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); + +// Returns true if the scheme argument can be passed to _CFURLComponentsSetScheme. A valid scheme string is an ALPHA character followed by 0 or more ALPHA, DIGIT, "+", "-", or "." characters. Because NULL can be passed to _CFURLComponentsSetScheme to clear the scheme component, passing NULL to this function also returns true. +CF_EXPORT Boolean _CFURLComponentsSchemeIsValid(_Nullable CFStringRef scheme) API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); // These return false if the conversion fails -CF_EXPORT Boolean _CFURLComponentsSetScheme(CFURLComponentsRef components, _Nullable CFStringRef scheme); -CF_EXPORT Boolean _CFURLComponentsSetUser(CFURLComponentsRef components, _Nullable CFStringRef user); -CF_EXPORT Boolean _CFURLComponentsSetPassword(CFURLComponentsRef components, _Nullable CFStringRef password); -CF_EXPORT Boolean _CFURLComponentsSetHost(CFURLComponentsRef components, _Nullable CFStringRef host); -CF_EXPORT Boolean _CFURLComponentsSetPort(CFURLComponentsRef components, _Nullable CFNumberRef port); -CF_EXPORT Boolean _CFURLComponentsSetPath(CFURLComponentsRef components, _Nullable CFStringRef path); -CF_EXPORT Boolean _CFURLComponentsSetQuery(CFURLComponentsRef components, _Nullable CFStringRef query); -CF_EXPORT Boolean _CFURLComponentsSetFragment(CFURLComponentsRef components, _Nullable CFStringRef fragment); - -CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyPercentEncodedUser(CFURLComponentsRef components); -CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyPercentEncodedPassword(CFURLComponentsRef components); -CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyPercentEncodedHost(CFURLComponentsRef components); -CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyPercentEncodedPath(CFURLComponentsRef components); -CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyPercentEncodedQuery(CFURLComponentsRef components); -CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyPercentEncodedFragment(CFURLComponentsRef components); +CF_EXPORT Boolean _CFURLComponentsSetScheme(CFURLComponentsRef components, _Nullable CFStringRef scheme) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT Boolean _CFURLComponentsSetUser(CFURLComponentsRef components, _Nullable CFStringRef user) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT Boolean _CFURLComponentsSetPassword(CFURLComponentsRef components, _Nullable CFStringRef password) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT Boolean _CFURLComponentsSetHost(CFURLComponentsRef components, _Nullable CFStringRef host) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT Boolean _CFURLComponentsSetPort(CFURLComponentsRef components, _Nullable CFNumberRef port) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT Boolean _CFURLComponentsSetPath(CFURLComponentsRef components, _Nullable CFStringRef path) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT Boolean _CFURLComponentsSetQuery(CFURLComponentsRef components, _Nullable CFStringRef query) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT Boolean _CFURLComponentsSetFragment(CFURLComponentsRef components, _Nullable CFStringRef fragment) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); + +CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyPercentEncodedUser(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyPercentEncodedPassword(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyPercentEncodedHost(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyPercentEncodedPath(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyPercentEncodedQuery(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT _Nullable CFStringRef _CFURLComponentsCopyPercentEncodedFragment(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); // These return false if the conversion fails -CF_EXPORT Boolean _CFURLComponentsSetPercentEncodedUser(CFURLComponentsRef components, _Nullable CFStringRef user); -CF_EXPORT Boolean _CFURLComponentsSetPercentEncodedPassword(CFURLComponentsRef components, _Nullable CFStringRef password); -CF_EXPORT Boolean _CFURLComponentsSetPercentEncodedHost(CFURLComponentsRef components, _Nullable CFStringRef host); -CF_EXPORT Boolean _CFURLComponentsSetPercentEncodedPath(CFURLComponentsRef components, _Nullable CFStringRef path); -CF_EXPORT Boolean _CFURLComponentsSetPercentEncodedQuery(CFURLComponentsRef components, _Nullable CFStringRef query); -CF_EXPORT Boolean _CFURLComponentsSetPercentEncodedFragment(CFURLComponentsRef components, _Nullable CFStringRef fragment); - -CF_EXPORT CFRange _CFURLComponentsGetRangeOfScheme(CFURLComponentsRef components); -CF_EXPORT CFRange _CFURLComponentsGetRangeOfUser(CFURLComponentsRef components); -CF_EXPORT CFRange _CFURLComponentsGetRangeOfPassword(CFURLComponentsRef components); -CF_EXPORT CFRange _CFURLComponentsGetRangeOfHost(CFURLComponentsRef components); -CF_EXPORT CFRange _CFURLComponentsGetRangeOfPort(CFURLComponentsRef components); -CF_EXPORT CFRange _CFURLComponentsGetRangeOfPath(CFURLComponentsRef components); -CF_EXPORT CFRange _CFURLComponentsGetRangeOfQuery(CFURLComponentsRef components); -CF_EXPORT CFRange _CFURLComponentsGetRangeOfFragment(CFURLComponentsRef components); - -CF_EXPORT CFStringRef _CFStringCreateByAddingPercentEncodingWithAllowedCharacters(CFAllocatorRef alloc, CFStringRef string, CFCharacterSetRef allowedCharacters); -CF_EXPORT CFStringRef _Nullable _CFStringCreateByRemovingPercentEncoding(CFAllocatorRef alloc, CFStringRef string); +CF_EXPORT Boolean _CFURLComponentsSetPercentEncodedUser(CFURLComponentsRef components, _Nullable CFStringRef user) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT Boolean _CFURLComponentsSetPercentEncodedPassword(CFURLComponentsRef components, _Nullable CFStringRef password) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT Boolean _CFURLComponentsSetPercentEncodedHost(CFURLComponentsRef components, _Nullable CFStringRef host) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT Boolean _CFURLComponentsSetPercentEncodedPath(CFURLComponentsRef components, _Nullable CFStringRef path) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT Boolean _CFURLComponentsSetPercentEncodedQuery(CFURLComponentsRef components, _Nullable CFStringRef query) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT Boolean _CFURLComponentsSetPercentEncodedFragment(CFURLComponentsRef components, _Nullable CFStringRef fragment) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); + +CF_EXPORT CFRange _CFURLComponentsGetRangeOfScheme(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT CFRange _CFURLComponentsGetRangeOfUser(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT CFRange _CFURLComponentsGetRangeOfPassword(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT CFRange _CFURLComponentsGetRangeOfHost(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT CFRange _CFURLComponentsGetRangeOfPort(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT CFRange _CFURLComponentsGetRangeOfPath(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT CFRange _CFURLComponentsGetRangeOfQuery(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT CFRange _CFURLComponentsGetRangeOfFragment(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); + +CF_EXPORT CFStringRef _CFStringCreateByAddingPercentEncodingWithAllowedCharacters(CFAllocatorRef alloc, CFStringRef string, CFCharacterSetRef allowedCharacters) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT CFStringRef _Nullable _CFStringCreateByRemovingPercentEncoding(CFAllocatorRef alloc, CFStringRef string) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); // These return singletons -CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLUserAllowedCharacterSet(void); -CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLPasswordAllowedCharacterSet(void); -CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLHostAllowedCharacterSet(void); -CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLPathAllowedCharacterSet(void); -CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLQueryAllowedCharacterSet(void); -CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLFragmentAllowedCharacterSet(void); +CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLUserAllowedCharacterSet(void) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLPasswordAllowedCharacterSet(void) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLHostAllowedCharacterSet(void) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLPathAllowedCharacterSet(void) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLQueryAllowedCharacterSet(void) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLFragmentAllowedCharacterSet(void) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); // keys for dictionaries returned by _CFURLComponentsCopyQueryItems -CF_EXPORT const CFStringRef _kCFURLComponentsNameKey; -CF_EXPORT const CFStringRef _kCFURLComponentsValueKey; +CF_EXPORT const CFStringRef _kCFURLComponentsNameKey API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)); +CF_EXPORT const CFStringRef _kCFURLComponentsValueKey API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)); -CF_EXPORT _Nullable CFArrayRef _CFURLComponentsCopyQueryItems(CFURLComponentsRef components); -CF_EXPORT void _CFURLComponentsSetQueryItems(CFURLComponentsRef components, CFArrayRef names, CFArrayRef values); +CF_EXPORT _Nullable CFArrayRef _CFURLComponentsCopyQueryItems(CFURLComponentsRef components) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +CF_EXPORT void _CFURLComponentsSetQueryItems(CFURLComponentsRef components, CFArrayRef names, CFArrayRef values) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); -CF_EXPORT _Nullable CFArrayRef _CFURLComponentsCopyPercentEncodedQueryItems(CFURLComponentsRef components); -CF_EXPORT Boolean _CFURLComponentsSetPercentEncodedQueryItems(CFURLComponentsRef components, CFArrayRef names, CFArrayRef values); +CF_EXPORT _Nullable CFArrayRef _CFURLComponentsCopyPercentEncodedQueryItems(CFURLComponentsRef components) API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)); +CF_EXPORT Boolean _CFURLComponentsSetPercentEncodedQueryItems(CFURLComponentsRef components, CFArrayRef names, CFArrayRef values) API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)); CF_ASSUME_NONNULL_END CF_EXTERN_C_END diff --git a/CoreFoundation/URL.subproj/CFURLComponents_Internal.h b/CoreFoundation/URL.subproj/CFURLComponents_Internal.h index 0ec96ad954..e2587bc9cc 100644 --- a/CoreFoundation/URL.subproj/CFURLComponents_Internal.h +++ b/CoreFoundation/URL.subproj/CFURLComponents_Internal.h @@ -1,7 +1,7 @@ /* CFURLComponents_Internal.h - Copyright (c) 2015-2018, Apple Inc. All rights reserved. + Copyright (c) 2015-2019, Apple Inc. All rights reserved. - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -21,7 +21,6 @@ struct _URIParseInfo { unsigned long hostOffset; unsigned long portOffset; unsigned long pathOffset; - unsigned long paramOffset; // param is obsolete, but old API needs it. unsigned long queryOffset; unsigned long fragmentOffset; unsigned long endOffset; @@ -34,7 +33,7 @@ struct _URIParseInfo { unsigned long hostExists : 1; unsigned long portExists : 1; // pathExists is not needed because there's always a path... it just might be zero length. - unsigned long paramExists : 1; // param is obsolete, but old API needs it. + unsigned long semicolonInPathExists : 1; // param is obsolete, but we still percent-encode the ';' for backwards compatiblity with NSURL/CFURL. unsigned long queryExists : 1; unsigned long fragmentExists : 1; }; @@ -59,7 +58,7 @@ CF_PRIVATE CFRange _CFURIParserGetUserinfoNameRange(const struct _URIParseInfo * CF_PRIVATE CFRange _CFURIParserGetUserinfoPasswordRange(const struct _URIParseInfo *parseInfo, Boolean includeSeparators); CF_PRIVATE CFRange _CFURIParserGetHostRange(const struct _URIParseInfo *parseInfo, Boolean includeSeparators); CF_PRIVATE CFRange _CFURIParserGetPortRange(const struct _URIParseInfo *parseInfo, Boolean includeSeparators); -CF_PRIVATE CFRange _CFURIParserGetPathRange(const struct _URIParseInfo *parseInfo, Boolean includeSeparators, Boolean minusParam); +CF_PRIVATE CFRange _CFURIParserGetPathRange(const struct _URIParseInfo *parseInfo, Boolean includeSeparators); CF_PRIVATE CFRange _CFURIParserGetQueryRange(const struct _URIParseInfo *parseInfo, Boolean includeSeparators); CF_PRIVATE CFRange _CFURIParserGetFragmentRange(const struct _URIParseInfo *parseInfo, Boolean includeSeparators); CF_PRIVATE Boolean _CFURIParserAlphaAllowed(UniChar ch); diff --git a/CoreFoundation/URL.subproj/CFURLComponents_URIParser.c b/CoreFoundation/URL.subproj/CFURLComponents_URIParser.c index e7b43bdfe7..e7d071100d 100644 --- a/CoreFoundation/URL.subproj/CFURLComponents_URIParser.c +++ b/CoreFoundation/URL.subproj/CFURLComponents_URIParser.c @@ -1,20 +1,11 @@ -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// - - /* CFURLComponents_URIParser.c - Copyright (c) 2015, Apple Inc. All rights reserved. + Copyright (c) 2015-2019, Apple Inc. All rights reserved. Responsibility: Jim Luther/Chris Linn */ #include #include +#include "CFOverflow.h" #include "CFURLComponents_Internal.h" #include "CFInternal.h" @@ -71,100 +62,100 @@ static const unsigned short sURLAllowedCharacters[128] = { /* rs */ 0, /* us */ 0, /* sp */ 0, - /* '!' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, + /* '!' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLQueryItemNameAllowed, /* '"' */ 0, /* '#' */ 0, - /* '$' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, + /* '$' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLQueryItemNameAllowed, /* '%' */ 0, /* '&' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, - /* ''' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, - /* '(' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, - /* ')' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, - /* '*' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, - /* '+' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, - /* ',' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, - /* '-' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, - /* '.' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, - /* '/' */ kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, - /* '0' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed, - /* '1' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed, - /* '2' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed, - /* '3' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed, - /* '4' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed, - /* '5' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed, - /* '6' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed, - /* '7' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed, - /* '8' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed, - /* '9' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed, - /* ':' */ kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, - /* ';' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, + /* ''' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLQueryItemNameAllowed, + /* '(' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLQueryItemNameAllowed, + /* ')' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLQueryItemNameAllowed, + /* '*' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLQueryItemNameAllowed, + /* '+' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLQueryItemNameAllowed, + /* ',' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLQueryItemNameAllowed, + /* '-' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLQueryItemNameAllowed, + /* '.' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLQueryItemNameAllowed, + /* '/' */ kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLQueryItemNameAllowed, + /* '0' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLQueryItemNameAllowed, + /* '1' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLQueryItemNameAllowed, + /* '2' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLQueryItemNameAllowed, + /* '3' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLQueryItemNameAllowed, + /* '4' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLQueryItemNameAllowed, + /* '5' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLQueryItemNameAllowed, + /* '6' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLQueryItemNameAllowed, + /* '7' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLQueryItemNameAllowed, + /* '8' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLQueryItemNameAllowed, + /* '9' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPortAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLQueryItemNameAllowed, + /* ':' */ kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLQueryItemNameAllowed, + /* ';' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLQueryItemNameAllowed, /* '<' */ 0, - /* '=' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, + /* '=' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed , /* '>' */ 0, - /* '?' */ kURLQueryAllowed | kURLFragmentAllowed, - /* '@' */ kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, - /* 'A' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed, - /* 'B' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed, - /* 'C' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed, - /* 'D' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed, - /* 'E' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed, - /* 'F' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed, - /* 'G' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'H' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'I' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'J' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'K' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'L' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'M' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'N' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'O' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'P' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'Q' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'R' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'S' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'T' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'U' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'V' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'W' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'X' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'Y' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'Z' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, + /* '?' */ kURLQueryAllowed | kURLFragmentAllowed | kURLQueryItemNameAllowed, + /* '@' */ kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLQueryItemNameAllowed, + /* 'A' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'B' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'C' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'D' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'E' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'F' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'G' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'H' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'I' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'J' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'K' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'L' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'M' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'N' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'O' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'P' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'Q' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'R' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'S' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'T' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'U' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'V' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'W' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'X' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'Y' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'Z' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, /* '[' */ 0, /* '\' */ 0, /* ']' */ 0, /* '^' */ 0, - /* '_' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, + /* '_' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLQueryItemNameAllowed, /* '`' */ 0, - /* 'a' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed, - /* 'b' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed, - /* 'c' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed, - /* 'd' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed, - /* 'e' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed, - /* 'f' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed, - /* 'g' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'h' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'i' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'j' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'k' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'l' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'm' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'n' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'o' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'p' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'q' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'r' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 's' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 't' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'u' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'v' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'w' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'x' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'y' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, - /* 'z' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed, + /* 'a' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'b' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'c' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'd' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'e' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'f' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLHexDigAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'g' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'h' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'i' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'j' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'k' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'l' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'm' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'n' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'o' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'p' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'q' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'r' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 's' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 't' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'u' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'v' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'w' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'x' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'y' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, + /* 'z' */ kURLSchemeAllowed | kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLAlphaAllowed | kURLQueryItemNameAllowed, /* '{' */ 0, /* '|' */ 0, /* '}' */ 0, - /* '~' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed, + /* '~' */ kURLUserAllowed | kURLPasswordAllowed | kURLHostAllowed | kURLPathAllowed | kURLQueryAllowed | kURLFragmentAllowed | kURLQueryItemNameAllowed, /* del */ 0, }; @@ -273,83 +264,118 @@ CF_EXPORT CFStringRef _CFStringCreateByAddingPercentEncodingWithAllowedCharacter else { static const UInt8 hexchars[] = "0123456789ABCDEF"; CFIndex maxBufferSize = CFStringGetMaximumSizeForEncoding(inLength, kCFStringEncodingUTF8); - enum { - kStackBufferSize = 4096, - kInStackBufferSize = kStackBufferSize / 4, - kOutStackBufferSize = kInStackBufferSize * 3, - }; - STACK_BUFFER_DECL(UInt8, stackBuffer, kStackBufferSize); - UInt8 *inBuf; - UInt8 *outBuf; - // choose a buffer to put the input bytes AND output bytes into - if ( maxBufferSize <= kInStackBufferSize ) { - inBuf = &stackBuffer[0]; - } - else { - // not big enough? malloc it. - inBuf = (UInt8 *)malloc(maxBufferSize * 4); - } - if ( inBuf ) { - CFIndex charsConverted; - CFIndex inLen; - // use the other 3/4 of the buffer for the percent-encoded bytes - outBuf = &inBuf[maxBufferSize]; - - charsConverted = CFStringGetBytes(string, CFRangeMake(0, inLength), kCFStringEncodingUTF8, 0, false, inBuf, maxBufferSize, &inLen); - if ( charsConverted ) { - UInt8 *inBytePtr = inBuf; - UInt8 *outBytePtr = outBuf; - CFIndex idx; - - // there are two very similar loops below -- they aren't combined because I didn't want an extra comparison per character to determine which code was going to set the allowed variable. + // CFStringGetMaximumSizeForEncoding returns kCFNotFound if the result would be too big + if ( maxBufferSize != kCFNotFound ) { + enum { + kStackBufferSize = 4096, + kInStackBufferSize = kStackBufferSize / 4, + kOutStackBufferSize = kInStackBufferSize * 3, + }; + STACK_BUFFER_DECL(UInt8, stackBuffer, kStackBufferSize); + UInt8 *inBuf = NULL; + UInt8 *outBuf; + // choose a buffer to put the input bytes AND output bytes into + if ( maxBufferSize <= kInStackBufferSize ) { + inBuf = &stackBuffer[0]; + } + else { + // not big enough? malloc it. + size_t mallocSize; + if ( _CFMultiplyBufferSizeWithoutOverflow(maxBufferSize, 4, &mallocSize) ) { + inBuf = (UInt8 *)malloc(mallocSize); + } + } + if ( inBuf ) { + CFIndex charsConverted; + CFIndex inLen; + // use the other 3/4 of the buffer for the percent-encoded bytes + outBuf = &inBuf[maxBufferSize]; - URLPredefinedCharacterSet allowedSet = GetURLPredefinedCharacterSet(allowedCharacters); - if ( allowedSet != kURLAllowedCharacterSetIllegal ) { - // fastest -- allowedCharacters is one of the predefined sets so use sURLAllowedCharacters to determine what characters are allowed - unsigned char allowedMask; - Boolean isIPLiteral = false; + charsConverted = CFStringGetBytes(string, CFRangeMake(0, inLength), kCFStringEncodingUTF8, 0, false, inBuf, maxBufferSize, &inLen); + if ( charsConverted ) { + UInt8 *inBytePtr = inBuf; + UInt8 *outBytePtr = outBuf; + CFIndex idx; - // determine the allowedMask - switch (allowedSet) { - case kURLUserAllowedCharacterSet: - allowedMask = kURLUserAllowed; - break; - case kURLPasswordAllowedCharacterSet: - allowedMask = kURLPasswordAllowed; - break; - case kURLHostAllowedCharacterSet: - allowedMask = kURLHostAllowed; - // if the host is an IP-Literal, percent-encode everything within the brackets but not the brackets - if ( (inLen >= 2) && (*inBytePtr == '[') && (inBytePtr[inLen - 1] == ']') ) { - isIPLiteral = true; - ++inBytePtr; - // copy the open bracket - *outBytePtr++ = '['; - inLen -= 2; + // there are two very similar loops below -- they aren't combined because I didn't want an extra comparison per character to determine which code was going to set the allowed variable. + + URLPredefinedCharacterSet allowedSet = GetURLPredefinedCharacterSet(allowedCharacters); + if ( allowedSet != kURLAllowedCharacterSetIllegal ) { + // fastest -- allowedCharacters is one of the predefined sets so use sURLAllowedCharacters to determine what characters are allowed + unsigned char allowedMask; + Boolean isIPLiteral = false; + + // determine the allowedMask + switch (allowedSet) { + case kURLUserAllowedCharacterSet: + allowedMask = kURLUserAllowed; + break; + case kURLPasswordAllowedCharacterSet: + allowedMask = kURLPasswordAllowed; + break; + case kURLHostAllowedCharacterSet: + allowedMask = kURLHostAllowed; + // if the host is an IP-Literal, percent-encode everything within the brackets but not the brackets + if ( (inLen >= 2) && (*inBytePtr == '[') && (inBytePtr[inLen - 1] == ']') ) { + isIPLiteral = true; + ++inBytePtr; + // copy the open bracket + *outBytePtr++ = '['; + inLen -= 2; + } + break; + case kURLPathAllowedCharacterSet: + allowedMask = kURLPathAllowed; + break; + case kURLQueryAllowedCharacterSet: + allowedMask = kURLQueryAllowed; + break; + case kURLFragmentAllowedCharacterSet: + allowedMask = kURLFragmentAllowed; + break; + default: + // GetURLPredefinedCharacterSet will return one of the above or kURLAllowedCharacterSetIllegal so this will never be hit + allowedMask = 0; + break; + } + if ( allowedSet == kURLPathAllowedCharacterSet ) { + Boolean pastSlash = false; + for ( idx = 0; idx < inLen; ++idx ) { + UInt8 ch = *inBytePtr++; + if ( pastSlash ) { + // !!!: percent encode ';' for backwards compatibility with API which uses rfc1808 parsing + Boolean allowed = (ch <= 127) && (ch != ';') && ((sURLAllowedCharacters[ch] & allowedMask) != 0); + if ( allowed ) { + *outBytePtr++ = ch; + } + else { + *outBytePtr++ = '%'; + *outBytePtr++ = hexchars[ch >> 4]; + *outBytePtr++ = hexchars[ch & 0x0f]; + } + } + else { + if ( ch == '/' ) { + pastSlash = true; + } + // !!!: percent encode ';' for backwards compatibility with API which uses rfc1808 parsing + Boolean allowed = (ch <= 127) && (ch != ';') && (ch != ':') && ((sURLAllowedCharacters[ch] & allowedMask) != 0); + if ( allowed ) { + *outBytePtr++ = ch; + } + else { + *outBytePtr++ = '%'; + *outBytePtr++ = hexchars[ch >> 4]; + *outBytePtr++ = hexchars[ch & 0x0f]; + } + } } - break; - case kURLPathAllowedCharacterSet: - allowedMask = kURLPathAllowed; - break; - case kURLQueryAllowedCharacterSet: - allowedMask = kURLQueryAllowed; - break; - case kURLFragmentAllowedCharacterSet: - allowedMask = kURLFragmentAllowed; - break; - default: - // GetURLPredefinedCharacterSet will return one of the above or kURLAllowedCharacterSetIllegal so this will never be hit - allowedMask = 0; - break; - } - if ( allowedSet == kURLPathAllowedCharacterSet ) { - Boolean pastSlash = false; - for ( idx = 0; idx < inLen; ++idx ) { - UInt8 ch = *inBytePtr++; - if ( pastSlash ) { - // !!!: percent encode ';' for backwards compatibility with API which uses rfc1808 parsing - Boolean allowed = (ch <= 127) && (ch != ';') && ((sURLAllowedCharacters[ch] & allowedMask) != 0); - if ( allowed ) { + } + else if ( allowedSet == kURLHostAllowedCharacterSet ) { + for ( idx = 0; idx < inLen; ++idx ) { + UInt8 ch = *inBytePtr++; + Boolean allowed = (ch <= 127) && ((sURLAllowedCharacters[ch] & allowedMask) != 0); + if ( allowed || (isIPLiteral && ch == ':') ) { // the colon is allowed in IP-Literal *outBytePtr++ = ch; } else { @@ -358,12 +384,15 @@ CF_EXPORT CFStringRef _CFStringCreateByAddingPercentEncodingWithAllowedCharacter *outBytePtr++ = hexchars[ch & 0x0f]; } } - else { - if ( ch == '/' ) { - pastSlash = true; - } - // !!!: percent encode ';' for backwards compatibility with API which uses rfc1808 parsing - Boolean allowed = (ch <= 127) && (ch != ';') && (ch != ':') && ((sURLAllowedCharacters[ch] & allowedMask) != 0); + if ( isIPLiteral ) { + // copy the close bracket + *outBytePtr++ = ']'; + } + } + else { + for ( idx = 0; idx < inLen; ++idx ) { + UInt8 ch = *inBytePtr++; + Boolean allowed = (ch <= 127) && ((sURLAllowedCharacters[ch] & allowedMask) != 0); if ( allowed ) { *outBytePtr++ = ch; } @@ -375,28 +404,13 @@ CF_EXPORT CFStringRef _CFStringCreateByAddingPercentEncodingWithAllowedCharacter } } } - else if ( allowedSet == kURLHostAllowedCharacterSet ) { - for ( idx = 0; idx < inLen; ++idx ) { - UInt8 ch = *inBytePtr++; - Boolean allowed = (ch <= 127) && ((sURLAllowedCharacters[ch] & allowedMask) != 0); - if ( allowed || (isIPLiteral && ch == ':') ) { // the colon is allowed in IP-Literal - *outBytePtr++ = ch; - } - else { - *outBytePtr++ = '%'; - *outBytePtr++ = hexchars[ch >> 4]; - *outBytePtr++ = hexchars[ch & 0x0f]; - } - } - if ( isIPLiteral ) { - // copy the close bracket - *outBytePtr++ = ']'; - } - } else { + // use the allowedCharacters NSCharacterSet to determine what characters are allowed + // non-ASCII characters are ignored for ( idx = 0; idx < inLen; ++idx ) { UInt8 ch = *inBytePtr++; - Boolean allowed = (ch <= 127) && ((sURLAllowedCharacters[ch] & allowedMask) != 0); + // CFCharacterSet + Boolean allowed = (ch <= 127) && CFCharacterSetIsCharacterMember((CFCharacterSetRef)allowedCharacters, ch); if ( allowed ) { *outBytePtr++ = ch; } @@ -407,30 +421,13 @@ CF_EXPORT CFStringRef _CFStringCreateByAddingPercentEncodingWithAllowedCharacter } } } - } - else { - // use the allowedCharacters NSCharacterSet to determine what characters are allowed - // non-ASCII characters are ignored - for ( idx = 0; idx < inLen; ++idx ) { - UInt8 ch = *inBytePtr++; - // CFCharacterSet - Boolean allowed = (ch <= 127) && CFCharacterSetIsCharacterMember((CFCharacterSetRef)allowedCharacters, ch); - if ( allowed ) { - *outBytePtr++ = ch; - } - else { - *outBytePtr++ = '%'; - *outBytePtr++ = hexchars[ch >> 4]; - *outBytePtr++ = hexchars[ch & 0x0f]; - } - } + + result = CFStringCreateWithBytes(kCFAllocatorDefault, outBuf, outBytePtr - outBuf, kCFStringEncodingUTF8, false); } - result = CFStringCreateWithBytes(kCFAllocatorDefault, outBuf, outBytePtr - outBuf, kCFStringEncodingUTF8, false); - } - - if ( inBuf != stackBuffer ) { - free(inBuf); + if ( inBuf != stackBuffer ) { + free(inBuf); + } } } } @@ -442,113 +439,119 @@ CF_EXPORT CFStringRef _CFStringCreateByRemovingPercentEncoding(CFAllocatorRef al CFIndex strLength = CFStringGetLength(string); if ( strLength ) { CFIndex maxBufferSize = CFStringGetMaximumSizeForEncoding(strLength, kCFStringEncodingUTF8); - enum { - kStackBufferSize = 4096, - kHalfStackBufferSize = kStackBufferSize / 2, - - }; - STACK_BUFFER_DECL(UInt8, stackBuffer, kStackBufferSize); - UInt8 *encodedBuf; - UInt8 *decodedBuf; - // choose a buffer to put the percent-encoded bytes AND to percent-decode into - if ( maxBufferSize <= kHalfStackBufferSize ) { - encodedBuf = &stackBuffer[0]; - } - else { - // not big enough? malloc it. - encodedBuf = (UInt8 *)malloc(maxBufferSize * 2); - } - if ( encodedBuf ) { - CFIndex charsConverted; - CFIndex usedBufLen; - // use the other half of the buffer for the percent-decoded bytes - decodedBuf = &encodedBuf[maxBufferSize]; - charsConverted = CFStringGetBytes(string, CFRangeMake(0, strLength), kCFStringEncodingUTF8, 0, false, encodedBuf, maxBufferSize, &usedBufLen); - if ( charsConverted ) { - // 0x80 marks invalid hex digits so this table can validate the digits while getting the values - static const UInt8 hexvalues[] = { - /* 00 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* 08 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* 10 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* 18 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* 20 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* 28 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* 30 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - /* 38 */ 0x08, 0x09, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* 40 */ 0x80, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x80, - /* 48 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* 50 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* 58 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* 60 */ 0x80, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x80, - /* 68 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* 70 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* 78 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - - /* 80 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* 88 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* 90 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* 98 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* A0 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* A8 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* B0 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* B8 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* C0 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* C8 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* D0 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* D8 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* E0 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* E8 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* F0 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - /* F8 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - }; - UInt8 *bufStartPtr; - UInt8 *bufPtr; - const UInt8 *bytePtr = encodedBuf; - CFIndex idx; + // CFStringGetMaximumSizeForEncoding returns kCFNotFound if the result would be too big + if ( maxBufferSize != kCFNotFound ) { + enum { + kStackBufferSize = 4096, + kHalfStackBufferSize = kStackBufferSize / 2, - bufPtr = bufStartPtr = decodedBuf; - Boolean conversionOK = TRUE; - - for ( idx = 0; (idx < usedBufLen) && conversionOK; ++idx ) { - switch ( *bytePtr ) { - case '%': - idx += 2; - if ( idx < usedBufLen ) { - UInt8 hex1, hex2; - // skip over % - bytePtr++; - // get the hex digits - hex1 = hexvalues[*bytePtr++]; - hex2 = hexvalues[*bytePtr++]; - // validate them - if ( ((hex1 | hex2) & 0x80) == 0 ) { - // convert hex digits - *bufPtr = (hex1 << 4) + hex2; + }; + STACK_BUFFER_DECL(UInt8, stackBuffer, kStackBufferSize); + UInt8 *encodedBuf = NULL; + UInt8 *decodedBuf; + // choose a buffer to put the percent-encoded bytes AND to percent-decode into + if ( maxBufferSize <= kHalfStackBufferSize ) { + encodedBuf = &stackBuffer[0]; + } + else { + // not big enough? malloc it. + size_t mallocSize; + if ( _CFMultiplyBufferSizeWithoutOverflow(maxBufferSize, 2, &mallocSize) ) { + encodedBuf = (UInt8 *)malloc(mallocSize); + } + } + if ( encodedBuf ) { + CFIndex charsConverted; + CFIndex usedBufLen; + // use the other half of the buffer for the percent-decoded bytes + decodedBuf = &encodedBuf[maxBufferSize]; + charsConverted = CFStringGetBytes(string, CFRangeMake(0, strLength), kCFStringEncodingUTF8, 0, false, encodedBuf, maxBufferSize, &usedBufLen); + if ( charsConverted ) { + // 0x80 marks invalid hex digits so this table can validate the digits while getting the values + static const UInt8 hexvalues[] = { + /* 00 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* 08 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* 10 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* 18 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* 20 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* 28 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* 30 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + /* 38 */ 0x08, 0x09, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* 40 */ 0x80, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x80, + /* 48 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* 50 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* 58 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* 60 */ 0x80, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x80, + /* 68 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* 70 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* 78 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + + /* 80 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* 88 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* 90 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* 98 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* A0 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* A8 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* B0 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* B8 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* C0 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* C8 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* D0 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* D8 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* E0 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* E8 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* F0 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + /* F8 */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + }; + UInt8 *bufStartPtr; + UInt8 *bufPtr; + const UInt8 *bytePtr = encodedBuf; + CFIndex idx; + + bufPtr = bufStartPtr = decodedBuf; + Boolean conversionOK = TRUE; + + for ( idx = 0; (idx < usedBufLen) && conversionOK; ++idx ) { + switch ( *bytePtr ) { + case '%': + idx += 2; + if ( idx < usedBufLen ) { + UInt8 hex1, hex2; + // skip over % + bytePtr++; + // get the hex digits + hex1 = hexvalues[*bytePtr++]; + hex2 = hexvalues[*bytePtr++]; + // validate them + if ( ((hex1 | hex2) & 0x80) == 0 ) { + // convert hex digits + *bufPtr = (hex1 << 4) + hex2; + } + else { + conversionOK = FALSE; + } } else { conversionOK = FALSE; } - } - else { - conversionOK = FALSE; - } - break; - default: - // copy everything else - *bufPtr = *bytePtr++; - break; + break; + default: + // copy everything else + *bufPtr = *bytePtr++; + break; + } + ++bufPtr; + } + if ( conversionOK ) { + result = CFStringCreateWithBytes(kCFAllocatorDefault, decodedBuf, bufPtr - bufStartPtr, kCFStringEncodingUTF8, false); } - ++bufPtr; } - if ( conversionOK ) { - result = CFStringCreateWithBytes(kCFAllocatorDefault, decodedBuf, bufPtr - bufStartPtr, kCFStringEncodingUTF8, false); + + // free the buffer if we malloc'd it + if ( encodedBuf != &stackBuffer[0] ) { + free(encodedBuf); } } - - // free the buffer if we malloc'd it - if ( encodedBuf != &stackBuffer[0] ) { - free(encodedBuf); - } } } else { @@ -701,11 +704,11 @@ CF_PRIVATE Boolean _CFURIParserParseURIReference(CFStringRef urlString, struct _ unsigned long currentCharIndex; unsigned long urlStringLength = CFStringGetLength(urlString); UniChar currentUniChar; - + // clear the parseInfo - memset(parseInfo, 0, sizeof(*parseInfo)); - - // Make sure the URL string isn't too long. We're limiting it to 2GB for backwards compatibility with 32-bit executables using NS/CFURL + bzero(parseInfo, sizeof(*parseInfo)); + + // Make sure the URL string isn't too long. We're limiting it to 2GB for backwards compatibility with 32-bit excutables using NS/CFURL if ( (urlStringLength > 0) && (urlStringLength <= INT_MAX) ) { CFStringInitInlineBuffer(urlString, &buf, CFRangeMake(0, urlStringLength)); @@ -719,53 +722,56 @@ CF_PRIVATE Boolean _CFURIParserParseURIReference(CFStringRef urlString, struct _ currentCharIndex = 0; currentUniChar = CFStringGetCharacterFromInlineBuffer(&buf, currentCharIndex); - doneParsingComponent = false; - while ( !doneParsingComponent ) { - if ( currentUniChar == 0 ) { - doneParsingComponent = true; - // there was no scheme so this is a relative-ref -- reset currentChar and we're done looking for a scheme - currentCharIndex = 0; - currentUniChar = CFStringGetCharacterFromInlineBuffer(&buf, currentCharIndex); - } - else { - switch ( currentUniChar ) { - case ':': - // !!!: This checks to make sure the scheme is at least 1 character. However, it makes this parser completely different than CFURL's parser when the string starts with a ":" character. - if ( currentCharIndex > 0 ) { - parseInfo->schemeExists = true; - // the scheme's offset is always 0 - ++currentCharIndex; - currentUniChar = CFStringGetCharacterFromInlineBuffer(&buf, currentCharIndex); - doneParsingComponent = true; - } - else { - // there were no valid scheme characters before the ':' -- reset currentChar and we're done looking for a scheme - currentCharIndex = 0; - currentUniChar = CFStringGetCharacterFromInlineBuffer(&buf, currentCharIndex); - doneParsingComponent = true; - } - break; - // !!!: These cases are commented out because default handles them. The scheme is validated as the URI string is parsed (unlike CFURL's parser). - // case '/': - // case '?': - // case '#': - // // there was no scheme so this is a relative-ref -- reset currentChar and we're done looking for a scheme - // currentCharIndex = 0; - // currentUniChar = CFStringGetCharacterFromInlineBuffer(&buf, currentCharIndex); - // doneParsingComponent = true; - // break; - default: - if ( (currentUniChar <= 127) && ((sURLAllowedCharacters[currentUniChar] & kURLSchemeAllowed) != 0) ) { - ++currentCharIndex; - currentUniChar = CFStringGetCharacterFromInlineBuffer(&buf, currentCharIndex); - } - else { - // invalid scheme characters -- reset currentChar and we're done looking for a scheme - currentCharIndex = 0; - currentUniChar = CFStringGetCharacterFromInlineBuffer(&buf, currentCharIndex); - doneParsingComponent = true; - } - break; + // The first character of scheme has to be ALPHA so this is a quick outside the while loop check for that. In the switch statement below, the default case makes sure all characters are valid in a scheme, so only the lower bounds ('A') check is needed here to make sure the character is not a DIGIT. + if ( currentUniChar >= 'A' ) { + doneParsingComponent = false; + while ( !doneParsingComponent ) { + if ( currentUniChar == 0 ) { + doneParsingComponent = true; + // there was no scheme so this is a relative-ref -- reset currentChar and we're done looking for a scheme + currentCharIndex = 0; + currentUniChar = CFStringGetCharacterFromInlineBuffer(&buf, currentCharIndex); + } + else { + switch ( currentUniChar ) { + case ':': + // !!!: This checks to make sure the scheme is at least 1 character. However, it makes this parser completely different than CFURL's parser when the string starts with a ":" character. + if ( currentCharIndex > 0 ) { + parseInfo->schemeExists = true; + // the scheme's offset is always 0 + ++currentCharIndex; + currentUniChar = CFStringGetCharacterFromInlineBuffer(&buf, currentCharIndex); + doneParsingComponent = true; + } + else { + // there were no valid scheme characters before the ':' -- reset currentChar and we're done looking for a scheme + currentCharIndex = 0; + currentUniChar = CFStringGetCharacterFromInlineBuffer(&buf, currentCharIndex); + doneParsingComponent = true; + } + break; + // !!!: These cases are commented out because default handles them. The scheme is validated as the URI string is parsed (unlike CFURL's parser). + // case '/': + // case '?': + // case '#': + // // there was no scheme so this is a relative-ref -- reset currentChar and we're done looking for a scheme + // currentCharIndex = 0; + // currentUniChar = CFStringGetCharacterFromInlineBuffer(&buf, currentCharIndex); + // doneParsingComponent = true; + // break; + default: + if ( (currentUniChar <= 127) && ((sURLAllowedCharacters[currentUniChar] & kURLSchemeAllowed) != 0) ) { + ++currentCharIndex; + currentUniChar = CFStringGetCharacterFromInlineBuffer(&buf, currentCharIndex); + } + else { + // invalid scheme characters -- reset currentChar and we're done looking for a scheme + currentCharIndex = 0; + currentUniChar = CFStringGetCharacterFromInlineBuffer(&buf, currentCharIndex); + doneParsingComponent = true; + } + break; + } } } } @@ -829,10 +835,7 @@ CF_PRIVATE Boolean _CFURIParserParseURIReference(CFStringRef urlString, struct _ break; case ';': // keep track of the obsolete param subcomponent - if ( !(parseInfo->paramExists) ) { - parseInfo->paramExists = true; - parseInfo->paramOffset = currentCharIndex + 1; - } + parseInfo->semicolonInPathExists = true; // fall through to get next character default: ++currentCharIndex; @@ -1140,15 +1143,11 @@ CF_PRIVATE CFRange _CFURIParserGetPortRange(const struct _URIParseInfo *parseInf * is true, the path component ends at the first ';' character and the rest of * the rfc3986 path after ';' is considered the obsolete rfc1808 param component. */ -CF_PRIVATE CFRange _CFURIParserGetPathRange(const struct _URIParseInfo *parseInfo, Boolean includeSeparators, Boolean minusParam) +CF_PRIVATE CFRange _CFURIParserGetPathRange(const struct _URIParseInfo *parseInfo, Boolean includeSeparators) { CFRange result; - if ( minusParam && parseInfo->paramExists ) { - // end is paramOffset minus the ';' - result = CFRangeMake(parseInfo->pathOffset, parseInfo->paramOffset - parseInfo->pathOffset - (includeSeparators ? 0 : 1)); - } - else if ( parseInfo->queryExists ) { + if ( parseInfo->queryExists ) { // end is queryOffset minus the '?' result = CFRangeMake(parseInfo->pathOffset, parseInfo->queryOffset - parseInfo->pathOffset - (includeSeparators ? 0 : 1)); } @@ -1166,42 +1165,6 @@ CF_PRIVATE CFRange _CFURIParserGetPathRange(const struct _URIParseInfo *parseInf #if 0 // unused but might be needed in the future -/* - * Returns the range of the obsolete rfc1808 param component. - * - * If includeSeparators is true, the characters that separate the param - * from other components/subcomponents are included. - */ -static CFRange _CFURIParserGetParamRange(const struct _URIParseInfo *parseInfo, Boolean includeSeparators) -{ - CFRange result; - - if ( parseInfo->paramExists ) { - if ( parseInfo->queryExists ) { - // end is queryOffset minus the '?' - result = CFRangeMake(parseInfo->paramOffset, parseInfo->queryOffset - parseInfo->paramOffset - 1); - } - else if ( parseInfo->fragmentExists ) { - // end fragmentOffset is minus the '#' - result = CFRangeMake(parseInfo->paramOffset, parseInfo->fragmentOffset - parseInfo->paramOffset - 1); - } - else { - // end is endOffset - result = CFRangeMake(parseInfo->paramOffset, parseInfo->endOffset - parseInfo->paramOffset); - } - - if ( includeSeparators ) { - result.location--; - result.length += (parseInfo->queryExists || parseInfo->fragmentExists) ? 2 : 1; - } - } - else { - result = CFRangeMake(kCFNotFound, 0); - } - return ( result ); -} - - /* * Returns the range of the obsolete resource specifier component. * @@ -1212,11 +1175,7 @@ static CFRange _CFURIParserGetResourceSpecifierRange(const struct _URIParseInfo { CFRange result; - if ( parseInfo->paramExists ) { - // start is paramOffset; end is endOffset - result = CFRangeMake(parseInfo->paramOffset, parseInfo->endOffset - parseInfo->paramOffset); - } - else if ( parseInfo->queryExists ) { + if ( parseInfo->queryExists ) { // start is queryOffset; end is endOffset result = CFRangeMake(parseInfo->queryOffset, parseInfo->endOffset - parseInfo->queryOffset); } @@ -1382,7 +1341,7 @@ CF_PRIVATE Boolean _CFURIParserURLStringIsValid(CFStringRef urlString, struct _U if ( !result ) goto invalidComponent; // validate the path - componentRange = _CFURIParserGetPathRange(parseInfo, false, false); + componentRange = _CFURIParserGetPathRange(parseInfo, false); result = _CFURIParserValidateComponent(urlString, componentRange, kURLPathAllowed, true); if ( !result ) goto invalidComponent; diff --git a/CoreFoundation/URL.subproj/CFURLPriv.h b/CoreFoundation/URL.subproj/CFURLPriv.h index b4e677fa50..a600fc5acf 100644 --- a/CoreFoundation/URL.subproj/CFURLPriv.h +++ b/CoreFoundation/URL.subproj/CFURLPriv.h @@ -1,7 +1,7 @@ /* CFURLPriv.h - Copyright (c) 2008-2018, Apple Inc. and the Swift project authors + Copyright (c) 2008-2019, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -105,6 +105,18 @@ CF_EXPORT const CFStringRef _kCFURLIsRestrictedKey API_AVAILABLE(macos(10.11), i CF_EXPORT const CFStringRef _kCFURLIsSystemNoUnlinkKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); /* True if resource's SF_NOUNLINK flag is set (CFBoolean) */ +CF_EXPORT const CFStringRef _kCFURLIsSystemFirmlinkKey API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); + /* True if resource's SF_FIRMLINK flag is set (Read-only, value type CFBoolean) */ + +CF_EXPORT const CFStringRef _kCFURLIsSystemDatalessFaultKey API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); + /* True if resource's SF_DATALESS flag is set (Read-only, value type CFBoolean) */ + +CF_EXPORT const CFStringRef _kCFURLFileFlagsKey API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); + /* file flags from ATTR_CMN_FLAGS (same as stat(2)'s st_flags). (Read-only, UInt32 CFNumber) */ + +CF_EXPORT const CFStringRef _kCFURLGenerationCountKey API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); + /* the generation count from ATTR_CMN_GEN_COUNT. (Read-only, UInt32 CFNumber) */ + CF_EXPORT const CFStringRef _kCFURLIsApplicationKey API_DEPRECATED("Use kCFURLIsApplicationKey (API) instead", macos(10.6,10.11), ios(4.0,9.0), watchos(2.0,2.0), tvos(9.0,9.0)); /* Deprecated and scheduled for removal in 10.12/10.0 - Use the kCFURLIsApplicationKey or NSURLIsApplicationKey public property keys */ @@ -229,6 +241,18 @@ CF_EXPORT const CFStringRef _kCFURLApplicationPrefersExternalGPUKey API_AVAILABL CF_EXPORT const CFStringRef _kCFURLCanSetApplicationPrefersExternalGPUKey API_AVAILABLE(macos(10.14)) API_UNAVAILABLE(ios, watchos, tvos); /* False if app’s Info.plist specifies a eGPU policy, True if app does not specify an policy. Finder does not show a checkbox when this value is false. (Read-only, CFBoolean) */ +CF_EXPORT const CFStringRef _kCFURLApplicationDeviceManagementPolicyKey API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); + /* For app bundle URLs, value is the Device Management framework's policy for the application. If the value is unavailable, returns DMFPolicyOK. For non-app URLs, value is nil. The calling process must be properly entitled with the Device Management framework to use this property. (Read-only, value type CFNumber) */ + +CF_EXPORT const CFStringRef _kCFURLIsExcludedFromCloudBackupKey API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); + /* true if resource should be excluded from iCloud backups, false otherwise (Read-write, value type CFBoolean). */ + +CF_EXPORT const CFStringRef _kCFURLIsExcludedFromUnencryptedBackupKey API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); + /* true if resource should be excluded from unencrypted backups, false otherwise (Read-write, value type CFBoolean). */ + +CF_EXPORT const CFStringRef _kCFURLDeviceRefNumKey API_AVAILABLE(macos(10.15)) API_UNAVAILABLE(ios, watchos, tvos); + /* an unique per-volume non-persistent identifier for volumes (much like _kCFURLVolumeRefNumKey) that is also unique per-device when the volume is really two devices (i.e. ROSP) (64-bit integer CFNumber). */ + /* Additional volume properties */ CF_EXPORT const CFStringRef _kCFURLVolumeRefNumKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); @@ -432,7 +456,7 @@ typedef unsigned long long CFURLResourcePropertyFlags; CF_EXPORT Boolean _CFURLGetResourcePropertyFlags(CFURLRef url, CFURLResourcePropertyFlags mask, CFURLResourcePropertyFlags *flags, CFErrorRef *error) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); -#if TARGET_OS_MAC || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) +#if TARGET_OS_MAC || TARGET_OS_IPHONE /* File resource properties which can be obtained with _CFURLCopyFilePropertyValuesAndFlags(). */ @@ -506,23 +530,23 @@ typedef CF_OPTIONS(unsigned long long, CFURLVolumePropertyFlags) { kCFURLVolumeIsCD = 0x4000LL, kCFURLVolumeIsDVD = 0x8000LL, kCFURLVolumeIsDeviceFileSystem = 0x10000LL, - kCFURLVolumeIsTimeMachine CF_ENUM_AVAILABLE_MAC(10_9) + kCFURLVolumeIsTimeMachine API_AVAILABLE(macos(10.9)) API_UNAVAILABLE(ios, watchos, tvos) = 0x20000LL, - kCFURLVolumeIsAirport CF_ENUM_AVAILABLE_MAC(10_9) + kCFURLVolumeIsAirport API_AVAILABLE(macos(10.9)) API_UNAVAILABLE(ios, watchos, tvos) = 0x40000LL, - kCFURLVolumeIsVideoDisk CF_ENUM_AVAILABLE_MAC(10_9) + kCFURLVolumeIsVideoDisk API_AVAILABLE(macos(10.9)) API_UNAVAILABLE(ios, watchos, tvos) = 0x80000LL, - kCFURLVolumeIsDVDVideo CF_ENUM_AVAILABLE_MAC(10_9) + kCFURLVolumeIsDVDVideo API_AVAILABLE(macos(10.9)) API_UNAVAILABLE(ios, watchos, tvos) = 0x100000LL, - kCFURLVolumeIsBDVideo CF_ENUM_AVAILABLE_MAC(10_9) + kCFURLVolumeIsBDVideo API_AVAILABLE(macos(10.9)) API_UNAVAILABLE(ios, watchos, tvos) = 0x200000LL, - kCFURLVolumeIsMobileTimeMachine CF_ENUM_AVAILABLE_MAC(10_9) + kCFURLVolumeIsMobileTimeMachine API_AVAILABLE(macos(10.9)) API_UNAVAILABLE(ios, watchos, tvos) = 0x400000LL, - kCFURLVolumeIsNetworkOptical CF_ENUM_AVAILABLE_MAC(10_9) + kCFURLVolumeIsNetworkOptical API_AVAILABLE(macos(10.9)) API_UNAVAILABLE(ios, watchos, tvos) = 0x800000LL, - kCFURLVolumeIsBeingRepaired CF_ENUM_AVAILABLE_MAC(10_9) + kCFURLVolumeIsBeingRepaired API_AVAILABLE(macos(10.9)) API_UNAVAILABLE(ios, watchos, tvos) = 0x1000000LL, - kCFURLVolumeIsBeingUnmounted CF_ENUM_AVAILABLE_MAC(10_9) + kCFURLVolumeIsBeingUnmounted API_AVAILABLE(macos(10.9)) API_UNAVAILABLE(ios, watchos, tvos) = 0x2000000LL, kCFURLVolumeIsRootFileSystem API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)) = 0x4000000LL, @@ -676,6 +700,10 @@ CF_EXPORT void __CFURLSetResourceInfoPtr(CFURLRef url, void *ptr) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +/* Creates a URL from posixFilePath (only kCFURLPOSIXPathStyle paths are supported). It determines if the file system object is a directory or not to ensure the URL path is correctly terminated with a '/' or not. It also pre-caches the file system properties specified by keys. Note: not all resource properties can be pre-cached -- just those properties that come from the file system. */ +CF_EXPORT +CFURLRef _CFURLCreateWithFileSystemPathCachingResourcePropertiesForKeys(CFAllocatorRef allocator, CFStringRef posixFilePath, CFArrayRef keys, CFErrorRef *error) API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); + struct FSCatalogInfo; struct HFSUniStr255; @@ -720,7 +748,7 @@ void _CFURLSetPermanentResourcePropertyForKey(CFURLRef url, CFStringRef key, CFT CF_EXPORT CFStringRef _CFURLBookmarkCopyDescription(CFDataRef bookmarkRef) API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); -#if TARGET_OS_MAC || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) +#if TARGET_OS_MAC || TARGET_OS_IPHONE // private CFURLBookmarkCreationOptions enum { kCFURLBookmarkCreationWithFileProvider API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)) = ( 1UL << 26 ), // private option to create bookmarks with file provider string. The file provider string overrides the rest of the bookmark data at resolution time. @@ -728,7 +756,7 @@ enum { kCFURLBookmarkCreationAllowCreationIfResourceDoesNotExistMask = ( 1UL << 28 ), // allow creation of a bookmark to a file: scheme with a CFURLRef of item which may not exist. If the filesystem item does not exist, the created bookmark contains essentially no properties beyond the url string. Available 10_7, 5_0. kCFURLBookmarkCreationDoNotIncludeSandboxExtensionsMask = ( 1UL << 29 ), // If set, sandbox extensions are not included in created bookmarks. Ordinarily, bookmarks (except those created suitable for putting into a bookmark file) will have a sandbox extension added for the item. Available 10_7, NA. kCFURLBookmarkCreationAllowOnlyReadAccess API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) = ( 1UL << 30 ), // at resolution time only read access to the resource will be granted (works with regular non-security scoped bookmarks) - kCFURLBookmarkCreationSuitableForOdocAppleEvent CF_ENUM_DEPRECATED(10_6, 10_11, NA, NA, "kCFURLBookmarkCreationSuitableForOdocAppleEvent does nothing and has no effect on bookmark resolution" ) = ( 1UL << 31 ), // add properties we guarantee will be in an odoc AppleEvent. Available 10_10, NA (but supported back to 10.6). + kCFURLBookmarkCreationSuitableForOdocAppleEvent API_DEPRECATED("kCFURLBookmarkCreationSuitableForOdocAppleEvent does nothing and has no effect on bookmark resolution", macos(10.6, 10.11)) API_UNAVAILABLE(ios, watchos, tvos) = ( 1UL << 31 ), // add properties we guarantee will be in an odoc AppleEvent. Available 10_10, NA (but supported back to 10.6). }; // private CFURLBookmarkFileCreationOptions @@ -760,7 +788,7 @@ CF_EXPORT CFURLBookmarkMatchResult _CFURLBookmarkDataCompare(CFDataRef bookmark1Ref, CFDataRef bookmark2Ref, CFURLRef relativeToURL, CFArrayRef* matchingPropertyKeys) API_AVAILABLE(macos(10.7)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT -OSStatus _CFURLBookmarkDataToAliasHandle(CFDataRef bookmarkRef, void* aliasHandleP) API_AVAILABLE(macos(10.7)) API_UNAVAILABLE(ios, watchos, tvos); +OSStatus _CFURLBookmarkDataToAliasHandle(CFDataRef bookmarkRef, void* aliasHandleP) API_DEPRECATED("don't use AliasHandles", macos(10.7, 10.15)) API_UNAVAILABLE(ios, watchos, tvos); CF_EXPORT CFURLRef _CFURLCreateByResolvingAliasFile(CFAllocatorRef allocator, CFURLRef url, CFURLBookmarkResolutionOptions options, CFArrayRef propertiesToInclude, CFErrorRef *error ) API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); diff --git a/Foundation.xcodeproj/project.pbxproj b/Foundation.xcodeproj/project.pbxproj index 92dc677b40..74828c5c78 100644 --- a/Foundation.xcodeproj/project.pbxproj +++ b/Foundation.xcodeproj/project.pbxproj @@ -17,7 +17,6 @@ 153E951220111DC500F250BE /* CFKnownLocations.c in Sources */ = {isa = PBXBuildFile; fileRef = 153E951020111DC500F250BE /* CFKnownLocations.c */; }; 15496CF1212CAEBA00450F5A /* CFAttributedStringPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 15496CF0212CAEBA00450F5A /* CFAttributedStringPriv.h */; }; 15500FB722EA24D10088F082 /* CFXMLInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B40F9EC1C124F45000E72E3 /* CFXMLInterface.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1550102C22EA24D10088F082 /* CFXMLInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B40F9EB1C124F45000E72E3 /* CFXMLInterface.c */; }; 1550106D22EA25280088F082 /* module.map in Headers */ = {isa = PBXBuildFile; fileRef = 1550106B22EA25140088F082 /* module.map */; settings = {ATTRIBUTES = (Public, ); }; }; 1550107322EA266B0088F082 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B40F9F31C12524C000E72E3 /* libxml2.dylib */; }; 1550110D22EA268E0088F082 /* SwiftFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B5D885D1BBC938800234F36 /* SwiftFoundation.framework */; }; @@ -27,7 +26,6 @@ 1550111122EA26CA0088F082 /* XMLElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B8C1BD15DFF00C49C64 /* XMLElement.swift */; }; 1550111222EA26CA0088F082 /* XMLNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B8D1BD15DFF00C49C64 /* XMLNode.swift */; }; 1550111322EA26CA0088F082 /* XMLParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B8F1BD15DFF00C49C64 /* XMLParser.swift */; }; - 1550111422EA42780088F082 /* libCFXMLInterface.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1550106A22EA24D10088F082 /* libCFXMLInterface.a */; }; 1550111722EA43E00088F082 /* SwiftFoundationXML.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1550110922EA266B0088F082 /* SwiftFoundationXML.framework */; }; 1550111822EA43E00088F082 /* SwiftFoundationXML.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1550110922EA266B0088F082 /* SwiftFoundationXML.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 1550111B22EA43E20088F082 /* SwiftFoundationNetworking.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15B8043A228F376000B30FF6 /* SwiftFoundationNetworking.framework */; }; @@ -50,11 +48,16 @@ 1578DA13212B4C35003C9516 /* CFOverflow.h in Headers */ = {isa = PBXBuildFile; fileRef = 1578DA12212B4C35003C9516 /* CFOverflow.h */; }; 1578DA15212B6F33003C9516 /* CFCollections_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 1578DA14212B6F33003C9516 /* CFCollections_Internal.h */; }; 1581706322B1A29100348861 /* TestURLCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1581706222B1A29100348861 /* TestURLCache.swift */; }; + 158B66A32450D72E00892EFB /* CFNumber_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 158B66A22450D72E00892EFB /* CFNumber_Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 158B66A62450F0C400892EFB /* CFBundle_SplitFileName.c in Sources */ = {isa = PBXBuildFile; fileRef = 158B66A42450F0C300892EFB /* CFBundle_SplitFileName.c */; }; + 158B66A72450F0C400892EFB /* CFBundle_SplitFileName.h in Headers */ = {isa = PBXBuildFile; fileRef = 158B66A52450F0C400892EFB /* CFBundle_SplitFileName.h */; }; 158BCCAA2220A12600750239 /* TestDateIntervalFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 158BCCA92220A12600750239 /* TestDateIntervalFormatter.swift */; }; 158BCCAD2220A18F00750239 /* CFDateIntervalFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 158BCCAB2220A18F00750239 /* CFDateIntervalFormatter.h */; settings = {ATTRIBUTES = (Private, ); }; }; 158BCCAE2220A18F00750239 /* CFDateIntervalFormatter.c in Sources */ = {isa = PBXBuildFile; fileRef = 158BCCAC2220A18F00750239 /* CFDateIntervalFormatter.c */; }; 159870BE228F73F800ADE509 /* SwiftFoundationNetworking.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15B8043A228F376000B30FF6 /* SwiftFoundationNetworking.framework */; }; 159884921DCC877700E3314C /* TestHTTPCookieStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 159884911DCC877700E3314C /* TestHTTPCookieStorage.swift */; }; + 15A619DC245A2895003C8C62 /* libCFXMLInterface.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1550106A22EA24D10088F082 /* libCFXMLInterface.a */; }; + 15A619E0245A298C003C8C62 /* CFXMLInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = 15A619DF245A298C003C8C62 /* CFXMLInterface.c */; }; 15B80388228F376000B30FF6 /* libcurl.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B1FD9E01D6D178E0080E83C /* libcurl.3.dylib */; }; 15B8039E228F376000B30FF6 /* URLProtectionSpace.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B821BD15DFF00C49C64 /* URLProtectionSpace.swift */; }; 15B803B4228F376000B30FF6 /* URLCredential.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B7F1BD15DFF00C49C64 /* URLCredential.swift */; }; @@ -141,7 +144,6 @@ 5B2B59841C24D01100271109 /* CFConcreteStreams.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D89831BBDB13800234F36 /* CFConcreteStreams.c */; }; 5B4092101D1B304C0022B067 /* StringEncodings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B40920F1D1B304C0022B067 /* StringEncodings.swift */; }; 5B4092121D1B30B40022B067 /* ExtraStringAPIs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B4092111D1B30B40022B067 /* ExtraStringAPIs.swift */; }; - 5B40F9EF1C124F47000E72E3 /* CFXMLInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B40F9EB1C124F45000E72E3 /* CFXMLInterface.c */; }; 5B40F9F01C125011000E72E3 /* CFXMLInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B40F9EC1C124F45000E72E3 /* CFXMLInterface.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5B40F9F41C12524C000E72E3 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B40F9F31C12524C000E72E3 /* libxml2.dylib */; }; 5B424C761D0B6E5B007B39C8 /* IndexPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B424C751D0B6E5B007B39C8 /* IndexPath.swift */; }; @@ -188,10 +190,6 @@ 5B7C8A8F1BEA7FEC00C5B690 /* CFBinaryPList.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D89891BBDB1EF00234F36 /* CFBinaryPList.c */; }; 5B7C8A901BEA7FEC00C5B690 /* CFOldStylePList.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D898F1BBDBFB100234F36 /* CFOldStylePList.c */; }; 5B7C8A911BEA7FEC00C5B690 /* CFPropertyList.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88FB1BBC9B9500234F36 /* CFPropertyList.c */; }; - 5B7C8A921BEA7FEC00C5B690 /* CFXMLInputStream.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D89961BBDBFDA00234F36 /* CFXMLInputStream.c */; }; - 5B7C8A931BEA7FEC00C5B690 /* CFXMLNode.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D899A1BBDBFEA00234F36 /* CFXMLNode.c */; }; - 5B7C8A941BEA7FEC00C5B690 /* CFXMLParser.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D89931BBDBFCE00234F36 /* CFXMLParser.c */; }; - 5B7C8A951BEA7FEC00C5B690 /* CFXMLTree.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D899B1BBDBFEA00234F36 /* CFXMLTree.c */; }; 5B7C8A961BEA7FF900C5B690 /* CFBundle_Binary.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88EE1BBC9B5C00234F36 /* CFBundle_Binary.c */; }; 5B7C8A971BEA7FF900C5B690 /* CFBundle_Grok.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88ED1BBC9B5C00234F36 /* CFBundle_Grok.c */; }; 5B7C8A981BEA7FF900C5B690 /* CFBundle_InfoPlist.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88EB1BBC9B5C00234F36 /* CFBundle_InfoPlist.c */; }; @@ -199,9 +197,6 @@ 5B7C8A9A1BEA7FF900C5B690 /* CFBundle_Resources.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88EA1BBC9B5C00234F36 /* CFBundle_Resources.c */; }; 5B7C8A9B1BEA7FF900C5B690 /* CFBundle_Strings.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88EC1BBC9B5C00234F36 /* CFBundle_Strings.c */; }; 5B7C8A9C1BEA7FF900C5B690 /* CFBundle.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88E91BBC9B5C00234F36 /* CFBundle.c */; }; - 5B7C8A9D1BEA7FF900C5B690 /* CFPlugIn_Factory.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D894A1BBDA9EE00234F36 /* CFPlugIn_Factory.c */; }; - 5B7C8A9E1BEA7FF900C5B690 /* CFPlugIn_Instance.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D894B1BBDA9EE00234F36 /* CFPlugIn_Instance.c */; }; - 5B7C8A9F1BEA7FF900C5B690 /* CFPlugIn_PlugIn.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D89491BBDA9EE00234F36 /* CFPlugIn_PlugIn.c */; }; 5B7C8AA01BEA7FF900C5B690 /* CFPlugIn.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D89481BBDA9EE00234F36 /* CFPlugIn.c */; }; 5B7C8AA11BEA800400C5B690 /* CFApplicationPreferences.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D886A1BBC948300234F36 /* CFApplicationPreferences.c */; }; 5B7C8AA21BEA800400C5B690 /* CFPreferences.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D898B1BBDBF6500234F36 /* CFPreferences.c */; }; @@ -245,8 +240,6 @@ 5B7C8AD01BEA80FC00C5B690 /* CFNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B5D88D31BBC9AC500234F36 /* CFNumber.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5B7C8AD11BEA80FC00C5B690 /* CFTimeZone.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B5D88BE1BBC980100234F36 /* CFTimeZone.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5B7C8AD21BEA80FC00C5B690 /* CFPropertyList.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B5D88FA1BBC9B9500234F36 /* CFPropertyList.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5B7C8AD31BEA80FC00C5B690 /* CFXMLNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B5D89991BBDBFEA00234F36 /* CFXMLNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5B7C8AD41BEA80FC00C5B690 /* CFXMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B5D89911BBDBFC500234F36 /* CFXMLParser.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5B7C8AD51BEA80FC00C5B690 /* CFBundle.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B5D88E51BBC9B5C00234F36 /* CFBundle.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5B7C8AD61BEA80FC00C5B690 /* CFPlugIn.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B5D89451BBDA9EE00234F36 /* CFPlugIn.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5B7C8AD71BEA80FC00C5B690 /* CFPlugInCOM.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B5D89461BBDA9EE00234F36 /* CFPlugInCOM.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -270,7 +263,6 @@ 5B7C8AE91BEA81AC00C5B690 /* CFLocaleInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B5D88AE1BBC974700234F36 /* CFLocaleInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5B7C8AEA1BEA81AC00C5B690 /* CFICULogging.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BDC3F191BCC440100ED97BB /* CFICULogging.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5B7C8AEB1BEA81AC00C5B690 /* CFBigNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B5D891D1BBDA65F00234F36 /* CFBigNumber.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 5B7C8AEC1BEA81AC00C5B690 /* CFXMLInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B5D89951BBDBFDA00234F36 /* CFXMLInputStream.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5B7C8AED1BEA81AC00C5B690 /* CFBundle_BinaryTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B5D88E71BBC9B5C00234F36 /* CFBundle_BinaryTypes.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5B7C8AEE1BEA81AC00C5B690 /* CFBundle_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B5D88E81BBC9B5C00234F36 /* CFBundle_Internal.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5B7C8AEF1BEA81AC00C5B690 /* CFBundlePriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B5D88E61BBC9B5C00234F36 /* CFBundlePriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -530,13 +522,6 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 1550110B22EA26780088F082 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 5B5D88541BBC938800234F36 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 15500FA722EA24D10088F082; - remoteInfo = CFXMLInterface; - }; 1550111922EA43E00088F082 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 5B5D88541BBC938800234F36 /* Project object */; @@ -558,6 +543,13 @@ remoteGlobalIDString = 15B80384228F376000B30FF6; remoteInfo = SwiftFoundationNetworking; }; + 15A619DD245A2895003C8C62 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5B5D88541BBC938800234F36 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 15500FA722EA24D10088F082; + remoteInfo = CFXMLInterface; + }; 15B80386228F376000B30FF6 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 5B5D88541BBC938800234F36 /* Project object */; @@ -778,10 +770,14 @@ 1578DA12212B4C35003C9516 /* CFOverflow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFOverflow.h; sourceTree = ""; }; 1578DA14212B6F33003C9516 /* CFCollections_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFCollections_Internal.h; sourceTree = ""; }; 1581706222B1A29100348861 /* TestURLCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestURLCache.swift; sourceTree = ""; }; + 158B66A22450D72E00892EFB /* CFNumber_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFNumber_Private.h; sourceTree = ""; }; + 158B66A42450F0C300892EFB /* CFBundle_SplitFileName.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFBundle_SplitFileName.c; sourceTree = ""; }; + 158B66A52450F0C400892EFB /* CFBundle_SplitFileName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFBundle_SplitFileName.h; sourceTree = ""; }; 158BCCA92220A12600750239 /* TestDateIntervalFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestDateIntervalFormatter.swift; sourceTree = ""; }; 158BCCAB2220A18F00750239 /* CFDateIntervalFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFDateIntervalFormatter.h; sourceTree = ""; }; 158BCCAC2220A18F00750239 /* CFDateIntervalFormatter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFDateIntervalFormatter.c; sourceTree = ""; }; 159884911DCC877700E3314C /* TestHTTPCookieStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestHTTPCookieStorage.swift; sourceTree = ""; }; + 15A619DF245A298C003C8C62 /* CFXMLInterface.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFXMLInterface.c; sourceTree = ""; }; 15B8043A228F376000B30FF6 /* SwiftFoundationNetworking.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftFoundationNetworking.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 15F10CDB218909BF00D88114 /* TestNSCalendar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestNSCalendar.swift; sourceTree = ""; }; 15FCF4E223021C020095E52E /* TestSocketPort.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestSocketPort.swift; sourceTree = ""; }; @@ -817,7 +813,6 @@ 5B2A98CC1D021886008A0B75 /* NSCFCharacterSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSCFCharacterSet.swift; sourceTree = ""; }; 5B40920F1D1B304C0022B067 /* StringEncodings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringEncodings.swift; sourceTree = ""; }; 5B4092111D1B30B40022B067 /* ExtraStringAPIs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExtraStringAPIs.swift; sourceTree = ""; }; - 5B40F9EB1C124F45000E72E3 /* CFXMLInterface.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFXMLInterface.c; sourceTree = ""; }; 5B40F9EC1C124F45000E72E3 /* CFXMLInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFXMLInterface.h; sourceTree = ""; }; 5B40F9F11C125187000E72E3 /* TestXMLParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestXMLParser.swift; sourceTree = ""; }; 5B40F9F31C12524C000E72E3 /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; }; @@ -928,9 +923,6 @@ 5B5D89461BBDA9EE00234F36 /* CFPlugInCOM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFPlugInCOM.h; sourceTree = ""; }; 5B5D89471BBDA9EE00234F36 /* CFPlugIn_Factory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFPlugIn_Factory.h; sourceTree = ""; }; 5B5D89481BBDA9EE00234F36 /* CFPlugIn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFPlugIn.c; sourceTree = ""; }; - 5B5D89491BBDA9EE00234F36 /* CFPlugIn_PlugIn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFPlugIn_PlugIn.c; sourceTree = ""; }; - 5B5D894A1BBDA9EE00234F36 /* CFPlugIn_Factory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFPlugIn_Factory.c; sourceTree = ""; }; - 5B5D894B1BBDA9EE00234F36 /* CFPlugIn_Instance.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFPlugIn_Instance.c; sourceTree = ""; }; 5B5D89531BBDAA0100234F36 /* CFUUID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFUUID.h; sourceTree = ""; }; 5B5D89541BBDAA0100234F36 /* CFUUID.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFUUID.c; sourceTree = ""; }; 5B5D89571BBDAAC600234F36 /* CFBasicHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFBasicHash.h; sourceTree = ""; }; @@ -962,13 +954,6 @@ 5B5D898B1BBDBF6500234F36 /* CFPreferences.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFPreferences.c; sourceTree = ""; }; 5B5D898D1BBDBF8C00234F36 /* CFBuiltinConverters.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFBuiltinConverters.c; sourceTree = ""; }; 5B5D898F1BBDBFB100234F36 /* CFOldStylePList.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFOldStylePList.c; sourceTree = ""; }; - 5B5D89911BBDBFC500234F36 /* CFXMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFXMLParser.h; sourceTree = ""; }; - 5B5D89931BBDBFCE00234F36 /* CFXMLParser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFXMLParser.c; sourceTree = ""; }; - 5B5D89951BBDBFDA00234F36 /* CFXMLInputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFXMLInputStream.h; sourceTree = ""; }; - 5B5D89961BBDBFDA00234F36 /* CFXMLInputStream.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFXMLInputStream.c; sourceTree = ""; }; - 5B5D89991BBDBFEA00234F36 /* CFXMLNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFXMLNode.h; sourceTree = ""; }; - 5B5D899A1BBDBFEA00234F36 /* CFXMLNode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFXMLNode.c; sourceTree = ""; }; - 5B5D899B1BBDBFEA00234F36 /* CFXMLTree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFXMLTree.c; sourceTree = ""; }; 5B5D899F1BBDC01E00234F36 /* CFICUConverters.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFICUConverters.c; sourceTree = ""; }; 5B5D89A31BBDC04100234F36 /* CFPlatformConverters.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFPlatformConverters.c; sourceTree = ""; }; 5B5D89A51BBDC06800234F36 /* CFStringEncodingDatabase.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFStringEncodingDatabase.c; sourceTree = ""; }; @@ -1298,7 +1283,7 @@ files = ( 1550110D22EA268E0088F082 /* SwiftFoundation.framework in Frameworks */, 1550107322EA266B0088F082 /* libxml2.dylib in Frameworks */, - 1550111422EA42780088F082 /* libCFXMLInterface.a in Frameworks */, + 15A619DC245A2895003C8C62 /* libCFXMLInterface.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1593,6 +1578,7 @@ 5B5D88B81BBC97D100234F36 /* CFDate.h */, 5B5D88D41BBC9AC500234F36 /* CFNumber.c */, 5B5D88D31BBC9AC500234F36 /* CFNumber.h */, + 158B66A22450D72E00892EFB /* CFNumber_Private.h */, 5B5D88BF1BBC980100234F36 /* CFTimeZone.c */, 5B5D88BE1BBC980100234F36 /* CFTimeZone.h */, ); @@ -1633,10 +1619,7 @@ 5B5D88E91BBC9B5C00234F36 /* CFBundle.c */, 5B5D88E51BBC9B5C00234F36 /* CFBundle.h */, 5B5D88E61BBC9B5C00234F36 /* CFBundlePriv.h */, - 5B5D894A1BBDA9EE00234F36 /* CFPlugIn_Factory.c */, 5B5D89471BBDA9EE00234F36 /* CFPlugIn_Factory.h */, - 5B5D894B1BBDA9EE00234F36 /* CFPlugIn_Instance.c */, - 5B5D89491BBDA9EE00234F36 /* CFPlugIn_PlugIn.c */, 5B5D89481BBDA9EE00234F36 /* CFPlugIn.c */, 5B5D89451BBDA9EE00234F36 /* CFPlugIn.h */, 5B5D89461BBDA9EE00234F36 /* CFPlugInCOM.h */, @@ -1645,6 +1628,8 @@ 5BF9B7F41FABD5D300EE1A7C /* CFBundle_Main.c */, 5BF9B7F61FABD5D400EE1A7C /* CFBundle_ResourceFork.c */, 5BF9B7F71FABD5D400EE1A7C /* CFBundle_Tables.c */, + 158B66A52450F0C400892EFB /* CFBundle_SplitFileName.h */, + 158B66A42450F0C300892EFB /* CFBundle_SplitFileName.c */, ); name = PlugIn; path = CoreFoundation/PlugIn.subproj; @@ -1660,15 +1645,8 @@ 5B5D88FB1BBC9B9500234F36 /* CFPropertyList.c */, 5B5D88FA1BBC9B9500234F36 /* CFPropertyList.h */, 5BF9B7F11FABBDB000EE1A7C /* CFPropertyList_Private.h */, - 5B5D89961BBDBFDA00234F36 /* CFXMLInputStream.c */, - 5B5D89951BBDBFDA00234F36 /* CFXMLInputStream.h */, - 5B5D899A1BBDBFEA00234F36 /* CFXMLNode.c */, - 5B5D89991BBDBFEA00234F36 /* CFXMLNode.h */, - 5B5D89931BBDBFCE00234F36 /* CFXMLParser.c */, - 5B5D89911BBDBFC500234F36 /* CFXMLParser.h */, - 5B5D899B1BBDBFEA00234F36 /* CFXMLTree.c */, - 5B40F9EB1C124F45000E72E3 /* CFXMLInterface.c */, 5B40F9EC1C124F45000E72E3 /* CFXMLInterface.h */, + 15A619DF245A298C003C8C62 /* CFXMLInterface.c */, ); name = Parsing; path = CoreFoundation/Parsing.subproj; @@ -2321,7 +2299,6 @@ 5B7C8AC81BEA80FC00C5B690 /* CFSet.h in Headers */, 5B7C8ADC1BEA80FC00C5B690 /* CFSocket.h in Headers */, 5B7C8ACC1BEA80FC00C5B690 /* CFDateFormatter.h in Headers */, - 5B7C8AD41BEA80FC00C5B690 /* CFXMLParser.h in Headers */, 1578DA09212B4061003C9516 /* CFRuntime_Internal.h in Headers */, 5B7C8AD11BEA80FC00C5B690 /* CFTimeZone.h in Headers */, 5B7C8AC31BEA80FC00C5B690 /* CFBag.h in Headers */, @@ -2345,7 +2322,6 @@ 5B7C8ACB1BEA80FC00C5B690 /* CFCalendar.h in Headers */, 5B7C8AF81BEA81AC00C5B690 /* CFStringEncodingConverterPriv.h in Headers */, 5B7C8AC71BEA80FC00C5B690 /* CFDictionary.h in Headers */, - 5B7C8AEC1BEA81AC00C5B690 /* CFXMLInputStream.h in Headers */, 5B7C8ADF1BEA80FC00C5B690 /* CFString.h in Headers */, 5B7C8ABD1BEA806100C5B690 /* CFBase.h in Headers */, 5B7C8AED1BEA81AC00C5B690 /* CFBundle_BinaryTypes.h in Headers */, @@ -2374,7 +2350,6 @@ 5B7C8AE61BEA81AC00C5B690 /* ForSwiftFoundationOnly.h in Headers */, 5B7C8AC61BEA80FC00C5B690 /* CFData.h in Headers */, 5B7C8AC01BEA807A00C5B690 /* CFUUID.h in Headers */, - 5B7C8AD31BEA80FC00C5B690 /* CFXMLNode.h in Headers */, 5B7C8AC21BEA80FC00C5B690 /* CFArray.h in Headers */, 1578DA15212B6F33003C9516 /* CFCollections_Internal.h in Headers */, 5B7C8AFD1BEA81AC00C5B690 /* CFUnicodePrecomposition.h in Headers */, @@ -2394,6 +2369,7 @@ 5B7C8AEE1BEA81AC00C5B690 /* CFBundle_Internal.h in Headers */, 5B7C8AF01BEA81AC00C5B690 /* CFPlugIn_Factory.h in Headers */, 5B7C8AE41BEA81AC00C5B690 /* CFPriv.h in Headers */, + 158B66A32450D72E00892EFB /* CFNumber_Private.h in Headers */, 5B7C8AD91BEA80FC00C5B690 /* CFMachPort.h in Headers */, 5B7C8AE71BEA81AC00C5B690 /* CFBasicHash.h in Headers */, 5B7C8AC41BEA80FC00C5B690 /* CFBinaryHeap.h in Headers */, @@ -2413,6 +2389,7 @@ 5B6228BD1C179049009587FE /* CFRunArray.h in Headers */, 5B7C8ACE1BEA80FC00C5B690 /* CFNumberFormatter.h in Headers */, 1578DA13212B4C35003C9516 /* CFOverflow.h in Headers */, + 158B66A72450F0C400892EFB /* CFBundle_SplitFileName.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2451,8 +2428,8 @@ ); dependencies = ( F023078423F0BDF40023DBEC /* PBXTargetDependency */, - 1550110C22EA26780088F082 /* PBXTargetDependency */, 15F14D3A22EB9F80001598B5 /* PBXTargetDependency */, + 15A619DE245A2895003C8C62 /* PBXTargetDependency */, ); name = SwiftFoundationXML; productName = CoreFoundation; @@ -2772,7 +2749,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1550102C22EA24D10088F082 /* CFXMLInterface.c in Sources */, + 15A619E0245A298C003C8C62 /* CFXMLInterface.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2982,7 +2959,6 @@ 5B7C8AB71BEA801700C5B690 /* CFUnicodePrecomposition.c in Sources */, 5BF9B7FE1FABD5DA00EE1A7C /* CFBundle_DebugStrings.c in Sources */, 5B7C8A721BEA7FCE00C5B690 /* CFBase.c in Sources */, - 5B7C8A951BEA7FEC00C5B690 /* CFXMLTree.c in Sources */, 5B7C8AB81BEA802100C5B690 /* CFURLComponents_URIParser.c in Sources */, 5B7C8A8E1BEA7FE200C5B690 /* CFTimeZone.c in Sources */, 5B7C8A791BEA7FCE00C5B690 /* CFUUID.c in Sources */, @@ -2998,7 +2974,6 @@ 5B7C8AB01BEA801700C5B690 /* CFBuiltinConverters.c in Sources */, 5B7C8A761BEA7FCE00C5B690 /* CFSortFunctions.c in Sources */, 5B2B59831C24D00C00271109 /* CFSocketStream.c in Sources */, - 5B7C8A941BEA7FEC00C5B690 /* CFXMLParser.c in Sources */, 5B7C8AA11BEA800400C5B690 /* CFApplicationPreferences.c in Sources */, 5B2B59821C24D00500271109 /* CFStream.c in Sources */, 5B7C8A8B1BEA7FE200C5B690 /* CFBigNumber.c in Sources */, @@ -3011,7 +2986,6 @@ 5B7C8AB41BEA801700C5B690 /* CFStringEncodingDatabase.c in Sources */, 5B7C8A831BEA7FCE00C5B690 /* CFTree.c in Sources */, 5B7C8A981BEA7FF900C5B690 /* CFBundle_InfoPlist.c in Sources */, - 5B40F9EF1C124F47000E72E3 /* CFXMLInterface.c in Sources */, 5B7C8A961BEA7FF900C5B690 /* CFBundle_Binary.c in Sources */, 5B7C8AAC1BEA800D00C5B690 /* CFString.c in Sources */, 5B7C8A821BEA7FCE00C5B690 /* CFStorage.c in Sources */, @@ -3023,19 +2997,17 @@ 5B7C8A751BEA7FCE00C5B690 /* CFRuntime.c in Sources */, 5B7C8A7C1BEA7FCE00C5B690 /* CFBasicHash.c in Sources */, 61E011821C1B599A000037DD /* CFMachPort.c in Sources */, - 5B7C8A921BEA7FEC00C5B690 /* CFXMLInputStream.c in Sources */, 5B7C8AAA1BEA800D00C5B690 /* CFBurstTrie.c in Sources */, - 5B7C8A9E1BEA7FF900C5B690 /* CFPlugIn_Instance.c in Sources */, D51239DF1CD9DA0800D433EE /* CFSocket.c in Sources */, 5B7C8A801BEA7FCE00C5B690 /* CFDictionary.c in Sources */, 5BC2C00F1C07833200CC214E /* CFStringTransform.c in Sources */, + 158B66A62450F0C400892EFB /* CFBundle_SplitFileName.c in Sources */, 5B7C8AAE1BEA800D00C5B690 /* CFStringScanner.c in Sources */, 5B7C8A771BEA7FCE00C5B690 /* CFSystemDirectories.c in Sources */, 5B7C8AAD1BEA800D00C5B690 /* CFStringEncodings.c in Sources */, 5B7C8AB21BEA801700C5B690 /* CFPlatformConverters.c in Sources */, 5B7C8AB91BEA802100C5B690 /* CFURLComponents.c in Sources */, 1569BFA12187D04C009518FA /* CFCalendar_Enumerate.c in Sources */, - 5B7C8A9D1BEA7FF900C5B690 /* CFPlugIn_Factory.c in Sources */, 5B7C8A861BEA7FDB00C5B690 /* CFDateFormatter.c in Sources */, 5B7C8AAB1BEA800D00C5B690 /* CFCharacterSet.c in Sources */, 5B7C8A7A1BEA7FCE00C5B690 /* CFArray.c in Sources */, @@ -3056,14 +3028,12 @@ 5B7C8A9B1BEA7FF900C5B690 /* CFBundle_Strings.c in Sources */, 5B2B59841C24D01100271109 /* CFConcreteStreams.c in Sources */, 5B7C8A851BEA7FDB00C5B690 /* CFCalendar.c in Sources */, - 5B7C8A9F1BEA7FF900C5B690 /* CFPlugIn_PlugIn.c in Sources */, 5B7C8AB11BEA801700C5B690 /* CFICUConverters.c in Sources */, 1569BFA52187D0E0009518FA /* CFDateInterval.c in Sources */, 5B7C8A841BEA7FDB00C5B690 /* CFError.c in Sources */, 5B7C8A8D1BEA7FE200C5B690 /* CFNumber.c in Sources */, 5B7C8A991BEA7FF900C5B690 /* CFBundle_Locale.c in Sources */, 5B7C8A741BEA7FCE00C5B690 /* CFPlatform.c in Sources */, - 5B7C8A931BEA7FEC00C5B690 /* CFXMLNode.c in Sources */, 5B7C8A781BEA7FCE00C5B690 /* CFUtilities.c in Sources */, 5B7C8AB31BEA801700C5B690 /* CFStringEncodingConverter.c in Sources */, 5B6228BF1C179052009587FE /* CFAttributedString.c in Sources */, @@ -3213,11 +3183,6 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 1550110C22EA26780088F082 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 15500FA722EA24D10088F082 /* CFXMLInterface */; - targetProxy = 1550110B22EA26780088F082 /* PBXContainerItemProxy */; - }; 1550111A22EA43E00088F082 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 1550106E22EA266B0088F082 /* SwiftFoundationXML */; @@ -3233,6 +3198,11 @@ target = 15B80384228F376000B30FF6 /* SwiftFoundationNetworking */; targetProxy = 159870BF228F741000ADE509 /* PBXContainerItemProxy */; }; + 15A619DE245A2895003C8C62 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 15500FA722EA24D10088F082 /* CFXMLInterface */; + targetProxy = 15A619DD245A2895003C8C62 /* PBXContainerItemProxy */; + }; 15B80385228F376000B30FF6 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 5B7C8A6D1BEA7F8F00C5B690 /* CoreFoundation */; @@ -3987,6 +3957,7 @@ buildSettings = { CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_FLOAT_CONVERSION = YES_ERROR; CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_PREFIX = lib; @@ -4035,6 +4006,7 @@ buildSettings = { CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_FLOAT_CONVERSION = YES_ERROR; CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_PREFIX = lib; diff --git a/Sources/Foundation/NSURL.swift b/Sources/Foundation/NSURL.swift index 3b88be41dc..190e1f84ce 100644 --- a/Sources/Foundation/NSURL.swift +++ b/Sources/Foundation/NSURL.swift @@ -559,6 +559,7 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying { return CFURLCopyFragment(_cfObject, nil)?._swiftObject } + @available(swift, deprecated: 5.3, message: "The parameterString property is deprecated. When executing on Swift 5.3 or later, parameterString will always return nil, and the path method will return the complete path including the semicolon separator and params component if the URL string contains them.") open var parameterString: String? { return CFURLCopyParameterString(_cfObject, nil)?._swiftObject } diff --git a/Tests/Foundation/Resources/NSURLTestData.plist b/Tests/Foundation/Resources/NSURLTestData.plist index 443235abc0..c713b4b87f 100644 --- a/Tests/Foundation/Resources/NSURLTestData.plist +++ b/Tests/Foundation/Resources/NSURLTestData.plist @@ -3008,9 +3008,9 @@ baseURLString <null> deletingLastPathComponent - http://sega.com/pc/catalog/;$sessionid$MMBAWYIAABHS4CRSBUKCM4YKGIGQUMS0?PRODID=193 + http://sega.com/pc/catalog/?PRODID=193 deletingLastPathExtension - http://sega.com/pc/catalog/SegaProduct;$sessionid$MMBAWYIAABHS4CRSBUKCM4YKGIGQUMS0?PRODID=193 + http://sega.com/pc/catalog/SegaProduct?PRODID=193 fragment <null> host @@ -3018,7 +3018,9 @@ isFileURL NO lastPathComponent - SegaProduct.jhtml + SegaProduct.jhtml;$sessionid$MMBAWYIAABHS4CRSBUKCM4YKGIGQUMS0 + parameterString + <null> password <null> path @@ -3028,10 +3030,10 @@ / pc catalog - SegaProduct.jhtml + SegaProduct.jhtml;$sessionid$MMBAWYIAABHS4CRSBUKCM4YKGIGQUMS0 pathExtension - jhtml + jhtml;$sessionid$MMBAWYIAABHS4CRSBUKCM4YKGIGQUMS0 port <null> query @@ -3224,9 +3226,9 @@ baseURLString <null> deletingLastPathComponent - scheme://user:pass@host:1/path/path2/;params?query#fragment + scheme://user:pass@host:1/path/path2/?query#fragment deletingLastPathExtension - scheme://user:pass@host:1/path/path2/file;params?query#fragment + scheme://user:pass@host:1/path/path2/file?query#fragment fragment fragment host @@ -3234,7 +3236,9 @@ isFileURL NO lastPathComponent - file.html + file.html;params + parameterString + <null> password pass path @@ -3244,10 +3248,10 @@ / path path2 - file.html + file.html;params pathExtension - html + html;params port 1 query @@ -3442,7 +3446,7 @@ baseURLString <null> deletingLastPathComponent - scheme://us%60%58er:pass%60%58word@host%60%58name.com:80/pa%60%58th/;par%60%58ameter?qu%60%58ery=val%60%58ue&foo%60%58=bar#frag%60%58ment + scheme://us%60%58er:pass%60%58word@host%60%58name.com:80/pa%60%58th/?qu%60%58ery=val%60%58ue&foo%60%58=bar#frag%60%58ment deletingLastPathExtension scheme://us%60%58er:pass%60%58word@host%60%58name.com:80/pa%60%58th/na%60%58me;par%60%58ameter?qu%60%58ery=val%60%58ue&foo%60%58=bar#frag%60%58ment fragment @@ -3452,16 +3456,18 @@ isFileURL NO lastPathComponent - na`Xme + na`Xme;par`Xameter + parameterString + <null> password pass%60%58word path - /pa`Xth/na`Xme;par%60%58ameter + /pa`Xth/na`Xme;par`Xameter pathComponents / pa`Xth - na`Xme + na`Xme;par`Xameter pathExtension @@ -3470,7 +3476,7 @@ query qu%60%58ery=val%60%58ue&foo%60%58=bar relativePath - /pa`Xth/na`Xme;par%60%58ameter + /pa`Xth/na`Xme;par`Xameter relativeString scheme://us%60%58er:pass%60%58word@host%60%58name.com:80/pa%60%58th/na%60%58me;par%60%58ameter?qu%60%58ery=val%60%58ue&foo%60%58=bar#frag%60%58ment scheme @@ -3553,7 +3559,7 @@ http://test.com/unescaped%7Cpipe user <null> - + In-Title @@ -4950,9 +4956,9 @@ baseURLString <null> deletingLastPathComponent - http://ad.doubleclick.net/;h=v2%7C2e88%7C0%7C0%7C%2a%7Co;4461766;0-0;0;7314133;255-0%7C0;1407955%7C1406690%7C1;;%3fhttp://meninblack2.station.sony.com/playgames.jsp + http://ad.doubleclick.net/click;h=v2%7C2e88%7C0%7C0%7C%2a%7Co;4461766;0-0;0;7314133;255-0%7C0;1407955%7C1406690%7C1;;%3fhttp://meninblack2.station.sony.com/ deletingLastPathExtension - http://ad.doubleclick.net/click;h=v2%7C2e88%7C0%7C0%7C%2a%7Co;4461766;0-0;0;7314133;255-0%7C0;1407955%7C1406690%7C1;;%3fhttp://meninblack2.station.sony.com/playgames.jsp + http://ad.doubleclick.net/click;h=v2%7C2e88%7C0%7C0%7C%2a%7Co;4461766;0-0;0;7314133;255-0%7C0;1407955%7C1406690%7C1;;%3fhttp://meninblack2.station.sony.com/playgames fragment <null> host @@ -4960,24 +4966,28 @@ isFileURL NO lastPathComponent - click + playgames.jsp + parameterString + <null> password <null> path - /click;h=v2%7C2e88%7C0%7C0%7C%2a%7Co;4461766;0-0;0;7314133;255-0%7C0;1407955%7C1406690%7C1;;%3fhttp://meninblack2.station.sony.com/playgames.jsp + /click;h=v2|2e88|0|0|*|o;4461766;0-0;0;7314133;255-0|0;1407955|1406690|1;;?http://meninblack2.station.sony.com/playgames.jsp pathComponents / - click + click;h=v2|2e88|0|0|*|o;4461766;0-0;0;7314133;255-0|0;1407955|1406690|1;;?http: + meninblack2.station.sony.com + playgames.jsp pathExtension - + jsp port <null> query <null> relativePath - /click;h=v2%7C2e88%7C0%7C0%7C%2a%7Co;4461766;0-0;0;7314133;255-0%7C0;1407955%7C1406690%7C1;;%3fhttp://meninblack2.station.sony.com/playgames.jsp + /click;h=v2|2e88|0|0|*|o;4461766;0-0;0;7314133;255-0|0;1407955|1406690|1;;?http://meninblack2.station.sony.com/playgames.jsp relativeString http://ad.doubleclick.net/click;h=v2%7C2e88%7C0%7C0%7C%2a%7Co;4461766;0-0;0;7314133;255-0%7C0;1407955%7C1406690%7C1;;%3fhttp://meninblack2.station.sony.com/playgames.jsp scheme @@ -5730,7 +5740,9 @@ isFileURL NO lastPathComponent - path + path;param + parameterString + <null> password pass path @@ -5739,7 +5751,7 @@ / some - path + path;param pathExtension @@ -5748,7 +5760,7 @@ query name=value relativePath - ;param + relativeString #zoo scheme @@ -6311,7 +6323,9 @@ isFileURL NO lastPathComponent - path + path;param + parameterString + <null> password pass path @@ -6320,7 +6334,7 @@ / some - path + path;param pathExtension @@ -6329,7 +6343,7 @@ query ?? relativePath - ;param + relativeString ??? scheme @@ -6704,7 +6718,9 @@ isFileURL NO lastPathComponent - d + d;p + parameterString + <null> password <null> path @@ -6714,7 +6730,7 @@ / b c - d + d;p pathExtension @@ -6723,7 +6739,7 @@ query y relativePath - ;p + relativeString ?y scheme @@ -6820,7 +6836,9 @@ isFileURL NO lastPathComponent - d + d;p + parameterString + <null> password <null> path @@ -6830,7 +6848,7 @@ / b c - d + d;p pathExtension @@ -6839,7 +6857,7 @@ query q relativePath - ;p + relativeString #s scheme @@ -6978,13 +6996,13 @@ Out-NSResults absoluteString - http://a/b/c/d;x + http://a/b/c/;x absoluteURLString - http://a/b/c/d;x + http://a/b/c/;x baseURLString http://a/b/c/d;p?q deletingLastPathComponent - ;x + ./ deletingLastPathExtension ;x fragment @@ -6994,17 +7012,19 @@ isFileURL NO lastPathComponent - d + ;x + parameterString + <null> password <null> path - /b/c/d;x + /b/c/;x pathComponents / b c - d + ;x pathExtension @@ -7042,7 +7062,7 @@ baseURLString http://a/b/c/d;p?q deletingLastPathComponent - ./;x + ./ deletingLastPathExtension g;x fragment @@ -7052,7 +7072,9 @@ isFileURL NO lastPathComponent - g + g;x + parameterString + <null> password <null> path @@ -7062,7 +7084,7 @@ / b c - g + g;x pathExtension @@ -7100,7 +7122,7 @@ baseURLString http://a/b/c/d;p?q deletingLastPathComponent - ./;x?y#s + ./?y#s deletingLastPathExtension g;x?y#s fragment @@ -7110,7 +7132,9 @@ isFileURL NO lastPathComponent - g + g;x + parameterString + <null> password <null> path @@ -7120,7 +7144,7 @@ / b c - g + g;x pathExtension @@ -8306,13 +8330,13 @@ Out-NSResults absoluteString - http://a/b/c/g;x=1/./y + http://a/b/c/g;x=1/y absoluteURLString - http://a/b/c/g;x=1/./y + http://a/b/c/g;x=1/y baseURLString http://a/b/c/d;p?q deletingLastPathComponent - ./;x=1/./y + g;x=1/./ deletingLastPathExtension g;x=1/./y fragment @@ -8322,17 +8346,20 @@ isFileURL NO lastPathComponent - g + y + parameterString + <null> password <null> path - /b/c/g;x=1/./y + /b/c/g;x=1/y pathComponents / b c - g + g;x=1 + y pathExtension @@ -8347,7 +8374,7 @@ scheme http standardizedURL - g;x=1/./y + g;x=1/y user <null> @@ -8364,13 +8391,13 @@ Out-NSResults absoluteString - http://a/b/c/g;x=1/../y + http://a/b/c/y absoluteURLString - http://a/b/c/g;x=1/../y + http://a/b/c/y baseURLString http://a/b/c/d;p?q deletingLastPathComponent - ./;x=1/../y + g;x=1/../ deletingLastPathExtension g;x=1/../y fragment @@ -8380,17 +8407,19 @@ isFileURL NO lastPathComponent - g + y + parameterString + <null> password <null> path - /b/c/g;x=1/../y + /b/c/y pathComponents / b c - g + y pathExtension @@ -8405,7 +8434,7 @@ scheme http standardizedURL - g;x=1/../y + y user <null> @@ -9052,19 +9081,19 @@ In-URLCreator NSURLWithString In-Url - databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 + databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 Out-NSResults absoluteString - http://[fe80::7e6d:62ff:fe75:9e88%25en0]:3689/databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 + http://[fe80::7e6d:62ff:fe75:9e88%25en0]:3689/databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 absoluteURLString - http://[fe80::7e6d:62ff:fe75:9e88%25en0]:3689/databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 + http://[fe80::7e6d:62ff:fe75:9e88%25en0]:3689/databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 baseURLString http://[fe80::7e6d:62ff:fe75:9e88%25en0]:3689 deletingLastPathComponent - databases/76/containers/2891/?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 + databases/76/containers/2891/?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 deletingLastPathExtension - databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 + databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 fragment <null> host @@ -9091,15 +9120,15 @@ port 3689 query - sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 + sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 relativePath databases/76/containers/2891/items relativeString - databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 + databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 scheme http standardizedURL - databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 + databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 user <null> @@ -10319,7 +10348,7 @@ baseURLString <null> deletingLastPathComponent - http://a/b/c/;x=1/./y + http://a/b/c/g;x=1/./ deletingLastPathExtension http://a/b/c/g;x=1/./y fragment @@ -10329,7 +10358,9 @@ isFileURL NO lastPathComponent - g + y + parameterString + <null> password <null> path @@ -10339,7 +10370,9 @@ / b c - g + g;x=1 + . + y pathExtension @@ -10354,7 +10387,7 @@ scheme http standardizedURL - http://a/b/c/g;x=1/./y + http://a/b/c/g;x=1/y user <null> @@ -10375,7 +10408,7 @@ baseURLString <null> deletingLastPathComponent - http://a/b/c/;x=1/../y + http://a/b/c/g;x=1/../ deletingLastPathExtension http://a/b/c/g;x=1/../y fragment @@ -10385,7 +10418,9 @@ isFileURL NO lastPathComponent - g + y + parameterString + <null> password <null> path @@ -10395,7 +10430,9 @@ / b c - g + g;x=1 + .. + y pathExtension @@ -10410,7 +10447,7 @@ scheme http standardizedURL - http://a/b/c/g;x=1/../y + http://a/b/c/y user <null> @@ -12563,7 +12600,7 @@ In-URLCreator CFURLCreateWithString In-Url - databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 + databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 Out-NSResults <null url> @@ -14669,7 +14706,7 @@ In-URLCreator CFURLCreateWithBytes In-Url - databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 + databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 Out-NSResults <null url> @@ -16775,7 +16812,7 @@ In-URLCreator CFURLCreateAbsoluteURLWithBytes In-Url - databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 + databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 Out-NSResults <null url> @@ -19219,7 +19256,7 @@ In-URLCreator CFURLCreateWithBytes In-Url - databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 + databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 Out-NSResults <null url> @@ -21721,7 +21758,7 @@ In-URLCreator CFURLCreateWithBytes In-Url - databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 + databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 Out-NSResults <null url> @@ -24223,7 +24260,7 @@ In-URLCreator CFURLCreateWithBytes In-Url - databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 + databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 Out-NSResults <null url> @@ -26725,7 +26762,7 @@ In-URLCreator CFURLCreateWithBytes In-Url - databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 + databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 Out-NSResults <null url> @@ -29227,7 +29264,7 @@ In-URLCreator CFURLCreateWithBytes In-Url - databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 + databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 Out-NSResults <null url> @@ -31729,7 +31766,7 @@ In-URLCreator CFURLCreateWithBytes In-Url - databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 + databases/76/containers/2891/items?sort=dateadded&invert-sort-order=1&session-id=1866048351&query=(('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')+'daap.songdatakind:0')&meta=dmap.persistentid,dmap.itemname,daap.songalbum,com.apple.itunes.extended-media-kind,daap.songalbumid,daap.songformat,com.apple.itunes.gapless-heur,com.apple.itunes.gapless-enc-del,com.apple.itunes.gapless-enc-dr,com.apple.itunes.gapless-dur,com.apple.itunes.gapless-resy,com.apple.itunes.norm-volume,daap.songbookmark,daap.songhasbeenplayed,daap.songuserplaycount,daap.songtime,com.apple.itunes.is-hd-video,daap.songcontentrating,com.apple.itunes.content-rating,daap.songcontentdescription,daap.songlongcontentdescription,com.apple.itunes.movie-info-xml,daap.songstarttime,daap.songstoptime,com.apple.itunes.drm-key1-id,com.apple.itunes.rental-start,com.apple.itunes.drm-user-id,com.apple.itunes.rental-duration,com.apple.itunes.rental-pb-start,com.apple.itunes.rental-pb-duration,daap.songdateadded,com.apple.itunes.itms-songid,daap.songdisabled,dmap.itemid,com.apple.itunes.artworkchecksum&index=0-99 Out-NSResults <null url> diff --git a/Tests/Foundation/Tests/TestBridging.swift b/Tests/Foundation/Tests/TestBridging.swift index 417c80d3fd..c37c2f8634 100644 --- a/Tests/Foundation/Tests/TestBridging.swift +++ b/Tests/Foundation/Tests/TestBridging.swift @@ -30,6 +30,22 @@ class TestBridging : XCTestCase { } func testBridgedDescription() throws { + #if canImport(Foundation) && canImport(SwiftFoundation) + /* + Do not test this on Darwin. + On systems where swift-corelibs-foundation is the Foundation module, + the stdlib gives us the ability to specify how bridging works + (by using our __SwiftValue class), which is what we're testing + here when we do 'a as AnyObject'. But on Darwin, bridging is out + of SCF's hands — there is an ObjC __SwiftValue class vended by + the runtime. + Deceptively, below, when we say 'NSObject', we mean SwiftFoundation.NSObject, + not the ObjC NSObject class — which is what __SwiftValue actually + derives from. So, as? NSObject below returns nil on Darwin. + Since this functionality is tested by the stdlib tests on Darwin, + just skip this test here. + */ + #else // Struct with working (debug)description properties: let a = StructWithDescriptionAndDebugDescription() XCTAssertEqual("description", a.description) @@ -44,5 +60,6 @@ class TestBridging : XCTestCase { // to the wrapped description property. XCTAssertEqual("description", c.description) XCTAssertEqual("description", c.debugDescription) + #endif } } diff --git a/Tests/Foundation/Tests/TestURL.swift b/Tests/Foundation/Tests/TestURL.swift index 855e842fb7..dac98a213a 100644 --- a/Tests/Foundation/Tests/TestURL.swift +++ b/Tests/Foundation/Tests/TestURL.swift @@ -202,11 +202,15 @@ class TestURL : XCTestCase { internal func compareResults(_ url : URL, expected : [String : Any], got : [String : Any]) -> (Bool, [String]) { var differences = [String]() - for (key, obj) in expected { + for (key, expectation) in expected { // Skip non-string expected results if ["port", "standardizedURL", "pathComponents"].contains(key) { continue } + var obj: Any? = expectation + if obj as? String == kNullString { + obj = nil + } if let expectedValue = obj as? String { if let testedValue = got[key] as? String { if expectedValue != testedValue { @@ -231,6 +235,10 @@ class TestURL : XCTestCase { } else { differences.append(" \(key) Expected = '\(expectedValue)', Got = '\(String(describing: got[key]))'") } + } else if obj == nil { + if got[key] != nil && got[key] as? String != kNullString { + differences.append(" \(key) Expected = '\(String(describing: obj))', Got = '\(String(describing: got[key]))'") + } } } diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/alphaindex.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/alphaindex.h index 7969962e55..5f49b309f7 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/alphaindex.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/alphaindex.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -13,6 +15,7 @@ #include "unicode/utypes.h" #include "unicode/uobject.h" #include "unicode/locid.h" +#include "unicode/unistr.h" #if !UCONFIG_NO_COLLATION @@ -66,6 +69,7 @@ typedef enum UAlphabeticIndexLabelType { struct UHashtable; U_CDECL_END +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN // Forward Declarations @@ -263,6 +267,8 @@ class U_I18N_API AlphabeticIndex: public UObject { * Use getBucket() to get the bucket's properties. * * @param name the string to be sorted into an index bucket + * @param errorCode Error code, will be set with the reason if the + * operation fails. * @return the bucket number for the name * @stable ICU 51 */ @@ -374,9 +380,10 @@ class U_I18N_API AlphabeticIndex: public UObject { /** - * Get the default label used for abbreviated buckets between other index characters. - * For example, consider the labels when Latin and Greek are used: - * X Y Z ... Α Β Γ. + * Get the default label used for abbreviated buckets *between* other index characters. + * For example, consider the labels when Latin (X Y Z) and Greek (Α Β Γ) are used: + * + * X Y Z ... Α Β Γ. * * @return inflow label * @stable ICU 4.8 @@ -645,7 +652,7 @@ class U_I18N_API AlphabeticIndex: public UObject { /** * No assignment. */ - AlphabeticIndex &operator =(const AlphabeticIndex & /*other*/) { return *this;}; + AlphabeticIndex &operator =(const AlphabeticIndex & /*other*/) { return *this;} /** * No Equality operators. @@ -697,6 +704,7 @@ class U_I18N_API AlphabeticIndex: public UObject { /** * A (name, data) pair, to be sorted by name into one of the index buckets. * The user data is not used by the index implementation. + * \cond * @internal */ struct Record: public UMemory { @@ -705,6 +713,7 @@ class U_I18N_API AlphabeticIndex: public UObject { Record(const UnicodeString &name, const void *data); ~Record(); }; + /** \endcond */ #endif /* U_HIDE_INTERNAL_API */ private: @@ -747,6 +756,7 @@ class U_I18N_API AlphabeticIndex: public UObject { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // !UCONFIG_NO_COLLATION #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/appendable.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/appendable.h index a6a83b15cf..e6f7276bb8 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/appendable.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/appendable.h @@ -1,10 +1,12 @@ +// © 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 others. All Rights Reserved. ******************************************************************************* * file name: appendable.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -17,12 +19,13 @@ /** * \file - * \brief C++ API: Appendable class: Sink for Unicode code points and 16-bit code units (UChars). + * \brief C++ API: Appendable class: Sink for Unicode code points and 16-bit code units (char16_ts). */ #include "unicode/utypes.h" #include "unicode/uobject.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class UnicodeString; @@ -32,10 +35,10 @@ class UnicodeString; * Combines elements of Java Appendable and ICU4C ByteSink. * * This class can be used in APIs where it does not matter whether the actual destination is - * a UnicodeString, a UChar[] array, a UnicodeSet, or any other object + * a UnicodeString, a char16_t[] array, a UnicodeSet, or any other object * that receives and processes characters and/or strings. * - * Implementation classes must implement at least appendCodeUnit(UChar). + * Implementation classes must implement at least appendCodeUnit(char16_t). * The base class provides default implementations for the other methods. * * The methods do not take UErrorCode parameters. @@ -60,11 +63,11 @@ class U_COMMON_API Appendable : public UObject { * @return TRUE if the operation succeeded * @stable ICU 4.8 */ - virtual UBool appendCodeUnit(UChar c) = 0; + virtual UBool appendCodeUnit(char16_t c) = 0; /** * Appends a code point. - * The default implementation calls appendCodeUnit(UChar) once or twice. + * The default implementation calls appendCodeUnit(char16_t) once or twice. * @param c code point 0..0x10ffff * @return TRUE if the operation succeeded * @stable ICU 4.8 @@ -73,20 +76,20 @@ class U_COMMON_API Appendable : public UObject { /** * Appends a string. - * The default implementation calls appendCodeUnit(UChar) for each code unit. + * The default implementation calls appendCodeUnit(char16_t) for each code unit. * @param s string, must not be NULL if length!=0 * @param length string length, or -1 if NUL-terminated * @return TRUE if the operation succeeded * @stable ICU 4.8 */ - virtual UBool appendString(const UChar *s, int32_t length); + virtual UBool appendString(const char16_t *s, int32_t length); /** * Tells the object that the caller is going to append roughly - * appendCapacity UChars. A subclass might use this to pre-allocate + * appendCapacity char16_ts. A subclass might use this to pre-allocate * a larger buffer if necessary. * The default implementation does nothing. (It always returns TRUE.) - * @param appendCapacity estimated number of UChars that will be appended + * @param appendCapacity estimated number of char16_ts that will be appended * @return TRUE if the operation succeeded * @stable ICU 4.8 */ @@ -100,19 +103,19 @@ class U_COMMON_API Appendable : public UObject { * The returned buffer is only valid until the next operation * on this Appendable. * - * After writing at most *resultCapacity UChars, call appendString() with the - * pointer returned from this function and the number of UChars written. - * Many appendString() implementations will avoid copying UChars if this function + * After writing at most *resultCapacity char16_ts, call appendString() with the + * pointer returned from this function and the number of char16_ts written. + * Many appendString() implementations will avoid copying char16_ts if this function * returned an internal buffer. * * Partial usage example: * \code * int32_t capacity; - * UChar* buffer = app.getAppendBuffer(..., &capacity); - * ... Write n UChars into buffer, with n <= capacity. + * char16_t* buffer = app.getAppendBuffer(..., &capacity); + * ... Write n char16_ts into buffer, with n <= capacity. * app.appendString(buffer, n); * \endcode - * In many implementations, that call to append will avoid copying UChars. + * In many implementations, that call to append will avoid copying char16_ts. * * If the Appendable allocates or reallocates an internal buffer, it should use * the desiredCapacityHint if appropriate. @@ -136,9 +139,9 @@ class U_COMMON_API Appendable : public UObject { * @return a buffer with *resultCapacity>=minCapacity * @stable ICU 4.8 */ - virtual UChar *getAppendBuffer(int32_t minCapacity, + virtual char16_t *getAppendBuffer(int32_t minCapacity, int32_t desiredCapacityHint, - UChar *scratch, int32_t scratchCapacity, + char16_t *scratch, int32_t scratchCapacity, int32_t *resultCapacity); }; @@ -169,7 +172,7 @@ class U_COMMON_API UnicodeStringAppendable : public Appendable { * @return TRUE if the operation succeeded * @stable ICU 4.8 */ - virtual UBool appendCodeUnit(UChar c); + virtual UBool appendCodeUnit(char16_t c); /** * Appends a code point to the string. @@ -186,12 +189,12 @@ class U_COMMON_API UnicodeStringAppendable : public Appendable { * @return TRUE if the operation succeeded * @stable ICU 4.8 */ - virtual UBool appendString(const UChar *s, int32_t length); + virtual UBool appendString(const char16_t *s, int32_t length); /** * Tells the UnicodeString that the caller is going to append roughly - * appendCapacity UChars. - * @param appendCapacity estimated number of UChars that will be appended + * appendCapacity char16_ts. + * @param appendCapacity estimated number of char16_ts that will be appended * @return TRUE if the operation succeeded * @stable ICU 4.8 */ @@ -218,9 +221,9 @@ class U_COMMON_API UnicodeStringAppendable : public Appendable { * @return a buffer with *resultCapacity>=minCapacity * @stable ICU 4.8 */ - virtual UChar *getAppendBuffer(int32_t minCapacity, + virtual char16_t *getAppendBuffer(int32_t minCapacity, int32_t desiredCapacityHint, - UChar *scratch, int32_t scratchCapacity, + char16_t *scratch, int32_t scratchCapacity, int32_t *resultCapacity); private: @@ -228,5 +231,6 @@ class U_COMMON_API UnicodeStringAppendable : public Appendable { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // __APPENDABLE_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/basictz.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/basictz.h index f1e477f474..3beb2ed1ba 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/basictz.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/basictz.h @@ -1,3 +1,5 @@ +// © 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 @@ -20,6 +22,7 @@ #include "unicode/tzrule.h" #include "unicode/tztrans.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN // forward declarations @@ -206,6 +209,7 @@ class U_I18N_API BasicTimeZone: public TimeZone { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/brkiter.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/brkiter.h index 4aa5e55279..42a0fbfa1d 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/brkiter.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/brkiter.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** -* Copyright (C) 1997-2014, International Business Machines +* Copyright (C) 1997-2016, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************** * @@ -29,6 +31,7 @@ #if UCONFIG_NO_BREAK_ITERATION +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /* @@ -38,6 +41,7 @@ U_NAMESPACE_BEGIN class BreakIterator; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #else @@ -50,6 +54,7 @@ U_NAMESPACE_END #include "unicode/utext.h" #include "unicode/umisc.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -168,6 +173,11 @@ class U_COMMON_API BreakIterator : public UObject { /** * Change the text over which this operates. The text boundary is * reset to the start. + * + * The BreakIterator will retain a reference to the supplied string. + * The caller must not modify or delete the text while the BreakIterator + * retains the reference. + * * @param text The UnicodeString used to change the text. * @stable ICU 2.0 */ @@ -243,7 +253,7 @@ class U_COMMON_API BreakIterator : public UObject { virtual int32_t next(void) = 0; /** - * Return character index of the current interator position within the text. + * Return character index of the current iterator position within the text. * @return The boundary most recently returned. * @stable ICU 2.0 */ @@ -270,7 +280,7 @@ class U_COMMON_API BreakIterator : public UObject { virtual int32_t preceding(int32_t offset) = 0; /** - * Return true if the specfied position is a boundary position. + * Return true if the specified position is a boundary position. * As a side effect, the current position of the iterator is set * to the first boundary position at or following the specified offset. * @param offset the offset to check. @@ -285,21 +295,20 @@ class U_COMMON_API BreakIterator : public UObject { * does nothing. Negative values move to previous boundaries * and positive values move to later boundaries. * @return The new iterator position, or - * DONE if there are fewer than |n| boundaries in the specfied direction. + * DONE if there are fewer than |n| boundaries in the specified direction. * @stable ICU 2.0 */ virtual int32_t next(int32_t n) = 0; /** - * For RuleBasedBreakIterators, return the status tag from the - * break rule that determined the most recently - * returned break position. + * For RuleBasedBreakIterators, return the status tag from the break rule + * that determined the boundary at the current iteration position. *

* For break iterator types that do not support a rule status, * a default value of 0 is returned. *

- * @return the status from the break rule that determined the most recently - * returned break position. + * @return the status from the break rule that determined the boundary at + * the current iteration position. * @see RuleBaseBreakIterator::getRuleStatus() * @see UWordBreak * @stable ICU 52 @@ -307,8 +316,8 @@ class U_COMMON_API BreakIterator : public UObject { virtual int32_t getRuleStatus() const; /** - * For RuleBasedBreakIterators, get the status (tag) values from the break rule(s) - * that determined the most recently returned break position. + * For RuleBasedBreakIterators, get the status (tag) values from the break rule(s) + * that determined the boundary at the current iteration position. *

* For break iterator types that do not support rule status, * no values are returned. @@ -324,10 +333,10 @@ class U_COMMON_API BreakIterator : public UObject { * @param fillInVec an array to be filled in with the status values. * @param capacity the length of the supplied vector. A length of zero causes * the function to return the number of status values, in the - * normal way, without attemtping to store any values. + * normal way, without attempting to store any values. * @param status receives error codes. * @return The number of rule status values from rules that determined - * the most recent boundary returned by the break iterator. + * the boundary at the current iteration position. * In the event of a U_BUFFER_OVERFLOW_ERROR, the return value * is the total number of status values that were available, * not the reduced number that were actually returned. @@ -425,12 +434,13 @@ class U_COMMON_API BreakIterator : public UObject { static BreakIterator* U_EXPORT2 createSentenceInstance(const Locale& where, UErrorCode& status); +#ifndef U_HIDE_DEPRECATED_API /** * Create BreakIterator for title-casing breaks using the specified locale * Returns an instance of a BreakIterator implementing title breaks. * The iterator returned locates title boundaries as described for * Unicode 3.2 only. For Unicode 4.0 and above title boundary iteration, - * please use Word Boundary iterator.{@link #createWordInstance } + * please use a word boundary iterator. See {@link #createWordInstance }. * * @param where the locale. * @param status The error code. @@ -445,10 +455,11 @@ class U_COMMON_API BreakIterator : public UObject { * used; neither the requested locale nor any of its fall back locales * could be found. * The caller owns the returned object and is responsible for deleting it. - * @stable ICU 2.1 + * @deprecated ICU 64 Use createWordInstance instead. */ static BreakIterator* U_EXPORT2 createTitleInstance(const Locale& where, UErrorCode& status); +#endif /* U_HIDE_DEPRECATED_API */ /** * Get the set of Locales for which TextBoundaries are installed. @@ -462,7 +473,7 @@ class U_COMMON_API BreakIterator : public UObject { static const Locale* U_EXPORT2 getAvailableLocales(int32_t& count); /** - * Get name of the object for the desired Locale, in the desired langauge. + * Get name of the object for the desired Locale, in the desired language. * @param objectLocale must be from getAvailableLocales. * @param displayLocale specifies the desired locale for output. * @param name the fill-in parameter of the return value @@ -475,7 +486,7 @@ class U_COMMON_API BreakIterator : public UObject { UnicodeString& name); /** - * Get name of the object for the desired Locale, in the langauge of the + * Get name of the object for the desired Locale, in the language of the * default locale. * @param objectLocale must be from getMatchingLocales * @param name the fill-in parameter of the return value @@ -608,8 +619,17 @@ class U_COMMON_API BreakIterator : public UObject { */ virtual BreakIterator &refreshInputText(UText *input, UErrorCode &status) = 0; +#ifndef U_HIDE_INTERNAL_API + /** + * Set the ULineWordOptions for this break iterator. + * @param lineWordOpts The ULineWordOptions to set. + * @internal Apple only + */ + void setLineWordOpts(ULineWordOptions lineWordOpts); +#endif /* U_HIDE_INTERNAL_API */ + private: - static BreakIterator* buildInstance(const Locale& loc, const char *type, int32_t kind, UErrorCode& status); + static BreakIterator* buildInstance(const Locale& loc, const char *type, UErrorCode& status); static BreakIterator* createInstance(const Locale& loc, int32_t kind, UErrorCode& status); static BreakIterator* makeInstance(const Locale& loc, int32_t kind, UErrorCode& status); @@ -622,22 +642,27 @@ class U_COMMON_API BreakIterator : public UObject { /** @internal */ BreakIterator(); /** @internal */ - BreakIterator (const BreakIterator &other) : UObject(other) {} + BreakIterator (const BreakIterator &other); +#ifndef U_HIDE_INTERNAL_API /** @internal */ - BreakIterator (const Locale& valid, const Locale& actual); + BreakIterator (const Locale& valid, const Locale &actual); + /** @internal. Assignment Operator, used by RuleBasedBreakIterator. */ + BreakIterator &operator = (const BreakIterator &other); +#endif /* U_HIDE_INTERNAL_API */ + ULineWordOptions fLineWordOpts; + private: - /** @internal */ + /** @internal (private) */ char actualLocale[ULOC_FULLNAME_CAPACITY]; char validLocale[ULOC_FULLNAME_CAPACITY]; - - /** - * The assignment operator has no real implementation. - * It's provided to make the compiler happy. Do not call. - */ - BreakIterator& operator=(const BreakIterator&); }; +inline void BreakIterator::setLineWordOpts(ULineWordOptions lineWordOpts) +{ + fLineWordOpts = lineWordOpts; +} + #ifndef U_HIDE_DEPRECATED_API inline UBool BreakIterator::isBufferClone() @@ -648,8 +673,9 @@ inline UBool BreakIterator::isBufferClone() #endif /* U_HIDE_DEPRECATED_API */ U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_BREAK_ITERATION */ -#endif // _BRKITER +#endif // BRKITER_H //eof diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/bytestream.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/bytestream.h index 174aa38afc..b12e64d736 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/bytestream.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/bytestream.h @@ -1,3 +1,5 @@ +// © 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 others. All Rights Reserved. // @@ -39,6 +41,7 @@ #include "unicode/uobject.h" #include "unicode/std_string.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -124,8 +127,8 @@ class U_COMMON_API ByteSink : public UMemory { virtual void Flush(); private: - ByteSink(const ByteSink &); // copy constructor not implemented - ByteSink &operator=(const ByteSink &); // assignment operator not implemented + ByteSink(const ByteSink &) = delete; + ByteSink &operator=(const ByteSink &) = delete; }; // ------------------------------------------------------------- @@ -215,12 +218,11 @@ class U_COMMON_API CheckedArrayByteSink : public ByteSink { int32_t size_; int32_t appended_; UBool overflowed_; - CheckedArrayByteSink(); ///< default constructor not implemented - CheckedArrayByteSink(const CheckedArrayByteSink &); ///< copy constructor not implemented - CheckedArrayByteSink &operator=(const CheckedArrayByteSink &); ///< assignment operator not implemented -}; -#if U_HAVE_STD_STRING + CheckedArrayByteSink() = delete; + CheckedArrayByteSink(const CheckedArrayByteSink &) = delete; + CheckedArrayByteSink &operator=(const CheckedArrayByteSink &) = delete; +}; /** * Implementation of ByteSink that writes to a "string". @@ -236,6 +238,19 @@ class StringByteSink : public ByteSink { * @stable ICU 4.2 */ StringByteSink(StringClass* dest) : dest_(dest) { } + /** + * Constructs a ByteSink that reserves append capacity and will append bytes to the dest string. + * + * @param dest pointer to string object to append to + * @param initialAppendCapacity capacity beyond dest->length() to be reserve()d + * @stable ICU 60 + */ + StringByteSink(StringClass* dest, int32_t initialAppendCapacity) : dest_(dest) { + if (initialAppendCapacity > 0 && + (uint32_t)initialAppendCapacity > (dest->capacity() - dest->length())) { + dest->reserve(dest->length() + initialAppendCapacity); + } + } /** * Append "bytes[0,n-1]" to this. * @param data the pointer to the bytes @@ -245,13 +260,13 @@ class StringByteSink : public ByteSink { virtual void Append(const char* data, int32_t n) { dest_->append(data, n); } private: StringClass* dest_; - StringByteSink(); ///< default constructor not implemented - StringByteSink(const StringByteSink &); ///< copy constructor not implemented - StringByteSink &operator=(const StringByteSink &); ///< assignment operator not implemented -}; -#endif + StringByteSink() = delete; + StringByteSink(const StringByteSink &) = delete; + StringByteSink &operator=(const StringByteSink &) = delete; +}; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // __BYTESTREAM_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/bytestrie.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/bytestrie.h index 9c7782740d..56b41b6fa8 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/bytestrie.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/bytestrie.h @@ -1,10 +1,12 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2010-2012, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* * file name: bytestrie.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -25,6 +27,7 @@ #include "unicode/uobject.h" #include "unicode/ustringtrie.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class ByteSink; @@ -306,7 +309,7 @@ class U_COMMON_API BytesTrie : public UMemory { * @return The NUL-terminated byte sequence for the last successful next(). * @stable ICU 4.8 */ - const StringPiece &getString() const { return sp_; } + StringPiece getString() const; /** * @return The value for the last successful next(). * @stable ICU 4.8 @@ -325,7 +328,6 @@ class U_COMMON_API BytesTrie : public UMemory { int32_t initialRemainingMatchLength_; CharString *str_; - StringPiece sp_; int32_t maxLength_; int32_t value_; @@ -515,5 +517,6 @@ class U_COMMON_API BytesTrie : public UMemory { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // __BYTESTRIE_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/bytestriebuilder.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/bytestriebuilder.h index d00ab9b3b0..652ba55fbf 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/bytestriebuilder.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/bytestriebuilder.h @@ -1,10 +1,12 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* -* Copyright (C) 2010-2014, International Business Machines +* Copyright (C) 2010-2016, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* * file name: bytestriebuilder.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -25,11 +27,11 @@ #include "unicode/stringpiece.h" #include "unicode/stringtriebuilder.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class BytesTrieElement; class CharString; - /** * Builder class for BytesTrie. * @@ -65,7 +67,7 @@ class U_COMMON_API BytesTrieBuilder : public StringTrieBuilder { * @return *this * @stable ICU 4.8 */ - BytesTrieBuilder &add(const StringPiece &s, int32_t value, UErrorCode &errorCode); + BytesTrieBuilder &add(StringPiece s, int32_t value, UErrorCode &errorCode); /** * Builds a BytesTrie for the add()ed data. @@ -126,14 +128,14 @@ class U_COMMON_API BytesTrieBuilder : public StringTrieBuilder { void buildBytes(UStringTrieBuildOption buildOption, UErrorCode &errorCode); virtual int32_t getElementStringLength(int32_t i) const; - virtual UChar getElementUnit(int32_t i, int32_t byteIndex) const; + virtual char16_t getElementUnit(int32_t i, int32_t byteIndex) const; virtual int32_t getElementValue(int32_t i) const; virtual int32_t getLimitOfLinearMatch(int32_t first, int32_t last, int32_t byteIndex) const; virtual int32_t countElementUnits(int32_t start, int32_t limit, int32_t byteIndex) const; virtual int32_t skipElementsBySomeUnits(int32_t i, int32_t byteIndex, int32_t count) const; - virtual int32_t indexOfElementWithNextUnit(int32_t i, int32_t byteIndex, UChar byte) const; + virtual int32_t indexOfElementWithNextUnit(int32_t i, int32_t byteIndex, char16_t byte) const; virtual UBool matchNodesCanHaveValues() const { return FALSE; } @@ -142,7 +144,7 @@ class U_COMMON_API BytesTrieBuilder : public StringTrieBuilder { virtual int32_t getMaxLinearMatchLength() const { return BytesTrie::kMaxLinearMatchLength; } /** - * @internal + * @internal (private) */ class BTLinearMatchNode : public LinearMatchNode { public: @@ -152,7 +154,7 @@ class U_COMMON_API BytesTrieBuilder : public StringTrieBuilder { private: const char *s; }; - + virtual Node *createLinearMatchNode(int32_t i, int32_t byteIndex, int32_t length, Node *nextNode) const; @@ -177,5 +179,6 @@ class U_COMMON_API BytesTrieBuilder : public StringTrieBuilder { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // __BYTESTRIEBUILDER_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/calendar.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/calendar.h index 7f531ad09f..c22328d8ef 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/calendar.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/calendar.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 1997-2014, International Business Machines @@ -28,7 +30,7 @@ #include "unicode/utypes.h" /** - * \file + * \file * \brief C++ API: Calendar object */ #if !UCONFIG_NO_FORMATTING @@ -39,6 +41,7 @@ #include "unicode/ucal.h" #include "unicode/umisc.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class ICUServiceFactory; @@ -50,83 +53,64 @@ typedef int32_t UFieldResolutionTable[12][8]; class BasicTimeZone; /** - * Calendar is an abstract base class for converting between - * a UDate object and a set of integer fields such as - * YEAR, MONTH, DAY, HOUR, - * and so on. (A UDate object represents a specific instant in + * `Calendar` is an abstract base class for converting between + * a `UDate` object and a set of integer fields such as + * `YEAR`, `MONTH`, `DAY`, `HOUR`, and so on. + * (A `UDate` object represents a specific instant in * time with millisecond precision. See UDate - * for information about the UDate class.) + * for information about the `UDate` class.) * - *

- * Subclasses of Calendar interpret a UDate + * Subclasses of `Calendar` interpret a `UDate` * according to the rules of a specific calendar system. - * The most commonly used subclass of Calendar is - * GregorianCalendar. Other subclasses could represent + * The most commonly used subclass of `Calendar` is + * `GregorianCalendar`. Other subclasses could represent * the various types of lunar calendars in use in many parts of the world. * - *

- * NOTE: (ICU 2.6) The subclass interface should be considered unstable - * - it WILL change. + * **NOTE**: (ICU 2.6) The subclass interface should be considered unstable - + * it WILL change. * - *

- * Like other locale-sensitive classes, Calendar provides a - * static method, createInstance, for getting a generally useful - * object of this type. Calendar's createInstance method - * returns the appropriate Calendar subclass whose + * Like other locale-sensitive classes, `Calendar` provides a + * static method, `createInstance`, for getting a generally useful + * object of this type. `Calendar`'s `createInstance` method + * returns the appropriate `Calendar` subclass whose * time fields have been initialized with the current date and time: - * \htmlonly

\endhtmlonly - *
- * Calendar *rightNow = Calendar::createInstance(errCode);
- * 
- * \htmlonly
\endhtmlonly * - *

- * A Calendar object can produce all the time field values + * Calendar *rightNow = Calendar::createInstance(errCode); + * + * A `Calendar` object can produce all the time field values * needed to implement the date-time formatting for a particular language * and calendar style (for example, Japanese-Gregorian, Japanese-Traditional). * - *

- * When computing a UDate from time fields, some special circumstances + * When computing a `UDate` from time fields, some special circumstances * may arise: there may be insufficient information to compute the - * UDate (such as only year and month but no day in the month), + * `UDate` (such as only year and month but no day in the month), * there may be inconsistent information (such as "Tuesday, July 15, 1996" * -- July 15, 1996 is actually a Monday), or the input time might be ambiguous * because of time zone transition. * - *

- * Insufficient information. The calendar will use default + * **Insufficient information.** The calendar will use default * information to specify the missing fields. This may vary by calendar; for * the Gregorian calendar, the default for a field is the same as that of the * start of the epoch: i.e., YEAR = 1970, MONTH = JANUARY, DATE = 1, etc. * - *

- * Inconsistent information. If fields conflict, the calendar + * **Inconsistent information.** If fields conflict, the calendar * will give preference to fields set more recently. For example, when * determining the day, the calendar will look for one of the following * combinations of fields. The most recent combination, as determined by the * most recently set single field, will be used. * - * \htmlonly

\endhtmlonly - *
- * MONTH + DAY_OF_MONTH
- * MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
- * MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
- * DAY_OF_YEAR
- * DAY_OF_WEEK + WEEK_OF_YEAR
- * 
- * \htmlonly
\endhtmlonly + * MONTH + DAY_OF_MONTH + * MONTH + WEEK_OF_MONTH + DAY_OF_WEEK + * MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK + * DAY_OF_YEAR + * DAY_OF_WEEK + WEEK_OF_YEAR * * For the time of day: * - * \htmlonly
\endhtmlonly - *
- * HOUR_OF_DAY
- * AM_PM + HOUR
- * 
- * \htmlonly
\endhtmlonly + * HOUR_OF_DAY + * AM_PM + HOUR * - *

- * Ambiguous Wall Clock Time. When time offset from UTC has + * **Ambiguous Wall Clock Time.** When time offset from UTC has * changed, it produces an ambiguous time slot around the transition. For example, * many US locations observe daylight saving time. On the date switching to daylight * saving time in US, wall clock time jumps from 12:59 AM (standard) to 2:00 AM @@ -135,65 +119,67 @@ class BasicTimeZone; * Calendar resolves the time using the UTC offset before the transition by default. * In this example, 1:30 AM is interpreted as 1:30 AM standard time (non-exist), * so the final result will be 2:30 AM daylight time. - * - *

On the date switching back to standard time, wall clock time is moved back one + * + * On the date switching back to standard time, wall clock time is moved back one * hour at 2:00 AM. So wall clock time from 1:00 AM to 1:59 AM occur twice. In this * case, the ICU Calendar resolves the time using the UTC offset after the transition * by default. For example, 1:30 AM on the date is resolved as 1:30 AM standard time. * - *

Ambiguous wall clock time resolution behaviors can be customized by Calendar APIs + * Ambiguous wall clock time resolution behaviors can be customized by Calendar APIs * {@link #setRepeatedWallTimeOption} and {@link #setSkippedWallTimeOption}. * These methods are available in ICU 49 or later versions. * - *

- * Note: for some non-Gregorian calendars, different + * **Note:** for some non-Gregorian calendars, different * fields may be necessary for complete disambiguation. For example, a full - * specification of the historial Arabic astronomical calendar requires year, - * month, day-of-month and day-of-week in some cases. + * specification of the historical Arabic astronomical calendar requires year, + * month, day-of-month *and* day-of-week in some cases. * - *

- * Note: There are certain possible ambiguities in + * **Note:** There are certain possible ambiguities in * interpretation of certain singular times, which are resolved in the * following ways: - *

    - *
  1. 24:00:00 "belongs" to the following day. That is, - * 23:59 on Dec 31, 1969 < 24:00 on Jan 1, 1970 < 24:01:00 on Jan 1, 1970 * - *
  2. Although historically not precise, midnight also belongs to "am", - * and noon belongs to "pm", so on the same day, - * 12:00 am (midnight) < 12:01 am, and 12:00 pm (noon) < 12:01 pm - *
+ * 1. 24:00:00 "belongs" to the following day. That is, + * 23:59 on Dec 31, 1969 < 24:00 on Jan 1, 1970 < 24:01:00 on Jan 1, 1970 + * 2. Although historically not precise, midnight also belongs to "am", + * and noon belongs to "pm", so on the same day, + * 12:00 am (midnight) < 12:01 am, and 12:00 pm (noon) < 12:01 pm * - *

* The date or time format strings are not part of the definition of a * calendar, as those must be modifiable or overridable by the user at - * runtime. Use {@link DateFormat} - * to format dates. + * runtime. Use `DateFormat` to format dates. * - *

- * Calendar provides an API for field "rolling", where fields + * `Calendar` provides an API for field "rolling", where fields * can be incremented or decremented, but wrap around. For example, rolling the - * month up in the date December 12, 1996 results in - * January 12, 1996. + * month up in the date December 12, **1996** results in + * January 12, **1996**. * - *

- * Calendar also provides a date arithmetic function for + * `Calendar` also provides a date arithmetic function for * adding the specified (signed) amount of time to a particular time field. - * For example, subtracting 5 days from the date September 12, 1996 - * results in September 7, 1996. + * For example, subtracting 5 days from the date `September 12, 1996` + * results in `September 7, 1996`. * - *

Supported range + * ***Supported range*** * - *

The allowable range of Calendar has been - * narrowed. GregorianCalendar used to attempt to support - * the range of dates with millisecond values from - * Long.MIN_VALUE to Long.MAX_VALUE. - * The new Calendar protocol specifies the + * The allowable range of `Calendar` has been narrowed. `GregorianCalendar` used + * to attempt to support the range of dates with millisecond values from + * `Long.MIN_VALUE` to `Long.MAX_VALUE`. The new `Calendar` protocol specifies the * maximum range of supportable dates as those having Julian day numbers - * of -0x7F000000 to +0x7F000000. This - * corresponds to years from ~5,800,000 BCE to ~5,800,000 CE. Programmers - * should use the protected constants in Calendar to - * specify an extremely early or extremely late date.

+ * of `-0x7F000000` to `+0x7F000000`. This corresponds to years from ~5,800,000 BCE + * to ~5,800,000 CE. Programmers should use the protected constants in `Calendar` to + * specify an extremely early or extremely late date. + * + *

+ * The Japanese calendar uses a combination of era name and year number. + * When an emperor of Japan abdicates and a new emperor ascends the throne, + * a new era is declared and year number is reset to 1. Even if the date of + * abdication is scheduled ahead of time, the new era name might not be + * announced until just before the date. In such case, ICU4C may include + * a start date of future era without actual era name, but not enabled + * by default. ICU4C users who want to test the behavior of the future era + * can enable the tentative era by: + *

    + *
  • Environment variable ICU_ENABLE_TENTATIVE_ERA=true.
  • + *
* * @stable ICU 2.0 */ @@ -233,7 +219,7 @@ class U_I18N_API Calendar : public UObject { DST_OFFSET, // Example: 0 or U_MILLIS_PER_HOUR YEAR_WOY, // 'Y' Example: 1..big number - Year of Week of Year DOW_LOCAL, // 'e' Example: 1..7 - Day of Week / Localized - + EXTENDED_YEAR, JULIAN_DAY, MILLISECONDS_IN_DAY, @@ -901,7 +887,7 @@ class U_I18N_API Calendar : public UObject { /** * Sets the behavior for handling wall time repeating multiple times * at negative time zone offset transitions. For example, 1:30 AM on - * November 6, 2011 in US Eastern time (Ameirca/New_York) occurs twice; + * November 6, 2011 in US Eastern time (America/New_York) occurs twice; * 1:30 AM EDT, then 1:30 AM EST one hour later. When UCAL_WALLTIME_FIRST * is used, the wall time 1:30AM in this example will be interpreted as 1:30 AM EDT * (first occurrence). When UCAL_WALLTIME_LAST is used, it will be @@ -912,7 +898,7 @@ class U_I18N_API Calendar : public UObject { * option for this. When the argument is neither UCAL_WALLTIME_FIRST * nor UCAL_WALLTIME_LAST, this method has no effect and will keep * the current setting. - * + * * @param option the behavior for handling repeating wall time, either * UCAL_WALLTIME_FIRST or UCAL_WALLTIME_LAST. * @see #getRepeatedWallTimeOption @@ -923,7 +909,7 @@ class U_I18N_API Calendar : public UObject { /** * Gets the behavior for handling wall time repeating multiple times * at negative time zone offset transitions. - * + * * @return the behavior for handling repeating wall time, either * UCAL_WALLTIME_FIRST or UCAL_WALLTIME_LAST. * @see #setRepeatedWallTimeOption @@ -944,12 +930,12 @@ class U_I18N_API Calendar : public UObject { *

* Note:This option is effective only when this calendar is lenient. * When the calendar is strict, such non-existing wall time will cause an error. - * + * * @param option the behavior for handling skipped wall time at positive time zone * offset transitions, one of UCAL_WALLTIME_FIRST, UCAL_WALLTIME_LAST and * UCAL_WALLTIME_NEXT_VALID. * @see #getSkippedWallTimeOption - * + * * @stable ICU 49 */ void setSkippedWallTimeOption(UCalendarWallTimeOption option); @@ -957,7 +943,7 @@ class U_I18N_API Calendar : public UObject { /** * Gets the behavior for handling skipped wall time at positive time zone offset * transitions. - * + * * @return the behavior for handling skipped wall time, one of * UCAL_WALLTIME_FIRST, UCAL_WALLTIME_LAST * and UCAL_WALLTIME_NEXT_VALID. @@ -1725,9 +1711,7 @@ class U_I18N_API Calendar : public UObject { /** * Validate a single field of this calendar. Subclasses should * override this method to validate any calendar-specific fields. - * Generic fields can be handled by - * Calendar::validateField(). - * @see #validateField(int, int, int, int&) + * Generic fields can be handled by `Calendar::validateField()`. * @internal */ virtual void validateField(UCalendarDateFields field, UErrorCode &status); @@ -1748,7 +1732,7 @@ class U_I18N_API Calendar : public UObject { * reflects local zone wall time. * @internal */ - int32_t computeMillisInDay(); + double computeMillisInDay(); /** * This method can assume EXTENDED_YEAR has been set. @@ -1759,7 +1743,7 @@ class U_I18N_API Calendar : public UObject { * when this function fails. * @internal */ - int32_t computeZoneOffset(double millis, int32_t millisInDay, UErrorCode &ec); + int32_t computeZoneOffset(double millis, double millisInDay, UErrorCode &ec); /** @@ -2178,7 +2162,7 @@ class U_I18N_API Calendar : public UObject { TimeZone* fZone; /** - * Option for rpeated wall time + * Option for repeated wall time * @see #setRepeatedWallTimeOption */ UCalendarWallTimeOption fRepeatedWallTime; @@ -2463,7 +2447,7 @@ class U_I18N_API Calendar : public UObject { BasicTimeZone* getBasicTimeZone() const; /** - * Find the previous zone transtion near the given time. + * Find the previous zone transition near the given time. * @param base The base time, inclusive * @param transitionTime Receives the result time * @param status The error status @@ -2552,6 +2536,7 @@ inline int32_t Calendar::weekNumber(int32_t dayOfPeriod, int32_t dayOfWeek) #endif /* U_HIDE_INTERNAL_API */ U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/caniter.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/caniter.h index 3bd79f768e..fe222515a3 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/caniter.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/caniter.h @@ -1,3 +1,5 @@ +// © 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 @@ -28,6 +30,7 @@ #define CANITER_SKIP_ZEROES TRUE #endif +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class Hashtable; @@ -151,13 +154,13 @@ class U_COMMON_API CanonicalIterator U_FINAL : public UObject { /** * Copy constructor. Private for now. - * @internal + * @internal (private) */ CanonicalIterator(const CanonicalIterator& other); /** * Assignment operator. Private for now. - * @internal + * @internal (private) */ CanonicalIterator& operator=(const CanonicalIterator& other); @@ -185,7 +188,7 @@ class U_COMMON_API CanonicalIterator U_FINAL : public UObject { UnicodeString *getEquivalents(const UnicodeString &segment, int32_t &result_len, UErrorCode &status); //private String[] getEquivalents(String segment) //Set getEquivalents2(String segment); - Hashtable *getEquivalents2(Hashtable *fillinResult, const UChar *segment, int32_t segLen, UErrorCode &status); + Hashtable *getEquivalents2(Hashtable *fillinResult, const char16_t *segment, int32_t segLen, UErrorCode &status); //Hashtable *getEquivalents2(const UnicodeString &segment, int32_t segLen, UErrorCode &status); /** @@ -194,7 +197,7 @@ class U_COMMON_API CanonicalIterator U_FINAL : public UObject { * If so, take the remainder, and return the equivalents */ //Set extract(int comp, String segment, int segmentPos, StringBuffer buffer); - Hashtable *extract(Hashtable *fillinResult, UChar32 comp, const UChar *segment, int32_t segLen, int32_t segmentPos, UErrorCode &status); + Hashtable *extract(Hashtable *fillinResult, UChar32 comp, const char16_t *segment, int32_t segLen, int32_t segmentPos, UErrorCode &status); //Hashtable *extract(UChar32 comp, const UnicodeString &segment, int32_t segLen, int32_t segmentPos, UErrorCode &status); void cleanPieces(); @@ -202,6 +205,7 @@ class U_COMMON_API CanonicalIterator U_FINAL : public UObject { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_NORMALIZATION */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/casemap.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/casemap.h new file mode 100644 index 0000000000..e5ec8e8dae --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/casemap.h @@ -0,0 +1,494 @@ +// © 2017 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +// casemap.h +// created: 2017jan12 Markus W. Scherer + +#ifndef __CASEMAP_H__ +#define __CASEMAP_H__ + +#include "unicode/utypes.h" +#include "unicode/stringpiece.h" +#include "unicode/uobject.h" + +/** + * \file + * \brief C++ API: Low-level C++ case mapping functions. + */ + +#if U_SHOW_CPLUSPLUS_API +U_NAMESPACE_BEGIN + +class BreakIterator; +class ByteSink; +class Edits; + +/** + * Low-level C++ case mapping functions. + * + * @stable ICU 59 + */ +class U_COMMON_API CaseMap U_FINAL : public UMemory { +public: + /** + * Lowercases a UTF-16 string and optionally records edits. + * Casing is locale-dependent and context-sensitive. + * The result may be longer or shorter than the original. + * The source string and the destination buffer must not overlap. + * + * @param locale The locale ID. ("" = root locale, NULL = default locale.) + * @param options Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET. + * @param src The original string. + * @param srcLength The length of the original string. If -1, then src must be NUL-terminated. + * @param dest A buffer for the result string. The result will be NUL-terminated if + * the buffer is large enough. + * The contents is undefined in case of failure. + * @param destCapacity The size of the buffer (number of char16_ts). If it is 0, then + * dest may be NULL and the function will only return the length of the result + * without writing any of the result string. + * @param edits Records edits for index mapping, working with styled text, + * and getting only changes (if any). + * The Edits contents is undefined if any error occurs. + * This function calls edits->reset() first unless + * options includes U_EDITS_NO_RESET. edits can be NULL. + * @param errorCode Reference to an in/out error code value + * which must not indicate a failure before the function call. + * @return The length of the result string, if successful. + * When the result would be longer than destCapacity, + * the full length is returned and a U_BUFFER_OVERFLOW_ERROR is set. + * + * @see u_strToLower + * @stable ICU 59 + */ + static int32_t toLower( + const char *locale, uint32_t options, + const char16_t *src, int32_t srcLength, + char16_t *dest, int32_t destCapacity, Edits *edits, + UErrorCode &errorCode); + + /** + * Uppercases a UTF-16 string and optionally records edits. + * Casing is locale-dependent and context-sensitive. + * The result may be longer or shorter than the original. + * The source string and the destination buffer must not overlap. + * + * @param locale The locale ID. ("" = root locale, NULL = default locale.) + * @param options Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET. + * @param src The original string. + * @param srcLength The length of the original string. If -1, then src must be NUL-terminated. + * @param dest A buffer for the result string. The result will be NUL-terminated if + * the buffer is large enough. + * The contents is undefined in case of failure. + * @param destCapacity The size of the buffer (number of char16_ts). If it is 0, then + * dest may be NULL and the function will only return the length of the result + * without writing any of the result string. + * @param edits Records edits for index mapping, working with styled text, + * and getting only changes (if any). + * The Edits contents is undefined if any error occurs. + * This function calls edits->reset() first unless + * options includes U_EDITS_NO_RESET. edits can be NULL. + * @param errorCode Reference to an in/out error code value + * which must not indicate a failure before the function call. + * @return The length of the result string, if successful. + * When the result would be longer than destCapacity, + * the full length is returned and a U_BUFFER_OVERFLOW_ERROR is set. + * + * @see u_strToUpper + * @stable ICU 59 + */ + static int32_t toUpper( + const char *locale, uint32_t options, + const char16_t *src, int32_t srcLength, + char16_t *dest, int32_t destCapacity, Edits *edits, + UErrorCode &errorCode); + +#if !UCONFIG_NO_BREAK_ITERATION + + /** + * Titlecases a UTF-16 string and optionally records edits. + * Casing is locale-dependent and context-sensitive. + * The result may be longer or shorter than the original. + * The source string and the destination buffer must not overlap. + * + * Titlecasing uses a break iterator to find the first characters of words + * that are to be titlecased. It titlecases those characters and lowercases + * all others. (This can be modified with options bits.) + * + * @param locale The locale ID. ("" = root locale, NULL = default locale.) + * @param options Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT, U_EDITS_NO_RESET, + * U_TITLECASE_NO_LOWERCASE, + * U_TITLECASE_NO_BREAK_ADJUSTMENT, U_TITLECASE_ADJUST_TO_CASED, + * U_TITLECASE_WHOLE_STRING, U_TITLECASE_SENTENCES. + * @param iter A break iterator to find the first characters of words that are to be titlecased. + * It is set to the source string (setText()) + * and used one or more times for iteration (first() and next()). + * If NULL, then a word break iterator for the locale is used + * (or something equivalent). + * @param src The original string. + * @param srcLength The length of the original string. If -1, then src must be NUL-terminated. + * @param dest A buffer for the result string. The result will be NUL-terminated if + * the buffer is large enough. + * The contents is undefined in case of failure. + * @param destCapacity The size of the buffer (number of char16_ts). If it is 0, then + * dest may be NULL and the function will only return the length of the result + * without writing any of the result string. + * @param edits Records edits for index mapping, working with styled text, + * and getting only changes (if any). + * The Edits contents is undefined if any error occurs. + * This function calls edits->reset() first unless + * options includes U_EDITS_NO_RESET. edits can be NULL. + * @param errorCode Reference to an in/out error code value + * which must not indicate a failure before the function call. + * @return The length of the result string, if successful. + * When the result would be longer than destCapacity, + * the full length is returned and a U_BUFFER_OVERFLOW_ERROR is set. + * + * @see u_strToTitle + * @see ucasemap_toTitle + * @stable ICU 59 + */ + static int32_t toTitle( + const char *locale, uint32_t options, BreakIterator *iter, + const char16_t *src, int32_t srcLength, + char16_t *dest, int32_t destCapacity, Edits *edits, + UErrorCode &errorCode); + +#endif // UCONFIG_NO_BREAK_ITERATION + + /** + * Case-folds a UTF-16 string and optionally records edits. + * + * Case folding is locale-independent and not context-sensitive, + * but there is an option for whether to include or exclude mappings for dotted I + * and dotless i that are marked with 'T' in CaseFolding.txt. + * + * The result may be longer or shorter than the original. + * The source string and the destination buffer must not overlap. + * + * @param options Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT, U_EDITS_NO_RESET, + * U_FOLD_CASE_DEFAULT, U_FOLD_CASE_EXCLUDE_SPECIAL_I. + * @param src The original string. + * @param srcLength The length of the original string. If -1, then src must be NUL-terminated. + * @param dest A buffer for the result string. The result will be NUL-terminated if + * the buffer is large enough. + * The contents is undefined in case of failure. + * @param destCapacity The size of the buffer (number of char16_ts). If it is 0, then + * dest may be NULL and the function will only return the length of the result + * without writing any of the result string. + * @param edits Records edits for index mapping, working with styled text, + * and getting only changes (if any). + * The Edits contents is undefined if any error occurs. + * This function calls edits->reset() first unless + * options includes U_EDITS_NO_RESET. edits can be NULL. + * @param errorCode Reference to an in/out error code value + * which must not indicate a failure before the function call. + * @return The length of the result string, if successful. + * When the result would be longer than destCapacity, + * the full length is returned and a U_BUFFER_OVERFLOW_ERROR is set. + * + * @see u_strFoldCase + * @stable ICU 59 + */ + static int32_t fold( + uint32_t options, + const char16_t *src, int32_t srcLength, + char16_t *dest, int32_t destCapacity, Edits *edits, + UErrorCode &errorCode); + + /** + * Lowercases a UTF-8 string and optionally records edits. + * Casing is locale-dependent and context-sensitive. + * The result may be longer or shorter than the original. + * + * @param locale The locale ID. ("" = root locale, NULL = default locale.) + * @param options Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET. + * @param src The original string. + * @param sink A ByteSink to which the result string is written. + * sink.Flush() is called at the end. + * @param edits Records edits for index mapping, working with styled text, + * and getting only changes (if any). + * The Edits contents is undefined if any error occurs. + * This function calls edits->reset() first unless + * options includes U_EDITS_NO_RESET. edits can be NULL. + * @param errorCode Reference to an in/out error code value + * which must not indicate a failure before the function call. + * + * @see ucasemap_utf8ToLower + * @stable ICU 60 + */ + static void utf8ToLower( + const char *locale, uint32_t options, + StringPiece src, ByteSink &sink, Edits *edits, + UErrorCode &errorCode); + + /** + * Uppercases a UTF-8 string and optionally records edits. + * Casing is locale-dependent and context-sensitive. + * The result may be longer or shorter than the original. + * + * @param locale The locale ID. ("" = root locale, NULL = default locale.) + * @param options Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET. + * @param src The original string. + * @param sink A ByteSink to which the result string is written. + * sink.Flush() is called at the end. + * @param edits Records edits for index mapping, working with styled text, + * and getting only changes (if any). + * The Edits contents is undefined if any error occurs. + * This function calls edits->reset() first unless + * options includes U_EDITS_NO_RESET. edits can be NULL. + * @param errorCode Reference to an in/out error code value + * which must not indicate a failure before the function call. + * + * @see ucasemap_utf8ToUpper + * @stable ICU 60 + */ + static void utf8ToUpper( + const char *locale, uint32_t options, + StringPiece src, ByteSink &sink, Edits *edits, + UErrorCode &errorCode); + +#if !UCONFIG_NO_BREAK_ITERATION + + /** + * Titlecases a UTF-8 string and optionally records edits. + * Casing is locale-dependent and context-sensitive. + * The result may be longer or shorter than the original. + * + * Titlecasing uses a break iterator to find the first characters of words + * that are to be titlecased. It titlecases those characters and lowercases + * all others. (This can be modified with options bits.) + * + * @param locale The locale ID. ("" = root locale, NULL = default locale.) + * @param options Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT, U_EDITS_NO_RESET, + * U_TITLECASE_NO_LOWERCASE, + * U_TITLECASE_NO_BREAK_ADJUSTMENT, U_TITLECASE_ADJUST_TO_CASED, + * U_TITLECASE_WHOLE_STRING, U_TITLECASE_SENTENCES. + * @param iter A break iterator to find the first characters of words that are to be titlecased. + * It is set to the source string (setUText()) + * and used one or more times for iteration (first() and next()). + * If NULL, then a word break iterator for the locale is used + * (or something equivalent). + * @param src The original string. + * @param sink A ByteSink to which the result string is written. + * sink.Flush() is called at the end. + * @param edits Records edits for index mapping, working with styled text, + * and getting only changes (if any). + * The Edits contents is undefined if any error occurs. + * This function calls edits->reset() first unless + * options includes U_EDITS_NO_RESET. edits can be NULL. + * @param errorCode Reference to an in/out error code value + * which must not indicate a failure before the function call. + * + * @see ucasemap_utf8ToTitle + * @stable ICU 60 + */ + static void utf8ToTitle( + const char *locale, uint32_t options, BreakIterator *iter, + StringPiece src, ByteSink &sink, Edits *edits, + UErrorCode &errorCode); + +#endif // UCONFIG_NO_BREAK_ITERATION + + /** + * Case-folds a UTF-8 string and optionally records edits. + * + * Case folding is locale-independent and not context-sensitive, + * but there is an option for whether to include or exclude mappings for dotted I + * and dotless i that are marked with 'T' in CaseFolding.txt. + * + * The result may be longer or shorter than the original. + * + * @param options Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET. + * @param src The original string. + * @param sink A ByteSink to which the result string is written. + * sink.Flush() is called at the end. + * @param edits Records edits for index mapping, working with styled text, + * and getting only changes (if any). + * The Edits contents is undefined if any error occurs. + * This function calls edits->reset() first unless + * options includes U_EDITS_NO_RESET. edits can be NULL. + * @param errorCode Reference to an in/out error code value + * which must not indicate a failure before the function call. + * + * @see ucasemap_utf8FoldCase + * @stable ICU 60 + */ + static void utf8Fold( + uint32_t options, + StringPiece src, ByteSink &sink, Edits *edits, + UErrorCode &errorCode); + + /** + * Lowercases a UTF-8 string and optionally records edits. + * Casing is locale-dependent and context-sensitive. + * The result may be longer or shorter than the original. + * The source string and the destination buffer must not overlap. + * + * @param locale The locale ID. ("" = root locale, NULL = default locale.) + * @param options Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET. + * @param src The original string. + * @param srcLength The length of the original string. If -1, then src must be NUL-terminated. + * @param dest A buffer for the result string. The result will be NUL-terminated if + * the buffer is large enough. + * The contents is undefined in case of failure. + * @param destCapacity The size of the buffer (number of bytes). If it is 0, then + * dest may be NULL and the function will only return the length of the result + * without writing any of the result string. + * @param edits Records edits for index mapping, working with styled text, + * and getting only changes (if any). + * The Edits contents is undefined if any error occurs. + * This function calls edits->reset() first unless + * options includes U_EDITS_NO_RESET. edits can be NULL. + * @param errorCode Reference to an in/out error code value + * which must not indicate a failure before the function call. + * @return The length of the result string, if successful. + * When the result would be longer than destCapacity, + * the full length is returned and a U_BUFFER_OVERFLOW_ERROR is set. + * + * @see ucasemap_utf8ToLower + * @stable ICU 59 + */ + static int32_t utf8ToLower( + const char *locale, uint32_t options, + const char *src, int32_t srcLength, + char *dest, int32_t destCapacity, Edits *edits, + UErrorCode &errorCode); + + /** + * Uppercases a UTF-8 string and optionally records edits. + * Casing is locale-dependent and context-sensitive. + * The result may be longer or shorter than the original. + * The source string and the destination buffer must not overlap. + * + * @param locale The locale ID. ("" = root locale, NULL = default locale.) + * @param options Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET. + * @param src The original string. + * @param srcLength The length of the original string. If -1, then src must be NUL-terminated. + * @param dest A buffer for the result string. The result will be NUL-terminated if + * the buffer is large enough. + * The contents is undefined in case of failure. + * @param destCapacity The size of the buffer (number of bytes). If it is 0, then + * dest may be NULL and the function will only return the length of the result + * without writing any of the result string. + * @param edits Records edits for index mapping, working with styled text, + * and getting only changes (if any). + * The Edits contents is undefined if any error occurs. + * This function calls edits->reset() first unless + * options includes U_EDITS_NO_RESET. edits can be NULL. + * @param errorCode Reference to an in/out error code value + * which must not indicate a failure before the function call. + * @return The length of the result string, if successful. + * When the result would be longer than destCapacity, + * the full length is returned and a U_BUFFER_OVERFLOW_ERROR is set. + * + * @see ucasemap_utf8ToUpper + * @stable ICU 59 + */ + static int32_t utf8ToUpper( + const char *locale, uint32_t options, + const char *src, int32_t srcLength, + char *dest, int32_t destCapacity, Edits *edits, + UErrorCode &errorCode); + +#if !UCONFIG_NO_BREAK_ITERATION + + /** + * Titlecases a UTF-8 string and optionally records edits. + * Casing is locale-dependent and context-sensitive. + * The result may be longer or shorter than the original. + * The source string and the destination buffer must not overlap. + * + * Titlecasing uses a break iterator to find the first characters of words + * that are to be titlecased. It titlecases those characters and lowercases + * all others. (This can be modified with options bits.) + * + * @param locale The locale ID. ("" = root locale, NULL = default locale.) + * @param options Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT, U_EDITS_NO_RESET, + * U_TITLECASE_NO_LOWERCASE, + * U_TITLECASE_NO_BREAK_ADJUSTMENT, U_TITLECASE_ADJUST_TO_CASED, + * U_TITLECASE_WHOLE_STRING, U_TITLECASE_SENTENCES. + * @param iter A break iterator to find the first characters of words that are to be titlecased. + * It is set to the source string (setUText()) + * and used one or more times for iteration (first() and next()). + * If NULL, then a word break iterator for the locale is used + * (or something equivalent). + * @param src The original string. + * @param srcLength The length of the original string. If -1, then src must be NUL-terminated. + * @param dest A buffer for the result string. The result will be NUL-terminated if + * the buffer is large enough. + * The contents is undefined in case of failure. + * @param destCapacity The size of the buffer (number of bytes). If it is 0, then + * dest may be NULL and the function will only return the length of the result + * without writing any of the result string. + * @param edits Records edits for index mapping, working with styled text, + * and getting only changes (if any). + * The Edits contents is undefined if any error occurs. + * This function calls edits->reset() first unless + * options includes U_EDITS_NO_RESET. edits can be NULL. + * @param errorCode Reference to an in/out error code value + * which must not indicate a failure before the function call. + * @return The length of the result string, if successful. + * When the result would be longer than destCapacity, + * the full length is returned and a U_BUFFER_OVERFLOW_ERROR is set. + * + * @see ucasemap_utf8ToTitle + * @stable ICU 59 + */ + static int32_t utf8ToTitle( + const char *locale, uint32_t options, BreakIterator *iter, + const char *src, int32_t srcLength, + char *dest, int32_t destCapacity, Edits *edits, + UErrorCode &errorCode); + +#endif // UCONFIG_NO_BREAK_ITERATION + + /** + * Case-folds a UTF-8 string and optionally records edits. + * + * Case folding is locale-independent and not context-sensitive, + * but there is an option for whether to include or exclude mappings for dotted I + * and dotless i that are marked with 'T' in CaseFolding.txt. + * + * The result may be longer or shorter than the original. + * The source string and the destination buffer must not overlap. + * + * @param options Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT, U_EDITS_NO_RESET, + * U_FOLD_CASE_DEFAULT, U_FOLD_CASE_EXCLUDE_SPECIAL_I. + * @param src The original string. + * @param srcLength The length of the original string. If -1, then src must be NUL-terminated. + * @param dest A buffer for the result string. The result will be NUL-terminated if + * the buffer is large enough. + * The contents is undefined in case of failure. + * @param destCapacity The size of the buffer (number of bytes). If it is 0, then + * dest may be NULL and the function will only return the length of the result + * without writing any of the result string. + * @param edits Records edits for index mapping, working with styled text, + * and getting only changes (if any). + * The Edits contents is undefined if any error occurs. + * This function calls edits->reset() first unless + * options includes U_EDITS_NO_RESET. edits can be NULL. + * @param errorCode Reference to an in/out error code value + * which must not indicate a failure before the function call. + * @return The length of the result string, if successful. + * When the result would be longer than destCapacity, + * the full length is returned and a U_BUFFER_OVERFLOW_ERROR is set. + * + * @see ucasemap_utf8FoldCase + * @stable ICU 59 + */ + static int32_t utf8Fold( + uint32_t options, + const char *src, int32_t srcLength, + char *dest, int32_t destCapacity, Edits *edits, + UErrorCode &errorCode); + +private: + CaseMap() = delete; + CaseMap(const CaseMap &other) = delete; + CaseMap &operator=(const CaseMap &other) = delete; +}; + +U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API + +#endif // __CASEMAP_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/char16ptr.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/char16ptr.h new file mode 100644 index 0000000000..d58029f7f0 --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/char16ptr.h @@ -0,0 +1,310 @@ +// © 2017 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +// char16ptr.h +// created: 2017feb28 Markus W. Scherer + +#ifndef __CHAR16PTR_H__ +#define __CHAR16PTR_H__ + +#include +#include "unicode/utypes.h" + +/** + * \file + * \brief C++ API: char16_t pointer wrappers with + * implicit conversion from bit-compatible raw pointer types. + * Also conversion functions from char16_t * to UChar * and OldUChar *. + */ + +#if U_SHOW_CPLUSPLUS_API +U_NAMESPACE_BEGIN + +/** + * \def U_ALIASING_BARRIER + * Barrier for pointer anti-aliasing optimizations even across function boundaries. + * @internal + */ +#ifdef U_ALIASING_BARRIER + // Use the predefined value. +#elif (defined(__clang__) || defined(__GNUC__)) && U_PLATFORM != U_PF_BROWSER_NATIVE_CLIENT +# define U_ALIASING_BARRIER(ptr) asm volatile("" : : "rm"(ptr) : "memory") +#elif defined(U_IN_DOXYGEN) +# define U_ALIASING_BARRIER(ptr) +#endif + +/** + * char16_t * wrapper with implicit conversion from distinct but bit-compatible pointer types. + * @stable ICU 59 + */ +class U_COMMON_API Char16Ptr U_FINAL { +public: + /** + * Copies the pointer. + * @param p pointer + * @stable ICU 59 + */ + inline Char16Ptr(char16_t *p); +#if !U_CHAR16_IS_TYPEDEF + /** + * Converts the pointer to char16_t *. + * @param p pointer to be converted + * @stable ICU 59 + */ + inline Char16Ptr(uint16_t *p); +#endif +#if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN) + /** + * Converts the pointer to char16_t *. + * (Only defined if U_SIZEOF_WCHAR_T==2.) + * @param p pointer to be converted + * @stable ICU 59 + */ + inline Char16Ptr(wchar_t *p); +#endif + /** + * nullptr constructor. + * @param p nullptr + * @stable ICU 59 + */ + inline Char16Ptr(std::nullptr_t p); + /** + * Destructor. + * @stable ICU 59 + */ + inline ~Char16Ptr(); + + /** + * Pointer access. + * @return the wrapped pointer + * @stable ICU 59 + */ + inline char16_t *get() const; + /** + * char16_t pointer access via type conversion (e.g., static_cast). + * @return the wrapped pointer + * @stable ICU 59 + */ + inline operator char16_t *() const { return get(); } + +private: + Char16Ptr() = delete; + +#ifdef U_ALIASING_BARRIER + template static char16_t *cast(T *t) { + U_ALIASING_BARRIER(t); + return reinterpret_cast(t); + } + + char16_t *p_; +#else + union { + char16_t *cp; + uint16_t *up; + wchar_t *wp; + } u_; +#endif +}; + +/// \cond +#ifdef U_ALIASING_BARRIER + +Char16Ptr::Char16Ptr(char16_t *p) : p_(p) {} +#if !U_CHAR16_IS_TYPEDEF +Char16Ptr::Char16Ptr(uint16_t *p) : p_(cast(p)) {} +#endif +#if U_SIZEOF_WCHAR_T==2 +Char16Ptr::Char16Ptr(wchar_t *p) : p_(cast(p)) {} +#endif +Char16Ptr::Char16Ptr(std::nullptr_t p) : p_(p) {} +Char16Ptr::~Char16Ptr() { + U_ALIASING_BARRIER(p_); +} + +char16_t *Char16Ptr::get() const { return p_; } + +#else + +Char16Ptr::Char16Ptr(char16_t *p) { u_.cp = p; } +#if !U_CHAR16_IS_TYPEDEF +Char16Ptr::Char16Ptr(uint16_t *p) { u_.up = p; } +#endif +#if U_SIZEOF_WCHAR_T==2 +Char16Ptr::Char16Ptr(wchar_t *p) { u_.wp = p; } +#endif +Char16Ptr::Char16Ptr(std::nullptr_t p) { u_.cp = p; } +Char16Ptr::~Char16Ptr() {} + +char16_t *Char16Ptr::get() const { return u_.cp; } + +#endif +/// \endcond + +/** + * const char16_t * wrapper with implicit conversion from distinct but bit-compatible pointer types. + * @stable ICU 59 + */ +class U_COMMON_API ConstChar16Ptr U_FINAL { +public: + /** + * Copies the pointer. + * @param p pointer + * @stable ICU 59 + */ + inline ConstChar16Ptr(const char16_t *p); +#if !U_CHAR16_IS_TYPEDEF + /** + * Converts the pointer to char16_t *. + * @param p pointer to be converted + * @stable ICU 59 + */ + inline ConstChar16Ptr(const uint16_t *p); +#endif +#if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN) + /** + * Converts the pointer to char16_t *. + * (Only defined if U_SIZEOF_WCHAR_T==2.) + * @param p pointer to be converted + * @stable ICU 59 + */ + inline ConstChar16Ptr(const wchar_t *p); +#endif + /** + * nullptr constructor. + * @param p nullptr + * @stable ICU 59 + */ + inline ConstChar16Ptr(const std::nullptr_t p); + + /** + * Destructor. + * @stable ICU 59 + */ + inline ~ConstChar16Ptr(); + + /** + * Pointer access. + * @return the wrapped pointer + * @stable ICU 59 + */ + inline const char16_t *get() const; + /** + * char16_t pointer access via type conversion (e.g., static_cast). + * @return the wrapped pointer + * @stable ICU 59 + */ + inline operator const char16_t *() const { return get(); } + +private: + ConstChar16Ptr() = delete; + +#ifdef U_ALIASING_BARRIER + template static const char16_t *cast(const T *t) { + U_ALIASING_BARRIER(t); + return reinterpret_cast(t); + } + + const char16_t *p_; +#else + union { + const char16_t *cp; + const uint16_t *up; + const wchar_t *wp; + } u_; +#endif +}; + +/// \cond +#ifdef U_ALIASING_BARRIER + +ConstChar16Ptr::ConstChar16Ptr(const char16_t *p) : p_(p) {} +#if !U_CHAR16_IS_TYPEDEF +ConstChar16Ptr::ConstChar16Ptr(const uint16_t *p) : p_(cast(p)) {} +#endif +#if U_SIZEOF_WCHAR_T==2 +ConstChar16Ptr::ConstChar16Ptr(const wchar_t *p) : p_(cast(p)) {} +#endif +ConstChar16Ptr::ConstChar16Ptr(const std::nullptr_t p) : p_(p) {} +ConstChar16Ptr::~ConstChar16Ptr() { + U_ALIASING_BARRIER(p_); +} + +const char16_t *ConstChar16Ptr::get() const { return p_; } + +#else + +ConstChar16Ptr::ConstChar16Ptr(const char16_t *p) { u_.cp = p; } +#if !U_CHAR16_IS_TYPEDEF +ConstChar16Ptr::ConstChar16Ptr(const uint16_t *p) { u_.up = p; } +#endif +#if U_SIZEOF_WCHAR_T==2 +ConstChar16Ptr::ConstChar16Ptr(const wchar_t *p) { u_.wp = p; } +#endif +ConstChar16Ptr::ConstChar16Ptr(const std::nullptr_t p) { u_.cp = p; } +ConstChar16Ptr::~ConstChar16Ptr() {} + +const char16_t *ConstChar16Ptr::get() const { return u_.cp; } + +#endif +/// \endcond + +/** + * Converts from const char16_t * to const UChar *. + * Includes an aliasing barrier if available. + * @param p pointer + * @return p as const UChar * + * @stable ICU 59 + */ +inline const UChar *toUCharPtr(const char16_t *p) { +#ifdef U_ALIASING_BARRIER + U_ALIASING_BARRIER(p); +#endif + return reinterpret_cast(p); +} + +/** + * Converts from char16_t * to UChar *. + * Includes an aliasing barrier if available. + * @param p pointer + * @return p as UChar * + * @stable ICU 59 + */ +inline UChar *toUCharPtr(char16_t *p) { +#ifdef U_ALIASING_BARRIER + U_ALIASING_BARRIER(p); +#endif + return reinterpret_cast(p); +} + +/** + * Converts from const char16_t * to const OldUChar *. + * Includes an aliasing barrier if available. + * @param p pointer + * @return p as const OldUChar * + * @stable ICU 59 + */ +inline const OldUChar *toOldUCharPtr(const char16_t *p) { +#ifdef U_ALIASING_BARRIER + U_ALIASING_BARRIER(p); +#endif + return reinterpret_cast(p); +} + +/** + * Converts from char16_t * to OldUChar *. + * Includes an aliasing barrier if available. + * @param p pointer + * @return p as OldUChar * + * @stable ICU 59 + */ +inline OldUChar *toOldUCharPtr(char16_t *p) { +#ifdef U_ALIASING_BARRIER + U_ALIASING_BARRIER(p); +#endif + return reinterpret_cast(p); +} + +U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API + +#endif // __CHAR16PTR_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/chariter.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/chariter.h index e8d65090a4..218398bf38 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/chariter.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/chariter.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************** * @@ -18,6 +20,7 @@ * \brief C++ API: Character Iterator */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** * Abstract class that defines an API for forward-only iteration @@ -76,7 +79,7 @@ U_NAMESPACE_BEGIN * } * * void function1(ForwardCharacterIterator &it) { - * UChar c; + * char16_t c; * while((c=it.nextPostInc())!=ForwardCharacterIterator::DONE) { * // use c * } @@ -147,7 +150,7 @@ class U_COMMON_API ForwardCharacterIterator : public UObject { * @return the current code unit. * @stable ICU 2.0 */ - virtual UChar nextPostInc(void) = 0; + virtual char16_t nextPostInc(void) = 0; /** * Gets the current code point for returning and advances to the next code point @@ -228,7 +231,7 @@ class U_COMMON_API ForwardCharacterIterator : public UObject { * showing a way to convert simple for() loops: * \code * void forward2(CharacterIterator &it) { - * UChar c; + * char16_t c; * for(c=it.firstPostInc(); c!=CharacterIterator::DONE; c=it.nextPostInc()) { * // use c * } @@ -247,7 +250,7 @@ class U_COMMON_API ForwardCharacterIterator : public UObject { * Backward iteration with a more traditional for() loop: * \code * void backward2(CharacterIterator &it) { - * UChar c; + * char16_t c; * for(c=it.last(); c!=CharacterIterator::DONE; c=it.previous()) { * // use c * } @@ -264,7 +267,7 @@ class U_COMMON_API ForwardCharacterIterator : public UObject { * // get the position * int32_t pos=it.getIndex(); * // get the previous code unit - * UChar u=it.previous(); + * char16_t u=it.previous(); * // move back one more code unit * it.move(-1, CharacterIterator::kCurrent); * // set the position back to where it was @@ -281,7 +284,7 @@ class U_COMMON_API ForwardCharacterIterator : public UObject { * Function processing characters, in this example simple output *

  * \code
- *  void processChar( UChar c )
+ *  void processChar( char16_t c )
  *  {
  *      cout << " " << c;
  *  }
@@ -292,7 +295,7 @@ class U_COMMON_API ForwardCharacterIterator : public UObject {
  * \code
  *  void traverseForward(CharacterIterator& iter)
  *  {
- *      for(UChar c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
+ *      for(char16_t c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
  *          processChar(c);
  *      }
  *  }
@@ -303,7 +306,7 @@ class U_COMMON_API ForwardCharacterIterator : public UObject {
  * \code
  *  void traverseBackward(CharacterIterator& iter)
  *  {
- *      for(UChar c = iter.last(); c != CharacterIterator.DONE; c = iter.previous()) {
+ *      for(char16_t c = iter.last(); c != CharacterIterator.DONE; c = iter.previous()) {
  *          processChar(c);
  *      }
  *  }
@@ -315,7 +318,7 @@ class U_COMMON_API ForwardCharacterIterator : public UObject {
  * \code
  * void traverseOut(CharacterIterator& iter, int32_t pos)
  * {
- *      UChar c;
+ *      char16_t c;
  *      for (c = iter.setIndex(pos);
  *      c != CharacterIterator.DONE && (Unicode::isLetter(c) || Unicode::isDigit(c));
  *          c = iter.next()) {}
@@ -384,7 +387,7 @@ class U_COMMON_API CharacterIterator : public ForwardCharacterIterator {
      * @return the first code unit in its iteration range.
      * @stable ICU 2.0
      */
-    virtual UChar         first(void) = 0;
+    virtual char16_t         first(void) = 0;
 
     /**
      * Sets the iterator to refer to the first code unit in its
@@ -394,7 +397,7 @@ class U_COMMON_API CharacterIterator : public ForwardCharacterIterator {
      * @return the first code unit in its iteration range.
      * @stable ICU 2.0
      */
-    virtual UChar         firstPostInc(void);
+    virtual char16_t         firstPostInc(void);
 
     /**
      * Sets the iterator to refer to the first code point in its
@@ -433,7 +436,7 @@ class U_COMMON_API CharacterIterator : public ForwardCharacterIterator {
      * @return the last code unit.
      * @stable ICU 2.0
      */
-    virtual UChar         last(void) = 0;
+    virtual char16_t         last(void) = 0;
         
     /**
      * Sets the iterator to refer to the last code point in its
@@ -461,7 +464,7 @@ class U_COMMON_API CharacterIterator : public ForwardCharacterIterator {
      * @return the "position"-th code unit.
      * @stable ICU 2.0
      */
-    virtual UChar         setIndex(int32_t position) = 0;
+    virtual char16_t         setIndex(int32_t position) = 0;
 
     /**
      * Sets the iterator to refer to the beginning of the code point
@@ -481,7 +484,7 @@ class U_COMMON_API CharacterIterator : public ForwardCharacterIterator {
      * @return the current code unit. 
      * @stable ICU 2.0
      */
-    virtual UChar         current(void) const = 0;
+    virtual char16_t         current(void) const = 0;
         
     /**
      * Returns the code point the iterator currently refers to.  
@@ -497,7 +500,7 @@ class U_COMMON_API CharacterIterator : public ForwardCharacterIterator {
      * @return the next code unit.
      * @stable ICU 2.0
      */
-    virtual UChar         next(void) = 0;
+    virtual char16_t         next(void) = 0;
         
     /**
      * Advances to the next code point in the iteration range
@@ -518,7 +521,7 @@ class U_COMMON_API CharacterIterator : public ForwardCharacterIterator {
      * @return the previous code unit.
      * @stable ICU 2.0
      */
-    virtual UChar         previous(void) = 0;
+    virtual char16_t         previous(void) = 0;
 
     /**
      * Advances to the previous code point in the iteration range
@@ -567,7 +570,7 @@ class U_COMMON_API CharacterIterator : public ForwardCharacterIterator {
      * Returns the numeric index in the underlying text-storage
      * object of the character the iterator currently refers to
      * (i.e., the character returned by current()).  
-     * @return the numberic index in the text-storage object of 
+     * @return the numeric index in the text-storage object of 
      * the character the iterator currently refers to
      * @stable ICU 2.0
      */
@@ -605,6 +608,10 @@ class U_COMMON_API CharacterIterator : public ForwardCharacterIterator {
      * @return the new position
      * @stable ICU 2.0
      */
+#ifdef move32
+     // One of the system headers right now is sometimes defining a conflicting macro we don't use
+#undef move32
+#endif
     virtual int32_t      move32(int32_t delta, EOrigin origin) = 0;
 
     /**
@@ -719,4 +726,5 @@ CharacterIterator::getLength(void) const {
 }
 
 U_NAMESPACE_END
+#endif // U_SHOW_CPLUSPLUS_API
 #endif
diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/choicfmt.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/choicfmt.h
index cfd520624d..7e7d2618dd 100644
--- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/choicfmt.h
+++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/choicfmt.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ********************************************************************************
 *   Copyright (C) 1997-2013, International Business Machines
@@ -38,6 +40,7 @@
 #include "unicode/numfmt.h"
 #include "unicode/unistr.h"
 
+#if U_SHOW_CPLUSPLUS_API
 U_NAMESPACE_BEGIN
 
 class MessageFormat;
@@ -586,6 +589,7 @@ class U_I18N_API ChoiceFormat: public NumberFormat {
 
 
 U_NAMESPACE_END
+#endif // U_SHOW_CPLUSPLUS_API
 
 #endif  // U_HIDE_DEPRECATED_API
 #endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/coleitr.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/coleitr.h
index 8c5d0e94f5..91efb9b2b1 100644
--- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/coleitr.h
+++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/coleitr.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  ******************************************************************************
  *   Copyright (C) 1997-2014, International Business Machines
@@ -41,10 +43,12 @@
 struct UCollationElements;
 struct UHashtable;
 
+#if U_SHOW_CPLUSPLUS_API
 U_NAMESPACE_BEGIN
 
 struct CollationData;
 
+class CharacterIterator;
 class CollationIterator;
 class RuleBasedCollator;
 class UCollationPCE;
@@ -398,6 +402,7 @@ inline UBool CollationElementIterator::isIgnorable(int32_t order)
 }
 
 U_NAMESPACE_END
+#endif // U_SHOW_CPLUSPLUS_API
 
 #endif /* #if !UCONFIG_NO_COLLATION */
 
diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/coll.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/coll.h
index add6b5ba36..76663c4c33 100644
--- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/coll.h
+++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/coll.h
@@ -1,15 +1,17 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
-*   Copyright (C) 1996-2015, International Business Machines
+*   Copyright (C) 1996-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 ******************************************************************************
 */
 
 /**
- * \file 
+ * \file
  * \brief C++ API: Collation Service.
  */
- 
+
 /**
 * File coll.h
 *
@@ -56,13 +58,14 @@
 
 #include "unicode/uobject.h"
 #include "unicode/ucol.h"
-#include "unicode/normlzr.h"
+#include "unicode/unorm.h"
 #include "unicode/locid.h"
 #include "unicode/uniset.h"
 #include "unicode/umisc.h"
 #include "unicode/uiter.h"
 #include "unicode/stringpiece.h"
 
+#if U_SHOW_CPLUSPLUS_API
 U_NAMESPACE_BEGIN
 
 class StringEnumeration;
@@ -156,7 +159,7 @@ class CollationKey;
 * @see         CollationKey
 * @see         CollationElementIterator
 * @see         Locale
-* @see         Normalizer
+* @see         Normalizer2
 * @version     2.0 11/15/01
 */
 
@@ -199,6 +202,9 @@ class U_I18N_API Collator : public UObject {
         IDENTICAL  = UCOL_IDENTICAL  // 15
     };
 
+
+    // Cannot use #ifndef U_HIDE_DEPRECATED_API for the following, it is
+    // used by virtual methods that cannot have that conditional.
     /**
      * LESS is returned if source string is compared to be less than target
      * string in the compare() method.
@@ -230,16 +236,16 @@ class U_I18N_API Collator : public UObject {
      * Returns TRUE if "other" is the same as "this".
      *
      * The base class implementation returns TRUE if "other" has the same type/class as "this":
-     * typeid(*this) == typeid(other).
+     * `typeid(*this) == typeid(other)`.
      *
      * Subclass implementations should do something like the following:
-     * 
-     *   if (this == &other) { return TRUE; }
-     *   if (!Collator::operator==(other)) { return FALSE; }  // not the same class
      *
-     *   const MyCollator &o = (const MyCollator&)other;
-     *   (compare this vs. o's subclass fields)
-     * 
+ * if (this == &other) { return TRUE; } + * if (!Collator::operator==(other)) { return FALSE; } // not the same class + * + * const MyCollator &o = (const MyCollator&)other; + * (compare this vs. o's subclass fields) + * * @param other Collator object to be compared * @return TRUE if other is the same as this. * @stable ICU 2.0 @@ -388,8 +394,8 @@ class U_I18N_API Collator : public UObject { * is less than, greater than or equal to another string array. *

Example of use: *

-     * .       UChar ABC[] = {0x41, 0x42, 0x43, 0};  // = "ABC"
-     * .       UChar abc[] = {0x61, 0x62, 0x63, 0};  // = "abc"
+     * .       char16_t ABC[] = {0x41, 0x42, 0x43, 0};  // = "ABC"
+     * .       char16_t abc[] = {0x61, 0x62, 0x63, 0};  // = "abc"
      * .       UErrorCode status = U_ZERO_ERROR;
      * .       Collator *myCollation =
      * .                         Collator::createInstance(Locale::getUS(), status);
@@ -415,8 +421,8 @@ class U_I18N_API Collator : public UObject {
      *         target
      * @deprecated ICU 2.6 use the overload with UErrorCode &
      */
-    virtual EComparisonResult compare(const UChar* source, int32_t sourceLength,
-                                      const UChar* target, int32_t targetLength)
+    virtual EComparisonResult compare(const char16_t* source, int32_t sourceLength,
+                                      const char16_t* target, int32_t targetLength)
                                       const;
 
     /**
@@ -435,8 +441,8 @@ class U_I18N_API Collator : public UObject {
      * than target
      * @stable ICU 2.6
      */
-    virtual UCollationResult compare(const UChar* source, int32_t sourceLength,
-                                      const UChar* target, int32_t targetLength,
+    virtual UCollationResult compare(const char16_t* source, int32_t sourceLength,
+                                      const char16_t* target, int32_t targetLength,
                                       UErrorCode &status) const = 0;
 
     /**
@@ -479,7 +485,7 @@ class U_I18N_API Collator : public UObject {
      * generated sort keys.
      * If the source string is null, a null collation key will be returned.
      *
-     * Note that sort keys are often less efficient than simply doing comparison.  
+     * Note that sort keys are often less efficient than simply doing comparison.
      * For more details, see the ICU User Guide.
      *
      * @param source the source string to be transformed into a sort key.
@@ -501,7 +507,7 @@ class U_I18N_API Collator : public UObject {
      * generated sort keys.
      * 

If the source string is null, a null collation key will be returned. * - * Note that sort keys are often less efficient than simply doing comparison. + * Note that sort keys are often less efficient than simply doing comparison. * For more details, see the ICU User Guide. * * @param source the source string to be transformed into a sort key. @@ -512,7 +518,7 @@ class U_I18N_API Collator : public UObject { * @see CollationKey#compare * @stable ICU 2.0 */ - virtual CollationKey& getCollationKey(const UChar*source, + virtual CollationKey& getCollationKey(const char16_t*source, int32_t sourceLength, CollationKey& key, UErrorCode& status) const = 0; @@ -616,7 +622,7 @@ class U_I18N_API Collator : public UObject { * @see Collator#setReorderCodes * @see UScriptCode * @see UColReorderCode - * @stable ICU 4.8 + * @stable ICU 4.8 */ virtual int32_t getReorderCodes(int32_t *dest, int32_t destCapacity, @@ -626,7 +632,7 @@ class U_I18N_API Collator : public UObject { * Sets the ordering of scripts for this collator. * *

The reordering codes are a combination of script codes and reorder codes. - * @param reorderCodes An array of script codes in the new order. This can be NULL if the + * @param reorderCodes An array of script codes in the new order. This can be NULL if the * length is also set to 0. An empty array will clear any reordering codes on the collator. * @param reorderCodesLength The length of reorderCodes. * @param status error code @@ -635,7 +641,7 @@ class U_I18N_API Collator : public UObject { * @see Collator#getEquivalentReorderCodes * @see UScriptCode * @see UColReorderCode - * @stable ICU 4.8 + * @stable ICU 4.8 */ virtual void setReorderCodes(const int32_t* reorderCodes, int32_t reorderCodesLength, @@ -647,11 +653,11 @@ class U_I18N_API Collator : public UObject { * Beginning with ICU 55, scripts only reorder together if they are primary-equal, * for example Hiragana and Katakana. * - * @param reorderCode The reorder code to determine equivalence for. + * @param reorderCode The reorder code to determine equivalence for. * @param dest The array to fill with the script equivalence reordering codes. - * @param destCapacity The length of dest. If it is 0, then dest may be NULL and the + * @param destCapacity The length of dest. If it is 0, then dest may be NULL and the * function will only return the length of the result without writing any codes (pre-flighting). - * @param status A reference to an error code value, which must not indicate + * @param status A reference to an error code value, which must not indicate * a failure before the function call. * @return The length of the of the reordering code equivalence array. * @see ucol_setReorderCodes @@ -659,7 +665,7 @@ class U_I18N_API Collator : public UObject { * @see Collator#setReorderCodes * @see UScriptCode * @see UColReorderCode - * @stable ICU 4.8 + * @stable ICU 4.8 */ static int32_t U_EXPORT2 getEquivalentReorderCodes(int32_t reorderCode, int32_t* dest, @@ -667,7 +673,7 @@ class U_I18N_API Collator : public UObject { UErrorCode& status); /** - * Get name of the object for the desired Locale, in the desired langauge + * Get name of the object for the desired Locale, in the desired language * @param objectLocale must be from getAvailableLocales * @param displayLocale specifies the desired locale for output * @param name the fill-in parameter of the return value @@ -680,7 +686,7 @@ class U_I18N_API Collator : public UObject { UnicodeString& name); /** - * Get name of the object for the desired Locale, in the langauge of the + * Get name of the object for the desired Locale, in the language of the * default locale. * @param objectLocale must be from getAvailableLocales * @param name the fill-in parameter of the return value @@ -906,7 +912,7 @@ class U_I18N_API Collator : public UObject { * the top of one of the supported reordering groups, * and it must not be beyond the last of those groups. * See setMaxVariable(). - * @param varTop one or more (if contraction) UChars to which the variable top should be set + * @param varTop one or more (if contraction) char16_ts to which the variable top should be set * @param len length of variable top string. If -1 it is considered to be zero terminated. * @param status error code. If error code is set, the return value is undefined. Errors set by this function are:
* U_CE_NOT_FOUND_ERROR if more than one character was passed and there is no such contraction
@@ -915,7 +921,7 @@ class U_I18N_API Collator : public UObject { * @return variable top primary weight * @deprecated ICU 53 Call setMaxVariable() instead. */ - virtual uint32_t setVariableTop(const UChar *varTop, int32_t len, UErrorCode &status) = 0; + virtual uint32_t setVariableTop(const char16_t *varTop, int32_t len, UErrorCode &status) = 0; /** * Sets the variable top to the primary weight of the specified string. @@ -924,7 +930,7 @@ class U_I18N_API Collator : public UObject { * the top of one of the supported reordering groups, * and it must not be beyond the last of those groups. * See setMaxVariable(). - * @param varTop a UnicodeString size 1 or more (if contraction) of UChars to which the variable top should be set + * @param varTop a UnicodeString size 1 or more (if contraction) of char16_ts to which the variable top should be set * @param status error code. If error code is set, the return value is undefined. Errors set by this function are:
* U_CE_NOT_FOUND_ERROR if more than one character was passed and there is no such contraction
* U_ILLEGAL_ARGUMENT_ERROR if the variable top is beyond @@ -981,7 +987,7 @@ class U_I18N_API Collator : public UObject { * Sort key byte arrays are zero-terminated and can be compared using * strcmp(). * - * Note that sort keys are often less efficient than simply doing comparison. + * Note that sort keys are often less efficient than simply doing comparison. * For more details, see the ICU User Guide. * * @param source string to be processed. @@ -997,11 +1003,11 @@ class U_I18N_API Collator : public UObject { int32_t resultLength) const = 0; /** - * Get the sort key as an array of bytes from a UChar buffer. + * Get the sort key as an array of bytes from a char16_t buffer. * Sort key byte arrays are zero-terminated and can be compared using * strcmp(). * - * Note that sort keys are often less efficient than simply doing comparison. + * Note that sort keys are often less efficient than simply doing comparison. * For more details, see the ICU User Guide. * * @param source string to be processed. @@ -1015,7 +1021,7 @@ class U_I18N_API Collator : public UObject { * @return Number of bytes needed for storing the sort key * @stable ICU 2.2 */ - virtual int32_t getSortKey(const UChar*source, int32_t sourceLength, + virtual int32_t getSortKey(const char16_t*source, int32_t sourceLength, uint8_t*result, int32_t resultLength) const = 0; /** @@ -1111,18 +1117,18 @@ class U_I18N_API Collator : public UObject { virtual void setLocales(const Locale& requestedLocale, const Locale& validLocale, const Locale& actualLocale); /** Get the short definition string for a collator. This internal API harvests the collator's - * locale and the attribute set and produces a string that can be used for opening + * locale and the attribute set and produces a string that can be used for opening * a collator with the same attributes using the ucol_openFromShortString API. * This string will be normalized. * The structure and the syntax of the string is defined in the "Naming collators" - * section of the users guide: + * section of the users guide: * http://userguide.icu-project.org/collation/concepts#TOC-Collator-naming-scheme * This function supports preflighting. - * + * * This is internal, and intended to be used with delegate converters. * * @param locale a locale that will appear as a collators locale in the resulting - * short string definition. If NULL, the locale will be harvested + * short string definition. If NULL, the locale will be harvested * from the collator. * @param buffer space to hold the resulting string * @param capacity capacity of the buffer @@ -1263,6 +1269,7 @@ class U_I18N_API CollatorFactory : public UObject { // Collator inline methods ----------------------------------------------- U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_COLLATION */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/compactdecimalformat.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/compactdecimalformat.h index bd8fdba8e8..a91bd57005 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/compactdecimalformat.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/compactdecimalformat.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** -* Copyright (C) 2012-2014, International Business Machines +* Copyright (C) 2012-2016, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************** * @@ -14,7 +16,7 @@ #include "unicode/utypes.h" /** * \file - * \brief C++ API: Formats decimal numbers in compact form. + * \brief C++ API: Compatibility APIs for compact decimal number formatting. */ #if !UCONFIG_NO_FORMATTING @@ -23,30 +25,37 @@ struct UHashtable; +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class PluralRules; /** + * **IMPORTANT:** New users are strongly encouraged to see if + * numberformatter.h fits their use case. Although not deprecated, this header + * is provided for backwards compatibility only. + * + * ----------------------------------------------------------------------------- + * * The CompactDecimalFormat produces abbreviated numbers, suitable for display in * environments will limited real estate. For example, 'Hits: 1.2B' instead of * 'Hits: 1,200,000,000'. The format will be appropriate for the given language, * such as "1,2 Mrd." for German. - *

+ * * For numbers under 1000 trillion (under 10^15, such as 123,456,789,012,345), * the result will be short for supported languages. However, the result may * sometimes exceed 7 characters, such as when there are combining marks or thin * characters. In such cases, the visual width in fonts should still be short. - *

+ * * By default, there are 3 significant digits. After creation, if more than * three significant digits are set (with setMaximumSignificantDigits), or if a * fixed number of digits are set (with setMaximumIntegerDigits or * setMaximumFractionDigits), then result may be wider. - *

+ * * At this time, parsing is not supported, and will produce a U_UNSUPPORTED_ERROR. * Resetting the pattern prefixes or suffixes is not supported; the method calls * are ignored. - *

+ * * @stable ICU 51 */ class U_I18N_API CompactDecimalFormat : public DecimalFormat { @@ -54,6 +63,9 @@ class U_I18N_API CompactDecimalFormat : public DecimalFormat { /** * Returns a compact decimal instance for specified locale. + * + * **NOTE:** New users are strongly encouraged to use + * `number::NumberFormatter` instead of NumberFormat. * @param inLocale the given locale. * @param style whether to use short or long style. * @param status error code returned here. @@ -74,7 +86,7 @@ class U_I18N_API CompactDecimalFormat : public DecimalFormat { * Destructor. * @stable ICU 51 */ - virtual ~CompactDecimalFormat(); + ~CompactDecimalFormat() U_OVERRIDE; /** * Assignment operator. @@ -91,176 +103,34 @@ class U_I18N_API CompactDecimalFormat : public DecimalFormat { * @return a polymorphic copy of this CompactDecimalFormat. * @stable ICU 51 */ - virtual Format* clone() const; - - /** - * Return TRUE if the given Format objects are semantically equal. - * Objects of different subclasses are considered unequal. - * - * @param other the object to be compared with. - * @return TRUE if the given Format objects are semantically equal. - * @stable ICU 51 - */ - virtual UBool operator==(const Format& other) const; - + Format* clone() const U_OVERRIDE; using DecimalFormat::format; /** - * Format a double or long number using base-10 representation. - * - * @param number The value to be formatted. - * @param appendTo Output parameter to receive result. - * Result is appended to existing contents. - * @param pos On input: an alignment field, if desired. - * On output: the offsets of the alignment field. - * @return Reference to 'appendTo' parameter. - * @stable ICU 51 - */ - virtual UnicodeString& format(double number, - UnicodeString& appendTo, - FieldPosition& pos) const; - - /** - * Format a double or long number using base-10 representation. - * Currently sets status to U_UNSUPPORTED_ERROR. - * - * @param number The value to be formatted. - * @param appendTo Output parameter to receive result. - * Result is appended to existing contents. - * @param posIter On return, can be used to iterate over positions - * of fields generated by this format call. - * Can be NULL. - * @param status Output param filled with success/failure status. - * @return Reference to 'appendTo' parameter. - * @internal - */ - virtual UnicodeString& format(double number, - UnicodeString& appendTo, - FieldPositionIterator* posIter, - UErrorCode& status) const; - - /** - * Format an int64 number using base-10 representation. - * - * @param number The value to be formatted. - * @param appendTo Output parameter to receive result. - * Result is appended to existing contents. - * @param pos On input: an alignment field, if desired. - * On output: the offsets of the alignment field. - * @return Reference to 'appendTo' parameter. + * CompactDecimalFormat does not support parsing. This implementation + * does nothing. + * @param text Unused. + * @param result Does not change. + * @param parsePosition Does not change. + * @see Formattable * @stable ICU 51 */ - virtual UnicodeString& format(int64_t number, - UnicodeString& appendTo, - FieldPosition& pos) const; - - /** - * Format an int64 number using base-10 representation. - * Currently sets status to U_UNSUPPORTED_ERROR - * - * @param number The value to be formatted. - * @param appendTo Output parameter to receive result. - * Result is appended to existing contents. - * @param posIter On return, can be used to iterate over positions - * of fields generated by this format call. - * Can be NULL. - * @param status Output param filled with success/failure status. - * @return Reference to 'appendTo' parameter. - * @internal - */ - virtual UnicodeString& format(int64_t number, - UnicodeString& appendTo, - FieldPositionIterator* posIter, - UErrorCode& status) const; - - /** - * Format a decimal number. Currently sets status to U_UNSUPPORTED_ERROR - * The syntax of the unformatted number is a "numeric string" - * as defined in the Decimal Arithmetic Specification, available at - * http://speleotrove.com/decimal - * - * @param number The unformatted number, as a string. - * @param appendTo Output parameter to receive result. - * Result is appended to existing contents. - * @param posIter On return, can be used to iterate over positions - * of fields generated by this format call. - * Can be NULL. - * @param status Output param filled with success/failure status. - * @return Reference to 'appendTo' parameter. - * @internal - */ - virtual UnicodeString& format(const StringPiece &number, - UnicodeString& appendTo, - FieldPositionIterator* posIter, - UErrorCode& status) const; - - /** - * Format a decimal number. Currently sets status to U_UNSUPPORTED_ERROR - * The number is a DigitList wrapper onto a floating point decimal number. - * The default implementation in NumberFormat converts the decimal number - * to a double and formats that. - * - * @param number The number, a DigitList format Decimal Floating Point. - * @param appendTo Output parameter to receive result. - * Result is appended to existing contents. - * @param posIter On return, can be used to iterate over positions - * of fields generated by this format call. - * @param status Output param filled with success/failure status. - * @return Reference to 'appendTo' parameter. - * @internal - */ - virtual UnicodeString& format(const DigitList &number, - UnicodeString& appendTo, - FieldPositionIterator* posIter, - UErrorCode& status) const; - - /** - * Format a decimal number. Currently sets status to U_UNSUPPORTED_ERROR. - * The number is a DigitList wrapper onto a floating point decimal number. - * The default implementation in NumberFormat converts the decimal number - * to a double and formats that. - * - * @param number The number, a DigitList format Decimal Floating Point. - * @param appendTo Output parameter to receive result. - * Result is appended to existing contents. - * @param pos On input: an alignment field, if desired. - * On output: the offsets of the alignment field. - * @param status Output param filled with success/failure status. - * @return Reference to 'appendTo' parameter. - * @internal - */ - virtual UnicodeString& format(const DigitList &number, - UnicodeString& appendTo, - FieldPosition& pos, - UErrorCode& status) const; - - /** - * CompactDecimalFormat does not support parsing. This implementation - * does nothing. - * @param text Unused. - * @param result Does not change. - * @param parsePosition Does not change. - * @see Formattable - * @stable ICU 51 - */ - virtual void parse(const UnicodeString& text, - Formattable& result, - ParsePosition& parsePosition) const; + void parse(const UnicodeString& text, Formattable& result, + ParsePosition& parsePosition) const U_OVERRIDE; /** * CompactDecimalFormat does not support parsing. This implementation * sets status to U_UNSUPPORTED_ERROR * - * @param text Unused. + * @param text Unused. * @param result Does not change. * @param status Always set to U_UNSUPPORTED_ERROR. * @stable ICU 51 */ - virtual void parse(const UnicodeString& text, - Formattable& result, - UErrorCode& status) const; + void parse(const UnicodeString& text, Formattable& result, UErrorCode& status) const U_OVERRIDE; +#ifndef U_HIDE_INTERNAL_API /** * Parses text from the given string as a currency amount. Unlike * the parse() method, this method will attempt to parse a generic @@ -281,8 +151,8 @@ class U_I18N_API CompactDecimalFormat : public DecimalFormat { * the parsed currency; if parse fails, this is NULL. * @internal */ - virtual CurrencyAmount* parseCurrency(const UnicodeString& text, - ParsePosition& pos) const; + CurrencyAmount* parseCurrency(const UnicodeString& text, ParsePosition& pos) const U_OVERRIDE; +#endif /* U_HIDE_INTERNAL_API */ /** * Return the class ID for this class. This is useful only for @@ -308,21 +178,14 @@ class U_I18N_API CompactDecimalFormat : public DecimalFormat { * other classes have different class IDs. * @stable ICU 51 */ - virtual UClassID getDynamicClassID() const; - -private: - - const UHashtable* _unitsByVariant; - const double* _divisors; - PluralRules* _pluralRules; - - // Default constructor not implemented. - CompactDecimalFormat(const DecimalFormat &, const UHashtable* unitsByVariant, const double* divisors, PluralRules* pluralRules); + UClassID getDynamicClassID() const U_OVERRIDE; - UBool eqHelper(const CompactDecimalFormat& that) const; + private: + CompactDecimalFormat(const Locale& inLocale, UNumberCompactStyle style, UErrorCode& status); }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/curramt.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/curramt.h index c33e6f1f83..ad91df7b41 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/curramt.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/curramt.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2004-2006, International Business Machines @@ -23,6 +25,7 @@ * \brief C++ API: Currency Amount Object. */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -44,7 +47,7 @@ class U_I18N_API CurrencyAmount: public Measure { * is invalid, then this will be set to a failing value. * @stable ICU 3.0 */ - CurrencyAmount(const Formattable& amount, const UChar* isoCode, + CurrencyAmount(const Formattable& amount, ConstChar16Ptr isoCode, UErrorCode &ec); /** @@ -57,7 +60,7 @@ class U_I18N_API CurrencyAmount: public Measure { * then this will be set to a failing value. * @stable ICU 3.0 */ - CurrencyAmount(double amount, const UChar* isoCode, + CurrencyAmount(double amount, ConstChar16Ptr isoCode, UErrorCode &ec); /** @@ -113,18 +116,19 @@ class U_I18N_API CurrencyAmount: public Measure { * Return the ISO currency code of this object. * @stable ICU 3.0 */ - inline const UChar* getISOCurrency() const; + inline const char16_t* getISOCurrency() const; }; inline const CurrencyUnit& CurrencyAmount::getCurrency() const { return (const CurrencyUnit&) getUnit(); } -inline const UChar* CurrencyAmount::getISOCurrency() const { +inline const char16_t* CurrencyAmount::getISOCurrency() const { return getCurrency().getISOCurrency(); } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // !UCONFIG_NO_FORMATTING #endif // __CURRENCYAMOUNT_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/currpinf.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/currpinf.h index 9ade99a09e..fc9cb02ace 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/currpinf.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/currpinf.h @@ -1,6 +1,8 @@ +// © 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 * + * Copyright (C) 2009-2015, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* */ @@ -18,6 +20,7 @@ #include "unicode/unistr.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class Locale; @@ -191,6 +194,7 @@ class U_I18N_API CurrencyPluralInfo : public UObject { private: friend class DecimalFormat; + friend class DecimalFormatImpl; void initialize(const Locale& loc, UErrorCode& status); @@ -237,20 +241,30 @@ class U_I18N_API CurrencyPluralInfo : public UObject { /* * The plural rule is used to format currency plural name, * for example: "3.00 US Dollars". - * If there are 3 currency signs in the currency patttern, + * If there are 3 currency signs in the currency pattern, * the 3 currency signs will be replaced by currency plural name. */ PluralRules* fPluralRules; // locale Locale* fLocale; + +private: + /** + * An internal status variable used to indicate that the object is in an 'invalid' state. + * Used by copy constructor, the assignment operator and the clone method. + */ + UErrorCode fInternalStatus; }; inline UBool -CurrencyPluralInfo::operator!=(const CurrencyPluralInfo& info) const { return !operator==(info); } +CurrencyPluralInfo::operator!=(const CurrencyPluralInfo& info) const { + return !operator==(info); +} U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/currunit.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/currunit.h index d79836bb74..46d15d6a3b 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/currunit.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/currunit.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2004-2014, International Business Machines @@ -22,11 +24,12 @@ * \brief C++ API: Currency Unit Information. */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** * A unit of currency, such as USD (U.S. dollars) or JPY (Japanese - * yen). This class is a thin wrapper over a UChar string that + * yen). This class is a thin wrapper over a char16_t string that * subclasses MeasureUnit, for use with Measure and MeasureFormat. * * @author Alan Liu @@ -34,15 +37,36 @@ U_NAMESPACE_BEGIN */ class U_I18N_API CurrencyUnit: public MeasureUnit { public: + /** + * Default constructor. Initializes currency code to "XXX" (no currency). + * @stable ICU 60 + */ + CurrencyUnit(); + /** * Construct an object with the given ISO currency code. - * @param isoCode the 3-letter ISO 4217 currency code; must not be - * NULL and must have length 3 + * + * @param isoCode the 3-letter ISO 4217 currency code; must have + * length 3 and need not be NUL-terminated. If NULL, the currency + * is initialized to the unknown currency XXX. * @param ec input-output error code. If the isoCode is invalid, * then this will be set to a failing value. * @stable ICU 3.0 */ - CurrencyUnit(const UChar* isoCode, UErrorCode &ec); + CurrencyUnit(ConstChar16Ptr isoCode, UErrorCode &ec); + +#ifndef U_HIDE_DRAFT_API + /** + * Construct an object with the given ISO currency code. + * + * @param isoCode the 3-letter ISO 4217 currency code; must have + * length 3. If invalid, the currency is initialized to XXX. + * @param ec input-output error code. If the isoCode is invalid, + * then this will be set to a failing value. + * @draft ICU 64 + */ + CurrencyUnit(StringPiece isoCode, UErrorCode &ec); +#endif /* U_HIDE_DRAFT_API */ /** * Copy constructor @@ -50,6 +74,16 @@ class U_I18N_API CurrencyUnit: public MeasureUnit { */ CurrencyUnit(const CurrencyUnit& other); + /** + * Copy constructor from MeasureUnit. This constructor allows you to + * restore a CurrencyUnit that was sliced to MeasureUnit. + * + * @param measureUnit The MeasureUnit to copy from. + * @param ec Set to a failing value if the MeasureUnit is not a currency. + * @stable ICU 60 + */ + CurrencyUnit(const MeasureUnit& measureUnit, UErrorCode &ec); + /** * Assignment operator * @stable ICU 3.0 @@ -91,20 +125,21 @@ class U_I18N_API CurrencyUnit: public MeasureUnit { * Return the ISO currency code of this object. * @stable ICU 3.0 */ - inline const UChar* getISOCurrency() const; + inline const char16_t* getISOCurrency() const; private: /** * The ISO 4217 code of this object. */ - UChar isoCode[4]; + char16_t isoCode[4]; }; -inline const UChar* CurrencyUnit::getISOCurrency() const { +inline const char16_t* CurrencyUnit::getISOCurrency() const { return isoCode; } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // !UCONFIG_NO_FORMATTING #endif // __CURRENCYUNIT_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/datefmt.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/datefmt.h index 983f13635c..50e47b092d 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/datefmt.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/datefmt.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** - * Copyright (C) 1997-2015, International Business Machines + * Copyright (C) 1997-2016, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************** * @@ -36,17 +38,23 @@ * \brief C++ API: Abstract class for converting dates. */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class TimeZone; class DateTimePatternGenerator; -// explicit template instantiation. see digitlst.h -#if defined (_MSC_VER) +/** + * \cond + * Export an explicit template instantiation. (See digitlst.h, datefmt.h, and others.) + * (When building DLLs for Windows this is required.) + */ +#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN && !defined(U_IN_DOXYGEN) template class U_I18N_API EnumSet; #endif +/** \endcond */ /** * DateFormat is an abstract class for a family of classes that convert dates and @@ -571,7 +579,20 @@ class U_I18N_API DateFormat : public Format { EStyle timeStyle = kDefault, const Locale& aLocale = Locale::getDefault()); -#ifndef U_HIDE_DRAFT_API +#ifndef U_HIDE_INTERNAL_API + /** + * Returns the best pattern given a skeleton and locale. + * @param locale the locale + * @param skeleton the skeleton + * @param status ICU error returned here + * @return the best pattern. + * @internal For ICU use only. + */ + static UnicodeString getBestPattern( + const Locale &locale, + const UnicodeString &skeleton, + UErrorCode &status); +#endif /* U_HIDE_INTERNAL_API */ /** * Creates a date/time formatter for the given skeleton and @@ -584,7 +605,7 @@ class U_I18N_API DateFormat : public Format { * order for that locale. * @param status Any error returned here. * @return A date/time formatter which the caller owns. - * @draft ICU 55 + * @stable ICU 55 */ static DateFormat* U_EXPORT2 createInstanceForSkeleton( const UnicodeString& skeleton, @@ -601,7 +622,7 @@ class U_I18N_API DateFormat : public Format { * @param locale The given locale. * @param status Any error returned here. * @return A date/time formatter which the caller owns. - * @draft ICU 55 + * @stable ICU 55 */ static DateFormat* U_EXPORT2 createInstanceForSkeleton( const UnicodeString& skeleton, @@ -620,7 +641,7 @@ class U_I18N_API DateFormat : public Format { * @param locale The given locale. * @param status Any error returned here. * @return A date/time formatter which the caller owns. - * @draft ICU 55 + * @stable ICU 55 */ static DateFormat* U_EXPORT2 createInstanceForSkeleton( Calendar *calendarToAdopt, @@ -628,42 +649,6 @@ class U_I18N_API DateFormat : public Format { const Locale &locale, UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ - -#ifndef U_HIDE_INTERNAL_API - - /** - * Creates a date/time formatter for the given skeleton and locale and - * uses the given DateTimePatternGenerator to convert the skeleton to - * a format pattern. As creating a DateTimePatternGenerator is - * expensive, callers can supply it here (if they already have it) to save - * this method from creating its own. - * - * @param skeleton The skeleton e.g "yMMMMd." Fields in the skeleton can - * be in any order, and this method uses the provided - * DateTimePatternGenerator to map the skeleton to a - * pattern that includes appropriate separators with - * the fields in the appropriate order. - * @param locale The given locale. - * @param dpng The user supplied DateTimePatternGenerator. dpng - * must be created for the same locale as locale. - * Moreover, the caller must not modify dpng between - * creating it by locale and calling this method. - * Although dpng is a non-const reference, the caller - * must not regard it as an out or in-out parameter. - * The only reason dpng is a non-const reference is - * because its method, getBestPattern, which converts - * a skeleton to a date format pattern is non-const. - * @return A date/time formatter which the caller owns. - * @internal For ICU use only - */ - static DateFormat* U_EXPORT2 internalCreateInstanceForSkeleton( - const UnicodeString& skeleton, - const Locale &locale, - DateTimePatternGenerator &dpng, - UErrorCode &status); - -#endif /* U_HIDE_INTERNAL_API */ /** * Gets the set of locales for which DateFormats are installed. @@ -887,6 +872,7 @@ class U_I18N_API DateFormat : public Format { private: + /** * Gets the date/time formatter with the given formatting styles for the * given locale. @@ -965,6 +951,7 @@ class U_I18N_API DateFormat : public Format { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dbbi.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dbbi.h index 7187c3c20f..6f598febe6 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dbbi.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dbbi.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2006,2013 IBM Corp. All rights reserved. @@ -20,6 +22,7 @@ * \brief C++ API: Dictionary Based Break Iterator */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN #ifndef U_HIDE_DEPRECATED_API @@ -34,6 +37,7 @@ typedef RuleBasedBreakIterator DictionaryBasedBreakIterator; #endif /* U_HIDE_DEPRECATED_API */ U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_BREAK_ITERATION */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dcfmtsym.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dcfmtsym.h index 46ef22241b..c2207e7b2e 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dcfmtsym.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dcfmtsym.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** -* Copyright (C) 1997-2015, International Business Machines +* Copyright (C) 1997-2016, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************** * @@ -32,7 +34,9 @@ #include "unicode/uobject.h" #include "unicode/locid.h" +#include "unicode/numsys.h" #include "unicode/unum.h" +#include "unicode/unistr.h" /** * \file @@ -40,6 +44,7 @@ */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -76,10 +81,6 @@ U_NAMESPACE_BEGIN * If you supply a pattern with multiple grouping characters, the interval * between the last one and the end of the integer is the one that is * used. So "#,##,###,####" == "######,####" == "##,####,####". - *

- * This class only handles localized digits where the 10 digits are - * contiguous in Unicode, from 0 to 9. Other digits sets (such as - * superscripts) would need a different subclass. */ class U_I18N_API DecimalFormatSymbols : public UObject { public: @@ -163,12 +164,10 @@ class U_I18N_API DecimalFormatSymbols : public UObject { * @stable ICU 4.6 */ kNineDigitSymbol, -#ifndef U_HIDE_DRAFT_API /** Multiplication sign. - * @draft ICU 54 + * @stable ICU 54 */ kExponentMultiplicationSymbol, -#endif /* U_HIDE_DRAFT_API */ /** count symbol constants */ kFormatSymbolCount = kNineDigitSymbol + 2 }; @@ -183,6 +182,24 @@ class U_I18N_API DecimalFormatSymbols : public UObject { */ DecimalFormatSymbols(const Locale& locale, UErrorCode& status); + /** + * Creates a DecimalFormatSymbols instance for the given locale with digits and symbols + * corresponding to the given NumberingSystem. + * + * This constructor behaves equivalently to the normal constructor called with a locale having a + * "numbers=xxxx" keyword specifying the numbering system by name. + * + * In this constructor, the NumberingSystem argument will be used even if the locale has its own + * "numbers=xxxx" keyword. + * + * @param locale The locale to get symbols for. + * @param ns The numbering system. + * @param status Input/output parameter, set to success or + * failure code upon return. + * @stable ICU 60 + */ + DecimalFormatSymbols(const Locale& locale, const NumberingSystem& ns, UErrorCode& status); + /** * Create a DecimalFormatSymbols object for the default locale. * This constructor will not fail. If the resource file data is @@ -345,8 +362,11 @@ class U_I18N_API DecimalFormatSymbols : public UObject { * @param success Input/output parameter, set to success or * failure code upon return. * @param useLastResortData determine if use last resort data + * @param ns The NumberingSystem to use; otherwise, fall + * back to the locale. */ - void initialize(const Locale& locale, UErrorCode& success, UBool useLastResortData = FALSE); + void initialize(const Locale& locale, UErrorCode& success, + UBool useLastResortData = FALSE, const NumberingSystem* ns = nullptr); /** * Initialize the symbols with default values. @@ -356,26 +376,77 @@ class U_I18N_API DecimalFormatSymbols : public UObject { void setCurrencyForSymbols(); public: + +#ifndef U_HIDE_INTERNAL_API + /** + * @internal For ICU use only + */ + inline UBool isCustomCurrencySymbol() const { + return fIsCustomCurrencySymbol; + } + + /** + * @internal For ICU use only + */ + inline UBool isCustomIntlCurrencySymbol() const { + return fIsCustomIntlCurrencySymbol; + } + + /** + * @internal For ICU use only + */ + inline UChar32 getCodePointZero() const { + return fCodePointZero; + } +#endif /* U_HIDE_INTERNAL_API */ + /** * _Internal_ function - more efficient version of getSymbol, * returning a const reference to one of the symbol strings. * The returned reference becomes invalid when the symbol is changed * or when the DecimalFormatSymbols are destroyed. - * ### TODO markus 2002oct11: Consider proposing getConstSymbol() to be really public. - * Note: moved #ifndef U_HIDE_INTERNAL_API after this, since this is needed for inline in DecimalFormat + * Note: moved \#ifndef U_HIDE_INTERNAL_API after this, since this is needed for inline in DecimalFormat + * + * This is not currently stable API, but if you think it should be stable, + * post a comment on the following ticket and the ICU team will take a look: + * http://bugs.icu-project.org/trac/ticket/13580 * * @param symbol Constant to indicate a number format symbol. * @return the format symbol by the param 'symbol' * @internal */ - inline const UnicodeString &getConstSymbol(ENumberFormatSymbol symbol) const; + inline const UnicodeString& getConstSymbol(ENumberFormatSymbol symbol) const; #ifndef U_HIDE_INTERNAL_API + /** + * Returns the const UnicodeString reference, like getConstSymbol, + * corresponding to the digit with the given value. This is equivalent + * to accessing the symbol from getConstSymbol with the corresponding + * key, such as kZeroDigitSymbol or kOneDigitSymbol. + * + * This is not currently stable API, but if you think it should be stable, + * post a comment on the following ticket and the ICU team will take a look: + * http://bugs.icu-project.org/trac/ticket/13580 + * + * @param digit The digit, an integer between 0 and 9 inclusive. + * If outside the range 0 to 9, the zero digit is returned. + * @return the format symbol for the given digit. + * @internal This API is currently for ICU use only. + */ + inline const UnicodeString& getConstDigitSymbol(int32_t digit) const; + /** * Returns that pattern stored in currecy info. Internal API for use by NumberFormat API. * @internal */ - inline const UChar* getCurrencyPattern(void) const; + inline const char16_t* getCurrencyPattern(void) const; + + /** + * Returns the name of the numbering system used for this object. + * @internal + */ + inline const char* getNSName() const; + #endif /* U_HIDE_INTERNAL_API */ private: @@ -402,14 +473,33 @@ class U_I18N_API DecimalFormatSymbols : public UObject { */ UnicodeString fNoSymbol; + /** + * Dealing with code points is faster than dealing with strings when formatting. Because of + * this, we maintain a value containing the zero code point that is used whenever digitStrings + * represents a sequence of ten code points in order. + * + *

If the value stored here is positive, it means that the code point stored in this value + * corresponds to the digitStrings array, and codePointZero can be used instead of the + * digitStrings array for the purposes of efficient formatting; if -1, then digitStrings does + * *not* contain a sequence of code points, and it must be used directly. + * + *

It is assumed that codePointZero always shadows the value in digitStrings. codePointZero + * should never be set directly; rather, it should be updated only when digitStrings mutates. + * That is, the flow of information is digitStrings -> codePointZero, not the other way. + */ + UChar32 fCodePointZero; + Locale locale; char actualLocale[ULOC_FULLNAME_CAPACITY]; char validLocale[ULOC_FULLNAME_CAPACITY]; - const UChar* currPattern; + const char16_t* currPattern; UnicodeString currencySpcBeforeSym[UNUM_CURRENCY_SPACING_COUNT]; UnicodeString currencySpcAfterSym[UNUM_CURRENCY_SPACING_COUNT]; + UBool fIsCustomCurrencySymbol; + UBool fIsCustomIntlCurrencySymbol; + char fNSName[9]; // Apple rdar://51672521 }; // ------------------------------------- @@ -425,8 +515,7 @@ DecimalFormatSymbols::getSymbol(ENumberFormatSymbol symbol) const { return *strPtr; } -//#ifndef U_HIDE_INTERNAL_API -// See comments above for this function. Not hidden. +// See comments above for this function. Not hidden with #ifdef U_HIDE_INTERNAL_API inline const UnicodeString & DecimalFormatSymbols::getConstSymbol(ENumberFormatSymbol symbol) const { const UnicodeString *strPtr; @@ -438,27 +527,49 @@ DecimalFormatSymbols::getConstSymbol(ENumberFormatSymbol symbol) const { return *strPtr; } -//#endif /* U_HIDE_INTERNAL_API */ - +#ifndef U_HIDE_INTERNAL_API +inline const UnicodeString& DecimalFormatSymbols::getConstDigitSymbol(int32_t digit) const { + if (digit < 0 || digit > 9) { + digit = 0; + } + if (digit == 0) { + return fSymbols[kZeroDigitSymbol]; + } + ENumberFormatSymbol key = static_cast(kOneDigitSymbol + digit - 1); + return fSymbols[key]; +} +#endif /* U_HIDE_INTERNAL_API */ // ------------------------------------- inline void DecimalFormatSymbols::setSymbol(ENumberFormatSymbol symbol, const UnicodeString &value, const UBool propogateDigits = TRUE) { + if (symbol == kCurrencySymbol) { + fIsCustomCurrencySymbol = TRUE; + } + else if (symbol == kIntlCurrencySymbol) { + fIsCustomIntlCurrencySymbol = TRUE; + } if(symbol= kOneDigitSymbol && symbol <= kNineDigitSymbol) { + fCodePointZero = -1; } } @@ -470,13 +581,19 @@ DecimalFormatSymbols::getLocale() const { } #ifndef U_HIDE_INTERNAL_API -inline const UChar* +inline const char16_t* DecimalFormatSymbols::getCurrencyPattern() const { return currPattern; } + +inline const char* +DecimalFormatSymbols::getNSName() const { + return fNSName; +} #endif /* U_HIDE_INTERNAL_API */ U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/decimfmt.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/decimfmt.h index 00d4851a36..6e6a7ff001 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/decimfmt.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/decimfmt.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** -* Copyright (C) 1997-2015, International Business Machines +* Copyright (C) 1997-2016, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************** * @@ -28,7 +30,7 @@ #include "unicode/utypes.h" /** * \file - * \brief C++ API: Formats decimal numbers. + * \brief C++ API: Compatibility APIs for decimal formatting. */ #if !UCONFIG_NO_FORMATTING @@ -41,33 +43,32 @@ #include "unicode/curramt.h" #include "unicode/enumset.h" -/** - * \def UNUM_DECIMALFORMAT_INTERNAL_SIZE - * @internal - */ -#if UCONFIG_FORMAT_FASTPATHS_49 -#define UNUM_DECIMALFORMAT_INTERNAL_SIZE 16 -#endif - +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN -class DigitList; -class ChoiceFormat; class CurrencyPluralInfo; -class Hashtable; -class UnicodeSet; -class FieldPositionHandler; -class DecimalFormatStaticSets; -class FixedDecimal; - -// explicit template instantiation. see digitlst.h -#if defined (_MSC_VER) -template class U_I18N_API EnumSet; -#endif +class CompactDecimalFormat; + +namespace number { +class LocalizedNumberFormatter; +class FormattedNumber; +namespace impl { +class DecimalQuantity; +struct DecimalFormatFields; +} +} + +namespace numparse { +namespace impl { +class NumberParserImpl; +} +} /** + * **IMPORTANT:** New users are strongly encouraged to see if + * numberformatter.h fits their use case. Although not deprecated, this header + * is provided for backwards compatibility only. + * * DecimalFormat is a concrete subclass of NumberFormat that formats decimal * numbers. It has a variety of features designed to make it possible to parse * and format numbers in any locale, including support for Western, Arabic, or @@ -76,13 +77,13 @@ template class U_I18N_API EnumSetTo obtain a NumberFormat for a specific locale (including the default + * To obtain a NumberFormat for a specific locale (including the default * locale) call one of NumberFormat's factory methods such as * createInstance(). Do not call the DecimalFormat constructors directly, unless * you know what you are doing, since the NumberFormat factory methods may * return subclasses other than DecimalFormat. * - *

Example Usage + * **Example Usage** * * \code * // Normally we would have a GUI with a menu for this @@ -126,11 +127,11 @@ template class U_I18N_API EnumSet - * Another example use createInstance(style) - *

- *

- * // Print out a number using the localized number, currency,
+ *
+ * **Another example use createInstance(style)**
+ *
+ * \code
+ * // Print out a number using the localized number, currency,
  * // percent, scientific, integer, iso currency, and plural currency
  * // format for each locale
  * Locale* locale = new Locale("en", "US");
@@ -141,11 +142,13 @@ template class U_I18N_API    EnumSetformat(myNumber, str) << endl;
  *     format->parse(form->format(myNumber, str), fmtable, success);
- * }
+ * delete form; + * } + * \endcode * * *

Patterns @@ -274,7 +277,7 @@ template class U_I18N_API EnumSetPad escape, precedes pad character * * - *

A DecimalFormat pattern contains a postive and negative + *

A DecimalFormat pattern contains a positive and negative * subpattern, for example, "#,##0.00;(#,##0.00)". Each subpattern has a * prefix, a numeric part, and a suffix. If there is no explicit negative * subpattern, the negative subpattern is the localized minus sign prefixed to the @@ -408,7 +411,7 @@ template class U_I18N_API EnumSetIf the number of actual fraction digits is less than the * minimum fraction digits, then trailing zeros are added. - * For example, 0.125 is formatted as "0.1250" if the mimimum fraction + * For example, 0.125 is formatted as "0.1250" if the minimum fraction * digits is set to 4. * *

  • Trailing fractional zeros are not displayed if they occur @@ -573,9 +576,9 @@ template class U_I18N_API EnumSetgetMaximumSignificantDigits() - 1. For example, the * pattern "@@###E0" is equivalent to "0.0###E0". * - *
  • If signficant digits are in use, then the integer and fraction + *
  • If significant digits are in use, then the integer and fraction * digit counts, as set via the API, are ignored. If significant - * digits are not in use, then the signficant digit counts, as set via + * digits are not in use, then the significant digit counts, as set via * the API, are ignored. * * @@ -597,7 +600,7 @@ template class U_I18N_API EnumSet"* #0 o''clock", the format width is 10. * - *
  • The width is counted in 16-bit code units (UChars). + *
  • The width is counted in 16-bit code units (char16_ts). * *
  • Some parameters which usually do not matter have meaning when padding is * used, because the pattern width is significant with padding. In the pattern @@ -629,7 +632,7 @@ template class U_I18N_API EnumSetIn the absense of an explicit rounding increment numbers are + *

    In the absence of an explicit rounding increment numbers are * rounded to their formatted width. * *

      @@ -659,39 +662,14 @@ template class U_I18N_API EnumSet + * NOTE: New users are strongly encouraged to use + * #icu::number::NumberFormatter instead of DecimalFormat. * @param status Output param set to success/failure code. If the * pattern is invalid this will be set to a failure code. * @stable ICU 2.0 @@ -718,13 +699,15 @@ class U_I18N_API DecimalFormat: public NumberFormat { * on NumberFormat such as createInstance. These factories will * return the most appropriate sub-class of NumberFormat for a given * locale. + *

      + * NOTE: New users are strongly encouraged to use + * #icu::number::NumberFormatter instead of DecimalFormat. * @param pattern A non-localized pattern string. * @param status Output param set to success/failure code. If the * pattern is invalid this will be set to a failure code. * @stable ICU 2.0 */ - DecimalFormat(const UnicodeString& pattern, - UErrorCode& status); + DecimalFormat(const UnicodeString& pattern, UErrorCode& status); /** * Create a DecimalFormat from the given pattern and symbols. @@ -736,6 +719,9 @@ class U_I18N_API DecimalFormat: public NumberFormat { * createInstance or createCurrencyInstance. If you need only minor adjustments * to a standard format, you can modify the format returned by * a NumberFormat factory method. + *

      + * NOTE: New users are strongly encouraged to use + * #icu::number::NumberFormatter instead of DecimalFormat. * * @param pattern a non-localized pattern string * @param symbolsToAdopt the set of symbols to be used. The caller should not @@ -744,11 +730,10 @@ class U_I18N_API DecimalFormat: public NumberFormat { * pattern is invalid this will be set to a failure code. * @stable ICU 2.0 */ - DecimalFormat( const UnicodeString& pattern, - DecimalFormatSymbols* symbolsToAdopt, - UErrorCode& status); + DecimalFormat(const UnicodeString& pattern, DecimalFormatSymbols* symbolsToAdopt, UErrorCode& status); #ifndef U_HIDE_INTERNAL_API + /** * This API is for ICU use only. * Create a DecimalFormat from the given pattern, symbols, and style. @@ -761,34 +746,41 @@ class U_I18N_API DecimalFormat: public NumberFormat { * pattern is invalid this will be set to a failure code. * @internal */ - DecimalFormat( const UnicodeString& pattern, - DecimalFormatSymbols* symbolsToAdopt, - UNumberFormatStyle style, - UErrorCode& status); + DecimalFormat(const UnicodeString& pattern, DecimalFormatSymbols* symbolsToAdopt, + UNumberFormatStyle style, UErrorCode& status); #if UCONFIG_HAVE_PARSEALLINPUT + /** * @internal */ void setParseAllInput(UNumberFormatAttributeValue value); + #endif #endif /* U_HIDE_INTERNAL_API */ + private: + + /** + * Internal constructor for DecimalFormat; sets up internal fields. All public constructors should + * call this constructor. + */ + DecimalFormat(const DecimalFormatSymbols* symbolsToAdopt, UErrorCode& status); + + public: /** * Set an integer attribute on this DecimalFormat. * May return U_UNSUPPORTED_ERROR if this instance does not support * the specified attribute. * @param attr the attribute to set - * @param newvalue new value + * @param newValue new value * @param status the error type * @return *this - for chaining (example: format.setAttribute(...).setAttribute(...) ) * @stable ICU 51 */ - virtual DecimalFormat& setAttribute( UNumberFormatAttribute attr, - int32_t newvalue, - UErrorCode &status); + virtual DecimalFormat& setAttribute(UNumberFormatAttribute attr, int32_t newValue, UErrorCode& status); /** * Get an integer @@ -799,17 +791,16 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @return the attribute value. Undefined if there is an error. * @stable ICU 51 */ - virtual int32_t getAttribute( UNumberFormatAttribute attr, - UErrorCode &status) const; + virtual int32_t getAttribute(UNumberFormatAttribute attr, UErrorCode& status) const; + - /** * Set whether or not grouping will be used in this format. * @param newValue True, grouping will be used in this format. * @see getGroupingUsed * @stable ICU 53 */ - virtual void setGroupingUsed(UBool newValue); + void setGroupingUsed(UBool newValue) U_OVERRIDE; /** * Sets whether or not numbers should be parsed as integers only. @@ -818,18 +809,16 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @see isParseIntegerOnly * @stable ICU 53 */ - virtual void setParseIntegerOnly(UBool value); + void setParseIntegerOnly(UBool value) U_OVERRIDE; /** - * Set a particular UDisplayContext value in the formatter, such as - * UDISPCTX_CAPITALIZATION_FOR_STANDALONE. - * @param value The UDisplayContext value to set. - * @param status Input/output status. If at entry this indicates a failure - * status, the function will do nothing; otherwise this will be - * updated with any new status from the function. - * @stable ICU 53 + * Sets whether lenient parsing should be enabled (it is off by default). + * + * @param enable \c TRUE if lenient parsing should be used, + * \c FALSE otherwise. + * @stable ICU 4.8 */ - virtual void setContext(UDisplayContext value, UErrorCode& status); + void setLenient(UBool enable) U_OVERRIDE; /** * Create a DecimalFormat from the given pattern and symbols. @@ -841,19 +830,21 @@ class U_I18N_API DecimalFormat: public NumberFormat { * createInstance or createCurrencyInstance. If you need only minor adjustments * to a standard format, you can modify the format returned by * a NumberFormat factory method. + *

      + * NOTE: New users are strongly encouraged to use + * #icu::number::NumberFormatter instead of DecimalFormat. * * @param pattern a non-localized pattern string * @param symbolsToAdopt the set of symbols to be used. The caller should not * delete this object after making this call. - * @param parseError Output param to receive errors occured during parsing + * @param parseError Output param to receive errors occurred during parsing * @param status Output param set to success/failure code. If the * pattern is invalid this will be set to a failure code. * @stable ICU 2.0 */ - DecimalFormat( const UnicodeString& pattern, - DecimalFormatSymbols* symbolsToAdopt, - UParseError& parseError, - UErrorCode& status); + DecimalFormat(const UnicodeString& pattern, DecimalFormatSymbols* symbolsToAdopt, + UParseError& parseError, UErrorCode& status); + /** * Create a DecimalFormat from the given pattern and symbols. * Use this constructor when you need to completely customize the @@ -864,6 +855,9 @@ class U_I18N_API DecimalFormat: public NumberFormat { * createInstance or createCurrencyInstance. If you need only minor adjustments * to a standard format, you can modify the format returned by * a NumberFormat factory method. + *

      + * NOTE: New users are strongly encouraged to use + * #icu::number::NumberFormatter instead of DecimalFormat. * * @param pattern a non-localized pattern string * @param symbols the set of symbols to be used @@ -871,9 +865,7 @@ class U_I18N_API DecimalFormat: public NumberFormat { * pattern is invalid this will be set to a failure code. * @stable ICU 2.0 */ - DecimalFormat( const UnicodeString& pattern, - const DecimalFormatSymbols& symbols, - UErrorCode& status); + DecimalFormat(const UnicodeString& pattern, const DecimalFormatSymbols& symbols, UErrorCode& status); /** * Copy constructor. @@ -895,7 +887,7 @@ class U_I18N_API DecimalFormat: public NumberFormat { * Destructor. * @stable ICU 2.0 */ - virtual ~DecimalFormat(); + ~DecimalFormat() U_OVERRIDE; /** * Clone this Format object polymorphically. The caller owns the @@ -904,7 +896,7 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @return a polymorphic copy of this DecimalFormat. * @stable ICU 2.0 */ - virtual Format* clone(void) const; + Format* clone(void) const U_OVERRIDE; /** * Return true if the given Format objects are semantically equal. @@ -914,7 +906,7 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @return true if the given Format objects are semantically equal. * @stable ICU 2.0 */ - virtual UBool operator==(const Format& other) const; + UBool operator==(const Format& other) const U_OVERRIDE; using NumberFormat::format; @@ -930,11 +922,9 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @return Reference to 'appendTo' parameter. * @stable ICU 2.0 */ - virtual UnicodeString& format(double number, - UnicodeString& appendTo, - FieldPosition& pos) const; - + UnicodeString& format(double number, UnicodeString& appendTo, FieldPosition& pos) const U_OVERRIDE; +#ifndef U_HIDE_INTERNAL_API /** * Format a double or long number using base-10 representation. * @@ -947,10 +937,9 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @return Reference to 'appendTo' parameter. * @internal */ - virtual UnicodeString& format(double number, - UnicodeString& appendTo, - FieldPosition& pos, - UErrorCode &status) const; + UnicodeString& format(double number, UnicodeString& appendTo, FieldPosition& pos, + UErrorCode& status) const U_OVERRIDE; +#endif /* U_HIDE_INTERNAL_API */ /** * Format a double or long number using base-10 representation. @@ -963,12 +952,10 @@ class U_I18N_API DecimalFormat: public NumberFormat { * 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, - FieldPositionIterator* posIter, - UErrorCode& status) const; + UnicodeString& format(double number, UnicodeString& appendTo, FieldPositionIterator* posIter, + UErrorCode& status) const U_OVERRIDE; /** * Format a long number using base-10 representation. @@ -981,10 +968,9 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @return Reference to 'appendTo' parameter. * @stable ICU 2.0 */ - virtual UnicodeString& format(int32_t number, - UnicodeString& appendTo, - FieldPosition& pos) const; + UnicodeString& format(int32_t number, UnicodeString& appendTo, FieldPosition& pos) const U_OVERRIDE; +#ifndef U_HIDE_INTERNAL_API /** * Format a long number using base-10 representation. * @@ -993,13 +979,13 @@ class U_I18N_API DecimalFormat: public NumberFormat { * Result is appended to existing contents. * @param pos On input: an alignment field, if desired. * On output: the offsets of the alignment field. + * @param status Output param filled with success/failure status. * @return Reference to 'appendTo' parameter. * @internal */ - virtual UnicodeString& format(int32_t number, - UnicodeString& appendTo, - FieldPosition& pos, - UErrorCode &status) const; + UnicodeString& format(int32_t number, UnicodeString& appendTo, FieldPosition& pos, + UErrorCode& status) const U_OVERRIDE; +#endif /* U_HIDE_INTERNAL_API */ /** * Format a long number using base-10 representation. @@ -1012,12 +998,10 @@ class U_I18N_API DecimalFormat: public NumberFormat { * 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, - FieldPositionIterator* posIter, - UErrorCode& status) const; + UnicodeString& format(int32_t number, UnicodeString& appendTo, FieldPositionIterator* posIter, + UErrorCode& status) const U_OVERRIDE; /** * Format an int64 number using base-10 representation. @@ -1030,10 +1014,9 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @return Reference to 'appendTo' parameter. * @stable ICU 2.8 */ - virtual UnicodeString& format(int64_t number, - UnicodeString& appendTo, - FieldPosition& pos) const; + UnicodeString& format(int64_t number, UnicodeString& appendTo, FieldPosition& pos) const U_OVERRIDE; +#ifndef U_HIDE_INTERNAL_API /** * Format an int64 number using base-10 representation. * @@ -1042,13 +1025,13 @@ class U_I18N_API DecimalFormat: public NumberFormat { * Result is appended to existing contents. * @param pos On input: an alignment field, if desired. * On output: the offsets of the alignment field. + * @param status Output param filled with success/failure status. * @return Reference to 'appendTo' parameter. * @internal */ - virtual UnicodeString& format(int64_t number, - UnicodeString& appendTo, - FieldPosition& pos, - UErrorCode &status) const; + UnicodeString& format(int64_t number, UnicodeString& appendTo, FieldPosition& pos, + UErrorCode& status) const U_OVERRIDE; +#endif /* U_HIDE_INTERNAL_API */ /** * Format an int64 number using base-10 representation. @@ -1061,12 +1044,10 @@ class U_I18N_API DecimalFormat: public NumberFormat { * 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, - FieldPositionIterator* posIter, - UErrorCode& status) const; + UnicodeString& format(int64_t number, UnicodeString& appendTo, FieldPositionIterator* posIter, + UErrorCode& status) const U_OVERRIDE; /** * Format a decimal number. @@ -1082,21 +1063,20 @@ class U_I18N_API DecimalFormat: public NumberFormat { * 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, - UnicodeString& appendTo, - FieldPositionIterator* posIter, - UErrorCode& status) const; + UnicodeString& format(StringPiece number, UnicodeString& appendTo, FieldPositionIterator* posIter, + UErrorCode& status) const U_OVERRIDE; +#ifndef U_HIDE_INTERNAL_API /** * Format a decimal number. - * The number is a DigitList wrapper onto a floating point decimal number. + * The number is a DecimalQuantity wrapper onto a floating point decimal number. * The default implementation in NumberFormat converts the decimal number * to a double and formats that. * - * @param number The number, a DigitList format Decimal Floating Point. + * @param number The number, a DecimalQuantity format Decimal Floating Point. * @param appendTo Output parameter to receive result. * Result is appended to existing contents. * @param posIter On return, can be used to iterate over positions @@ -1105,18 +1085,16 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @return Reference to 'appendTo' parameter. * @internal */ - virtual UnicodeString& format(const DigitList &number, - UnicodeString& appendTo, - FieldPositionIterator* posIter, - UErrorCode& status) const; + UnicodeString& format(const number::impl::DecimalQuantity& number, UnicodeString& appendTo, + FieldPositionIterator* posIter, UErrorCode& status) const U_OVERRIDE; /** * Format a decimal number. - * The number is a DigitList wrapper onto a floating point decimal number. + * The number is a DecimalQuantity wrapper onto a floating point decimal number. * The default implementation in NumberFormat converts the decimal number * to a double and formats that. * - * @param number The number, a DigitList format Decimal Floating Point. + * @param number The number, a DecimalQuantity format Decimal Floating Point. * @param appendTo Output parameter to receive result. * Result is appended to existing contents. * @param pos On input: an alignment field, if desired. @@ -1125,35 +1103,34 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @return Reference to 'appendTo' parameter. * @internal */ - virtual UnicodeString& format(const DigitList &number, - UnicodeString& appendTo, - FieldPosition& pos, - UErrorCode& status) const; - - using NumberFormat::parse; - - /** - * Parse the given string using this object's choices. The method - * does string comparisons to try to find an optimal match. - * If no object can be parsed, index is unchanged, and NULL is - * returned. The result is returned as the most parsimonious - * type of Formattable that will accomodate all of the - * necessary precision. For example, if the result is exactly 12, - * it will be returned as a long. However, if it is 1.5, it will - * be returned as a double. - * - * @param text The text to be parsed. - * @param result Formattable to be set to the parse result. - * If parse fails, return contents are undefined. - * @param parsePosition The position to start parsing at on input. - * On output, moved to after the last successfully - * parse character. On parse failure, does not change. - * @see Formattable - * @stable ICU 2.0 - */ - virtual void parse(const UnicodeString& text, - Formattable& result, - ParsePosition& parsePosition) const; + UnicodeString& format(const number::impl::DecimalQuantity& number, UnicodeString& appendTo, + FieldPosition& pos, UErrorCode& status) const U_OVERRIDE; + +#endif // U_HIDE_INTERNAL_API + + using NumberFormat::parse; + + /** + * Parse the given string using this object's choices. The method + * does string comparisons to try to find an optimal match. + * If no object can be parsed, index is unchanged, and NULL is + * returned. The result is returned as the most parsimonious + * type of Formattable that will accommodate all of the + * necessary precision. For example, if the result is exactly 12, + * it will be returned as a long. However, if it is 1.5, it will + * be returned as a double. + * + * @param text The text to be parsed. + * @param result Formattable to be set to the parse result. + * If parse fails, return contents are undefined. + * @param parsePosition The position to start parsing at on input. + * On output, moved to after the last successfully + * parse character. On parse failure, does not change. + * @see Formattable + * @stable ICU 2.0 + */ + void parse(const UnicodeString& text, Formattable& result, + ParsePosition& parsePosition) const U_OVERRIDE; /** * Parses text from the given string as a currency amount. Unlike @@ -1174,8 +1151,7 @@ class U_I18N_API DecimalFormat: public NumberFormat { * the parsed currency; if parse fails, this is NULL. * @stable ICU 49 */ - virtual CurrencyAmount* parseCurrency(const UnicodeString& text, - ParsePosition& pos) const; + CurrencyAmount* parseCurrency(const UnicodeString& text, ParsePosition& pos) const U_OVERRIDE; /** * Returns the decimal format symbols, which is generally not changed @@ -1304,12 +1280,36 @@ class U_I18N_API DecimalFormat: public NumberFormat { */ virtual void setNegativeSuffix(const UnicodeString& newValue); +#ifndef U_HIDE_DRAFT_API + /** + * Whether to show the plus sign on positive (non-negative) numbers; for example, "+12" + * + * For more control over sign display, use NumberFormatter. + * + * @return Whether the sign is shown on positive numbers and zero. + * @draft ICU 64 + */ + UBool isSignAlwaysShown() const; + + /** + * Set whether to show the plus sign on positive (non-negative) numbers; for example, "+12". + * + * For more control over sign display, use NumberFormatter. + * + * @param value true to always show a sign; false to hide the sign on positive numbers and zero. + * @draft ICU 64 + */ + void setSignAlwaysShown(UBool value); +#endif /* U_HIDE_DRAFT_API */ + /** * Get the multiplier for use in percent, permill, etc. * For a percentage, set the suffixes to have "%" and the multiplier to be 100. * (For Arabic, use arabic percent symbol). * For a permill, set the suffixes to have "\\u2031" and the multiplier to be 1000. * + * The number may also be multiplied by a power of ten; see getMultiplierScale(). + * * @return the multiplier for use in percent, permill, etc. * Examples: with 100, 1.23 -> "123", and "123" -> 1.23 * @stable ICU 2.0 @@ -1322,12 +1322,52 @@ class U_I18N_API DecimalFormat: public NumberFormat { * (For Arabic, use arabic percent symbol). * For a permill, set the suffixes to have "\\u2031" and the multiplier to be 1000. * + * This method only supports integer multipliers. To multiply by a non-integer, pair this + * method with setMultiplierScale(). + * * @param newValue the new value of the multiplier for use in percent, permill, etc. * Examples: with 100, 1.23 -> "123", and "123" -> 1.23 * @stable ICU 2.0 */ virtual void setMultiplier(int32_t newValue); +#ifndef U_HIDE_DRAFT_API + /** + * Gets the power of ten by which number should be multiplied before formatting, which + * can be combined with setMultiplier() to multiply by any arbitrary decimal value. + * + * A multiplier scale of 2 corresponds to multiplication by 100, and a multiplier scale + * of -2 corresponds to multiplication by 0.01. + * + * This method is analogous to UNUM_SCALE in getAttribute. + * + * @return the current value of the power-of-ten multiplier. + * @draft ICU 62 + */ + int32_t getMultiplierScale(void) const; + + /** + * Sets a power of ten by which number should be multiplied before formatting, which + * can be combined with setMultiplier() to multiply by any arbitrary decimal value. + * + * A multiplier scale of 2 corresponds to multiplication by 100, and a multiplier scale + * of -2 corresponds to multiplication by 0.01. + * + * For example, to multiply numbers by 0.5 before formatting, you can do: + * + *

      +     * df.setMultiplier(5);
      +     * df.setMultiplierScale(-1);
      +     * 
      + * + * This method is analogous to UNUM_SCALE in setAttribute. + * + * @param newValue the new value of the power-of-ten multiplier. + * @draft ICU 62 + */ + void setMultiplierScale(int32_t newValue); +#endif /* U_HIDE_DRAFT_API */ + /** * Get the rounding increment. * @return A positive rounding increment, or 0.0 if a custom rounding @@ -1360,7 +1400,7 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @see #setRoundingMode * @stable ICU 2.0 */ - virtual ERoundingMode getRoundingMode(void) const; + virtual ERoundingMode getRoundingMode(void) const U_OVERRIDE; /** * Set the rounding mode. @@ -1370,7 +1410,7 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @see #getRoundingMode * @stable ICU 2.0 */ - virtual void setRoundingMode(ERoundingMode roundingMode); + virtual void setRoundingMode(ERoundingMode roundingMode) U_OVERRIDE; /** * Get the width to which the output of format() is padded. @@ -1419,8 +1459,8 @@ class U_I18N_API DecimalFormat: public NumberFormat { * Set the character used to pad to the format width. If padding * is not enabled, then this will take effect if padding is later * enabled. - * @param padChar a string containing the pad charcter. If the string - * has length 0, then the pad characer is set to ' '. Otherwise + * @param padChar a string containing the pad character. If the string + * has length 0, then the pad character is set to ' '. Otherwise * padChar.char32At(0) will be used as the pad character. * @see #setFormatWidth * @see #getFormatWidth @@ -1429,7 +1469,7 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @see #setPadPosition * @stable ICU 2.0 */ - virtual void setPadCharacter(const UnicodeString &padChar); + virtual void setPadCharacter(const UnicodeString& padChar); /** * Get the position at which padding will take place. This is the location @@ -1609,6 +1649,46 @@ class U_I18N_API DecimalFormat: public NumberFormat { */ virtual void setSecondaryGroupingSize(int32_t newValue); +#ifndef U_HIDE_DRAFT_API + /** + * Returns the minimum number of grouping digits. + * Grouping separators are output if there are at least this many + * digits to the left of the first (rightmost) grouping separator, + * that is, there are at least (minimum grouping + grouping size) integer digits. + * (Subject to isGroupingUsed().) + * + * For example, if this value is 2, and the grouping size is 3, then + * 9999 -> "9999" and 10000 -> "10,000" + * + * The default value for this attribute is 0. + * A value of 1, 0, or lower, means that the use of grouping separators + * only depends on the grouping size (and on isGroupingUsed()). + * + * NOTE: The CLDR data is used in NumberFormatter but not in DecimalFormat. + * This is for backwards compatibility reasons. + * + * For more control over grouping strategies, use NumberFormatter. + * + * @see setMinimumGroupingDigits + * @see getGroupingSize + * @draft ICU 64 + */ + int32_t getMinimumGroupingDigits() const; + + /** + * Sets the minimum grouping digits. Setting to a value less than or + * equal to 1 turns off minimum grouping digits. + * + * For more control over grouping strategies, use NumberFormatter. + * + * @param newValue the new value of minimum grouping digits. + * @see getMinimumGroupingDigits + * @draft ICU 64 + */ + void setMinimumGroupingDigits(int32_t newValue); +#endif /* U_HIDE_DRAFT_API */ + + /** * Allows you to get the behavior of the decimal separator with integers. * (The decimal separator will always appear with decimals.) @@ -1629,27 +1709,87 @@ class U_I18N_API DecimalFormat: public NumberFormat { */ virtual void setDecimalSeparatorAlwaysShown(UBool newValue); -#ifndef U_HIDE_DRAFT_API /** * Allows you to get the parse behavior of the pattern decimal mark. * * @return TRUE if input must contain a match to decimal mark in pattern - * @draft ICU 54 + * @stable ICU 54 */ UBool isDecimalPatternMatchRequired(void) const; -#endif /* U_HIDE_DRAFT_API */ /** - * Allows you to set the behavior of the pattern decimal mark. - * + * Allows you to set the parse behavior of the pattern decimal mark. + * * if TRUE, the input must have a decimal mark if one was specified in the pattern. When * FALSE the decimal mark may be omitted from the input. * * @param newValue set TRUE if input must contain a match to decimal mark in pattern - * @draft ICU 54 + * @stable ICU 54 */ virtual void setDecimalPatternMatchRequired(UBool newValue); +#ifndef U_HIDE_DRAFT_API + /** + * Returns whether to ignore exponents when parsing. + * + * @return Whether to ignore exponents when parsing. + * @see #setParseNoExponent + * @draft ICU 64 + */ + UBool isParseNoExponent() const; + + /** + * Specifies whether to stop parsing when an exponent separator is encountered. For + * example, parses "123E4" to 123 (with parse position 3) instead of 1230000 (with parse position + * 5). + * + * @param value true to prevent exponents from being parsed; false to allow them to be parsed. + * @draft ICU 64 + */ + void setParseNoExponent(UBool value); + + /** + * Returns whether parsing is sensitive to case (lowercase/uppercase). + * + * @return Whether parsing is case-sensitive. + * @see #setParseCaseSensitive + * @draft ICU 64 + */ + UBool isParseCaseSensitive() const; + + /** + * Whether to pay attention to case when parsing; default is to ignore case (perform + * case-folding). For example, "A" == "a" in case-insensitive but not case-sensitive mode. + * + * Currency symbols are never case-folded. For example, "us$1.00" will not parse in case-insensitive + * mode, even though "US$1.00" parses. + * + * @param value true to enable case-sensitive parsing (the default); false to force + * case-sensitive parsing behavior. + * @draft ICU 64 + */ + void setParseCaseSensitive(UBool value); + + /** + * Returns whether truncation of high-order integer digits should result in an error. + * By default, setMaximumIntegerDigits truncates high-order digits silently. + * + * @return Whether an error code is set if high-order digits are truncated. + * @see setFormatFailIfMoreThanMaxDigits + * @draft ICU 64 + */ + UBool isFormatFailIfMoreThanMaxDigits() const; + + /** + * Sets whether truncation of high-order integer digits should result in an error. + * By default, setMaximumIntegerDigits truncates high-order digits silently. + * + * @param value Whether to set an error code if high-order digits are truncated. + * @draft ICU 64 + */ + void setFormatFailIfMoreThanMaxDigits(UBool value); +#endif /* U_HIDE_DRAFT_API */ + /** * Synthesizes a pattern string that represents the current state @@ -1704,9 +1844,8 @@ class U_I18N_API DecimalFormat: public NumberFormat { * set to a failure result. * @stable ICU 2.0 */ - virtual void applyPattern(const UnicodeString& pattern, - UParseError& parseError, - UErrorCode& status); + virtual void applyPattern(const UnicodeString& pattern, UParseError& parseError, UErrorCode& status); + /** * Sets the pattern. * @param pattern The pattern to be applied. @@ -1715,8 +1854,7 @@ class U_I18N_API DecimalFormat: public NumberFormat { * set to a failure result. * @stable ICU 2.0 */ - virtual void applyPattern(const UnicodeString& pattern, - UErrorCode& status); + virtual void applyPattern(const UnicodeString& pattern, UErrorCode& status); /** * Apply the given pattern to this Format object. The pattern @@ -1748,8 +1886,7 @@ class U_I18N_API DecimalFormat: public NumberFormat { * set to a failure result. * @stable ICU 2.0 */ - virtual void applyLocalizedPattern(const UnicodeString& pattern, - UParseError& parseError, + virtual void applyLocalizedPattern(const UnicodeString& pattern, UParseError& parseError, UErrorCode& status); /** @@ -1761,8 +1898,7 @@ class U_I18N_API DecimalFormat: public NumberFormat { * set to a failure result. * @stable ICU 2.0 */ - virtual void applyLocalizedPattern(const UnicodeString& pattern, - UErrorCode& status); + virtual void applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& status); /** @@ -1774,7 +1910,7 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @see NumberFormat#setMaximumIntegerDigits * @stable ICU 2.0 */ - virtual void setMaximumIntegerDigits(int32_t newValue); + void setMaximumIntegerDigits(int32_t newValue) U_OVERRIDE; /** * Sets the minimum number of digits allowed in the integer portion of a @@ -1785,7 +1921,7 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @see NumberFormat#setMinimumIntegerDigits * @stable ICU 2.0 */ - virtual void setMinimumIntegerDigits(int32_t newValue); + void setMinimumIntegerDigits(int32_t newValue) U_OVERRIDE; /** * Sets the maximum number of digits allowed in the fraction portion of a @@ -1796,7 +1932,7 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @see NumberFormat#setMaximumFractionDigits * @stable ICU 2.0 */ - virtual void setMaximumFractionDigits(int32_t newValue); + void setMaximumFractionDigits(int32_t newValue) U_OVERRIDE; /** * Sets the minimum number of digits allowed in the fraction portion of a @@ -1807,7 +1943,7 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @see NumberFormat#setMinimumFractionDigits * @stable ICU 2.0 */ - virtual void setMinimumFractionDigits(int32_t newValue); + void setMinimumFractionDigits(int32_t newValue) U_OVERRIDE; /** * Returns the minimum number of significant digits that will be @@ -1870,7 +2006,18 @@ class U_I18N_API DecimalFormat: public NumberFormat { */ void setSignificantDigitsUsed(UBool useSignificantDigits); - public: + /** + * Group-set several settings used for numbers in date formats. + * Avoids calls to touch for each separate setting. + * Equivalent to: + * setGroupingUsed(FALSE); + * setDecimalSeparatorAlwaysShown(FALSE); + * setParseIntegerOnly(TRUE); + * setMinimumFractionDigits(0); + * @internal + */ + void setDateSettings(void) U_OVERRIDE; + /** * Sets the currency used to display currency * amounts. This takes effect immediately, if this format is a @@ -1883,69 +2030,116 @@ class U_I18N_API DecimalFormat: public NumberFormat { * @param ec input-output error code * @stable ICU 3.0 */ - virtual void setCurrency(const UChar* theCurrency, UErrorCode& ec); + void setCurrency(const char16_t* theCurrency, UErrorCode& ec) U_OVERRIDE; /** * Sets the currency used to display currency amounts. See - * setCurrency(const UChar*, UErrorCode&). - * @deprecated ICU 3.0. Use setCurrency(const UChar*, UErrorCode&). + * setCurrency(const char16_t*, UErrorCode&). + * @deprecated ICU 3.0. Use setCurrency(const char16_t*, UErrorCode&). */ - virtual void setCurrency(const UChar* theCurrency); + virtual void setCurrency(const char16_t* theCurrency); -#ifndef U_HIDE_DRAFT_API /** - * Sets the Currency Context object used to display currency. + * Sets the `Currency Usage` object used to display currency. * This takes effect immediately, if this format is a - * currency format. - * @param currencyContext new currency context object to use. - * @draft ICU 54 + * currency format. + * @param newUsage new currency usage object to use. + * @param ec input-output error code + * @stable ICU 54 */ void setCurrencyUsage(UCurrencyUsage newUsage, UErrorCode* ec); /** - * Returns the Currency Context object used to display currency - * @draft ICU 54 + * Returns the `Currency Usage` object used to display currency + * @stable ICU 54 */ UCurrencyUsage getCurrencyUsage() const; -#endif /* U_HIDE_DRAFT_API */ - - -#ifndef U_HIDE_DEPRECATED_API - /** - * The resource tags we use to retrieve decimal format data from - * locale resource bundles. - * @deprecated ICU 3.4. This string has no public purpose. Please don't use it. - */ - static const char fgNumberPatterns[]; -#endif /* U_HIDE_DEPRECATED_API */ #ifndef U_HIDE_INTERNAL_API + /** - * Get a FixedDecimal corresponding to a double as it would be - * formatted by this DecimalFormat. + * Format a number and save it into the given DecimalQuantity. * Internal, not intended for public use. * @internal */ - FixedDecimal getFixedDecimal(double number, UErrorCode &status) const; + void formatToDecimalQuantity(double number, number::impl::DecimalQuantity& output, + UErrorCode& status) const; /** - * Get a FixedDecimal corresponding to a formattable as it would be + * Get a DecimalQuantity corresponding to a formattable as it would be * formatted by this DecimalFormat. * Internal, not intended for public use. * @internal */ - FixedDecimal getFixedDecimal(const Formattable &number, UErrorCode &status) const; + void formatToDecimalQuantity(const Formattable& number, number::impl::DecimalQuantity& output, + UErrorCode& status) const; +#endif /* U_HIDE_INTERNAL_API */ + +#ifndef U_HIDE_DRAFT_API /** - * Get a FixedDecimal corresponding to a DigitList as it would be - * formatted by this DecimalFormat. Note: the DigitList may be modified. - * Internal, not intended for public use. - * @internal + * Converts this DecimalFormat to a (Localized)NumberFormatter. Starting + * in ICU 60, NumberFormatter is the recommended way to format numbers. + * You can use the returned LocalizedNumberFormatter to format numbers and + * get a FormattedNumber, which contains a string as well as additional + * annotations about the formatted value. + * + * If a memory allocation failure occurs, the return value of this method + * might be null. If you are concerned about correct recovery from + * out-of-memory situations, use this pattern: + * + *
      +     * FormattedNumber result;
      +     * if (auto* ptr = df->toNumberFormatter(status)) {
      +     *     result = ptr->formatDouble(123, status);
      +     * }
      +     * 
      + * + * If you are not concerned about out-of-memory situations, or if your + * environment throws exceptions when memory allocation failure occurs, + * you can chain the methods, like this: + * + *
      +     * FormattedNumber result = df
      +     *     ->toNumberFormatter(status)
      +     *     ->formatDouble(123, status);
      +     * 
      + * + * NOTE: The returned LocalizedNumberFormatter is owned by this DecimalFormat. + * If a non-const method is called on the DecimalFormat, or if the DecimalFormat + * is deleted, the object becomes invalid. If you plan to keep the return value + * beyond the lifetime of the DecimalFormat, copy it to a local variable: + * + *
      +     * LocalizedNumberFormatter lnf;
      +     * if (auto* ptr = df->toNumberFormatter(status)) {
      +     *     lnf = *ptr;
      +     * }
      +     * 
      + * + * @param status Set on failure, like U_MEMORY_ALLOCATION_ERROR. + * @return A pointer to an internal object, or nullptr on failure. + * Do not delete the return value! + * @draft ICU 64 */ - FixedDecimal getFixedDecimal(DigitList &number, UErrorCode &status) const; -#endif /* U_HIDE_INTERNAL_API */ + const number::LocalizedNumberFormatter* toNumberFormatter(UErrorCode& status) const; +#endif /* U_HIDE_DRAFT_API */ -public: +#ifndef U_HIDE_DEPRECATED_API + /** + * Deprecated: Like {@link #toNumberFormatter(UErrorCode&) const}, + * but does not take an error code. + * + * The new signature should be used in case an error occurs while returning the + * LocalizedNumberFormatter. + * + * This old signature will be removed in ICU 65. + * + * @return A reference to an internal object. + * @deprecated ICU 64 + */ + const number::LocalizedNumberFormatter& toNumberFormatter() const; +#endif /* U_HIDE_DEPRECATED_API */ /** * Return the class ID for this class. This is useful only for @@ -1971,505 +2165,78 @@ class U_I18N_API DecimalFormat: public NumberFormat { * other classes have different class IDs. * @stable ICU 2.0 */ - virtual UClassID getDynamicClassID(void) const; - -private: - - DecimalFormat(); // default constructor not implemented - - int32_t precision() const; - - /** - * Initialize all fields of a new DecimalFormatter to a safe default value. - * Common code for use by constructors. - */ - void init(); + UClassID getDynamicClassID(void) const U_OVERRIDE; - /** - * Do real work of constructing a new DecimalFormat. - */ - void construct(UErrorCode& status, - UParseError& parseErr, - const UnicodeString* pattern = 0, - DecimalFormatSymbols* symbolsToAdopt = 0 - ); - - /** - * Does the real work of generating a pattern. - * - * @param result Output param which will receive the pattern. - * Previous contents are deleted. - * @param localized TRUE return localized pattern. - * @return A reference to 'result'. - */ - UnicodeString& toPattern(UnicodeString& result, UBool localized) const; +#ifndef U_HIDE_INTERNAL_API /** - * Does the real work of applying a pattern. - * @param pattern The pattern to be applied. - * @param localized If true, the pattern is localized; else false. - * @param parseError Struct to recieve information on position - * of error if an error is encountered - * @param status Output param set to success/failure code on - * exit. If the pattern is invalid, this will be - * set to a failure result. - */ - void applyPattern(const UnicodeString& pattern, - UBool localized, - UParseError& parseError, - UErrorCode& status); - - /* - * similar to applyPattern, but without re-gen affix for currency + * Set whether DecimalFormatSymbols copy in toNumberFormatter + * is deep (clone) or shallow (pointer copy). Apple + * @internal */ - void applyPatternInternally(const UnicodeString& pluralCount, - const UnicodeString& pattern, - UBool localized, - UParseError& parseError, - UErrorCode& status); + void setDFSShallowCopy(UBool shallow); - /* - * only apply pattern without expand affixes - */ - void applyPatternWithoutExpandAffix(const UnicodeString& pattern, - UBool localized, - UParseError& parseError, - UErrorCode& status); +#endif /* U_HIDE_INTERNAL_API */ +private: - /* - * expand affixes (after apply patter) and re-compute fFormatWidth - */ - void expandAffixAdjustWidth(const UnicodeString* pluralCount); + /** Rebuilds the formatter object from the property bag. */ + void touch(UErrorCode& status); + /** Rebuilds the formatter object, ignoring any error code. */ + void touchNoError(); /** - * Do the work of formatting a number, either a double or a long. + * Updates the property bag with settings from the given pattern. * - * @param appendTo Output parameter to receive result. - * Result is appended to existing contents. - * @param handler Records information about field positions. - * @param digits the digits to be formatted. - * @param isInteger if TRUE format the digits as Integer. - * @return Reference to 'appendTo' parameter. + * @param pattern The pattern string to parse. + * @param ignoreRounding Whether to leave out rounding information (minFrac, maxFrac, and rounding + * increment) when parsing the pattern. This may be desirable if a custom rounding mode, such + * as CurrencyUsage, is to be used instead. One of {@link + * PatternStringParser#IGNORE_ROUNDING_ALWAYS}, {@link PatternStringParser#IGNORE_ROUNDING_IF_CURRENCY}, + * or {@link PatternStringParser#IGNORE_ROUNDING_NEVER}. + * @see PatternAndPropertyUtils#parseToExistingProperties */ - UnicodeString& subformat(UnicodeString& appendTo, - FieldPositionHandler& handler, - DigitList& digits, - UBool isInteger, - UErrorCode &status) const; - - - void parse(const UnicodeString& text, - Formattable& result, - ParsePosition& pos, - UChar* currency) const; - - enum { - fgStatusInfinite, - fgStatusLength // Leave last in list. - } StatusFlags; - - UBool subparse(const UnicodeString& text, - const UnicodeString* negPrefix, - const UnicodeString* negSuffix, - const UnicodeString* posPrefix, - const UnicodeString* posSuffix, - UBool complexCurrencyParsing, - int8_t type, - ParsePosition& parsePosition, - DigitList& digits, UBool* status, - UChar* currency) const; - - // Mixed style parsing for currency. - // It parses against the current currency pattern - // using complex affix comparison - // parses against the currency plural patterns using complex affix comparison, - // and parses against the current pattern using simple affix comparison. - UBool parseForCurrency(const UnicodeString& text, - ParsePosition& parsePosition, - DigitList& digits, - UBool* status, - UChar* currency) const; - - int32_t skipPadding(const UnicodeString& text, int32_t position) const; - - int32_t compareAffix(const UnicodeString& input, - int32_t pos, - UBool isNegative, - UBool isPrefix, - const UnicodeString* affixPat, - UBool complexCurrencyParsing, - int8_t type, - UChar* currency) const; - - static UnicodeString& trimMarksFromAffix(const UnicodeString& affix, UnicodeString& trimmedAffix); - - UBool equalWithSignCompatibility(UChar32 lhs, UChar32 rhs) const; - - int32_t compareSimpleAffix(const UnicodeString& affix, - const UnicodeString& input, - int32_t pos, - UBool lenient) const; + void setPropertiesFromPattern(const UnicodeString& pattern, int32_t ignoreRounding, + UErrorCode& status); - static int32_t skipPatternWhiteSpace(const UnicodeString& text, int32_t pos); + const numparse::impl::NumberParserImpl* getParser(UErrorCode& status) const; - static int32_t skipUWhiteSpace(const UnicodeString& text, int32_t pos); + const numparse::impl::NumberParserImpl* getCurrencyParser(UErrorCode& status) const; - static int32_t skipUWhiteSpaceAndMarks(const UnicodeString& text, int32_t pos); + static void fieldPositionHelper(const number::FormattedNumber& formatted, FieldPosition& fieldPosition, + int32_t offset, UErrorCode& status); - static int32_t skipBidiMarks(const UnicodeString& text, int32_t pos); + static void fieldPositionIteratorHelper(const number::FormattedNumber& formatted, + FieldPositionIterator* fpi, int32_t offset, UErrorCode& status); - int32_t compareComplexAffix(const UnicodeString& affixPat, - const UnicodeString& input, - int32_t pos, - int8_t type, - UChar* currency) const; + void setupFastFormat(); - static int32_t match(const UnicodeString& text, int32_t pos, UChar32 ch); + bool fastFormatDouble(double input, UnicodeString& output) const; - static int32_t match(const UnicodeString& text, int32_t pos, const UnicodeString& str); + bool fastFormatInt64(int64_t input, UnicodeString& output) const; - static UBool matchSymbol(const UnicodeString &text, int32_t position, int32_t length, const UnicodeString &symbol, - UnicodeSet *sset, UChar32 schar); + void doFastFormatInt32(int32_t input, bool isNegative, UnicodeString& output) const; - static UBool matchDecimal(UChar32 symbolChar, - UBool sawDecimal, UChar32 sawDecimalChar, - const UnicodeSet *sset, UChar32 schar); + //=====================================================================================// + // INSTANCE FIELDS // + //=====================================================================================// - static UBool matchGrouping(UChar32 groupingChar, - UBool sawGrouping, UChar32 sawGroupingChar, - const UnicodeSet *sset, - UChar32 decimalChar, const UnicodeSet *decimalSet, - UChar32 schar); - /** - * Get a decimal format symbol. - * Returns a const reference to the symbol string. - * @internal - */ - inline const UnicodeString &getConstSymbol(DecimalFormatSymbols::ENumberFormatSymbol symbol) const; - - int32_t appendAffix(UnicodeString& buf, - double number, - FieldPositionHandler& handler, - UBool isNegative, - UBool isPrefix) const; - - /** - * Append an affix to the given UnicodeString, using quotes if - * there are special characters. Single quotes themselves must be - * escaped in either case. - */ - void appendAffixPattern(UnicodeString& appendTo, const UnicodeString& affix, - UBool localized) const; - - void appendAffixPattern(UnicodeString& appendTo, - const UnicodeString* affixPattern, - const UnicodeString& expAffix, UBool localized) const; - - void expandAffix(const UnicodeString& pattern, - UnicodeString& affix, - double number, - FieldPositionHandler& handler, - UBool doFormat, - const UnicodeString* pluralCount) const; - - void expandAffixes(const UnicodeString* pluralCount); - - void addPadding(UnicodeString& appendTo, - FieldPositionHandler& handler, - int32_t prefixLen, int32_t suffixLen) const; - - UBool isGroupingPosition(int32_t pos) const; - - void setCurrencyForSymbols(); - - // similar to setCurrency without re-compute the affixes for currency. - // If currency changes, the affix pattern for currency is not changed, - // but the affix will be changed. So, affixes need to be - // re-computed in setCurrency(), but not in setCurrencyInternally(). - virtual void setCurrencyInternally(const UChar* theCurrency, UErrorCode& ec); - - // set up currency affix patterns for mix parsing. - // The patterns saved here are the affix patterns of default currency - // pattern and the unique affix patterns of the plural currency patterns. - // Those patterns are used by parseForCurrency(). - void setupCurrencyAffixPatterns(UErrorCode& status); - - // set up the currency affixes used in currency plural formatting. - // It sets up both fAffixesForCurrency for currency pattern if the current - // pattern contains 3 currency signs, - // and it sets up fPluralAffixesForCurrency for currency plural patterns. - void setupCurrencyAffixes(const UnicodeString& pattern, - UBool setupForCurrentPattern, - UBool setupForPluralPattern, - UErrorCode& status); - - // get the currency rounding with respect to currency usage - double getCurrencyRounding(const UChar* currency, - UErrorCode* ec) const; - - // get the currency fraction with respect to currency usage - int getCurrencyFractionDigits(const UChar* currency, - UErrorCode* ec) const; - - // hashtable operations - Hashtable* initHashForAffixPattern(UErrorCode& status); - Hashtable* initHashForAffix(UErrorCode& status); - - void deleteHashForAffixPattern(); - void deleteHashForAffix(Hashtable*& table); - - void copyHashForAffixPattern(const Hashtable* source, - Hashtable* target, UErrorCode& status); - void copyHashForAffix(const Hashtable* source, - Hashtable* target, UErrorCode& status); - - UnicodeString& _format(int64_t number, - UnicodeString& appendTo, - FieldPositionHandler& handler, - UErrorCode &status) const; - UnicodeString& _format(double number, - UnicodeString& appendTo, - FieldPositionHandler& handler, - UErrorCode &status) const; - UnicodeString& _format(const DigitList &number, - UnicodeString& appendTo, - FieldPositionHandler& handler, - UErrorCode &status) const; - - /** - * Constants. - */ - - UnicodeString fPositivePrefix; - UnicodeString fPositiveSuffix; - UnicodeString fNegativePrefix; - UnicodeString fNegativeSuffix; - UnicodeString* fPosPrefixPattern; - UnicodeString* fPosSuffixPattern; - UnicodeString* fNegPrefixPattern; - UnicodeString* fNegSuffixPattern; - - /** - * Formatter for ChoiceFormat-based currency names. If this field - * is not null, then delegate to it to format currency symbols. - * @since ICU 2.6 - */ - ChoiceFormat* fCurrencyChoice; - - DigitList * fMultiplier; // NULL for multiplier of one - int32_t fScale; - int32_t fGroupingSize; - int32_t fGroupingSize2; - UBool fDecimalSeparatorAlwaysShown; - DecimalFormatSymbols* fSymbols; - - UBool fUseSignificantDigits; - int32_t fMinSignificantDigits; - int32_t fMaxSignificantDigits; - - UBool fUseExponentialNotation; - int8_t fMinExponentDigits; - UBool fExponentSignAlwaysShown; - - EnumSet - fBoolFlags; - - DigitList* fRoundingIncrement; // NULL if no rounding increment specified. - ERoundingMode fRoundingMode; - - UChar32 fPad; - int32_t fFormatWidth; - EPadPosition fPadPosition; - - /* - * Following are used for currency format - */ - // pattern used in this formatter - UnicodeString fFormatPattern; - // style is only valid when decimal formatter is constructed by - // DecimalFormat(pattern, decimalFormatSymbol, style) - int fStyle; - /* - * Represents whether this is a currency format, and which - * currency format style. - * 0: not currency format type; - * 1: currency style -- symbol name, such as "$" for US dollar. - * 2: currency style -- ISO name, such as USD for US dollar. - * 3: currency style -- plural long name, such as "US Dollar" for - * "1.00 US Dollar", or "US Dollars" for - * "3.00 US Dollars". - */ - int fCurrencySignCount; - - - /* For currency parsing purose, - * Need to remember all prefix patterns and suffix patterns of - * every currency format pattern, - * including the pattern of default currecny style - * and plural currency style. And the patterns are set through applyPattern. - */ - // TODO: innerclass? - /* This is not needed in the class declaration, so it is moved into decimfmp.cpp - struct AffixPatternsForCurrency : public UMemory { - // negative prefix pattern - UnicodeString negPrefixPatternForCurrency; - // negative suffix pattern - UnicodeString negSuffixPatternForCurrency; - // positive prefix pattern - UnicodeString posPrefixPatternForCurrency; - // positive suffix pattern - UnicodeString posSuffixPatternForCurrency; - int8_t patternType; - - AffixPatternsForCurrency(const UnicodeString& negPrefix, - const UnicodeString& negSuffix, - const UnicodeString& posPrefix, - const UnicodeString& posSuffix, - int8_t type) { - negPrefixPatternForCurrency = negPrefix; - negSuffixPatternForCurrency = negSuffix; - posPrefixPatternForCurrency = posPrefix; - posSuffixPatternForCurrency = posSuffix; - patternType = type; - } - }; - */ - - /* affix for currency formatting when the currency sign in the pattern - * equals to 3, such as the pattern contains 3 currency sign or - * the formatter style is currency plural format style. - */ - /* This is not needed in the class declaration, so it is moved into decimfmp.cpp - struct AffixesForCurrency : public UMemory { - // negative prefix - UnicodeString negPrefixForCurrency; - // negative suffix - UnicodeString negSuffixForCurrency; - // positive prefix - UnicodeString posPrefixForCurrency; - // positive suffix - UnicodeString posSuffixForCurrency; - - int32_t formatWidth; - - AffixesForCurrency(const UnicodeString& negPrefix, - const UnicodeString& negSuffix, - const UnicodeString& posPrefix, - const UnicodeString& posSuffix) { - negPrefixForCurrency = negPrefix; - negSuffixForCurrency = negSuffix; - posPrefixForCurrency = posPrefix; - posSuffixForCurrency = posSuffix; - } - }; - */ - - // Affix pattern set for currency. - // It is a set of AffixPatternsForCurrency, - // each element of the set saves the negative prefix pattern, - // negative suffix pattern, positive prefix pattern, - // and positive suffix pattern of a pattern. - // It is used for currency mixed style parsing. - // It is actually is a set. - // The set contains the default currency pattern from the locale, - // and the currency plural patterns. - // Since it is a set, it does not contain duplicated items. - // For example, if 2 currency plural patterns are the same, only one pattern - // is included in the set. When parsing, we do not check whether the plural - // count match or not. - Hashtable* fAffixPatternsForCurrency; - - // Following 2 are affixes for currency. - // It is a hash map from plural count to AffixesForCurrency. - // AffixesForCurrency saves the negative prefix, - // negative suffix, positive prefix, and positive suffix of a pattern. - // It is used during currency formatting only when the currency sign count - // is 3. In which case, the affixes are getting from here, not - // from the fNegativePrefix etc. - Hashtable* fAffixesForCurrency; // for current pattern - Hashtable* fPluralAffixesForCurrency; // for plural pattern - - // Information needed for DecimalFormat to format/parse currency plural. - CurrencyPluralInfo* fCurrencyPluralInfo; - -#if UCONFIG_HAVE_PARSEALLINPUT - UNumberFormatAttributeValue fParseAllInput; -#endif - - // Decimal Format Static Sets singleton. - const DecimalFormatStaticSets *fStaticSets; - - // Currency Usage(STANDARD vs CASH) - UCurrencyUsage fCurrencyUsage; - -protected: - -#ifndef U_HIDE_INTERNAL_API - /** - * Rounds a value according to the rules of this object. - * @internal - */ - DigitList& _round(const DigitList& number, DigitList& adjustedNum, UBool& isNegative, UErrorCode& status) const; -#endif /* U_HIDE_INTERNAL_API */ + // One instance field for the implementation, keep all fields inside of an implementation + // class defined in number_mapper.h + number::impl::DecimalFormatFields* fields = nullptr; - /** - * Returns the currency in effect for this formatter. Subclasses - * should override this method as needed. Unlike getCurrency(), - * this method should never return "". - * @result output parameter for null-terminated result, which must - * have a capacity of at least 4 - * @internal - */ - virtual void getEffectiveCurrency(UChar* result, UErrorCode& ec) const; - - /** number of integer digits - * @stable ICU 2.4 - */ - static const int32_t kDoubleIntegerDigits; - /** number of fraction digits - * @stable ICU 2.4 - */ - static const int32_t kDoubleFractionDigits; - - /** - * When someone turns on scientific mode, we assume that more than this - * number of digits is due to flipping from some other mode that didn't - * restrict the maximum, and so we force 1 integer digit. We don't bother - * to track and see if someone is using exponential notation with more than - * this number, it wouldn't make sense anyway, and this is just to make sure - * that someone turning on scientific mode with default settings doesn't - * end up with lots of zeroes. - * @stable ICU 2.8 - */ - static const int32_t kMaxScientificIntegerDigits; - -#if UCONFIG_FORMAT_FASTPATHS_49 - private: - /** - * Internal state. - * @internal - */ - uint8_t fReserved[UNUM_DECIMALFORMAT_INTERNAL_SIZE]; + // Allow child class CompactDecimalFormat to access fProperties: + friend class CompactDecimalFormat; + // Allow MeasureFormat to use fieldPositionHelper: + friend class MeasureFormat; - /** - * Called whenever any state changes. Recomputes whether fastpath is OK to use. - */ - void handleChanged(); -#endif }; -inline const UnicodeString & -DecimalFormat::getConstSymbol(DecimalFormatSymbols::ENumberFormatSymbol symbol) const { - return fSymbols->getConstSymbol(symbol); -} - U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/docmain.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/docmain.h index df3fe842aa..1e959cb359 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/docmain.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/docmain.h @@ -1,3 +1,5 @@ +// © 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 @@ -31,7 +33,7 @@ * then detailed member descriptions.

      * *

      C Programmers:

      - *

      Use Module List or File Members + *

      Use Module List or File Members * to find a list of all the functions and constants. * For example, to find BreakIterator functions you would click on * File List, @@ -86,6 +88,11 @@ * icu::UnicodeSet * * + * Maps from Unicode Code Points to Integer Values + * ucptrie.h, umutablecptrie.h + * C API + * + * * Maps from Strings to Integer Values * (no C API) * icu::BytesTrie, icu::UCharsTrie @@ -96,6 +103,11 @@ * C API * * + * Codepage Detection + * ucsdet.h + * C API + * + * * Unicode Text Compression * ucnv.h
      (encoding name "SCSU" or "BOCU-1") * C API @@ -103,7 +115,7 @@ * * Locales * uloc.h - * icu::Locale + * icu::Locale, icu::LocaleBuilder * * * Resource Bundles @@ -131,9 +143,14 @@ * icu::MessageFormat * * - * Number Formatting - * unum.h - * icu::NumberFormat + * Number Formatting
      (includes currency and unit formatting) + * unumberformatter.h, unum.h + * icu::number::NumberFormatter (ICU 60+) or icu::NumberFormat (older versions) + * + * + * Number Range Formatting
      (includes currency and unit ranges) + * (no C API) + * icu::number::NumberRangeFormatter * * * Number Spellout
      (Rule Based Number Formatting) @@ -147,7 +164,7 @@ * * * Bidirectional Algorithm - * ubidi.h + * ubidi.h, ubiditransform.h * C API * * @@ -201,9 +218,9 @@ * C API * * - * Layout Engine/Complex Text Layout - * loengine.h - * icu::LayoutEngine,icu::ParagraphLayout + * Paragraph Layout / Complex Text Layout + * playout.h + * icu::ParagraphLayout * * * ICU I/O diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtfmtsym.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtfmtsym.h index 78d0ceb5a9..c2c12dab0d 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtfmtsym.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtfmtsym.h @@ -1,6 +1,8 @@ -/* +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* ******************************************************************************** -* Copyright (C) 1997-2015, International Business Machines +* Copyright (C) 1997-2016, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************** * @@ -14,25 +16,27 @@ * Changed to match C++ conventions ******************************************************************************** */ - + #ifndef DTFMTSYM_H #define DTFMTSYM_H - + #include "unicode/utypes.h" #if !UCONFIG_NO_FORMATTING #include "unicode/calendar.h" +#include "unicode/strenum.h" #include "unicode/uobject.h" #include "unicode/locid.h" #include "unicode/udat.h" #include "unicode/ures.h" /** - * \file + * \file * \brief C++ API: Symbols for formatting dates. */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /* forward declaration */ @@ -115,7 +119,7 @@ class U_I18N_API DateFormatSymbols U_FINAL : public UObject { * data for the default locale, it will return a last-resort object * based on hard-coded strings. * - * @param type Type of calendar (as returned by Calendar::getType). + * @param type Type of calendar (as returned by Calendar::getType). * Will be used to access the correct set of strings. * (NULL or empty string defaults to "gregorian".) * @param status Status code. Failure @@ -130,7 +134,7 @@ class U_I18N_API DateFormatSymbols U_FINAL : public UObject { * resources for the given locale, in the default calendar (Gregorian). * * @param locale Locale to load format data from. - * @param type Type of calendar (as returned by Calendar::getType). + * @param type Type of calendar (as returned by Calendar::getType). * Will be used to access the correct set of strings. * (NULL or empty string defaults to "gregorian".) * @param status Status code. Failure @@ -270,9 +274,15 @@ class U_I18N_API DateFormatSymbols U_FINAL : public UObject { * @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 +290,21 @@ class U_I18N_API DateFormatSymbols U_FINAL : public UObject { * @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 }; /** @@ -414,33 +428,30 @@ class U_I18N_API DateFormatSymbols U_FINAL : public UObject { * doesn't specify any time separator, and always recognized when parsing. * @internal */ - static const UChar DEFAULT_TIME_SEPARATOR = 0x003a; // ':' + static const char16_t DEFAULT_TIME_SEPARATOR = 0x003a; // ':' /** * This alternate time separator is always recognized when parsing. * @internal */ - static const UChar ALTERNATE_TIME_SEPARATOR = 0x002e; // '.' -#endif /* U_HIDE_INTERNAL_API */ + static const char16_t ALTERNATE_TIME_SEPARATOR = 0x002e; // '.' -#ifndef U_HIDE_DRAFT_API /** * Gets the time separator string. For example: ":". * @param result Output param which will receive the time separator string. * @return A reference to 'result'. - * @draft ICU 55 + * @internal */ UnicodeString& getTimeSeparatorString(UnicodeString& result) const; /** * Sets the time separator string. For example: ":". * @param newTimeSeparator the new time separator string. - * @draft ICU 55 + * @internal */ void setTimeSeparatorString(const UnicodeString& newTimeSeparator); -#endif /* U_HIDE_DRAFT_API */ +#endif /* U_HIDE_INTERNAL_API */ -#ifndef U_HIDE_DRAFT_API /** * Gets cyclic year name strings if the calendar has them, by width and context. * For example: "jia-zi", "yi-chou", etc. @@ -449,7 +460,7 @@ class U_I18N_API DateFormatSymbols U_FINAL : public UObject { * @param width The requested name width: WIDE, ABBREVIATED, NARROW. * @return The year name strings (DateFormatSymbols retains ownership), * or null if they are not available for this calendar. - * @draft ICU 54 + * @stable ICU 54 */ const UnicodeString* getYearNames(int32_t& count, DtContextType context, DtWidthType width) const; @@ -461,7 +472,7 @@ class U_I18N_API DateFormatSymbols U_FINAL : public UObject { * @param count The length of the array. * @param context The usage context: FORMAT, STANDALONE (currently only FORMAT is supported). * @param width The name width: WIDE, ABBREVIATED, NARROW (currently only ABBREVIATED is supported). - * @draft ICU 54 + * @stable ICU 54 */ void setYearNames(const UnicodeString* yearNames, int32_t count, DtContextType context, DtWidthType width); @@ -474,7 +485,7 @@ class U_I18N_API DateFormatSymbols U_FINAL : public UObject { * @param width The requested name width: WIDE, ABBREVIATED, NARROW. * @return The zodiac name strings (DateFormatSymbols retains ownership), * or null if they are not available for this calendar. - * @draft ICU 54 + * @stable ICU 54 */ const UnicodeString* getZodiacNames(int32_t& count, DtContextType context, DtWidthType width) const; @@ -486,13 +497,11 @@ class U_I18N_API DateFormatSymbols U_FINAL : public UObject { * @param count The length of the array. * @param context The usage context: FORMAT, STANDALONE (currently only FORMAT is supported). * @param width The name width: WIDE, ABBREVIATED, NARROW (currently only ABBREVIATED is supported). - * @draft ICU 54 + * @stable ICU 54 */ void setZodiacNames(const UnicodeString* zodiacNames, int32_t count, DtContextType context, DtWidthType width); -#endif /* U_HIDE_DRAFT_API */ - #ifndef U_HIDE_INTERNAL_API /** * Somewhat temporary constants for leap month pattern types, adequate for supporting @@ -559,7 +568,7 @@ class U_I18N_API DateFormatSymbols U_FINAL : public UObject { * @return the non-localized date-time pattern characters * @stable ICU 2.0 */ - static const UChar * U_EXPORT2 getPatternUChars(void); + static const char16_t * U_EXPORT2 getPatternUChars(void); /** * Gets localized date-time pattern characters. For example: 'u', 't', etc. @@ -855,6 +864,42 @@ class U_I18N_API DateFormatSymbols U_FINAL : public UObject { */ UBool fCapitalization[kCapContextUsageTypeCount][2]; + /** + * Abbreviated (== short) day period strings. + */ + UnicodeString *fAbbreviatedDayPeriods; + int32_t fAbbreviatedDayPeriodsCount; + + /** + * Wide day period strings. + */ + UnicodeString *fWideDayPeriods; + int32_t fWideDayPeriodsCount; + + /** + * Narrow day period strings. + */ + UnicodeString *fNarrowDayPeriods; + int32_t fNarrowDayPeriodsCount; + + /** + * Stand-alone abbreviated (== short) day period strings. + */ + UnicodeString *fStandaloneAbbreviatedDayPeriods; + int32_t fStandaloneAbbreviatedDayPeriodsCount; + + /** + * Stand-alone wide day period strings. + */ + UnicodeString *fStandaloneWideDayPeriods; + int32_t fStandaloneWideDayPeriodsCount; + + /** + * Stand-alone narrow day period strings. + */ + UnicodeString *fStandaloneNarrowDayPeriods; + int32_t fStandaloneNarrowDayPeriodsCount; + private: /** valid/actual locale information * these are always ICU locales, so the length should not be a problem @@ -934,7 +979,7 @@ class U_I18N_API DateFormatSymbols U_FINAL : public UObject { * Returns the date format field index of the pattern character c, * or UDAT_FIELD_COUNT if c is not a pattern character. */ - static UDateFormatField U_EXPORT2 getPatternCharIndex(UChar c); + static UDateFormatField U_EXPORT2 getPatternCharIndex(char16_t c); /** * Returns TRUE if f (with its pattern character repeated count times) is a numeric field. @@ -944,7 +989,7 @@ class U_I18N_API DateFormatSymbols U_FINAL : public UObject { /** * Returns TRUE if c (repeated count times) is the pattern character for a numeric field. */ - static UBool U_EXPORT2 isNumericPatternChar(UChar c, int32_t count); + static UBool U_EXPORT2 isNumericPatternChar(char16_t c, int32_t count); public: #ifndef U_HIDE_INTERNAL_API /** @@ -960,10 +1005,27 @@ class U_I18N_API DateFormatSymbols U_FINAL : public UObject { */ static DateFormatSymbols * U_EXPORT2 createForLocale( const Locale &locale, UErrorCode &status); + + /** + * Apple addition + * Get whether to capitalize based on usage. + * @param usage the usage. + * @param context 0 for menu, 1 for standalone + * @return TRUE to capitalize, FALSE otherwise + * @internal For ICU use only. + */ + UBool capitalizeForUsage(ECapitalizationContextUsageType usage, int32_t context) const; #endif /* U_HIDE_INTERNAL_API */ }; +inline UBool +DateFormatSymbols::capitalizeForUsage(DateFormatSymbols::ECapitalizationContextUsageType usage, int32_t context) const +{ + return fCapitalization[usage][context]; +} + U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtintrv.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtintrv.h index 5bacce8844..cc6b988f68 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtintrv.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtintrv.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2008-2009, International Business Machines Corporation and @@ -21,6 +23,7 @@ */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN @@ -51,14 +54,14 @@ class U_COMMON_API DateInterval : public UObject { * @return the from date in dateInterval. * @stable ICU 4.0 */ - UDate getFromDate() const; + inline UDate getFromDate() const; /** * Get the to date. * @return the to date in dateInterval. * @stable ICU 4.0 */ - UDate getToDate() const; + inline UDate getToDate() const; /** @@ -67,7 +70,7 @@ class U_COMMON_API DateInterval : public UObject { *

            * .   Base* polymorphic_pointer = createPolymorphicObject();
            * .   if (polymorphic_pointer->getDynamicClassID() ==
      -     * .       erived::getStaticClassID()) ...
      +     * .       derived::getStaticClassID()) ...
            * 
      * @return The class ID for all objects of this class. * @stable ICU 4.0 @@ -112,7 +115,7 @@ class U_COMMON_API DateInterval : public UObject { * @return TRUE if the two DateIntervals are not the same * @stable ICU 4.0 */ - UBool operator!=(const DateInterval& other) const; + inline UBool operator!=(const DateInterval& other) const; /** @@ -154,5 +157,6 @@ DateInterval::operator!=(const DateInterval& other) const { U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtitvfmt.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtitvfmt.h index 38eff4c29a..46c3985bfc 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtitvfmt.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtitvfmt.h @@ -1,5 +1,7 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /******************************************************************************** -* Copyright (C) 2008-2013,2015, International Business Machines Corporation and +* Copyright (C) 2008-2016, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************************* * @@ -26,11 +28,91 @@ #include "unicode/dtintrv.h" #include "unicode/dtitvinf.h" #include "unicode/dtptngen.h" +#include "unicode/formattedvalue.h" +#include "unicode/udisplaycontext.h" +// Apple-specific #include "unicode/udateintervalformat.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN +class FormattedDateIntervalData; +class DateIntervalFormat; + +#ifndef U_HIDE_DRAFT_API +/** + * An immutable class containing the result of a date interval formatting operation. + * + * Instances of this class are immutable and thread-safe. + * + * When calling nextPosition(): + * The fields are returned from left to right. The special field category + * UFIELD_CATEGORY_DATE_INTERVAL_SPAN is used to indicate which datetime + * primitives came from which arguments: 0 means fromCalendar, and 1 means + * toCalendar. The span category will always occur before the + * corresponding fields in UFIELD_CATEGORY_DATE + * in the nextPosition() iterator. + * + * Not intended for public subclassing. + * + * @draft ICU 64 + */ +class U_I18N_API FormattedDateInterval : public UMemory, public FormattedValue { + public: + /** + * Default constructor; makes an empty FormattedDateInterval. + * @draft ICU 64 + */ + FormattedDateInterval() : fData(nullptr), fErrorCode(U_INVALID_STATE_ERROR) {} + + /** + * Move constructor: Leaves the source FormattedDateInterval in an undefined state. + * @draft ICU 64 + */ + FormattedDateInterval(FormattedDateInterval&& src) U_NOEXCEPT; + + /** + * Destruct an instance of FormattedDateInterval. + * @draft ICU 64 + */ + virtual ~FormattedDateInterval() U_OVERRIDE; + + /** Copying not supported; use move constructor instead. */ + FormattedDateInterval(const FormattedDateInterval&) = delete; + + /** Copying not supported; use move assignment instead. */ + FormattedDateInterval& operator=(const FormattedDateInterval&) = delete; + + /** + * Move assignment: Leaves the source FormattedDateInterval in an undefined state. + * @draft ICU 64 + */ + FormattedDateInterval& operator=(FormattedDateInterval&& src) U_NOEXCEPT; + + /** @copydoc FormattedValue::toString() */ + UnicodeString toString(UErrorCode& status) const U_OVERRIDE; + + /** @copydoc FormattedValue::toTempString() */ + UnicodeString toTempString(UErrorCode& status) const U_OVERRIDE; + + /** @copydoc FormattedValue::appendTo() */ + Appendable &appendTo(Appendable& appendable, UErrorCode& status) const U_OVERRIDE; + + /** @copydoc FormattedValue::nextPosition() */ + UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE; + + private: + FormattedDateIntervalData *fData; + UErrorCode fErrorCode; + explicit FormattedDateInterval(FormattedDateIntervalData *results) + : fData(results), fErrorCode(U_ZERO_ERROR) {} + explicit FormattedDateInterval(UErrorCode errorCode) + : fData(nullptr), fErrorCode(errorCode) {} + friend class DateIntervalFormat; +}; +#endif /* U_HIDE_DRAFT_API */ + /** * DateIntervalFormat is a class for formatting and parsing date @@ -217,7 +299,6 @@ U_NAMESPACE_BEGIN * \endcode *
  • */ - class U_I18N_API DateIntervalFormat : public Format { public: @@ -390,6 +471,9 @@ class U_I18N_API DateIntervalFormat : public Format { * Result is appended to existing contents. * @param fieldPosition On input: an alignment field, if desired. * On output: the offsets of the alignment field. + * There may be multiple instances of a given field type + * in an interval format; in this case the fieldPosition + * offsets refer to the first instance. * @param status Output param filled with success/failure status. * @return Reference to 'appendTo' parameter. * @stable ICU 4.0 @@ -409,6 +493,9 @@ class U_I18N_API DateIntervalFormat : public Format { * Result is appended to existing contents. * @param fieldPosition On input: an alignment field, if desired. * On output: the offsets of the alignment field. + * There may be multiple instances of a given field type + * in an interval format; in this case the fieldPosition + * offsets refer to the first instance. * @param status Output param filled with success/failure status. * @return Reference to 'appendTo' parameter. * @stable ICU 4.0 @@ -418,6 +505,21 @@ class U_I18N_API DateIntervalFormat : public Format { FieldPosition& fieldPosition, UErrorCode& status) const ; +#ifndef U_HIDE_DRAFT_API + /** + * Format a DateInterval to produce a FormattedDateInterval. + * + * The FormattedDateInterval exposes field information about the formatted string. + * + * @param dtInterval DateInterval to be formatted. + * @param status Set if an error occurs. + * @return A FormattedDateInterval containing the format result. + * @draft ICU 64 + */ + FormattedDateInterval formatToValue( + const DateInterval& dtInterval, + UErrorCode& status) const; +#endif /* U_HIDE_DRAFT_API */ /** * Format 2 Calendars to produce a string. @@ -433,6 +535,9 @@ class U_I18N_API DateIntervalFormat : public Format { * Result is appended to existing contents. * @param fieldPosition On input: an alignment field, if desired. * On output: the offsets of the alignment field. + * There may be multiple instances of a given field type + * in an interval format; in this case the fieldPosition + * offsets refer to the first instance. * @param status Output param filled with success/failure status. * Caller needs to make sure it is SUCCESS * at the function entrance @@ -445,6 +550,29 @@ class U_I18N_API DateIntervalFormat : public Format { FieldPosition& fieldPosition, UErrorCode& status) const ; +#ifndef U_HIDE_DRAFT_API + /** + * Format 2 Calendars to produce a FormattedDateInterval. + * + * The FormattedDateInterval exposes field information about the formatted string. + * + * Note: "fromCalendar" and "toCalendar" are not const, + * since calendar is not const in SimpleDateFormat::format(Calendar&), + * + * @param fromCalendar calendar set to the from date in date interval + * to be formatted into date interval string + * @param toCalendar calendar set to the to date in date interval + * to be formatted into date interval string + * @param status Set if an error occurs. + * @return A FormattedDateInterval containing the format result. + * @draft ICU 64 + */ + FormattedDateInterval formatToValue( + Calendar& fromCalendar, + Calendar& toCalendar, + UErrorCode& status) const; +#endif /* U_HIDE_DRAFT_API */ + /** * Date interval parsing is not supported. Please do not use. *

    @@ -496,7 +624,13 @@ class U_I18N_API DateIntervalFormat : public Format { /** - * Gets the date formatter + * Gets the date formatter. The DateIntervalFormat instance continues to own + * the returned DateFormatter object, and will use and possibly modify it + * during format operations. In a multi-threaded environment, the returned + * DateFormat can only be used if it is certain that no other threads are + * concurrently using this DateIntervalFormatter, even for nominally const + * functions. + * * @return the date formatter associated with this date interval formatter. * @stable ICU 4.0 */ @@ -538,6 +672,32 @@ class U_I18N_API DateIntervalFormat : public Format { UDateIntervalFormatAttributeValue value, UErrorCode &status); + /** + * Set a particular UDisplayContext value in the formatter, such as + * UDISPCTX_CAPITALIZATION_FOR_STANDALONE. This causes the formatted + * result to be capitalized appropriately for the context in which + * it is intended to be used, considering both the locale and the + * type of field at the beginning of the formatted result. + * @param value The UDisplayContext value to set. + * @param status Input/output status. If at entry this indicates a failure + * status, the function will do nothing; otherwise this will be + * updated with any new status from the function. + * @draft ICU 65 + */ + virtual void setContext(UDisplayContext value, UErrorCode& status); + + /** + * Get the formatter's UDisplayContext value for the specified UDisplayContextType, + * such as UDISPCTX_TYPE_CAPITALIZATION. + * @param type The UDisplayContextType whose value to return + * @param status Input/output status. If at entry this indicates a failure + * status, the function will do nothing; otherwise this will be + * updated with any new status from the function. + * @return The UDisplayContextValue for the specified type. + * @draft ICU 65 + */ + virtual UDisplayContext getContext(UDisplayContextType type, UErrorCode& status) const; + /** * Return the class ID for this class. This is useful only for comparing to * a return value from getDynamicClassID(). For example: @@ -615,7 +775,7 @@ class U_I18N_API DateIntervalFormat : public Format { /** * default constructor - * @internal ICU 4.0 + * @internal (private) */ DateIntervalFormat(); @@ -658,44 +818,18 @@ class U_I18N_API DateIntervalFormat : public Format { const UnicodeString* skeleton, UErrorCode& status); - /** - * Create a simple date/time formatter from skeleton, given locale, - * and date time pattern generator. - * - * @param skeleton the skeleton on which date format based. - * @param locale the given locale. - * @param dtpng the date time pattern generator. - * @param status Output param to be set to success/failure code. - * If it is failure, the returned date formatter will - * be NULL. - * @return a simple date formatter which the caller owns. - */ - static SimpleDateFormat* U_EXPORT2 createSDFPatternInstance( - const UnicodeString& skeleton, - const Locale& locale, - DateTimePatternGenerator* dtpng, - UErrorCode& status); - - /** * Below are for generating interval patterns local to the formatter */ - /** - * @param combiningPattern xxx - * @param pat0 xxx - * @param pos0 xxx - * @param pat1 xxx - * @param pos1 xxx - * @param posResult xxx - */ - static void - adjustPosition(UnicodeString& combiningPattern, // has {0} and {1} in it - UnicodeString& pat0, FieldPosition& pos0, // pattern and pos corresponding to {0} - UnicodeString& pat1, FieldPosition& pos1, // pattern and pos corresponding to {1} - FieldPosition& posResult); - - + /** Like fallbackFormat, but only formats the range part of the fallback. */ + void fallbackFormatRange( + Calendar& fromCalendar, + Calendar& toCalendar, + UnicodeString& appendTo, + int8_t& firstIndex, + FieldPositionHandler& fphandler, + UErrorCode& status) const; /** * Format 2 Calendars using fall-back interval pattern @@ -703,6 +837,8 @@ class U_I18N_API DateIntervalFormat : public Format { * The full pattern used in this fall-back format is the * full pattern of the date formatter. * + * gFormatterMutex must already be locked when calling this function. + * * @param fromCalendar calendar set to the from date in date interval * to be formatted into date interval string * @param toCalendar calendar set to the to date in date interval @@ -711,16 +847,18 @@ class U_I18N_API DateIntervalFormat : public Format { * (any difference is in ampm/hours or below) * @param appendTo Output parameter to receive result. * Result is appended to existing contents. - * @param pos On input: an alignment field, if desired. - * On output: the offsets of the alignment field. + * @param firstIndex See formatImpl for more information. + * @param fphandler See formatImpl for more information. * @param status output param set to success/failure code on exit * @return Reference to 'appendTo' parameter. + * @internal (private) */ UnicodeString& fallbackFormat(Calendar& fromCalendar, Calendar& toCalendar, UBool fromToOnSameDay, UnicodeString& appendTo, - FieldPosition& pos, + int8_t& firstIndex, + FieldPositionHandler& fphandler, UErrorCode& status) const; @@ -970,9 +1108,48 @@ class U_I18N_API DateIntervalFormat : public Format { const UnicodeString* secondPart, UBool laterDateFirst); + /** + * Format 2 Calendars to produce a string. + * Implementation of the similar public format function. + * Must be called with gFormatterMutex already locked. + * + * Note: "fromCalendar" and "toCalendar" are not const, + * since calendar is not const in SimpleDateFormat::format(Calendar&), + * + * @param fromCalendar calendar set to the from date in date interval + * to be formatted into date interval string + * @param toCalendar calendar set to the to date in date interval + * to be formatted into date interval string + * @param appendTo Output parameter to receive result. + * Result is appended to existing contents. + * @param firstIndex 0 if the first output date is fromCalendar; + * 1 if it corresponds to toCalendar; + * -1 if there is only one date printed. + * @param fphandler Handler for field position information. + * The fields will be from the UDateFormatField enum. + * @param status Output param filled with success/failure status. + * Caller needs to make sure it is SUCCESS + * at the function entrance + * @return Reference to 'appendTo' parameter. + * @internal (private) + */ + UnicodeString& formatImpl(Calendar& fromCalendar, + Calendar& toCalendar, + UnicodeString& appendTo, + int8_t& firstIndex, + FieldPositionHandler& fphandler, + UErrorCode& status) const ; + + /** Version of formatImpl for DateInterval. */ + UnicodeString& formatIntervalImpl(const DateInterval& dtInterval, + UnicodeString& appendTo, + int8_t& firstIndex, + FieldPositionHandler& fphandler, + UErrorCode& status) const; + // from calendar field to pattern letter - static const UChar fgCalendarFieldToPatternLetter[]; + static const char16_t fgCalendarFieldToPatternLetter[]; /** @@ -993,10 +1170,7 @@ class U_I18N_API DateIntervalFormat : public Format { Calendar* fFromCalendar; Calendar* fToCalendar; - /** - * Date time pattern generator - */ - DateTimePatternGenerator* fDtpng; + Locale fLocale; /** * Following are interval information relevant (locale) to this formatter. @@ -1015,6 +1189,8 @@ class U_I18N_API DateIntervalFormat : public Format { * Atttributes */ int32_t fMinimizeType; + + UDisplayContext fCapitalizationContext; }; inline UBool @@ -1023,6 +1199,7 @@ DateIntervalFormat::operator!=(const Format& other) const { } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtitvinf.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtitvinf.h index 444356d3f8..0e8f534b73 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtitvinf.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtitvinf.h @@ -1,6 +1,8 @@ +// © 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 + * Copyright (C) 2008-2016, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************************* * @@ -26,6 +28,7 @@ #include "unicode/ucal.h" #include "unicode/dtptngen.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -49,22 +52,22 @@ U_NAMESPACE_BEGIN * to (date_interval_pattern). * *

    - * A skeleton + * A skeleton *

      *
    1. - * only keeps the field pattern letter and ignores all other parts + * only keeps the field pattern letter and ignores all other parts * in a pattern, such as space, punctuations, and string literals. *
    2. - * hides the order of fields. + * hides the order of fields. *
    3. * might hide a field's pattern letter length. * - * For those non-digit calendar fields, the pattern letter length is - * important, such as MMM, MMMM, and MMMMM; EEE and EEEE, + * For those non-digit calendar fields, the pattern letter length is + * important, such as MMM, MMMM, and MMMMM; EEE and EEEE, * and the field's pattern letter length is honored. - * - * For the digit calendar fields, such as M or MM, d or dd, yy or yyyy, - * the field pattern length is ignored and the best match, which is defined + * + * For the digit calendar fields, such as M or MM, d or dd, yy or yyyy, + * the field pattern length is ignored and the best match, which is defined * in date time patterns, will be returned without honor the field pattern * letter length in skeleton. *
    @@ -73,21 +76,21 @@ U_NAMESPACE_BEGIN * The calendar fields we support for interval formatting are: * year, month, date, day-of-week, am-pm, hour, hour-of-day, and minute. * Those calendar fields can be defined in the following order: - * year > month > date > am-pm > hour > minute - * + * year > month > date > am-pm > hour > minute + * * The largest different calendar fields between 2 calendars is the * first different calendar field in above order. * - * For example: the largest different calendar fields between "Jan 10, 2007" + * For example: the largest different calendar fields between "Jan 10, 2007" * and "Feb 20, 2008" is year. - * + * *

    * There is a set of pre-defined static skeleton strings. * There are pre-defined interval patterns for those pre-defined skeletons * in locales' resource files. * For example, for a skeleton UDAT_YEAR_ABBR_MONTH_DAY, which is "yMMMd", - * in en_US, if the largest different calendar field between date1 and date2 - * is "year", the date interval pattern is "MMM d, yyyy - MMM d, yyyy", + * in en_US, if the largest different calendar field between date1 and date2 + * is "year", the date interval pattern is "MMM d, yyyy - MMM d, yyyy", * such as "Jan 10, 2007 - Jan 10, 2008". * If the largest different calendar field between date1 and date2 is "month", * the date interval pattern is "MMM d - MMM d, yyyy", @@ -95,7 +98,7 @@ U_NAMESPACE_BEGIN * If the largest different calendar field between date1 and date2 is "day", * the date interval pattern is "MMM d-d, yyyy", such as "Jan 10-20, 2007". * - * For date skeleton, the interval patterns when year, or month, or date is + * For date skeleton, the interval patterns when year, or month, or date is * different are defined in resource files. * For time skeleton, the interval patterns when am/pm, or hour, or minute is * different are defined in resource files. @@ -108,56 +111,54 @@ U_NAMESPACE_BEGIN * We use fallback format for the default order for the locale. * For example, if the fallback format is "{0} - {1}", it means * the first date in the interval pattern for this locale is earlier date. - * If the fallback format is "{1} - {0}", it means the first date is the + * If the fallback format is "{1} - {0}", it means the first date is the * later date. * For a particular interval pattern, the default order can be overriden * by prefixing "latestFirst:" or "earliestFirst:" to the interval pattern. * For example, if the fallback format is "{0}-{1}", - * but for skeleton "yMMMd", the interval pattern when day is different is + * but for skeleton "yMMMd", the interval pattern when day is different is * "latestFirst:d-d MMM yy", it means by default, the first date in interval * pattern is the earlier date. But for skeleton "yMMMd", when day is different, * the first date in "d-d MMM yy" is the later date. - * + * *

    - * The recommended way to create a DateIntervalFormat object is to pass in - * the locale. - * By using a Locale parameter, the DateIntervalFormat object is - * initialized with the pre-defined interval patterns for a given or + * The recommended way to create a DateIntervalFormat object is to pass in + * the locale. + * By using a Locale parameter, the DateIntervalFormat object is + * initialized with the pre-defined interval patterns for a given or * default locale. *

    - * Users can also create DateIntervalFormat object + * Users can also create DateIntervalFormat object * by supplying their own interval patterns. * It provides flexibility for power users. * *

    * After a DateIntervalInfo object is created, clients may modify * the interval patterns using setIntervalPattern function as so desired. - * Currently, users can only set interval patterns when the following - * calendar fields are different: ERA, YEAR, MONTH, DATE, DAY_OF_MONTH, + * Currently, users can only set interval patterns when the following + * calendar fields are different: ERA, YEAR, MONTH, DATE, DAY_OF_MONTH, * DAY_OF_WEEK, AM_PM, HOUR, HOUR_OF_DAY, and MINUTE. * Interval patterns when other calendar fields are different is not supported. *

    - * DateIntervalInfo objects are cloneable. - * When clients obtain a DateIntervalInfo object, + * DateIntervalInfo objects are cloneable. + * When clients obtain a DateIntervalInfo object, * they can feel free to modify it as necessary. *

    - * DateIntervalInfo are not expected to be subclassed. - * Data for a calendar is loaded out of resource bundles. + * DateIntervalInfo are not expected to be subclassed. + * Data for a calendar is loaded out of resource bundles. * Through ICU 4.4, date interval patterns are only supported in the Gregorian - * calendar; non-Gregorian calendars are supported from ICU 4.4.1. + * calendar; non-Gregorian calendars are supported from ICU 4.4.1. * @stable ICU 4.0 **/ - class U_I18N_API DateIntervalInfo U_FINAL : public UObject { public: -#ifndef U_HIDE_INTERNAL_API /** * Default constructor. * It does not initialize any interval patterns except * that it initialize default fall-back pattern as "{0} - {1}", * which can be reset by setFallbackIntervalPattern(). - * It should be followed by setFallbackIntervalPattern() and - * setIntervalPattern(), + * It should be followed by setFallbackIntervalPattern() and + * setIntervalPattern(), * and is recommended to be used only for power users who * wants to create their own interval patterns and use them to create * date interval formatter. @@ -165,10 +166,9 @@ class U_I18N_API DateIntervalInfo U_FINAL : public UObject { * @internal ICU 4.0 */ DateIntervalInfo(UErrorCode& status); -#endif /* U_HIDE_INTERNAL_API */ - /** + /** * Construct DateIntervalInfo for the given locale, * @param locale the interval patterns are loaded from the appropriate calendar * data (specified calendar or default calendar) in this locale. @@ -226,7 +226,7 @@ class U_I18N_API DateIntervalInfo U_FINAL : public UObject { - /** + /** * Provides a way for client to build interval patterns. * User could construct DateIntervalInfo by providing a list of skeletons * and their patterns. @@ -236,53 +236,53 @@ class U_I18N_API DateIntervalInfo U_FINAL : public UObject { * UErrorCode status = U_ZERO_ERROR; * DateIntervalInfo dIntervalInfo = new DateIntervalInfo(); * dIntervalInfo->setFallbackIntervalPattern("{0} ~ {1}"); - * dIntervalInfo->setIntervalPattern("yMd", UCAL_YEAR, "'from' yyyy-M-d 'to' yyyy-M-d", status); + * dIntervalInfo->setIntervalPattern("yMd", UCAL_YEAR, "'from' yyyy-M-d 'to' yyyy-M-d", status); * dIntervalInfo->setIntervalPattern("yMMMd", UCAL_MONTH, "'from' yyyy MMM d 'to' MMM d", status); * dIntervalInfo->setIntervalPattern("yMMMd", UCAL_DAY, "yyyy MMM d-d", status, status); *

    * - * Restriction: - * Currently, users can only set interval patterns when the following - * calendar fields are different: ERA, YEAR, MONTH, DATE, DAY_OF_MONTH, + * Restriction: + * Currently, users can only set interval patterns when the following + * calendar fields are different: ERA, YEAR, MONTH, DATE, DAY_OF_MONTH, * DAY_OF_WEEK, AM_PM, HOUR, HOUR_OF_DAY, and MINUTE. - * Interval patterns when other calendar fields are different are + * Interval patterns when other calendar fields are different are * not supported. * * @param skeleton the skeleton on which interval pattern based * @param lrgDiffCalUnit the largest different calendar unit. * @param intervalPattern the interval pattern on the largest different * calendar unit. - * For example, if lrgDiffCalUnit is + * For example, if lrgDiffCalUnit is * "year", the interval pattern for en_US when year * is different could be "'from' yyyy 'to' yyyy". * @param status output param set to success/failure code on exit * @stable ICU 4.0 */ - void setIntervalPattern(const UnicodeString& skeleton, - UCalendarDateFields lrgDiffCalUnit, + void setIntervalPattern(const UnicodeString& skeleton, + UCalendarDateFields lrgDiffCalUnit, const UnicodeString& intervalPattern, UErrorCode& status); /** - * Get the interval pattern given skeleton and + * Get the interval pattern given skeleton and * the largest different calendar field. * @param skeleton the skeleton * @param field the largest different calendar field * @param result output param to receive the pattern * @param status output param set to success/failure code on exit * @return a reference to 'result' - * @stable ICU 4.0 + * @stable ICU 4.0 */ UnicodeString& getIntervalPattern(const UnicodeString& skeleton, UCalendarDateFields field, UnicodeString& result, - UErrorCode& status) const; + UErrorCode& status) const; /** * Get the fallback interval pattern. * @param result output param to receive the pattern * @return a reference to 'result' - * @stable ICU 4.0 + * @stable ICU 4.0 */ UnicodeString& getFallbackIntervalPattern(UnicodeString& result) const; @@ -298,7 +298,7 @@ class U_I18N_API DateIntervalInfo U_FINAL : public UObject { * * @param fallbackPattern fall-back interval pattern. * @param status output param set to success/failure code on exit - * @stable ICU 4.0 + * @stable ICU 4.0 */ void setFallbackIntervalPattern(const UnicodeString& fallbackPattern, UErrorCode& status); @@ -308,7 +308,7 @@ class U_I18N_API DateIntervalInfo U_FINAL : public UObject { or not. * return default date ordering in interval pattern. TRUE if the first date * in pattern is later date, FALSE otherwise. - * @stable ICU 4.0 + * @stable ICU 4.0 */ UBool getDefaultOrder() const; @@ -339,6 +339,11 @@ class U_I18N_API DateIntervalInfo U_FINAL : public UObject { */ friend class DateIntervalFormat; + /** + * Internal struct used to load resource bundle data. + */ + struct DateIntervalSink; + /** * Following is for saving the interval patterns. * We only support interval patterns on @@ -360,7 +365,7 @@ class U_I18N_API DateIntervalInfo U_FINAL : public UObject { #ifndef U_HIDE_INTERNAL_API /** * Max index for stored interval patterns - * @internal ICU 4.4 + * @internal ICU 4.4 */ enum { kMaxIntervalPatternIndex = kIPI_MAX_INDEX @@ -369,7 +374,7 @@ class U_I18N_API DateIntervalInfo U_FINAL : public UObject { private: - /** + /** * Initialize the DateIntervalInfo from locale * @param locale the given locale. * @param status output param set to success/failure code on exit @@ -390,10 +395,10 @@ class U_I18N_API DateIntervalInfo U_FINAL : public UObject { void setIntervalPatternInternally(const UnicodeString& skeleton, UCalendarDateFields lrgDiffCalUnit, const UnicodeString& intervalPattern, - UErrorCode& status); + UErrorCode& status); - /**given an input skeleton, get the best match skeleton + /**given an input skeleton, get the best match skeleton * which has pre-defined interval pattern in resource file. * Also return the difference between the input skeleton * and the best match skeleton. @@ -404,7 +409,7 @@ class U_I18N_API DateIntervalInfo U_FINAL : public UObject { * @param bestMatchDistanceInfo the difference between input skeleton * and best match skeleton. * 0, if there is exact match for input skeleton - * 1, if there is only field width difference between + * 1, if there is only field width difference between * the best match and the input skeleton * 2, the only field difference is 'v' and 'z' * -1, if there is calendar field difference between @@ -422,7 +427,7 @@ class U_I18N_API DateIntervalInfo U_FINAL : public UObject { * @param skeleton skeleton to be parsed * @param skeletonFieldWidth parsed skeleton field width */ - static void U_EXPORT2 parseSkeleton(const UnicodeString& skeleton, + static void U_EXPORT2 parseSkeleton(const UnicodeString& skeleton, int32_t* skeletonFieldWidth); @@ -442,12 +447,12 @@ class U_I18N_API DateIntervalInfo U_FINAL : public UObject { char patternLetter); - /** - * Convert calendar field to the interval pattern index in + /** + * Convert calendar field to the interval pattern index in * hash table. * - * Since we only support the following calendar fields: - * ERA, YEAR, MONTH, DATE, DAY_OF_MONTH, DAY_OF_WEEK, + * Since we only support the following calendar fields: + * ERA, YEAR, MONTH, DATE, DAY_OF_MONTH, DAY_OF_WEEK, * AM_PM, HOUR, HOUR_OF_DAY, and MINUTE, * We reserve only 4 interval patterns for a skeleton. * @@ -489,7 +494,7 @@ class U_I18N_API DateIntervalInfo U_FINAL : public UObject { // data members - // fallback interval pattern + // fallback interval pattern UnicodeString fFallbackIntervalPattern; // default order UBool fFirstDateInPtnIsLaterDate; @@ -508,6 +513,7 @@ DateIntervalInfo::operator!=(const DateIntervalInfo& other) const { U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtptngen.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtptngen.h index 1907935b33..0803fc0830 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtptngen.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtptngen.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* -* Copyright (C) 2007-2015, International Business Machines Corporation and +* Copyright (C) 2007-2016, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************************* * @@ -16,7 +18,9 @@ #include "unicode/locid.h" #include "unicode/udat.h" #include "unicode/udatpg.h" +#include "unicode/unistr.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -25,6 +29,7 @@ U_NAMESPACE_BEGIN */ +class CharString; class Hashtable; class FormatParser; class DateTimeMatcher; @@ -34,15 +39,15 @@ class PtnSkeleton; class SharedDateTimePatternGenerator; /** - * This class provides flexible generation of date format patterns, like "yy-MM-dd". - * The user can build up the generator by adding successive patterns. Once that + * This class provides flexible generation of date format patterns, like "yy-MM-dd". + * The user can build up the generator by adding successive patterns. Once that * is done, a query can be made using a "skeleton", which is a pattern which just - * includes the desired fields and lengths. The generator will return the "best fit" + * includes the desired fields and lengths. The generator will return the "best fit" * pattern corresponding to that skeleton. *

    The main method people will use is getBestPattern(String skeleton), - * since normally this class is pre-built with data from a particular locale. + * since normally this class is pre-built with data from a particular locale. * However, generators can be built directly from other data as well. - *

    Issue: may be useful to also have a function that returns the list of + *

    Issue: may be useful to also have a function that returns the list of * fields in a pattern, in order, since we have that internally. * That would be useful for getting the UI order of field elements. * @stable ICU 3.8 @@ -64,7 +69,7 @@ class U_I18N_API DateTimePatternGenerator : public UObject { * which must not indicate a failure before the function call. * @stable ICU 3.8 */ - static DateTimePatternGenerator* U_EXPORT2 createInstance(const Locale& uLocale, UErrorCode& status); + static DateTimePatternGenerator* U_EXPORT2 createInstance(const Locale& uLocale, UErrorCode& status, UBool skipICUData = FALSE); #ifndef U_HIDE_INTERNAL_API @@ -84,7 +89,7 @@ class U_I18N_API DateTimePatternGenerator : public UObject { * @stable ICU 3.8 */ static DateTimePatternGenerator* U_EXPORT2 createEmptyInstance(UErrorCode& status); - + /** * Destructor. * @stable ICU 3.8 @@ -92,7 +97,7 @@ class U_I18N_API DateTimePatternGenerator : public UObject { virtual ~DateTimePatternGenerator(); /** - * Clone DateTimePatternGenerator object. Clients are responsible for + * Clone DateTimePatternGenerator object. Clients are responsible for * deleting the DateTimePatternGenerator object cloned. * @stable ICU 3.8 */ @@ -106,7 +111,7 @@ class U_I18N_API DateTimePatternGenerator : public UObject { * @stable ICU 3.8 */ UBool operator==(const DateTimePatternGenerator& other) const; - + /** * Return true if another object is semantically unequal to this one. * @@ -124,9 +129,43 @@ class U_I18N_API DateTimePatternGenerator : public UObject { * @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" + * @stable ICU 56 + */ + static UnicodeString staticGetSkeleton(const UnicodeString& pattern, UErrorCode& status); + + /** + * Utility to return a unique skeleton from a given pattern. For example, + * both "MMM-dd" and "dd/MMM" produce the skeleton "MMMdd". + * getSkeleton() works exactly like staticGetSkeleton(). + * Use staticGetSkeleton() instead of getSkeleton(). + * + * @param pattern Input pattern, such as "dd/MMM" + * @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" * @stable ICU 3.8 */ - UnicodeString getSkeleton(const UnicodeString& pattern, UErrorCode& status); + UnicodeString getSkeleton(const UnicodeString& pattern, UErrorCode& status); /* { + The function is commented out because it is a stable API calling a draft API. + After staticGetSkeleton becomes stable, staticGetSkeleton can be used and + these comments and the definition of getSkeleton in dtptngen.cpp should be removed. + return staticGetSkeleton(pattern, status); + }*/ + + /** + * 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 + * so as to only preserve the difference between string and numeric form. So + * for example, both "MMM-dd" and "d/MMM" produce the skeleton "MMMd" + * (notice the single d). + * + * @param pattern Input pattern, such as "dd/MMM" + * @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" + * @stable ICU 56 + */ + static UnicodeString staticGetBaseSkeleton(const UnicodeString& pattern, UErrorCode& status); /** * Utility to return a unique base skeleton from a given pattern. This is @@ -134,42 +173,49 @@ class U_I18N_API DateTimePatternGenerator : public UObject { * so as to only preserve the difference between string and numeric form. So * for example, both "MMM-dd" and "d/MMM" produce the skeleton "MMMd" * (notice the single d). + * getBaseSkeleton() works exactly like staticGetBaseSkeleton(). + * Use staticGetBaseSkeleton() instead of getBaseSkeleton(). * * @param pattern Input pattern, such as "dd/MMM" * @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 "Md" + * @return base skeleton, such as "MMMd" * @stable ICU 3.8 */ - UnicodeString getBaseSkeleton(const UnicodeString& pattern, UErrorCode& status); + UnicodeString getBaseSkeleton(const UnicodeString& pattern, UErrorCode& status); /* { + The function is commented out because it is a stable API calling a draft API. + After staticGetBaseSkeleton becomes stable, staticGetBaseSkeleton can be used and + these comments and the definition of getBaseSkeleton in dtptngen.cpp should be removed. + return staticGetBaseSkeleton(pattern, status); + }*/ /** * Adds a pattern to the generator. If the pattern has the same skeleton as * an existing pattern, and the override parameter is set, then the previous * value is overriden. Otherwise, the previous value is retained. In either - * case, the conflicting status is set and previous vale is stored in + * case, the conflicting status is set and previous vale is stored in * conflicting pattern. *

    * Note that single-field patterns (like "MMM") are automatically added, and * don't need to be added explicitly! * * @param pattern Input pattern, such as "dd/MMM" - * @param override When existing values are to be overridden use true, + * @param override When existing values are to be overridden use true, * otherwise use false. * @param conflictingPattern Previous pattern with the same skeleton. * @param status Output param set to success/failure code on exit, * which must not indicate a failure before the function call. - * @return conflicting status. The value could be UDATPG_NO_CONFLICT, + * @return conflicting status. The value could be UDATPG_NO_CONFLICT, * UDATPG_BASE_CONFLICT or UDATPG_CONFLICT. * @stable ICU 3.8 - *

    - *

    Sample code

    - * \snippet samples/dtptngsample/dtptngsample.cpp getBestPatternExample1 - * \snippet samples/dtptngsample/dtptngsample.cpp addPatternExample - *

    - */ - UDateTimePatternConflict addPattern(const UnicodeString& pattern, - UBool override, + *

    + *

    Sample code

    + * \snippet samples/dtptngsample/dtptngsample.cpp getBestPatternExample1 + * \snippet samples/dtptngsample/dtptngsample.cpp addPatternExample + *

    + */ + UDateTimePatternConflict addPattern(const UnicodeString& pattern, + UBool override, UnicodeString& conflictingPattern, UErrorCode& status); @@ -218,14 +264,27 @@ class U_I18N_API DateTimePatternGenerator : public UObject { /** * Getter corresponding to setAppendItemNames. Values below 0 or at or above - * UDATPG_FIELD_COUNT are illegal arguments. + * UDATPG_FIELD_COUNT are illegal arguments. Note: The more general method + * for getting date/time field display names is getFieldDisplayName. * * @param field such as UDATPG_ERA_FIELD. * @return name for field + * @see getFieldDisplayName * @stable ICU 3.8 */ const UnicodeString& getAppendItemName(UDateTimePatternField field) const; + /** + * The general interface to get a display name for a particular date/time field, + * in one of several possible display widths. + * + * @param field The desired UDateTimePatternField, such as UDATPG_ERA_FIELD. + * @param width The desired UDateTimePGDisplayWidth, such as UDATPG_ABBREVIATED. + * @return. The display name for field + * @stable ICU 61 + */ + UnicodeString getFieldDisplayName(UDateTimePatternField field, UDateTimePGDisplayWidth width) const; + /** * The DateTimeFormat is a message format pattern used to compose date and * time patterns. The default pattern in the root locale is "{1} {0}", where @@ -268,11 +327,11 @@ class U_I18N_API DateTimePatternGenerator : public UObject { * @return bestPattern * The best pattern found from the given skeleton. * @stable ICU 3.8 - *

    - *

    Sample code

    - * \snippet samples/dtptngsample/dtptngsample.cpp getBestPatternExample1 - * \snippet samples/dtptngsample/dtptngsample.cpp getBestPatternExample - *

    + *

    + *

    Sample code

    + * \snippet samples/dtptngsample/dtptngsample.cpp getBestPatternExample1 + * \snippet samples/dtptngsample/dtptngsample.cpp getBestPatternExample + *

    */ UnicodeString getBestPattern(const UnicodeString& skeleton, UErrorCode& status); @@ -316,14 +375,14 @@ class U_I18N_API DateTimePatternGenerator : public UObject { * which must not indicate a failure before the function call. * @return pattern adjusted to match the skeleton fields widths and subtypes. * @stable ICU 3.8 - *

    - *

    Sample code

    - * \snippet samples/dtptngsample/dtptngsample.cpp getBestPatternExample1 - * \snippet samples/dtptngsample/dtptngsample.cpp replaceFieldTypesExample - *

    - */ - UnicodeString replaceFieldTypes(const UnicodeString& pattern, - const UnicodeString& skeleton, + *

    + *

    Sample code

    + * \snippet samples/dtptngsample/dtptngsample.cpp getBestPatternExample1 + * \snippet samples/dtptngsample/dtptngsample.cpp replaceFieldTypesExample + *

    + */ + UnicodeString replaceFieldTypes(const UnicodeString& pattern, + const UnicodeString& skeleton, UErrorCode& status); /** @@ -348,8 +407,8 @@ class U_I18N_API DateTimePatternGenerator : public UObject { * @return pattern adjusted to match the skeleton fields widths and subtypes. * @stable ICU 4.4 */ - UnicodeString replaceFieldTypes(const UnicodeString& pattern, - const UnicodeString& skeleton, + UnicodeString replaceFieldTypes(const UnicodeString& pattern, + const UnicodeString& skeleton, UDateTimePatternMatchOptions options, UErrorCode& status); @@ -368,12 +427,12 @@ class U_I18N_API DateTimePatternGenerator : public UObject { /** * Get the pattern corresponding to a given skeleton. - * @param skeleton + * @param skeleton * @return pattern corresponding to a given skeleton. * @stable ICU 3.8 */ const UnicodeString& getPatternForSkeleton(const UnicodeString& skeleton) const; - + /** * Return a list of all the base skeletons (in canonical form) from this class. * @@ -387,11 +446,11 @@ class U_I18N_API DateTimePatternGenerator : public UObject { #ifndef U_HIDE_INTERNAL_API /** - * Return a list of redundant patterns are those which if removed, make no - * difference in the resulting getBestPattern values. This method returns a - * list of them, to help check the consistency of the patterns used to build + * Return a list of redundant patterns are those which if removed, make no + * difference in the resulting getBestPattern values. This method returns a + * list of them, to help check the consistency of the patterns used to build * this generator. - * + * * @param status Output param set to success/failure code on exit, * which must not indicate a failure before the function call. * @return a StringEnumeration with the redundant pattern. @@ -409,7 +468,7 @@ class U_I18N_API DateTimePatternGenerator : public UObject { * the decimal string is ",". Then the resulting pattern is modified to be * "H:mm:ss,SSSS" * - * @param decimal + * @param decimal * @stable ICU 3.8 */ void setDecimal(const UnicodeString& decimal); @@ -438,75 +497,97 @@ class U_I18N_API DateTimePatternGenerator : public UObject { private: /** * Constructor. - * @stable ICU 3.8 */ DateTimePatternGenerator(UErrorCode & status); /** * Constructor. - * @stable ICU 3.8 */ - DateTimePatternGenerator(const Locale& locale, UErrorCode & status); + DateTimePatternGenerator(const Locale& locale, UErrorCode & status, UBool skipICUData = FALSE); /** * Copy constructor. * @param other DateTimePatternGenerator to copy - * @stable ICU 3.8 */ DateTimePatternGenerator(const DateTimePatternGenerator& other); /** * Default assignment operator. * @param other DateTimePatternGenerator to copy - * @stable ICU 3.8 */ DateTimePatternGenerator& operator=(const DateTimePatternGenerator& other); + // TODO(ticket:13619): re-enable when UDATPG_NARROW no longer in draft mode. + // static const int32_t UDATPG_WIDTH_COUNT = UDATPG_NARROW + 1; + Locale pLocale; // pattern locale FormatParser *fp; DateTimeMatcher* dtMatcher; DistanceInfo *distanceInfo; PatternMap *patternMap; UnicodeString appendItemFormats[UDATPG_FIELD_COUNT]; - UnicodeString appendItemNames[UDATPG_FIELD_COUNT]; + // TODO(ticket:13619): [3] -> UDATPG_WIDTH_COUNT + UnicodeString fieldDisplayNames[UDATPG_FIELD_COUNT][3]; UnicodeString dateTimeFormat; UnicodeString decimal; DateTimeMatcher *skipMatcher; Hashtable *fAvailableFormatKeyHash; - UnicodeString hackPattern; UnicodeString emptyString; - UChar fDefaultHourFormatChar; - + char16_t fDefaultHourFormatChar; + + int32_t fAllowedHourFormats[7]; // Actually an array of AllowedHourFormat enum type, ending with UNKNOWN. + + // Internal error code used for recording/reporting errors that occur during methods that do not + // have a UErrorCode parameter. For example: the Copy Constructor, or the ::clone() method. + // When this is set to an error the object is in an invalid state. + UErrorCode internalErrorCode; + /* internal flags masks for adjustFieldTypes etc. */ enum { kDTPGNoFlags = 0, kDTPGFixFractionalSeconds = 1, kDTPGSkeletonUsesCapJ = 2 + // with #13183, no longer need flags for b, B }; - void initData(const Locale &locale, UErrorCode &status); - void addCanonicalItems(); + void initData(const Locale &locale, UErrorCode &status, UBool skipICUData = FALSE); + 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); void setDateTimeFromCalendar(const Locale& locale, UErrorCode& status); void setDecimalSymbols(const Locale& locale, UErrorCode& status); UDateTimePatternField getAppendFormatNumber(const char* field) const; - UDateTimePatternField getAppendNameNumber(const char* field) const; +#ifndef U_HIDE_DRAFT_API + // The following three have to be U_HIDE_DRAFT_API (though private) because UDateTimePGDisplayWidth is + UDateTimePatternField getFieldAndWidthIndices(const char* key, UDateTimePGDisplayWidth* widthP) const; + void setFieldDisplayName(UDateTimePatternField field, UDateTimePGDisplayWidth width, const UnicodeString& value); + UnicodeString& getMutableFieldDisplayName(UDateTimePatternField field, UDateTimePGDisplayWidth width); +#endif // U_HIDE_DRAFT_API void getAppendName(UDateTimePatternField field, UnicodeString& value); + UnicodeString mapSkeletonMetacharacters(const UnicodeString& patternForm, int32_t* flags, UDateTimePatternMatchOptions options, UErrorCode& status); int32_t getCanonicalIndex(const UnicodeString& field); - const UnicodeString* getBestRaw(DateTimeMatcher& source, int32_t includeMask, DistanceInfo* missingFields, const PtnSkeleton** specifiedSkeletonPtr = 0); + const UnicodeString* getBestRaw(DateTimeMatcher& source, int32_t includeMask, DistanceInfo* missingFields, UErrorCode& status, const PtnSkeleton** specifiedSkeletonPtr = 0); UnicodeString adjustFieldTypes(const UnicodeString& pattern, const PtnSkeleton* specifiedSkeleton, int32_t flags, UDateTimePatternMatchOptions options = UDATPG_MATCH_NO_OPTIONS); - UnicodeString getBestAppending(int32_t missingFields, int32_t flags, UDateTimePatternMatchOptions options = UDATPG_MATCH_NO_OPTIONS); - int32_t getTopBitNumber(int32_t foundMask); + UnicodeString getBestAppending(int32_t missingFields, int32_t flags, UErrorCode& status, UDateTimePatternMatchOptions options = UDATPG_MATCH_NO_OPTIONS); + int32_t getTopBitNumber(int32_t foundMask) const; void setAvailableFormat(const UnicodeString &key, UErrorCode& status); UBool isAvailableFormatSet(const UnicodeString &key) const; void copyHashtable(Hashtable *other, UErrorCode &status); UBool isCanonicalItem(const UnicodeString& item) const; + 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 +#endif // U_SHOW_CPLUSPLUS_API #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtrule.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtrule.h index cb526a152c..3a1f5d6040 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtrule.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/dtrule.h @@ -1,3 +1,5 @@ +// © 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 * @@ -18,6 +20,7 @@ #include "unicode/uobject.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** * DateTimeRule is a class representing a time in a year by @@ -243,6 +246,7 @@ class U_I18N_API DateTimeRule : public UObject { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/edits.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/edits.h new file mode 100644 index 0000000000..14ee94db28 --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/edits.h @@ -0,0 +1,528 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +// edits.h +// created: 2016dec30 Markus W. Scherer + +#ifndef __EDITS_H__ +#define __EDITS_H__ + +#include "unicode/utypes.h" +#include "unicode/uobject.h" + +/** + * \file + * \brief C++ API: C++ class Edits for low-level string transformations on styled text. + */ + +#if U_SHOW_CPLUSPLUS_API +U_NAMESPACE_BEGIN + +class UnicodeString; + +/** + * Records lengths of string edits but not replacement text. Supports replacements, insertions, deletions + * in linear progression. Does not support moving/reordering of text. + * + * There are two types of edits: change edits and no-change edits. Add edits to + * instances of this class using {@link #addReplace(int32_t, int32_t)} (for change edits) and + * {@link #addUnchanged(int32_t)} (for no-change edits). Change edits are retained with full granularity, + * whereas adjacent no-change edits are always merged together. In no-change edits, there is a one-to-one + * mapping between code points in the source and destination strings. + * + * After all edits have been added, instances of this class should be considered immutable, and an + * {@link Edits::Iterator} can be used for queries. + * + * There are four flavors of Edits::Iterator: + * + *

      + *
    • {@link #getFineIterator()} retains full granularity of change edits. + *
    • {@link #getFineChangesIterator()} retains full granularity of change edits, and when calling + * next() on the iterator, skips over no-change edits (unchanged regions). + *
    • {@link #getCoarseIterator()} treats adjacent change edits as a single edit. (Adjacent no-change + * edits are automatically merged during the construction phase.) + *
    • {@link #getCoarseChangesIterator()} treats adjacent change edits as a single edit, and when + * calling next() on the iterator, skips over no-change edits (unchanged regions). + *
    + * + * For example, consider the string "abcßDeF", which case-folds to "abcssdef". This string has the + * following fine edits: + *
      + *
    • abc ⇨ abc (no-change) + *
    • ß ⇨ ss (change) + *
    • D ⇨ d (change) + *
    • e ⇨ e (no-change) + *
    • F ⇨ f (change) + *
    + * and the following coarse edits (note how adjacent change edits get merged together): + *
      + *
    • abc ⇨ abc (no-change) + *
    • ßD ⇨ ssd (change) + *
    • e ⇨ e (no-change) + *
    • F ⇨ f (change) + *
    + * + * The "fine changes" and "coarse changes" iterators will step through only the change edits when their + * `Edits::Iterator::next()` methods are called. They are identical to the non-change iterators when + * their `Edits::Iterator::findSourceIndex()` or `Edits::Iterator::findDestinationIndex()` + * methods are used to walk through the string. + * + * For examples of how to use this class, see the test `TestCaseMapEditsIteratorDocs` in + * UCharacterCaseTest.java. + * + * An Edits object tracks a separate UErrorCode, but ICU string transformation functions + * (e.g., case mapping functions) merge any such errors into their API's UErrorCode. + * + * @stable ICU 59 + */ +class U_COMMON_API Edits U_FINAL : public UMemory { +public: + /** + * Constructs an empty object. + * @stable ICU 59 + */ + Edits() : + array(stackArray), capacity(STACK_CAPACITY), length(0), delta(0), numChanges(0), + errorCode_(U_ZERO_ERROR) {} + /** + * Copy constructor. + * @param other source edits + * @stable ICU 60 + */ + Edits(const Edits &other) : + array(stackArray), capacity(STACK_CAPACITY), length(other.length), + delta(other.delta), numChanges(other.numChanges), + errorCode_(other.errorCode_) { + copyArray(other); + } + /** + * Move constructor, might leave src empty. + * This object will have the same contents that the source object had. + * @param src source edits + * @stable ICU 60 + */ + Edits(Edits &&src) U_NOEXCEPT : + array(stackArray), capacity(STACK_CAPACITY), length(src.length), + delta(src.delta), numChanges(src.numChanges), + errorCode_(src.errorCode_) { + moveArray(src); + } + + /** + * Destructor. + * @stable ICU 59 + */ + ~Edits(); + + /** + * Assignment operator. + * @param other source edits + * @return *this + * @stable ICU 60 + */ + Edits &operator=(const Edits &other); + + /** + * Move assignment operator, might leave src empty. + * This object will have the same contents that the source object had. + * The behavior is undefined if *this and src are the same object. + * @param src source edits + * @return *this + * @stable ICU 60 + */ + Edits &operator=(Edits &&src) U_NOEXCEPT; + + /** + * Resets the data but may not release memory. + * @stable ICU 59 + */ + void reset() U_NOEXCEPT; + + /** + * Adds a no-change edit: a record for an unchanged segment of text. + * Normally called from inside ICU string transformation functions, not user code. + * @stable ICU 59 + */ + void addUnchanged(int32_t unchangedLength); + /** + * Adds a change edit: a record for a text replacement/insertion/deletion. + * Normally called from inside ICU string transformation functions, not user code. + * @stable ICU 59 + */ + void addReplace(int32_t oldLength, int32_t newLength); + /** + * Sets the UErrorCode if an error occurred while recording edits. + * Preserves older error codes in the outErrorCode. + * Normally called from inside ICU string transformation functions, not user code. + * @param outErrorCode Set to an error code if it does not contain one already + * and an error occurred while recording edits. + * Otherwise unchanged. + * @return TRUE if U_FAILURE(outErrorCode) + * @stable ICU 59 + */ + UBool copyErrorTo(UErrorCode &outErrorCode); + + /** + * How much longer is the new text compared with the old text? + * @return new length minus old length + * @stable ICU 59 + */ + int32_t lengthDelta() const { return delta; } + /** + * @return TRUE if there are any change edits + * @stable ICU 59 + */ + UBool hasChanges() const { return numChanges != 0; } + + /** + * @return the number of change edits + * @stable ICU 60 + */ + int32_t numberOfChanges() const { return numChanges; } + + /** + * Access to the list of edits. + * + * At any moment in time, an instance of this class points to a single edit: a "window" into a span + * of the source string and the corresponding span of the destination string. The source string span + * starts at {@link #sourceIndex()} and runs for {@link #oldLength()} chars; the destination string + * span starts at {@link #destinationIndex()} and runs for {@link #newLength()} chars. + * + * The iterator can be moved between edits using the `next()`, `findSourceIndex(int32_t, UErrorCode &)`, + * and `findDestinationIndex(int32_t, UErrorCode &)` methods. + * Calling any of these methods mutates the iterator to make it point to the corresponding edit. + * + * For more information, see the documentation for {@link Edits}. + * + * @see getCoarseIterator + * @see getFineIterator + * @stable ICU 59 + */ + struct U_COMMON_API Iterator U_FINAL : public UMemory { + /** + * Default constructor, empty iterator. + * @stable ICU 60 + */ + Iterator() : + array(nullptr), index(0), length(0), + remaining(0), onlyChanges_(FALSE), coarse(FALSE), + dir(0), changed(FALSE), oldLength_(0), newLength_(0), + srcIndex(0), replIndex(0), destIndex(0) {} + /** + * Copy constructor. + * @stable ICU 59 + */ + Iterator(const Iterator &other) = default; + /** + * Assignment operator. + * @stable ICU 59 + */ + Iterator &operator=(const Iterator &other) = default; + + /** + * Advances the iterator to the next edit. + * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test, + * or else the function returns immediately. Check for U_FAILURE() + * on output or use with function chaining. (See User Guide for details.) + * @return TRUE if there is another edit + * @stable ICU 59 + */ + UBool next(UErrorCode &errorCode) { return next(onlyChanges_, errorCode); } + + /** + * Moves the iterator to the edit that contains the source index. + * The source index may be found in a no-change edit + * even if normal iteration would skip no-change edits. + * Normal iteration can continue from a found edit. + * + * The iterator state before this search logically does not matter. + * (It may affect the performance of the search.) + * + * The iterator state after this search is undefined + * if the source index is out of bounds for the source string. + * + * @param i source index + * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test, + * or else the function returns immediately. Check for U_FAILURE() + * on output or use with function chaining. (See User Guide for details.) + * @return TRUE if the edit for the source index was found + * @stable ICU 59 + */ + UBool findSourceIndex(int32_t i, UErrorCode &errorCode) { + return findIndex(i, TRUE, errorCode) == 0; + } + + /** + * Moves the iterator to the edit that contains the destination index. + * The destination index may be found in a no-change edit + * even if normal iteration would skip no-change edits. + * Normal iteration can continue from a found edit. + * + * The iterator state before this search logically does not matter. + * (It may affect the performance of the search.) + * + * The iterator state after this search is undefined + * if the source index is out of bounds for the source string. + * + * @param i destination index + * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test, + * or else the function returns immediately. Check for U_FAILURE() + * on output or use with function chaining. (See User Guide for details.) + * @return TRUE if the edit for the destination index was found + * @stable ICU 60 + */ + UBool findDestinationIndex(int32_t i, UErrorCode &errorCode) { + return findIndex(i, FALSE, errorCode) == 0; + } + + /** + * Computes the destination index corresponding to the given source index. + * If the source index is inside a change edit (not at its start), + * then the destination index at the end of that edit is returned, + * since there is no information about index mapping inside a change edit. + * + * (This means that indexes to the start and middle of an edit, + * for example around a grapheme cluster, are mapped to indexes + * encompassing the entire edit. + * The alternative, mapping an interior index to the start, + * would map such an interval to an empty one.) + * + * This operation will usually but not always modify this object. + * The iterator state after this search is undefined. + * + * @param i source index + * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test, + * or else the function returns immediately. Check for U_FAILURE() + * on output or use with function chaining. (See User Guide for details.) + * @return destination index; undefined if i is not 0..string length + * @stable ICU 60 + */ + int32_t destinationIndexFromSourceIndex(int32_t i, UErrorCode &errorCode); + + /** + * Computes the source index corresponding to the given destination index. + * If the destination index is inside a change edit (not at its start), + * then the source index at the end of that edit is returned, + * since there is no information about index mapping inside a change edit. + * + * (This means that indexes to the start and middle of an edit, + * for example around a grapheme cluster, are mapped to indexes + * encompassing the entire edit. + * The alternative, mapping an interior index to the start, + * would map such an interval to an empty one.) + * + * This operation will usually but not always modify this object. + * The iterator state after this search is undefined. + * + * @param i destination index + * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test, + * or else the function returns immediately. Check for U_FAILURE() + * on output or use with function chaining. (See User Guide for details.) + * @return source index; undefined if i is not 0..string length + * @stable ICU 60 + */ + int32_t sourceIndexFromDestinationIndex(int32_t i, UErrorCode &errorCode); + + /** + * Returns whether the edit currently represented by the iterator is a change edit. + * + * @return TRUE if this edit replaces oldLength() units with newLength() different ones. + * FALSE if oldLength units remain unchanged. + * @stable ICU 59 + */ + UBool hasChange() const { return changed; } + + /** + * The length of the current span in the source string, which starts at {@link #sourceIndex}. + * + * @return the number of units in the original string which are replaced or remain unchanged. + * @stable ICU 59 + */ + int32_t oldLength() const { return oldLength_; } + + /** + * The length of the current span in the destination string, which starts at + * {@link #destinationIndex}, or in the replacement string, which starts at + * {@link #replacementIndex}. + * + * @return the number of units in the modified string, if hasChange() is TRUE. + * Same as oldLength if hasChange() is FALSE. + * @stable ICU 59 + */ + int32_t newLength() const { return newLength_; } + + /** + * The start index of the current span in the source string; the span has length + * {@link #oldLength}. + * + * @return the current index into the source string + * @stable ICU 59 + */ + int32_t sourceIndex() const { return srcIndex; } + + /** + * The start index of the current span in the replacement string; the span has length + * {@link #newLength}. Well-defined only if the current edit is a change edit. + * + * The *replacement string* is the concatenation of all substrings of the destination + * string corresponding to change edits. + * + * This method is intended to be used together with operations that write only replacement + * characters (e.g. operations specifying the \ref U_OMIT_UNCHANGED_TEXT option). + * The source string can then be modified in-place. + * + * @return the current index into the replacement-characters-only string, + * not counting unchanged spans + * @stable ICU 59 + */ + int32_t replacementIndex() const { + // TODO: Throw an exception if we aren't in a change edit? + return replIndex; + } + + /** + * The start index of the current span in the destination string; the span has length + * {@link #newLength}. + * + * @return the current index into the full destination string + * @stable ICU 59 + */ + int32_t destinationIndex() const { return destIndex; } + +#ifndef U_HIDE_INTERNAL_API + /** + * A string representation of the current edit represented by the iterator for debugging. You + * should not depend on the contents of the return string. + * @internal + */ + UnicodeString& toString(UnicodeString& appendTo) const; +#endif // U_HIDE_INTERNAL_API + + private: + friend class Edits; + + Iterator(const uint16_t *a, int32_t len, UBool oc, UBool crs); + + int32_t readLength(int32_t head); + void updateNextIndexes(); + void updatePreviousIndexes(); + UBool noNext(); + UBool next(UBool onlyChanges, UErrorCode &errorCode); + UBool previous(UErrorCode &errorCode); + /** @return -1: error or i<0; 0: found; 1: i>=string length */ + int32_t findIndex(int32_t i, UBool findSource, UErrorCode &errorCode); + + const uint16_t *array; + int32_t index, length; + // 0 if we are not within compressed equal-length changes. + // Otherwise the number of remaining changes, including the current one. + int32_t remaining; + UBool onlyChanges_, coarse; + + int8_t dir; // iteration direction: back(<0), initial(0), forward(>0) + UBool changed; + int32_t oldLength_, newLength_; + int32_t srcIndex, replIndex, destIndex; + }; + + /** + * Returns an Iterator for coarse-grained change edits + * (adjacent change edits are treated as one). + * Can be used to perform simple string updates. + * Skips no-change edits. + * @return an Iterator that merges adjacent changes. + * @stable ICU 59 + */ + Iterator getCoarseChangesIterator() const { + return Iterator(array, length, TRUE, TRUE); + } + + /** + * Returns an Iterator for coarse-grained change and no-change edits + * (adjacent change edits are treated as one). + * Can be used to perform simple string updates. + * Adjacent change edits are treated as one edit. + * @return an Iterator that merges adjacent changes. + * @stable ICU 59 + */ + Iterator getCoarseIterator() const { + return Iterator(array, length, FALSE, TRUE); + } + + /** + * Returns an Iterator for fine-grained change edits + * (full granularity of change edits is retained). + * Can be used for modifying styled text. + * Skips no-change edits. + * @return an Iterator that separates adjacent changes. + * @stable ICU 59 + */ + Iterator getFineChangesIterator() const { + return Iterator(array, length, TRUE, FALSE); + } + + /** + * Returns an Iterator for fine-grained change and no-change edits + * (full granularity of change edits is retained). + * Can be used for modifying styled text. + * @return an Iterator that separates adjacent changes. + * @stable ICU 59 + */ + Iterator getFineIterator() const { + return Iterator(array, length, FALSE, FALSE); + } + + /** + * Merges the two input Edits and appends the result to this object. + * + * Consider two string transformations (for example, normalization and case mapping) + * where each records Edits in addition to writing an output string.
    + * Edits ab reflect how substrings of input string a + * map to substrings of intermediate string b.
    + * Edits bc reflect how substrings of intermediate string b + * map to substrings of output string c.
    + * This function merges ab and bc such that the additional edits + * recorded in this object reflect how substrings of input string a + * map to substrings of output string c. + * + * If unrelated Edits are passed in where the output string of the first + * has a different length than the input string of the second, + * then a U_ILLEGAL_ARGUMENT_ERROR is reported. + * + * @param ab reflects how substrings of input string a + * map to substrings of intermediate string b. + * @param bc reflects how substrings of intermediate string b + * map to substrings of output string c. + * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test, + * or else the function returns immediately. Check for U_FAILURE() + * on output or use with function chaining. (See User Guide for details.) + * @return *this, with the merged edits appended + * @stable ICU 60 + */ + Edits &mergeAndAppend(const Edits &ab, const Edits &bc, UErrorCode &errorCode); + +private: + void releaseArray() U_NOEXCEPT; + Edits ©Array(const Edits &other); + Edits &moveArray(Edits &src) U_NOEXCEPT; + + void setLastUnit(int32_t last) { array[length - 1] = (uint16_t)last; } + int32_t lastUnit() const { return length > 0 ? array[length - 1] : 0xffff; } + + void append(int32_t r); + UBool growArray(); + + static const int32_t STACK_CAPACITY = 100; + uint16_t *array; + int32_t capacity; + int32_t length; + int32_t delta; + int32_t numChanges; + UErrorCode errorCode_; + uint16_t stackArray[STACK_CAPACITY]; +}; + +U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API + +#endif // __EDITS_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/enumset.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/enumset.h index 5106c37177..bde8c455c0 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/enumset.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/enumset.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * @@ -26,6 +28,7 @@ U_NAMESPACE_BEGIN * enum bitset for boolean fields. Similar to Java EnumSet<>. * Needs to range check. Used for private instance variables. * @internal + * \cond */ template class EnumSet { @@ -58,6 +61,8 @@ class EnumSet { uint32_t fBools; }; +/** \endcond */ + U_NAMESPACE_END #endif /* U_SHOW_CPLUSPLUS_API */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/errorcode.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/errorcode.h index 3b601810d7..f0113d966d 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/errorcode.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/errorcode.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -6,7 +8,7 @@ * ******************************************************************************* * file name: errorcode.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -26,6 +28,7 @@ #include "unicode/utypes.h" #include "unicode/uobject.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -133,5 +136,6 @@ class U_COMMON_API ErrorCode: public UMemory { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // __ERRORCODE_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/fieldpos.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/fieldpos.h index 38a9576e78..139873c318 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/fieldpos.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/fieldpos.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 1997-2006, International Business Machines @@ -33,6 +35,7 @@ #include "unicode/uobject.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -56,7 +59,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. * *

    * Below is an example of using FieldPosition to aid @@ -107,7 +110,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 }; @@ -284,6 +288,7 @@ FieldPosition::operator!=(const FieldPosition& copy) const } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/filteredbrk.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/filteredbrk.h index acf2df7d30..b057b75b6a 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/filteredbrk.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/filteredbrk.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 1997-2015, International Business Machines @@ -12,8 +14,8 @@ #include "unicode/brkiter.h" #if !UCONFIG_NO_BREAK_ITERATION && !UCONFIG_NO_FILTERED_BREAK_ITERATION -#ifndef U_HIDE_INTERNAL_API +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -30,27 +32,13 @@ U_NAMESPACE_BEGIN * but with "Mr." as an exception, a filtered break iterator * would consider the string "Mr. Smith" to be a single segment. * - *

    Note: An instance of {@link BreakIterator} returned by this builder - * class currently does not support following operations in this technology preview - * version: - *

      - *
    • {@link BreakIterator#next(int32_t) next(int32_t n)}
    • - *
    • {@link BreakIterator#previous(void) previous(void)}
    • - *
    • {@link BreakIterator#following(int32_t) following(int32_t offset)}
    • - *
    • {@link BreakIterator#preceding(int32_t) preceding(int32_t offset)}
    • - *
    - * When one of above methods is called, the corresponding method of the adopted - * BreakIterator will be invoked (i.e. no segment suppressions will be used). - * Note: This fallback behavior undoes r36410 in which these methods were changed - * to just return BreakIterator.DONE immediately without updating the internal state. - * - * @internal technology preview + * @stable ICU 56 */ class U_COMMON_API FilteredBreakIteratorBuilder : public UObject { public: /** * destructor. - * @internal technology preview + * @stable ICU 56 */ virtual ~FilteredBreakIteratorBuilder(); @@ -64,18 +52,30 @@ class U_COMMON_API FilteredBreakIteratorBuilder : public UObject { * @param where the locale. * @param status The error code. * @return the new builder - * @internal technology preview + * @stable ICU 56 */ static FilteredBreakIteratorBuilder *createInstance(const Locale& where, UErrorCode& status); +#ifndef U_HIDE_DEPRECATED_API + /** + * This function has been deprecated in favor of createEmptyInstance, which has + * identical behavior. + * @param status The error code. + * @return the new builder + * @deprecated ICU 60 use createEmptyInstance instead + * @see createEmptyInstance() + */ + static FilteredBreakIteratorBuilder *createInstance(UErrorCode &status); +#endif /* U_HIDE_DEPRECATED_API */ + /** * Construct an empty FilteredBreakIteratorBuilder. * In this state, it will not suppress any segment boundaries. * @param status The error code. * @return the new builder - * @internal technology preview + * @stable ICU 60 */ - static FilteredBreakIteratorBuilder *createInstance(UErrorCode &status); + static FilteredBreakIteratorBuilder *createEmptyInstance(UErrorCode &status); /** * Suppress a certain string from being the end of a segment. @@ -85,7 +85,7 @@ class U_COMMON_API FilteredBreakIteratorBuilder : public UObject { * @param status error code * @return returns TRUE if the string was not present and now added, * FALSE if the call was a no-op because the string was already being suppressed. - * @internal technology preview + * @stable ICU 56 */ virtual UBool suppressBreakAfter(const UnicodeString& string, UErrorCode& status) = 0; @@ -94,14 +94,25 @@ class U_COMMON_API FilteredBreakIteratorBuilder : public UObject { * This function does not create any new segment boundaries, but only serves to un-do * the effect of earlier calls to suppressBreakAfter, or to un-do the effect of * locale data which may be suppressing certain strings. - * @param exception the exception to remove + * @param string the exception to remove * @param status error code * @return returns TRUE if the string was present and now removed, * FALSE if the call was a no-op because the string was not being suppressed. - * @internal technology preview + * @stable ICU 56 */ virtual UBool unsuppressBreakAfter(const UnicodeString& string, UErrorCode& status) = 0; + /** + * This function has been deprecated in favor of wrapIteratorWithFilter() + * The behavior is identical. + * @param adoptBreakIterator the break iterator to adopt + * @param status error code + * @return the new BreakIterator, owned by the caller. + * @deprecated ICU 60 use wrapIteratorWithFilter() instead + * @see wrapBreakIteratorWithFilter() + */ + virtual BreakIterator *build(BreakIterator* adoptBreakIterator, UErrorCode& status) = 0; + /** * Wrap (adopt) an existing break iterator in a new filtered instance. * The resulting BreakIterator is owned by the caller. @@ -109,25 +120,28 @@ class U_COMMON_API FilteredBreakIteratorBuilder : public UObject { * Note that the adoptBreakIterator is adopted by the new BreakIterator * and should no longer be used by the caller. * The FilteredBreakIteratorBuilder may be reused. + * This function is an alias for build() * @param adoptBreakIterator the break iterator to adopt * @param status error code * @return the new BreakIterator, owned by the caller. - * @internal technology preview + * @stable ICU 60 */ - virtual BreakIterator *build(BreakIterator* adoptBreakIterator, UErrorCode& status) = 0; + inline BreakIterator *wrapIteratorWithFilter(BreakIterator* adoptBreakIterator, UErrorCode& status) { + return build(adoptBreakIterator, status); + } protected: /** * For subclass use - * @internal technology preview + * @stable ICU 56 */ FilteredBreakIteratorBuilder(); }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API -#endif /* U_HIDE_INTERNAL_API */ #endif // #if !UCONFIG_NO_BREAK_ITERATION && !UCONFIG_NO_FILTERED_BREAK_ITERATION #endif // #ifndef FILTEREDBRK_H diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/fmtable.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/fmtable.h index 6cad276f42..e825cb693c 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/fmtable.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/fmtable.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 1997-2014, International Business Machines @@ -28,20 +30,15 @@ #include "unicode/stringpiece.h" #include "unicode/uformattable.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class CharString; -class DigitList; - -/** - * \def UNUM_INTERNAL_STACKARRAY_SIZE - * @internal - */ -#if U_PLATFORM == U_PF_OS400 -#define UNUM_INTERNAL_STACKARRAY_SIZE 144 -#else -#define UNUM_INTERNAL_STACKARRAY_SIZE 128 -#endif +namespace number { +namespace impl { +class DecimalQuantity; +} +} /** * Formattable objects can be passed to the Format class or @@ -134,7 +131,7 @@ class U_I18N_API Formattable : public UObject { * 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 +578,7 @@ class U_I18N_API Formattable : public UObject { * incoming string is not a valid decimal number. * @stable ICU 4.4 */ - void setDecimalNumber(const StringPiece &numberString, + void setDecimalNumber(StringPiece numberString, UErrorCode &status); /** @@ -647,24 +644,25 @@ class U_I18N_API Formattable : public UObject { * Internal function, do not use. * TODO: figure out how to make this be non-public. * NumberFormat::format(Formattable, ... - * needs to get at the DigitList, if it exists, for + * needs to get at the DecimalQuantity, if it exists, for * big decimal formatting. * @internal */ - DigitList *getDigitList() const { return fDecimalNum;} + number::impl::DecimalQuantity *getDecimalQuantity() const { return fDecimalQuantity;} /** - * @internal + * Export the value of this Formattable to a DecimalQuantity. + * @internal */ - DigitList *getInternalDigitList(); + void populateDecimalQuantity(number::impl::DecimalQuantity& output, UErrorCode& status) const; /** - * Adopt, and set value from, a DigitList + * Adopt, and set value from, a DecimalQuantity * Internal Function, do not use. - * @param dl the Digit List to be adopted + * @param dq the DecimalQuantity to be adopted * @internal */ - void adoptDigitList(DigitList *dl); + void adoptDecimalQuantity(number::impl::DecimalQuantity *dq); /** * Internal function to return the CharString pointer. @@ -704,9 +702,7 @@ class U_I18N_API Formattable : public UObject { CharString *fDecimalStr; - DigitList *fDecimalNum; - - char fStackData[UNUM_INTERNAL_STACKARRAY_SIZE]; // must be big enough for DigitList + number::impl::DecimalQuantity *fDecimalQuantity; Type fType; UnicodeString fBogus; // Bogus string when it's needed. @@ -753,6 +749,7 @@ inline const Formattable* Formattable::fromUFormattable(const UFormattable *fmt) } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/format.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/format.h index cb8ea61f76..67fa5d9689 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/format.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/format.h @@ -1,3 +1,5 @@ +// © 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. @@ -39,6 +41,7 @@ #include "unicode/parseerr.h" #include "unicode/locid.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -298,6 +301,7 @@ class U_I18N_API Format : public UObject { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/formattedvalue.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/formattedvalue.h new file mode 100644 index 0000000000..733bc1b2af --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/formattedvalue.h @@ -0,0 +1,319 @@ +// © 2018 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#ifndef __FORMATTEDVALUE_H__ +#define __FORMATTEDVALUE_H__ + +#include "unicode/utypes.h" +#if !UCONFIG_NO_FORMATTING +#ifndef U_HIDE_DRAFT_API + +#include "unicode/appendable.h" +#include "unicode/fpositer.h" +#include "unicode/unistr.h" +#include "unicode/uformattedvalue.h" + +#if U_SHOW_CPLUSPLUS_API +U_NAMESPACE_BEGIN + +/** + * \file + * \brief C++ API: Abstract operations for localized strings. + * + * This file contains declarations for classes that deal with formatted strings. A number + * of APIs throughout ICU use these classes for expressing their localized output. + */ + + +/** + * Represents a span of a string containing a given field. + * + * This class differs from FieldPosition in the following ways: + * + * 1. It has information on the field category. + * 2. It allows you to set constraints to use when iterating over field positions. + * 3. It is used for the newer FormattedValue APIs. + * + * This class is not intended for public subclassing. + * + * @draft ICU 64 + */ +class U_I18N_API ConstrainedFieldPosition : public UMemory { + public: + + /** + * Initializes a ConstrainedFieldPosition. + * + * By default, the ConstrainedFieldPosition has no iteration constraints. + * + * @draft ICU 64 + */ + ConstrainedFieldPosition(); + + /** @draft ICU 64 */ + ~ConstrainedFieldPosition(); + + /** + * Resets this ConstrainedFieldPosition to its initial state, as if it were newly created: + * + * - Removes any constraints that may have been set on the instance. + * - Resets the iteration position. + * + * @draft ICU 64 + */ + void reset(); + + /** + * Sets a constraint on the field category. + * + * When this instance of ConstrainedFieldPosition is passed to FormattedValue#nextPosition, + * positions are skipped unless they have the given category. + * + * Any previously set constraints are cleared. + * + * For example, to loop over only the number-related fields: + * + * ConstrainedFieldPosition cfpos; + * cfpos.constrainCategory(UFIELDCATEGORY_NUMBER_FORMAT); + * while (fmtval.nextPosition(cfpos, status)) { + * // handle the number-related field position + * } + * + * Changing the constraint while in the middle of iterating over a FormattedValue + * does not generally have well-defined behavior. + * + * @param category The field category to fix when iterating. + * @draft ICU 64 + */ + void constrainCategory(int32_t category); + + /** + * Sets a constraint on the category and field. + * + * When this instance of ConstrainedFieldPosition is passed to FormattedValue#nextPosition, + * positions are skipped unless they have the given category and field. + * + * Any previously set constraints are cleared. + * + * For example, to loop over all grouping separators: + * + * ConstrainedFieldPosition cfpos; + * cfpos.constrainField(UFIELDCATEGORY_NUMBER_FORMAT, UNUM_GROUPING_SEPARATOR_FIELD); + * while (fmtval.nextPosition(cfpos, status)) { + * // handle the grouping separator position + * } + * + * Changing the constraint while in the middle of iterating over a FormattedValue + * does not generally have well-defined behavior. + * + * @param category The field category to fix when iterating. + * @param field The field to fix when iterating. + * @draft ICU 64 + */ + void constrainField(int32_t category, int32_t field); + + /** + * Gets the field category for the current position. + * + * The return value is well-defined only after + * FormattedValue#nextPosition returns TRUE. + * + * @return The field category saved in the instance. + * @draft ICU 64 + */ + inline int32_t getCategory() const { + return fCategory; + } + + /** + * Gets the field for the current position. + * + * The return value is well-defined only after + * FormattedValue#nextPosition returns TRUE. + * + * @return The field saved in the instance. + * @draft ICU 64 + */ + inline int32_t getField() const { + return fField; + } + + /** + * Gets the INCLUSIVE start index for the current position. + * + * The return value is well-defined only after FormattedValue#nextPosition returns TRUE. + * + * @return The start index saved in the instance. + * @draft ICU 64 + */ + inline int32_t getStart() const { + return fStart; + } + + /** + * Gets the EXCLUSIVE end index stored for the current position. + * + * The return value is well-defined only after FormattedValue#nextPosition returns TRUE. + * + * @return The end index saved in the instance. + * @draft ICU 64 + */ + inline int32_t getLimit() const { + return fLimit; + } + + //////////////////////////////////////////////////////////////////// + //// The following methods are for FormattedValue implementers; //// + //// most users can ignore them. //// + //////////////////////////////////////////////////////////////////// + + /** + * Gets an int64 that FormattedValue implementations may use for storage. + * + * The initial value is zero. + * + * Users of FormattedValue should not need to call this method. + * + * @return The current iteration context from {@link #setInt64IterationContext}. + * @draft ICU 64 + */ + inline int64_t getInt64IterationContext() const { + return fContext; + } + + /** + * Sets an int64 that FormattedValue implementations may use for storage. + * + * Intended to be used by FormattedValue implementations. + * + * @param context The new iteration context. + * @draft ICU 64 + */ + void setInt64IterationContext(int64_t context); + + /** + * Determines whether a given field should be included given the + * constraints. + * + * Intended to be used by FormattedValue implementations. + * + * @param category The category to test. + * @param field The field to test. + * @draft ICU 64 + */ + UBool matchesField(int32_t category, int32_t field) const; + + /** + * Sets new values for the primary public getters. + * + * Intended to be used by FormattedValue implementations. + * + * It is up to the implementation to ensure that the user-requested + * constraints are satisfied. This method does not check! + * + * @param category The new field category. + * @param field The new field. + * @param start The new inclusive start index. + * @param limit The new exclusive end index. + * @draft ICU 64 + */ + void setState( + int32_t category, + int32_t field, + int32_t start, + int32_t limit); + + private: + int64_t fContext = 0LL; + int32_t fField = 0; + int32_t fStart = 0; + int32_t fLimit = 0; + int32_t fCategory = UFIELD_CATEGORY_UNDEFINED; + int8_t fConstraint = 0; +}; + + +/** + * An abstract formatted value: a string with associated field attributes. + * Many formatters format to classes implementing FormattedValue. + * + * @draft ICU 64 + */ +class U_I18N_API FormattedValue /* not : public UObject because this is an interface/mixin class */ { + public: + /** @draft ICU 64 */ + virtual ~FormattedValue(); + + /** + * Returns the formatted string as a self-contained UnicodeString. + * + * If you need the string within the current scope only, consider #toTempString. + * + * @param status Set if an error occurs. + * @return a UnicodeString containing the formatted string. + * + * @draft ICU 64 + */ + virtual UnicodeString toString(UErrorCode& status) const = 0; + + /** + * Returns the formatted string as a read-only alias to memory owned by the FormattedValue. + * + * The return value is valid only as long as this FormattedValue is present and unchanged in + * memory. If you need the string outside the current scope, consider #toString. + * + * The buffer returned by calling UnicodeString#getBuffer() on the return value is + * guaranteed to be NUL-terminated. + * + * @param status Set if an error occurs. + * @return a temporary UnicodeString containing the formatted string. + * + * @draft ICU 64 + */ + virtual UnicodeString toTempString(UErrorCode& status) const = 0; + + /** + * Appends the formatted string to an Appendable. + * + * @param appendable + * The Appendable to which to append the string output. + * @param status Set if an error occurs. + * @return The same Appendable, for chaining. + * + * @draft ICU 64 + * @see Appendable + */ + virtual Appendable& appendTo(Appendable& appendable, UErrorCode& status) const = 0; + + /** + * Iterates over field positions in the FormattedValue. This lets you determine the position + * of specific types of substrings, like a month or a decimal separator. + * + * To loop over all field positions: + * + * ConstrainedFieldPosition cfpos; + * while (fmtval.nextPosition(cfpos, status)) { + * // handle the field position; get information from cfpos + * } + * + * @param cfpos + * The object used for iteration state. This can provide constraints to iterate over + * only one specific category or field; + * see ConstrainedFieldPosition#constrainCategory + * and ConstrainedFieldPosition#constrainField. + * @param status Set if an error occurs. + * @return TRUE if a new occurrence of the field was found; + * FALSE otherwise or if an error was set. + * + * @draft ICU 64 + */ + virtual UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const = 0; +}; + + +U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API + +#endif /* U_HIDE_DRAFT_API */ +#endif /* #if !UCONFIG_NO_FORMATTING */ +#endif // __FORMATTEDVALUE_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/fpositer.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/fpositer.h index b842161a69..5be78b007d 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/fpositer.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/fpositer.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2010-2012, International Business Machines @@ -26,6 +28,7 @@ #if UCONFIG_NO_FORMATTING +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /* @@ -35,12 +38,14 @@ U_NAMESPACE_BEGIN class FieldPositionIterator; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #else #include "unicode/fieldpos.h" #include "unicode/umisc.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class UVector32; @@ -97,8 +102,6 @@ class U_I18N_API FieldPositionIterator : public UObject { UBool next(FieldPosition& fp); private: - friend class FieldPositionIteratorHandler; - /** * Sets the data used by the iterator, and resets the position. * Returns U_ILLEGAL_ARGUMENT_ERROR in status if the data is not valid @@ -106,11 +109,14 @@ class U_I18N_API FieldPositionIterator : public UObject { */ void setData(UVector32 *adopt, UErrorCode& status); + friend class FieldPositionIteratorHandler; + UVector32 *data; int32_t pos; }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/gender.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/gender.h index 1a6ae8fe6c..dd103fbd54 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/gender.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/gender.h @@ -1,3 +1,5 @@ +// © 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 @@ -16,6 +18,11 @@ #ifndef _GENDER #define _GENDER +/** + * \file + * \brief C++ API: GenderInfo computes the gender of a list. + */ + #include "unicode/utypes.h" #if !UCONFIG_NO_FORMATTING @@ -26,9 +33,10 @@ class GenderInfoTest; +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN -// Forward Declaration +/** \internal Forward Declaration */ void U_CALLCONV GenderInfo_initCache(UErrorCode &status); /** @@ -104,6 +112,7 @@ class U_I18N_API GenderInfo : public UObject { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/gregocal.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/gregocal.h index e6ae4d6a1d..4ae5562536 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/gregocal.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/gregocal.h @@ -1,3 +1,5 @@ +// © 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. @@ -35,6 +37,7 @@ * \brief C++ API: Concrete class which provides the standard calendar. */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -769,6 +772,7 @@ class U_I18N_API GregorianCalendar: public Calendar { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/icudataver.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/icudataver.h index 609f580f06..1cb202e3d4 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/icudataver.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/icudataver.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/icuplug.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/icuplug.h index 61dc2a3eb0..2e57b149e1 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/icuplug.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/icuplug.h @@ -1,7 +1,9 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * -* Copyright (C) 2009-2012, International Business Machines +* Copyright (C) 2009-2015, International Business Machines * Corporation and others. All Rights Reserved. * ****************************************************************************** @@ -108,6 +110,10 @@ #include "unicode/utypes.h" +#if UCONFIG_ENABLE_PLUGINS || defined(U_IN_DOXYGEN) + + + /* === Basic types === */ #ifndef U_HIDE_INTERNAL_API @@ -153,7 +159,11 @@ typedef enum { UPLUG_REASON_QUERY = 0, /**< The plugin is being queried for info. **/ UPLUG_REASON_LOAD = 1, /**< The plugin is being loaded. **/ UPLUG_REASON_UNLOAD = 2, /**< The plugin is being unloaded. **/ - UPLUG_REASON_COUNT /**< count of known reasons **/ + /** + * Number of known reasons. + * @internal The numeric value may change over time, see ICU ticket #12420. + */ + UPLUG_REASON_COUNT } UPlugReason; @@ -169,7 +179,11 @@ typedef enum { UPLUG_LEVEL_UNKNOWN = 1, /**< The plugin is waiting to be installed. **/ UPLUG_LEVEL_LOW = 2, /**< The plugin must be called before u_init completes **/ UPLUG_LEVEL_HIGH = 3, /**< The plugin can run at any time. **/ - UPLUG_LEVEL_COUNT /**< count of known reasons **/ + /** + * Number of known levels. + * @internal The numeric value may change over time, see ICU ticket #12420. + */ + UPLUG_LEVEL_COUNT } UPlugLevel; /** @@ -368,4 +382,7 @@ U_INTERNAL void U_EXPORT2 uplug_removePlug(UPlugData *plug, UErrorCode *status); #endif /* U_HIDE_INTERNAL_API */ -#endif +#endif /* UCONFIG_ENABLE_PLUGINS */ + +#endif /* _ICUPLUG */ + diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/idna.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/idna.h index 90194a378f..208368cc63 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/idna.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/idna.h @@ -1,10 +1,12 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2010-2012, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* * file name: idna.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -29,6 +31,7 @@ #include "unicode/uidna.h" #include "unicode/unistr.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class IDNAInfo; @@ -198,7 +201,7 @@ class U_COMMON_API IDNA : public UObject { * @stable ICU 4.6 */ virtual void - labelToASCII_UTF8(const StringPiece &label, ByteSink &dest, + labelToASCII_UTF8(StringPiece label, ByteSink &dest, IDNAInfo &info, UErrorCode &errorCode) const; /** @@ -216,7 +219,7 @@ class U_COMMON_API IDNA : public UObject { * @stable ICU 4.6 */ virtual void - labelToUnicodeUTF8(const StringPiece &label, ByteSink &dest, + labelToUnicodeUTF8(StringPiece label, ByteSink &dest, IDNAInfo &info, UErrorCode &errorCode) const; /** @@ -234,7 +237,7 @@ class U_COMMON_API IDNA : public UObject { * @stable ICU 4.6 */ virtual void - nameToASCII_UTF8(const StringPiece &name, ByteSink &dest, + nameToASCII_UTF8(StringPiece name, ByteSink &dest, IDNAInfo &info, UErrorCode &errorCode) const; /** @@ -252,7 +255,7 @@ class U_COMMON_API IDNA : public UObject { * @stable ICU 4.6 */ virtual void - nameToUnicodeUTF8(const StringPiece &name, ByteSink &dest, + nameToUnicodeUTF8(StringPiece name, ByteSink &dest, IDNAInfo &info, UErrorCode &errorCode) const; }; @@ -318,6 +321,7 @@ class U_COMMON_API IDNAInfo : public UMemory { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // UCONFIG_NO_IDNA #endif // __IDNA_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/listformatter.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/listformatter.h index e48faaa127..0cb39e7cc8 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/listformatter.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/listformatter.h @@ -1,12 +1,14 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * -* Copyright (C) 2012-2014, International Business Machines +* Copyright (C) 2012-2016, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* * file name: listformatter.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -21,9 +23,16 @@ #include "unicode/unistr.h" #include "unicode/locid.h" +#include "unicode/formattedvalue.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN +class FieldPositionIterator; +class FieldPositionHandler; +class FormattedListData; +class ListFormatter; + /** @internal */ class Hashtable; @@ -31,7 +40,10 @@ class Hashtable; struct ListFormatInternal; /* The following can't be #ifndef U_HIDE_INTERNAL_API, needed for other .h file declarations */ -/** @internal */ +/** + * @internal + * \cond + */ struct ListFormatData : public UMemory { UnicodeString twoPattern; UnicodeString startPattern; @@ -41,6 +53,7 @@ struct ListFormatData : public UMemory { ListFormatData(const UnicodeString& two, const UnicodeString& start, const UnicodeString& middle, const UnicodeString& end) : twoPattern(two), startPattern(start), middlePattern(middle), endPattern(end) {} }; +/** \endcond */ /** @@ -49,6 +62,81 @@ struct ListFormatData : public UMemory { */ +#if !UCONFIG_NO_FORMATTING +#ifndef U_HIDE_DRAFT_API +/** + * An immutable class containing the result of a list formatting operation. + * + * Instances of this class are immutable and thread-safe. + * + * When calling nextPosition(): + * The fields are returned from start to end. The special field category + * UFIELD_CATEGORY_LIST_SPAN is used to indicate which argument + * was inserted at the given position. The span category will + * always occur before the corresponding instance of UFIELD_CATEGORY_LIST + * in the nextPosition() iterator. + * + * Not intended for public subclassing. + * + * @draft ICU 64 + */ +class U_I18N_API FormattedList : public UMemory, public FormattedValue { + public: + /** + * Default constructor; makes an empty FormattedList. + * @draft ICU 64 + */ + FormattedList() : fData(nullptr), fErrorCode(U_INVALID_STATE_ERROR) {} + + /** + * Move constructor: Leaves the source FormattedList in an undefined state. + * @draft ICU 64 + */ + FormattedList(FormattedList&& src) U_NOEXCEPT; + + /** + * Destruct an instance of FormattedList. + * @draft ICU 64 + */ + virtual ~FormattedList() U_OVERRIDE; + + /** Copying not supported; use move constructor instead. */ + FormattedList(const FormattedList&) = delete; + + /** Copying not supported; use move assignment instead. */ + FormattedList& operator=(const FormattedList&) = delete; + + /** + * Move assignment: Leaves the source FormattedList in an undefined state. + * @draft ICU 64 + */ + FormattedList& operator=(FormattedList&& src) U_NOEXCEPT; + + /** @copydoc FormattedValue::toString() */ + UnicodeString toString(UErrorCode& status) const U_OVERRIDE; + + /** @copydoc FormattedValue::toTempString() */ + UnicodeString toTempString(UErrorCode& status) const U_OVERRIDE; + + /** @copydoc FormattedValue::appendTo() */ + Appendable &appendTo(Appendable& appendable, UErrorCode& status) const U_OVERRIDE; + + /** @copydoc FormattedValue::nextPosition() */ + UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE; + + private: + FormattedListData *fData; + UErrorCode fErrorCode; + explicit FormattedList(FormattedListData *results) + : fData(results), fErrorCode(U_ZERO_ERROR) {} + explicit FormattedList(UErrorCode errorCode) + : fData(nullptr), fErrorCode(errorCode) {} + friend class ListFormatter; +}; +#endif /* U_HIDE_DRAFT_API */ +#endif // !UCONFIG_NO_FORMATTING + + /** * An immutable class for formatting a list, using data from CLDR (or supplied * separately). @@ -59,7 +147,7 @@ struct ListFormatData : public UMemory { * The ListFormatter class is not intended for public subclassing. * @stable ICU 50 */ -class U_COMMON_API ListFormatter : public UObject{ +class U_I18N_API ListFormatter : public UObject{ public: @@ -101,7 +189,7 @@ class U_COMMON_API ListFormatter : public UObject{ * Creates a ListFormatter appropriate for a locale and style. * * @param locale The locale. - * @param style the style, either "standard", "duration", or "duration-short" + * @param style the style, either "standard", "or", "unit", "unit-narrow", or "unit-short" * @param errorCode ICU error code, set if no data available for the given locale. * @return A ListFormatter object created from internal data derived from * CLDR data. @@ -131,6 +219,47 @@ class U_COMMON_API ListFormatter : public UObject{ UnicodeString& format(const UnicodeString items[], int32_t n_items, UnicodeString& appendTo, UErrorCode& errorCode) const; +#ifndef U_HIDE_DRAFT_API + /** + * Format a list of strings. + * + * @param items An array of strings to be combined and formatted. + * @param n_items Length of the array items. + * @param appendTo The string to which the formatted result will be + * appended. + * @param posIter On return, can be used to iterate over positions of + * fields generated by this format call. Field values are + * defined in UListFormatterField. Can be NULL. + * @param errorCode ICU error code returned here. + * @return Formatted string combining the elements of items, + * appended to appendTo. + * @draft ICU 63 + */ + UnicodeString& format(const UnicodeString items[], int32_t n_items, + UnicodeString & appendTo, FieldPositionIterator* posIter, + UErrorCode& errorCode) const; +#endif /* U_HIDE_DRAFT_API */ + +#if !UCONFIG_NO_FORMATTING +#ifndef U_HIDE_DRAFT_API + /** + * Formats a list of strings to a FormattedList, which exposes field + * position information. The FormattedList contains more information than + * a FieldPositionIterator. + * + * @param items An array of strings to be combined and formatted. + * @param n_items Length of the array items. + * @param errorCode ICU error code returned here. + * @return A FormattedList containing field information. + * @draft ICU 64 + */ + FormattedList formatStringsToValue( + const UnicodeString items[], + int32_t n_items, + UErrorCode& errorCode) const; +#endif /* U_HIDE_DRAFT_API */ +#endif // !UCONFIG_NO_FORMATTING + #ifndef U_HIDE_INTERNAL_API /** @internal for MeasureFormat @@ -145,7 +274,7 @@ class U_COMMON_API ListFormatter : public UObject{ /** * @internal constructor made public for testing. */ - ListFormatter(const ListFormatData &data); + ListFormatter(const ListFormatData &data, UErrorCode &errorCode); /** * @internal constructor made public for testing. */ @@ -155,6 +284,12 @@ class U_COMMON_API ListFormatter : public UObject{ private: static void initializeHash(UErrorCode& errorCode); static const ListFormatInternal* getListFormatInternal(const Locale& locale, const char *style, UErrorCode& errorCode); + struct ListPatternsSink; + static ListFormatInternal* loadListFormatInternal(const Locale& locale, const char* style, UErrorCode& errorCode); + + UnicodeString& format_( + const UnicodeString items[], int32_t n_items, UnicodeString& appendTo, + int32_t index, int32_t &offset, FieldPositionHandler* handler, UErrorCode& errorCode) const; ListFormatter(); @@ -163,5 +298,6 @@ class U_COMMON_API ListFormatter : public UObject{ }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API -#endif +#endif // __LISTFORMATTER_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/localebuilder.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/localebuilder.h new file mode 100644 index 0000000000..03b9eca5c5 --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/localebuilder.h @@ -0,0 +1,294 @@ +// © 2018 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html#License +#ifndef __LOCALEBUILDER_H__ +#define __LOCALEBUILDER_H__ + +#include "unicode/locid.h" +#include "unicode/stringpiece.h" +#include "unicode/uobject.h" +#include "unicode/utypes.h" + + +#ifndef U_HIDE_DRAFT_API +/** + * \file + * \brief C++ API: Builder API for Locale + */ + +#if U_SHOW_CPLUSPLUS_API +U_NAMESPACE_BEGIN +class CharString; + +/** + * LocaleBuilder is used to build instances of Locale + * from values configured by the setters. Unlike the Locale + * constructors, the LocaleBuilder checks if a value configured by a + * setter satisfies the syntax requirements defined by the Locale + * class. A Locale object created by a LocaleBuilder is + * well-formed and can be transformed to a well-formed IETF BCP 47 language tag + * without losing information. + * + *

    The following example shows how to create a Locale object + * with the LocaleBuilder. + *

    + *
    + *     UErrorCode status = U_ZERO_ERROR;
    + *     Locale aLocale = LocaleBuilder()
    + *                          .setLanguage("sr")
    + *                          .setScript("Latn")
    + *                          .setRegion("RS")
    + *                          .build(status);
    + *     if (U_SUCCESS(status)) {
    + *       // ...
    + *     }
    + * 
    + *
    + * + *

    LocaleBuilders can be reused; clear() resets all + * fields to their default values. + * + *

    LocaleBuilder tracks errors in an internal UErrorCode. For all setters, + * except setLanguageTag and setLocale, LocaleBuilder will return immediately + * if the internal UErrorCode is in error state. + * To reset internal state and error code, call clear method. + * The setLanguageTag and setLocale method will first clear the internal + * UErrorCode, then track the error of the validation of the input parameter + * into the internal UErrorCode. + * + * @draft ICU 64 + */ +class U_COMMON_API LocaleBuilder : public UObject { +public: + /** + * Constructs an empty LocaleBuilder. The default value of all + * fields, extensions, and private use information is the + * empty string. + * + * @draft ICU 64 + */ + LocaleBuilder(); + + /** + * Destructor + * @draft ICU 64 + */ + virtual ~LocaleBuilder(); + + /** + * Resets the LocaleBuilder to match the provided + * locale. Existing state is discarded. + * + *

    All fields of the locale must be well-formed. + *

    This method clears the internal UErrorCode. + * + * @param locale the locale + * @return This builder. + * + * @draft ICU 64 + */ + LocaleBuilder& setLocale(const Locale& locale); + + /** + * Resets the LocaleBuilder to match the provided + * [Unicode Locale Identifier](http://www.unicode.org/reports/tr35/tr35.html#unicode_locale_id) . + * Discards the existing state. the empty string cause the builder to be + * reset, like {@link #clear}. Grandfathered tags are converted to their + * canonical form before being processed. Otherwise, the language + * tag must be well-formed, or else the build() method will later + * report an U_ILLEGAL_ARGUMENT_ERROR. + * + *

    This method clears the internal UErrorCode. + * + * @param tag the language tag, defined as + * [unicode_locale_id](http://www.unicode.org/reports/tr35/tr35.html#unicode_locale_id). + * @return This builder. + * @draft ICU 64 + */ + LocaleBuilder& setLanguageTag(StringPiece tag); + + /** + * Sets the language. If language is the empty string, the + * language in this LocaleBuilder is removed. Otherwise, the + * language must be well-formed, or else the build() method will + * later report an U_ILLEGAL_ARGUMENT_ERROR. + * + *

    The syntax of language value is defined as + * [unicode_language_subtag](http://www.unicode.org/reports/tr35/tr35.html#unicode_language_subtag). + * + * @param language the language + * @return This builder. + * @draft ICU 64 + */ + LocaleBuilder& setLanguage(StringPiece language); + + /** + * Sets the script. If script is the empty string, the script in + * this LocaleBuilder is removed. + * Otherwise, the script must be well-formed, or else the build() + * method will later report an U_ILLEGAL_ARGUMENT_ERROR. + * + *

    The script value is a four-letter script code as + * [unicode_script_subtag](http://www.unicode.org/reports/tr35/tr35.html#unicode_script_subtag) + * defined by ISO 15924 + * + * @param script the script + * @return This builder. + * @draft ICU 64 + */ + LocaleBuilder& setScript(StringPiece script); + + /** + * Sets the region. If region is the empty string, the region in this + * LocaleBuilder is removed. Otherwise, the region + * must be well-formed, or else the build() method will later report an + * U_ILLEGAL_ARGUMENT_ERROR. + * + *

    The region value is defined by + * [unicode_region_subtag](http://www.unicode.org/reports/tr35/tr35.html#unicode_region_subtag) + * as a two-letter ISO 3166 code or a three-digit UN M.49 area code. + * + *

    The region value in the Locale created by the + * LocaleBuilder is always normalized to upper case. + * + * @param region the region + * @return This builder. + * @draft ICU 64 + */ + LocaleBuilder& setRegion(StringPiece region); + + /** + * Sets the variant. If variant is the empty string, the variant in this + * LocaleBuilder is removed. Otherwise, the variant + * must be well-formed, or else the build() method will later report an + * U_ILLEGAL_ARGUMENT_ERROR. + * + *

    Note: This method checks if variant + * satisfies the + * [unicode_variant_subtag](http://www.unicode.org/reports/tr35/tr35.html#unicode_variant_subtag) + * syntax requirements, and normalizes the value to lowercase letters. However, + * the Locale class does not impose any syntactic + * restriction on variant. To set an ill-formed variant, use a Locale constructor. + * If there are multiple unicode_variant_subtag, the caller must concatenate + * them with '-' as separator (ex: "foobar-fibar"). + * + * @param variant the variant + * @return This builder. + * @draft ICU 64 + */ + LocaleBuilder& setVariant(StringPiece variant); + + /** + * Sets the extension for the given key. If the value is the empty string, + * the extension is removed. Otherwise, the key and + * value must be well-formed, or else the build() method will + * later report an U_ILLEGAL_ARGUMENT_ERROR. + * + *

    Note: The key ('u') is used for the Unicode locale extension. + * Setting a value for this key replaces any existing Unicode locale key/type + * pairs with those defined in the extension. + * + *

    Note: The key ('x') is used for the private use code. To be + * well-formed, the value for this key needs only to have subtags of one to + * eight alphanumeric characters, not two to eight as in the general case. + * + * @param key the extension key + * @param value the extension value + * @return This builder. + * @draft ICU 64 + */ + LocaleBuilder& setExtension(char key, StringPiece value); + + /** + * Sets the Unicode locale keyword type for the given key. If the type + * StringPiece is constructed with a nullptr, the keyword is removed. + * If the type is the empty string, the keyword is set without type subtags. + * Otherwise, the key and type must be well-formed, or else the build() + * method will later report an U_ILLEGAL_ARGUMENT_ERROR. + * + *

    Keys and types are converted to lower case. + * + *

    Note:Setting the 'u' extension via {@link #setExtension} + * replaces all Unicode locale keywords with those defined in the + * extension. + * + * @param key the Unicode locale key + * @param type the Unicode locale type + * @return This builder. + * @draft ICU 64 + */ + LocaleBuilder& setUnicodeLocaleKeyword( + StringPiece key, StringPiece type); + + /** + * Adds a unicode locale attribute, if not already present, otherwise + * has no effect. The attribute must not be empty string and must be + * well-formed or U_ILLEGAL_ARGUMENT_ERROR will be set to status + * during the build() call. + * + * @param attribute the attribute + * @return This builder. + * @draft ICU 64 + */ + LocaleBuilder& addUnicodeLocaleAttribute(StringPiece attribute); + + /** + * Removes a unicode locale attribute, if present, otherwise has no + * effect. The attribute must not be empty string and must be well-formed + * or U_ILLEGAL_ARGUMENT_ERROR will be set to status during the build() call. + * + *

    Attribute comparison for removal is case-insensitive. + * + * @param attribute the attribute + * @return This builder. + * @draft ICU 64 + */ + LocaleBuilder& removeUnicodeLocaleAttribute(StringPiece attribute); + + /** + * Resets the builder to its initial, empty state. + *

    This method clears the internal UErrorCode. + * + * @return this builder + * @draft ICU 64 + */ + LocaleBuilder& clear(); + + /** + * Resets the extensions to their initial, empty state. + * Language, script, region and variant are unchanged. + * + * @return this builder + * @draft ICU 64 + */ + LocaleBuilder& clearExtensions(); + + /** + * Returns an instance of Locale created from the fields set + * on this builder. + * If any set methods or during the build() call require memory allocation + * but fail U_MEMORY_ALLOCATION_ERROR will be set to status. + * If any of the fields set by the setters are not well-formed, the status + * will be set to U_ILLEGAL_ARGUMENT_ERROR. The state of the builder will + * not change after the build() call and the caller is free to keep using + * the same builder to build more locales. + * + * @return a new Locale + * @draft ICU 64 + */ + Locale build(UErrorCode& status); + +private: + UErrorCode status_; + char language_[9]; + char script_[5]; + char region_[4]; + CharString *variant_; // Pointer not object so we need not #include internal charstr.h. + icu::Locale *extensions_; // Pointer not object. Storage for all other fields. + +}; + +U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API + +#endif // U_HIDE_DRAFT_API +#endif // __LOCALEBUILDER_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/localpointer.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/localpointer.h index e3aabf65c3..e011688b1a 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/localpointer.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/localpointer.h @@ -1,12 +1,14 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * -* Copyright (C) 2009-2014, International Business Machines +* Copyright (C) 2009-2016, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* * file name: localpointer.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -18,7 +20,7 @@ #define __LOCALPOINTER_H__ /** - * \file + * \file * \brief C++ API: "Smart pointers" for use with and in ICU4C C++ code. * * These classes are inspired by @@ -40,6 +42,8 @@ #if U_SHOW_CPLUSPLUS_API +#include + U_NAMESPACE_BEGIN /** @@ -52,7 +56,7 @@ U_NAMESPACE_BEGIN * Destructor and adoptInstead(). * * There is no operator T *() provided because the programmer must decide - * whether to use getAlias() (without transfer of ownership) or orpan() + * whether to use getAlias() (without transfer of ownership) or orphan() * (with transfer of ownership and NULLing of the pointer). * * @see LocalPointer @@ -63,6 +67,13 @@ U_NAMESPACE_BEGIN template class LocalPointerBase { public: + // No heap allocation. Use only on the stack. + static void* U_EXPORT2 operator new(size_t) = delete; + static void* U_EXPORT2 operator new[](size_t) = delete; +#if U_HAVE_PLACEMENT_NEW + static void* U_EXPORT2 operator new(size_t, void*) = delete; +#endif + /** * Constructor takes ownership. * @param p simple pointer to an object that is adopted @@ -151,17 +162,11 @@ class LocalPointerBase { T *ptr; private: // No comparison operators with other LocalPointerBases. - bool operator==(const LocalPointerBase &other); - bool operator!=(const LocalPointerBase &other); - // No ownership transfer: No copy constructor, no assignment operator. - LocalPointerBase(const LocalPointerBase &other); - void operator=(const LocalPointerBase &other); - // No heap allocation. Use only on the stack. - static void * U_EXPORT2 operator new(size_t size); - static void * U_EXPORT2 operator new[](size_t size); -#if U_HAVE_PLACEMENT_NEW - static void * U_EXPORT2 operator new(size_t, void *ptr); -#endif + bool operator==(const LocalPointerBase &other); + bool operator!=(const LocalPointerBase &other); + // No ownership sharing: No copy constructor, no assignment operator. + LocalPointerBase(const LocalPointerBase &other); + void operator=(const LocalPointerBase &other); }; /** @@ -172,9 +177,9 @@ class LocalPointerBase { * \code * LocalPointer s(new UnicodeString((UChar32)0x50005)); * int32_t length=s->length(); // 2 - * UChar lead=s->charAt(0); // 0xd900 + * char16_t lead=s->charAt(0); // 0xd900 * if(some condition) { return; } // no need to explicitly delete the pointer - * s.adoptInstead(new UnicodeString((UChar)0xfffc)); + * s.adoptInstead(new UnicodeString((char16_t)0xfffc)); * length=s->length(); // 1 * // no need to explicitly delete the pointer * \endcode @@ -185,13 +190,14 @@ class LocalPointerBase { template class LocalPointer : public LocalPointerBase { public: + using LocalPointerBase::operator*; + using LocalPointerBase::operator->; /** * Constructor takes ownership. * @param p simple pointer to an object that is adopted * @stable ICU 4.4 */ explicit LocalPointer(T *p=NULL) : LocalPointerBase(p) {} -#ifndef U_HIDE_DRAFT_API /** * Constructor takes ownership and reports an error if NULL. * @@ -203,14 +209,37 @@ class LocalPointer : public LocalPointerBase { * @param p simple pointer to an object that is adopted * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR * if p==NULL and no other failure code had been set - * @draft ICU 55 + * @stable ICU 55 */ LocalPointer(T *p, UErrorCode &errorCode) : LocalPointerBase(p) { if(p==NULL && U_SUCCESS(errorCode)) { errorCode=U_MEMORY_ALLOCATION_ERROR; } } + /** + * Move constructor, leaves src with isNull(). + * @param src source smart pointer + * @stable ICU 56 + */ + LocalPointer(LocalPointer &&src) U_NOEXCEPT : LocalPointerBase(src.ptr) { + src.ptr=NULL; + } + +#ifndef U_HIDE_DRAFT_API + /** + * Constructs a LocalPointer from a C++11 std::unique_ptr. + * The LocalPointer steals the object owned by the std::unique_ptr. + * + * This constructor works via move semantics. If your std::unique_ptr is + * in a local variable, you must use std::move. + * + * @param p The std::unique_ptr from which the pointer will be stolen. + * @draft ICU 64 + */ + explicit LocalPointer(std::unique_ptr &&p) + : LocalPointerBase(p.release()) {} #endif /* U_HIDE_DRAFT_API */ + /** * Destructor deletes the object it owns. * @stable ICU 4.4 @@ -218,6 +247,54 @@ class LocalPointer : public LocalPointerBase { ~LocalPointer() { delete LocalPointerBase::ptr; } + /** + * Move assignment operator, leaves src with isNull(). + * The behavior is undefined if *this and src are the same object. + * @param src source smart pointer + * @return *this + * @stable ICU 56 + */ + LocalPointer &operator=(LocalPointer &&src) U_NOEXCEPT { + delete LocalPointerBase::ptr; + LocalPointerBase::ptr=src.ptr; + src.ptr=NULL; + return *this; + } + +#ifndef U_HIDE_DRAFT_API + /** + * Move-assign from an std::unique_ptr to this LocalPointer. + * Steals the pointer from the std::unique_ptr. + * + * @param p The std::unique_ptr from which the pointer will be stolen. + * @return *this + * @draft ICU 64 + */ + LocalPointer &operator=(std::unique_ptr &&p) U_NOEXCEPT { + adoptInstead(p.release()); + return *this; + } +#endif /* U_HIDE_DRAFT_API */ + + /** + * Swap pointers. + * @param other other smart pointer + * @stable ICU 56 + */ + void swap(LocalPointer &other) U_NOEXCEPT { + T *temp=LocalPointerBase::ptr; + LocalPointerBase::ptr=other.ptr; + other.ptr=temp; + } + /** + * Non-member LocalPointer swap function. + * @param p1 will get p2's pointer + * @param p2 will get p1's pointer + * @stable ICU 56 + */ + friend inline void swap(LocalPointer &p1, LocalPointer &p2) U_NOEXCEPT { + p1.swap(p2); + } /** * Deletes the object it owns, * and adopts (takes ownership of) the one passed in. @@ -228,7 +305,6 @@ class LocalPointer : public LocalPointerBase { delete LocalPointerBase::ptr; LocalPointerBase::ptr=p; } -#ifndef U_HIDE_DRAFT_API /** * Deletes the object it owns, * and adopts (takes ownership of) the one passed in. @@ -242,7 +318,7 @@ class LocalPointer : public LocalPointerBase { * @param p simple pointer to an object that is adopted * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR * if p==NULL and no other failure code had been set - * @draft ICU 55 + * @stable ICU 55 */ void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) { if(U_SUCCESS(errorCode)) { @@ -255,6 +331,22 @@ class LocalPointer : public LocalPointerBase { delete p; } } + +#ifndef U_HIDE_DRAFT_API + /** + * Conversion operator to a C++11 std::unique_ptr. + * Disowns the object and gives it to the returned std::unique_ptr. + * + * This operator works via move semantics. If your LocalPointer is + * in a local variable, you must use std::move. + * + * @return An std::unique_ptr owning the pointer previously owned by this + * icu::LocalPointer. + * @draft ICU 64 + */ + operator std::unique_ptr () && { + return std::unique_ptr(LocalPointerBase::orphan()); + } #endif /* U_HIDE_DRAFT_API */ }; @@ -266,10 +358,10 @@ class LocalPointer : public LocalPointerBase { * Usage example: * \code * LocalArray a(new UnicodeString[2]); - * a[0].append((UChar)0x61); + * a[0].append((char16_t)0x61); * if(some condition) { return; } // no need to explicitly delete the array * a.adoptInstead(new UnicodeString[4]); - * a[3].append((UChar)0x62).append((UChar)0x63).reverse(); + * a[3].append((char16_t)0x62).append((char16_t)0x63).reverse(); * // no need to explicitly delete the array * \endcode * @@ -279,12 +371,56 @@ class LocalPointer : public LocalPointerBase { template class LocalArray : public LocalPointerBase { public: + using LocalPointerBase::operator*; + using LocalPointerBase::operator->; /** * Constructor takes ownership. * @param p simple pointer to an array of T objects that is adopted * @stable ICU 4.4 */ explicit LocalArray(T *p=NULL) : LocalPointerBase(p) {} + /** + * Constructor takes ownership and reports an error if NULL. + * + * This constructor is intended to be used with other-class constructors + * that may report a failure UErrorCode, + * so that callers need to check only for U_FAILURE(errorCode) + * and not also separately for isNull(). + * + * @param p simple pointer to an array of T objects that is adopted + * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR + * if p==NULL and no other failure code had been set + * @stable ICU 56 + */ + LocalArray(T *p, UErrorCode &errorCode) : LocalPointerBase(p) { + if(p==NULL && U_SUCCESS(errorCode)) { + errorCode=U_MEMORY_ALLOCATION_ERROR; + } + } + /** + * Move constructor, leaves src with isNull(). + * @param src source smart pointer + * @stable ICU 56 + */ + LocalArray(LocalArray &&src) U_NOEXCEPT : LocalPointerBase(src.ptr) { + src.ptr=NULL; + } + +#ifndef U_HIDE_DRAFT_API + /** + * Constructs a LocalArray from a C++11 std::unique_ptr of an array type. + * The LocalPointer steals the array owned by the std::unique_ptr. + * + * This constructor works via move semantics. If your std::unique_ptr is + * in a local variable, you must use std::move. + * + * @param p The std::unique_ptr from which the array will be stolen. + * @draft ICU 64 + */ + explicit LocalArray(std::unique_ptr &&p) + : LocalPointerBase(p.release()) {} +#endif /* U_HIDE_DRAFT_API */ + /** * Destructor deletes the array it owns. * @stable ICU 4.4 @@ -292,6 +428,54 @@ class LocalArray : public LocalPointerBase { ~LocalArray() { delete[] LocalPointerBase::ptr; } + /** + * Move assignment operator, leaves src with isNull(). + * The behavior is undefined if *this and src are the same object. + * @param src source smart pointer + * @return *this + * @stable ICU 56 + */ + LocalArray &operator=(LocalArray &&src) U_NOEXCEPT { + delete[] LocalPointerBase::ptr; + LocalPointerBase::ptr=src.ptr; + src.ptr=NULL; + return *this; + } + +#ifndef U_HIDE_DRAFT_API + /** + * Move-assign from an std::unique_ptr to this LocalPointer. + * Steals the array from the std::unique_ptr. + * + * @param p The std::unique_ptr from which the array will be stolen. + * @return *this + * @draft ICU 64 + */ + LocalArray &operator=(std::unique_ptr &&p) U_NOEXCEPT { + adoptInstead(p.release()); + return *this; + } +#endif /* U_HIDE_DRAFT_API */ + + /** + * Swap pointers. + * @param other other smart pointer + * @stable ICU 56 + */ + void swap(LocalArray &other) U_NOEXCEPT { + T *temp=LocalPointerBase::ptr; + LocalPointerBase::ptr=other.ptr; + other.ptr=temp; + } + /** + * Non-member LocalArray swap function. + * @param p1 will get p2's pointer + * @param p2 will get p1's pointer + * @stable ICU 56 + */ + friend inline void swap(LocalArray &p1, LocalArray &p2) U_NOEXCEPT { + p1.swap(p2); + } /** * Deletes the array it owns, * and adopts (takes ownership of) the one passed in. @@ -302,6 +486,32 @@ class LocalArray : public LocalPointerBase { delete[] LocalPointerBase::ptr; LocalPointerBase::ptr=p; } + /** + * Deletes the array it owns, + * and adopts (takes ownership of) the one passed in. + * + * If U_FAILURE(errorCode), then the current array is retained and the new one deleted. + * + * If U_SUCCESS(errorCode) but the input pointer is NULL, + * then U_MEMORY_ALLOCATION_ERROR is set, + * the current array is deleted, and NULL is set. + * + * @param p simple pointer to an array of T objects that is adopted + * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR + * if p==NULL and no other failure code had been set + * @stable ICU 56 + */ + void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) { + if(U_SUCCESS(errorCode)) { + delete[] LocalPointerBase::ptr; + LocalPointerBase::ptr=p; + if(p==NULL) { + errorCode=U_MEMORY_ALLOCATION_ERROR; + } + } else { + delete[] p; + } + } /** * Array item access (writable). * No index bounds check. @@ -310,6 +520,23 @@ class LocalArray : public LocalPointerBase { * @stable ICU 4.4 */ T &operator[](ptrdiff_t i) const { return LocalPointerBase::ptr[i]; } + +#ifndef U_HIDE_DRAFT_API + /** + * Conversion operator to a C++11 std::unique_ptr. + * Disowns the object and gives it to the returned std::unique_ptr. + * + * This operator works via move semantics. If your LocalPointer is + * in a local variable, you must use std::move. + * + * @return An std::unique_ptr owning the pointer previously owned by this + * icu::LocalPointer. + * @draft ICU 64 + */ + operator std::unique_ptr () && { + return std::unique_ptr(LocalPointerBase::orphan()); + } +#endif /* U_HIDE_DRAFT_API */ }; /** @@ -319,9 +546,6 @@ class LocalArray : public LocalPointerBase { * like LocalPointer except that this subclass will use the closeFunction * rather than the C++ delete operator. * - * Requirement: The closeFunction must tolerate a NULL pointer. - * (We could add a NULL check here but it is normally redundant.) - * * Usage example: * \code * LocalUCaseMapPointer csm(ucasemap_open(localeID, options, &errorCode)); @@ -338,12 +562,43 @@ class LocalArray : public LocalPointerBase { #define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \ class LocalPointerClassName : public LocalPointerBase { \ public: \ + using LocalPointerBase::operator*; \ + using LocalPointerBase::operator->; \ explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase(p) {} \ - ~LocalPointerClassName() { closeFunction(ptr); } \ + LocalPointerClassName(LocalPointerClassName &&src) U_NOEXCEPT \ + : LocalPointerBase(src.ptr) { \ + src.ptr=NULL; \ + } \ + /* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */ \ + explicit LocalPointerClassName(std::unique_ptr &&p) \ + : LocalPointerBase(p.release()) {} \ + ~LocalPointerClassName() { if (ptr != NULL) { closeFunction(ptr); } } \ + LocalPointerClassName &operator=(LocalPointerClassName &&src) U_NOEXCEPT { \ + if (ptr != NULL) { closeFunction(ptr); } \ + LocalPointerBase::ptr=src.ptr; \ + src.ptr=NULL; \ + return *this; \ + } \ + /* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */ \ + LocalPointerClassName &operator=(std::unique_ptr &&p) { \ + adoptInstead(p.release()); \ + return *this; \ + } \ + void swap(LocalPointerClassName &other) U_NOEXCEPT { \ + Type *temp=LocalPointerBase::ptr; \ + LocalPointerBase::ptr=other.ptr; \ + other.ptr=temp; \ + } \ + friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \ + p1.swap(p2); \ + } \ void adoptInstead(Type *p) { \ - closeFunction(ptr); \ + if (ptr != NULL) { closeFunction(ptr); } \ ptr=p; \ } \ + operator std::unique_ptr () && { \ + return std::unique_ptr(LocalPointerBase::orphan(), closeFunction); \ + } \ } U_NAMESPACE_END diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/locdspnm.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/locdspnm.h index 74862b6d8a..0ec415d5ea 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/locdspnm.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/locdspnm.h @@ -1,6 +1,8 @@ +// © 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 +* Copyright (C) 2010-2016, International Business Machines Corporation and * others. All Rights Reserved. ****************************************************************************** */ @@ -18,10 +20,12 @@ #if !UCONFIG_NO_FORMATTING #include "unicode/locid.h" +#include "unicode/strenum.h" #include "unicode/uscript.h" #include "unicode/uldnames.h" #include "unicode/udisplaycontext.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -30,7 +34,7 @@ U_NAMESPACE_BEGIN * values, see Locale. * @stable ICU 4.4 */ -class U_I18N_API LocaleDisplayNames : public UObject { +class U_COMMON_API LocaleDisplayNames : public UObject { public: /** * Destructor. @@ -46,7 +50,7 @@ class U_I18N_API LocaleDisplayNames : public UObject { * @return a LocaleDisplayNames instance * @stable ICU 4.4 */ - static LocaleDisplayNames* U_EXPORT2 createInstance(const Locale& locale); + inline static LocaleDisplayNames* U_EXPORT2 createInstance(const Locale& locale); /** * Returns an instance of LocaleDisplayNames that returns names @@ -198,6 +202,7 @@ inline LocaleDisplayNames* LocaleDisplayNames::createInstance(const Locale& loca } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/locid.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/locid.h index 1ad5cb546e..f25c212e80 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/locid.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/locid.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * @@ -29,23 +31,29 @@ #ifndef LOCID_H #define LOCID_H +#include "unicode/bytestream.h" +#include "unicode/localpointer.h" +#include "unicode/strenum.h" +#include "unicode/stringpiece.h" #include "unicode/utypes.h" #include "unicode/uobject.h" -#include "unicode/unistr.h" #include "unicode/putil.h" #include "unicode/uloc.h" -#include "unicode/strenum.h" /** * \file * \brief C++ API: Locale ID object. */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN // Forward Declarations void U_CALLCONV locale_available_init(); /**< @internal */ +class StringEnumeration; +class UnicodeString; + /** * A Locale object represents a specific geographical, political, * or cultural region. An operation that requires a Locale to perform @@ -85,7 +93,7 @@ void U_CALLCONV locale_available_init(); /**< @internal */ *

    * The third constructor requires a third argument--the Variant. * The Variant codes are vendor and browser-specific. - * For example, use REVISED for a langauge's revised script orthography, and POSIX for POSIX. + * For example, use REVISED for a language's revised script orthography, and POSIX for POSIX. * Where there are two variants, separate them with an underscore, and * put the most important one first. For * example, a Traditional Spanish collation might be referenced, with @@ -277,6 +285,16 @@ class U_COMMON_API Locale : public UObject { */ Locale(const Locale& other); +#ifndef U_HIDE_DRAFT_API + /** + * Move constructor; might leave source in bogus state. + * This locale will have the same contents that the source locale had. + * + * @param other The Locale object being moved in. + * @draft ICU 63 + */ + Locale(Locale&& other) U_NOEXCEPT; +#endif // U_HIDE_DRAFT_API /** * Destructor @@ -293,6 +311,19 @@ class U_COMMON_API Locale : public UObject { */ Locale& operator=(const Locale& other); +#ifndef U_HIDE_DRAFT_API + /** + * Move assignment operator; might leave source in bogus state. + * This locale will have the same contents that the source locale had. + * The behavior is undefined if *this and the source are the same object. + * + * @param other The Locale object being moved in. + * @return *this + * @draft ICU 63 + */ + Locale& operator=(Locale&& other) U_NOEXCEPT; +#endif // U_HIDE_DRAFT_API + /** * Checks if two locale keys are the same. * @@ -310,7 +341,7 @@ class U_COMMON_API Locale : public UObject { * otherwise. * @stable ICU 2.0 */ - UBool operator!=(const Locale& other) const; + inline UBool operator!=(const Locale& other) const; /** * Clone this object. @@ -350,7 +381,7 @@ class U_COMMON_API Locale : public UObject { * the default locale ID of the runtime environment. * * @param newLocale Locale to set to. If NULL, set to the value obtained - * from the runtime environement. + * from the runtime environment. * @param success The error code. * @system * @stable ICU 2.0 @@ -359,6 +390,55 @@ class U_COMMON_API Locale : public UObject { UErrorCode& success); #endif /* U_HIDE_SYSTEM_API */ +#ifndef U_HIDE_DRAFT_API + /** + * Returns a Locale for the specified BCP47 language tag string. + * If the specified language tag contains any ill-formed subtags, + * the first such subtag and all following subtags are ignored. + *

    + * This implements the 'Language-Tag' production of BCP47, and so + * supports grandfathered (regular and irregular) as well as private + * use language tags. Private use tags are represented as 'x-whatever', + * and grandfathered tags are converted to their canonical replacements + * where they exist. Note that a few grandfathered tags have no modern + * replacement, these will be converted using the fallback described in + * the first paragraph, so some information might be lost. + * @param tag the input BCP47 language tag. + * @param status error information if creating the Locale failed. + * @return the Locale for the specified BCP47 language tag. + * @draft ICU 63 + */ + static Locale U_EXPORT2 forLanguageTag(StringPiece tag, UErrorCode& status); + + /** + * Returns a well-formed language tag for this Locale. + *

    + * Note: Any locale fields which do not satisfy the BCP47 syntax + * requirement will be silently omitted from the result. + * + * If this function fails, partial output may have been written to the sink. + * + * @param sink the output sink receiving the BCP47 language + * tag for this Locale. + * @param status error information if creating the language tag failed. + * @draft ICU 63 + */ + void toLanguageTag(ByteSink& sink, UErrorCode& status) const; + + /** + * Returns a well-formed language tag for this Locale. + *

    + * Note: Any locale fields which do not satisfy the BCP47 syntax + * requirement will be silently omitted from the result. + * + * @param status error information if creating the language tag failed. + * @return the BCP47 language tag for this Locale. + * @draft ICU 63 + */ + template + inline StringClass toLanguageTag(UErrorCode& status) const; +#endif // U_HIDE_DRAFT_API + /** * Creates a locale which has had minimal canonicalization * as per uloc_getName(). @@ -429,6 +509,69 @@ class U_COMMON_API Locale : public UObject { */ const char * getBaseName() const; +#ifndef U_HIDE_DRAFT_API + /** + * Add the likely subtags for this Locale, per the algorithm described + * in the following CLDR technical report: + * + * http://www.unicode.org/reports/tr35/#Likely_Subtags + * + * If this Locale is already in the maximal form, or not valid, or there is + * no data available for maximization, the Locale will be unchanged. + * + * For example, "und-Zzzz" cannot be maximized, since there is no + * reasonable maximization. + * + * Examples: + * + * "en" maximizes to "en_Latn_US" + * + * "de" maximizes to "de_Latn_US" + * + * "sr" maximizes to "sr_Cyrl_RS" + * + * "sh" maximizes to "sr_Latn_RS" (Note this will not reverse.) + * + * "zh_Hani" maximizes to "zh_Hans_CN" (Note this will not reverse.) + * + * @param status error information if maximizing this Locale failed. + * If this Locale is not well-formed, the error code is + * U_ILLEGAL_ARGUMENT_ERROR. + * @draft ICU 63 + */ + void addLikelySubtags(UErrorCode& status); + + /** + * Minimize the subtags for this Locale, per the algorithm described + * in the following CLDR technical report: + * + * http://www.unicode.org/reports/tr35/#Likely_Subtags + * + * If this Locale is already in the minimal form, or not valid, or there is + * no data available for minimization, the Locale will be unchanged. + * + * Since the minimization algorithm relies on proper maximization, see the + * comments for addLikelySubtags for reasons why there might not be any + * data. + * + * Examples: + * + * "en_Latn_US" minimizes to "en" + * + * "de_Latn_US" minimizes to "de" + * + * "sr_Cyrl_RS" minimizes to "sr" + * + * "zh_Hant_TW" minimizes to "zh_TW" (The region is preferred to the + * script, and minimizing to "zh" would imply "zh_Hans_CN".) + * + * @param status error information if maximizing this Locale failed. + * If this Locale is not well-formed, the error code is + * U_ILLEGAL_ARGUMENT_ERROR. + * @draft ICU 63 + */ + void minimizeSubtags(UErrorCode& status); +#endif // U_HIDE_DRAFT_API /** * Gets the list of keywords for the specified locale. @@ -436,13 +579,62 @@ class U_COMMON_API Locale : public UObject { * @param status the status code * @return pointer to StringEnumeration class, or NULL if there are no keywords. * Client must dispose of it by calling delete. + * @see getKeywords * @stable ICU 2.8 */ StringEnumeration * createKeywords(UErrorCode &status) const; +#ifndef U_HIDE_DRAFT_API + + /** + * Gets the list of Unicode keywords for the specified locale. + * + * @param status the status code + * @return pointer to StringEnumeration class, or NULL if there are no keywords. + * Client must dispose of it by calling delete. + * @see getUnicodeKeywords + * @draft ICU 63 + */ + StringEnumeration * createUnicodeKeywords(UErrorCode &status) const; + + /** + * Gets the set of keywords for this Locale. + * + * A wrapper to call createKeywords() and write the resulting + * keywords as standard strings (or compatible objects) into any kind of + * container that can be written to by an STL style output iterator. + * + * @param iterator an STL style output iterator to write the keywords to. + * @param status error information if creating set of keywords failed. + * @draft ICU 63 + */ + template + inline void getKeywords(OutputIterator iterator, UErrorCode& status) const; + + /** + * Gets the set of Unicode keywords for this Locale. + * + * A wrapper to call createUnicodeKeywords() and write the resulting + * keywords as standard strings (or compatible objects) into any kind of + * container that can be written to by an STL style output iterator. + * + * @param iterator an STL style output iterator to write the keywords to. + * @param status error information if creating set of keywords failed. + * @draft ICU 63 + */ + template + inline void getUnicodeKeywords(OutputIterator iterator, UErrorCode& status) const; + +#endif // U_HIDE_DRAFT_API + /** * Gets the value for a keyword. * + * This uses legacy keyword=value pairs, like "collation=phonebook". + * + * ICU4C doesn't do automatic conversion between legacy and Unicode + * keywords and values in getters and setters (as opposed to ICU4J). + * * @param keywordName name of the keyword for which we want the value. Case insensitive. * @param buffer The buffer to receive the keyword value. * @param bufferCapacity The capacity of receiving buffer @@ -453,12 +645,81 @@ class U_COMMON_API Locale : public UObject { */ int32_t getKeywordValue(const char* keywordName, char *buffer, int32_t bufferCapacity, UErrorCode &status) const; +#ifndef U_HIDE_DRAFT_API + /** + * Gets the value for a keyword. + * + * This uses legacy keyword=value pairs, like "collation=phonebook". + * + * ICU4C doesn't do automatic conversion between legacy and Unicode + * keywords and values in getters and setters (as opposed to ICU4J). + * + * @param keywordName name of the keyword for which we want the value. + * @param sink the sink to receive the keyword value. + * @param status error information if getting the value failed. + * @draft ICU 63 + */ + void getKeywordValue(StringPiece keywordName, ByteSink& sink, UErrorCode& status) const; + + /** + * Gets the value for a keyword. + * + * This uses legacy keyword=value pairs, like "collation=phonebook". + * + * ICU4C doesn't do automatic conversion between legacy and Unicode + * keywords and values in getters and setters (as opposed to ICU4J). + * + * @param keywordName name of the keyword for which we want the value. + * @param status error information if getting the value failed. + * @return the keyword value. + * @draft ICU 63 + */ + template + inline StringClass getKeywordValue(StringPiece keywordName, UErrorCode& status) const; + + /** + * Gets the Unicode value for a Unicode keyword. + * + * This uses Unicode key-value pairs, like "co-phonebk". + * + * ICU4C doesn't do automatic conversion between legacy and Unicode + * keywords and values in getters and setters (as opposed to ICU4J). + * + * @param keywordName name of the keyword for which we want the value. + * @param sink the sink to receive the keyword value. + * @param status error information if getting the value failed. + * @draft ICU 63 + */ + void getUnicodeKeywordValue(StringPiece keywordName, ByteSink& sink, UErrorCode& status) const; + + /** + * Gets the Unicode value for a Unicode keyword. + * + * This uses Unicode key-value pairs, like "co-phonebk". + * + * ICU4C doesn't do automatic conversion between legacy and Unicode + * keywords and values in getters and setters (as opposed to ICU4J). + * + * @param keywordName name of the keyword for which we want the value. + * @param status error information if getting the value failed. + * @return the keyword value. + * @draft ICU 63 + */ + template + inline StringClass getUnicodeKeywordValue(StringPiece keywordName, UErrorCode& status) const; +#endif // U_HIDE_DRAFT_API + /** * Sets or removes the value for a keyword. * * For removing all keywords, use getBaseName(), * and construct a new Locale if it differs from getName(). * + * This uses legacy keyword=value pairs, like "collation=phonebook". + * + * ICU4C doesn't do automatic conversion between legacy and Unicode + * keywords and values in getters and setters (as opposed to ICU4J). + * * @param keywordName name of the keyword to be set. Case insensitive. * @param keywordValue value of the keyword to be set. If 0-length or * NULL, will result in the keyword being removed. No error is given if @@ -469,6 +730,48 @@ class U_COMMON_API Locale : public UObject { */ void setKeywordValue(const char* keywordName, const char* keywordValue, UErrorCode &status); +#ifndef U_HIDE_DRAFT_API + /** + * Sets or removes the value for a keyword. + * + * For removing all keywords, use getBaseName(), + * and construct a new Locale if it differs from getName(). + * + * This uses legacy keyword=value pairs, like "collation=phonebook". + * + * ICU4C doesn't do automatic conversion between legacy and Unicode + * keywords and values in getters and setters (as opposed to ICU4J). + * + * @param keywordName name of the keyword to be set. + * @param keywordValue value of the keyword to be set. If 0-length or + * NULL, will result in the keyword being removed. No error is given if + * that keyword does not exist. + * @param status Returns any error information while performing this operation. + * @draft ICU 63 + */ + void setKeywordValue(StringPiece keywordName, StringPiece keywordValue, UErrorCode& status); + + /** + * Sets or removes the Unicode value for a Unicode keyword. + * + * For removing all keywords, use getBaseName(), + * and construct a new Locale if it differs from getName(). + * + * This uses Unicode key-value pairs, like "co-phonebk". + * + * ICU4C doesn't do automatic conversion between legacy and Unicode + * keywords and values in getters and setters (as opposed to ICU4J). + * + * @param keywordName name of the keyword to be set. + * @param keywordValue value of the keyword to be set. If 0-length or + * NULL, will result in the keyword being removed. No error is given if + * that keyword does not exist. + * @param status Returns any error information while performing this operation. + * @draft ICU 63 + */ + void setUnicodeKeywordValue(StringPiece keywordName, StringPiece keywordValue, UErrorCode& status); +#endif // U_HIDE_DRAFT_API + /** * returns the locale's three-letter language code, as specified * in ISO draft standard ISO-639-2. @@ -493,7 +796,6 @@ class U_COMMON_API Locale : public UObject { */ uint32_t getLCID(void) const; -#ifndef U_HIDE_DRAFT_API /** * Returns whether this locale's script is written right-to-left. * If there is no script subtag, then the likely script is used, see uloc_addLikelySubtags(). @@ -505,10 +807,9 @@ class U_COMMON_API Locale : public UObject { * Returns TRUE for "ar" and "en-Hebr", FALSE for "zh" and "fa-Cyrl". * * @return TRUE if the locale's script is written right-to-left - * @draft ICU 54 + * @stable ICU 54 */ UBool isRightToLeft() const; -#endif /* U_HIDE_DRAFT_API */ /** * Fills in "dispLang" with the name of this locale's language in a format suitable for @@ -628,7 +929,7 @@ class U_COMMON_API Locale : public UObject { /** * Fills in "name" with the name of this locale in a format suitable for user display - * in the locale specfied by "displayLocale". This function uses getDisplayLanguage(), + * in the locale specified by "displayLocale". This function uses getDisplayLanguage(), * getDisplayCountry(), and getDisplayVariant() to do its work, and outputs the display * name in the format "language (country[,variant])". For example, if displayLocale is * fr_FR, then en_US's display name would be "Anglais (États-Unis)", and no_NO_NY's @@ -662,7 +963,7 @@ class U_COMMON_API Locale : public UObject { * @return FALSE if it is a real locale, TRUE if it is a bogus locale * @stable ICU 2.1 */ - UBool isBogus(void) const; + inline UBool isBogus(void) const; /** * Returns a list of all installed locales. @@ -758,12 +1059,12 @@ class U_COMMON_API Locale : public UObject { /** * A friend to allow the default locale to be set by either the C or C++ API. - * @internal + * @internal (private) */ friend Locale *locale_set_default_internal(const char *, UErrorCode& status); /** - * @internal + * @internal (private) */ friend void U_CALLCONV locale_available_init(); }; @@ -774,6 +1075,17 @@ Locale::operator!=(const Locale& other) const return !operator==(other); } +#ifndef U_HIDE_DRAFT_API +template inline StringClass +Locale::toLanguageTag(UErrorCode& status) const +{ + StringClass result; + StringByteSink sink(&result); + toLanguageTag(sink, status); + return result; +} +#endif // U_HIDE_DRAFT_API + inline const char * Locale::getCountry() const { @@ -804,11 +1116,68 @@ Locale::getName() const return fullName; } +#ifndef U_HIDE_DRAFT_API + +template inline void +Locale::getKeywords(OutputIterator iterator, UErrorCode& status) const +{ + LocalPointer keys(createKeywords(status)); + if (U_FAILURE(status)) { + return; + } + for (;;) { + int32_t resultLength; + const char* buffer = keys->next(&resultLength, status); + if (U_FAILURE(status) || buffer == nullptr) { + return; + } + *iterator++ = StringClass(buffer, resultLength); + } +} + +template inline void +Locale::getUnicodeKeywords(OutputIterator iterator, UErrorCode& status) const +{ + LocalPointer keys(createUnicodeKeywords(status)); + if (U_FAILURE(status)) { + return; + } + for (;;) { + int32_t resultLength; + const char* buffer = keys->next(&resultLength, status); + if (U_FAILURE(status) || buffer == nullptr) { + return; + } + *iterator++ = StringClass(buffer, resultLength); + } +} + +template inline StringClass +Locale::getKeywordValue(StringPiece keywordName, UErrorCode& status) const +{ + StringClass result; + StringByteSink sink(&result); + getKeywordValue(keywordName, sink, status); + return result; +} + +template inline StringClass +Locale::getUnicodeKeywordValue(StringPiece keywordName, UErrorCode& status) const +{ + StringClass result; + StringByteSink sink(&result); + getUnicodeKeywordValue(keywordName, sink, status); + return result; +} + +#endif // U_HIDE_DRAFT_API + inline UBool Locale::isBogus(void) const { return fIsBogus; } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/measfmt.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/measfmt.h index 2bd7631011..e5bdab2789 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/measfmt.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/measfmt.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** -* Copyright (c) 2004-2015, International Business Machines +* Copyright (c) 2004-2016, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * Author: Alan Liu @@ -17,10 +19,12 @@ #include "unicode/format.h" #include "unicode/udat.h" +// Apple specific: +#include "unicode/uameasureformat.h" /** * \file - * \brief C++ API: Formatter for measure objects. + * \brief C++ API: Compatibility APIs for measure formatting. */ /** @@ -59,15 +63,27 @@ 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 +#ifndef U_HIDE_INTERNAL_API + , + /** + * Apple-specific + * Shorter, between SHORT and NARROW (SHORT without space in unit pattern) + * @draft ICU 57 + */ + UMEASFMT_WIDTH_SHORTER = 8 +#endif /* U_HIDE_INTERNAL_API */ }; /** @stable ICU 53 */ typedef enum UMeasureFormatWidth UMeasureFormatWidth; +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class Measure; @@ -78,13 +94,15 @@ class MeasureFormatCacheData; class SharedNumberFormat; class SharedPluralRules; class QuantityFormatter; -class SimplePatternFormatter; +class SimpleFormatter; class ListFormatter; class DateFormat; +class FieldPositionHandler; /** - * - * A formatter for measure objects. + *

    IMPORTANT: New users are strongly encouraged to see if + * numberformatter.h fits their use case. Although not deprecated, this header + * is provided for backwards compatibility only. * * @see Format * @author Alan Liu @@ -97,6 +115,9 @@ class U_I18N_API MeasureFormat : public Format { /** * Constructor. + *

    + * NOTE: New users are strongly encouraged to use + * {@link icu::number::NumberFormatter} instead of NumberFormat. * @stable ICU 53 */ MeasureFormat( @@ -104,6 +125,9 @@ class U_I18N_API MeasureFormat : public Format { /** * Constructor. + *

    + * NOTE: New users are strongly encouraged to use + * {@link icu::number::NumberFormatter} instead of NumberFormat. * @stable ICU 53 */ MeasureFormat( @@ -187,27 +211,50 @@ class U_I18N_API MeasureFormat : public Format { UErrorCode &status) const; #ifndef U_HIDE_INTERNAL_API + /** + * Apple-specific for now. + * Like formatMeasures above, but with a + * FieldPositionIterator* instead of a FieldPosition& + * + * @param measures Array of measure objects. + * @param measureCount the number of measure objects. + * @param appendTo Formatted string appended here. + * @param posIter On return, can be used to iterate over positions + * of fields generated by this format call. Field + * values are defined in UAMeasureUnit. + * @param status The error. + * @return appendTo reference + * + * @internal. + */ + UnicodeString &formatMeasures( + const Measure *measures, + int32_t measureCount, + UnicodeString &appendTo, + FieldPositionIterator* posIter, + UErrorCode &status) const; + /** * Apple-specific for now * @internal. */ UMeasureFormatWidth getWidth(void) const; + #endif /* U_HIDE_INTERNAL_API */ -#ifndef U_HIDE_DRAFT_API /** * Formats a single measure per unit. An example of such a * formatted string is 3.5 meters per second. * @param measure The measure object. In above example, 3.5 meters. * @param perUnit The per unit. In above example, it is - * *MeasureUnit::createSecond(status). + * `*%MeasureUnit::createSecond(status)`. * @param appendTo formatted string appended here. * @param pos the field position. * @param status the error. * @return appendTo reference * - * @draft ICU 55 + * @stable ICU 55 */ UnicodeString &formatMeasurePerUnit( const Measure &measure, @@ -216,11 +263,26 @@ class U_I18N_API MeasureFormat : public Format { FieldPosition &pos, UErrorCode &status) const; -#endif /* 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 + * the MeasureFormat constructor, or null if there is no display name available + * for the specified unit. + * + * @stable ICU 58 + */ + UnicodeString getUnitDisplayName(const MeasureUnit& unit, UErrorCode &status) const; + /** * Return a formatter for CurrencyAmount objects in the given * locale. + *

    + * NOTE: New users are strongly encouraged to use + * {@link icu::number::NumberFormatter} instead of NumberFormat. * @param locale desired locale * @param ec input-output error code * @return a formatter object, or NULL upon error @@ -232,6 +294,9 @@ class U_I18N_API MeasureFormat : public Format { /** * Return a formatter for CurrencyAmount objects in the default * locale. + *

    + * NOTE: New users are strongly encouraged to use + * {@link icu::number::NumberFormatter} instead of NumberFormat. * @param ec input-output error code * @return a formatter object, or NULL upon error * @stable ICU 3.0 @@ -297,16 +362,53 @@ class U_I18N_API MeasureFormat : public Format { /** * ICU use only. * Let subclass change NumberFormat. - * @internal. + * @internal Apple */ void adoptNumberFormat(NumberFormat *nfToAdopt, UErrorCode &status); + /** + * Gets the display name for a unit. + * @param unit The unit whose display name to get. + * @param result Receives the name result, if any (if none, + * length will be 0) + * @return Reference to result + * + * @internal Apple + */ + UnicodeString &getUnitName( + const MeasureUnit* unit, + UnicodeString &result ) const; + + /** + * Gets the display name for a set of units. + * @param units Array of units whose display name to get. + * @param unitCount The count of units + * @param listStyle The list style used for combining the unit names. + * @param result Receives the name result, if any (if none, + * length will be 0) + * @return Reference to result + * + * @internal Apple + */ + UnicodeString &getMultipleUnitNames( + const MeasureUnit** units, + int32_t unitCount, + UAMeasureNameListStyle listStyle, + UnicodeString &result ) const; + protected: /** * ICU use only. * @internal. */ - const NumberFormat &getNumberFormat() const; + const NumberFormat &getNumberFormatInternal() const; + + /** + * ICU use only. + * Always returns the short form currency formatter. + * @internal. + */ + const NumberFormat& getCurrencyFormatInternal() const; /** * ICU use only. @@ -332,31 +434,14 @@ class U_I18N_API MeasureFormat : public Format { const MeasureFormatCacheData *cache; const SharedNumberFormat *numberFormat; const SharedPluralRules *pluralRules; - UMeasureFormatWidth width; + UMeasureFormatWidth fWidth; + UBool stripPatternSpaces; // Declared outside of MeasureFormatSharedData because ListFormatter // objects are relatively cheap to copy; therefore, they don't need to be // shared across instances. ListFormatter *listFormatter; - - const QuantityFormatter *getQuantityFormatter( - int32_t index, - int32_t widthIndex, - UErrorCode &status) const; - - const SimplePatternFormatter *getPerUnitFormatter( - int32_t index, - int32_t widthIndex) const; - - const SimplePatternFormatter *getPerFormatter( - int32_t widthIndex, - UErrorCode &status) const; - - int32_t withPerUnitAndAppend( - const UnicodeString &formatted, - const MeasureUnit &perUnit, - UnicodeString &appendTo, - UErrorCode &status) const; + ListFormatter *listFormatterStd; // standard list style, option for display names; Apple specific UnicodeString &formatMeasure( const Measure &measure, @@ -377,6 +462,7 @@ class U_I18N_API MeasureFormat : public Format { // minute; [2] is second. int32_t bitMap, // 1=hour set, 2=minute set, 4=second set UnicodeString &appendTo, + FieldPositionHandler& handler, UErrorCode &status) const; UnicodeString &formatNumeric( @@ -385,10 +471,12 @@ class U_I18N_API MeasureFormat : public Format { UDateFormatField smallestField, const Formattable &smallestAmount, UnicodeString &appendTo, + FieldPositionHandler& handler, UErrorCode &status) const; }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // #if !UCONFIG_NO_FORMATTING #endif // #ifndef MEASUREFORMAT_H diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/measunit.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/measunit.h index b1da2d59aa..1fd8df7e79 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/measunit.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/measunit.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** -* Copyright (c) 2004-2015, International Business Machines +* Copyright (c) 2004-2016, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * Author: Alan Liu @@ -22,6 +24,7 @@ * \brief C++ API: A unit for measuring a quantity. */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class StringEnumeration; @@ -38,11 +41,10 @@ class U_I18N_API MeasureUnit: public UObject { /** * Default constructor. + * Populates the instance with the base dimensionless unit. * @stable ICU 3.0 */ - MeasureUnit() : fTypeId(0), fSubTypeId(0) { - fCurrency[0] = 0; - } + MeasureUnit(); /** * Copy constructor. @@ -147,7 +149,7 @@ class U_I18N_API MeasureUnit: public UObject { *

          * .   Base* polymorphic_pointer = createPolymorphicObject();
          * .   if (polymorphic_pointer->getDynamicClassID() ==
    -     * .       erived::getStaticClassID()) ...
    +     * .       Derived::getStaticClassID()) ...
          * 
    * @return The class ID for all objects of this class. * @stable ICU 53 @@ -183,12 +185,20 @@ class U_I18N_API MeasureUnit: public UObject { */ static int32_t getIndexCount(); + /** + * ICU use only. + * @return the unit.getIndex() of the unit which has this unit.getType() and unit.getSubtype(), + * or a negative value if there is no such unit + * @internal + */ + static int32_t internalGetIndexForTypeAndSubtype(const char *type, const char *subtype); + /** * ICU use only. * @internal */ - static MeasureUnit *resolveUnitPerUnit( - const MeasureUnit &unit, const MeasureUnit &perUnit); + static MeasureUnit resolveUnitPerUnit( + const MeasureUnit &unit, const MeasureUnit &perUnit, bool* isResolved); #endif /* U_HIDE_INTERNAL_API */ // All code between the "Start generated createXXX methods" comment and @@ -200,8 +210,9 @@ class U_I18N_API MeasureUnit: public UObject { // Start generated createXXX methods /** - * Returns unit of acceleration: g-force. + * Returns by pointer, unit of acceleration: g-force. * Caller owns returned value and must free it. + * Also see {@link #getGForce()}. * @param status ICU error code. * @stable ICU 53 */ @@ -209,33 +220,71 @@ class U_I18N_API MeasureUnit: public UObject { #ifndef U_HIDE_DRAFT_API /** - * Returns unit of acceleration: meter-per-second-squared. + * Returns by value, unit of acceleration: g-force. + * Also see {@link #createGForce()}. + * @draft ICU 64 + */ + static MeasureUnit getGForce(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of acceleration: meter-per-second-squared. * Caller owns returned value and must free it. + * Also see {@link #getMeterPerSecondSquared()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ static MeasureUnit *createMeterPerSecondSquared(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DRAFT_API /** - * Returns unit of angle: arc-minute. + * Returns by value, unit of acceleration: meter-per-second-squared. + * Also see {@link #createMeterPerSecondSquared()}. + * @draft ICU 64 + */ + static MeasureUnit getMeterPerSecondSquared(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of angle: arc-minute. * Caller owns returned value and must free it. + * Also see {@link #getArcMinute()}. * @param status ICU error code. * @stable ICU 53 */ static MeasureUnit *createArcMinute(UErrorCode &status); +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of angle: arc-minute. + * Also see {@link #createArcMinute()}. + * @draft ICU 64 + */ + static MeasureUnit getArcMinute(); +#endif /* U_HIDE_DRAFT_API */ + /** - * Returns unit of angle: arc-second. + * Returns by pointer, unit of angle: arc-second. * Caller owns returned value and must free it. + * Also see {@link #getArcSecond()}. * @param status ICU error code. * @stable ICU 53 */ static MeasureUnit *createArcSecond(UErrorCode &status); +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of angle: arc-second. + * Also see {@link #createArcSecond()}. + * @draft ICU 64 + */ + static MeasureUnit getArcSecond(); +#endif /* U_HIDE_DRAFT_API */ + /** - * Returns unit of angle: degree. + * Returns by pointer, unit of angle: degree. * Caller owns returned value and must free it. + * Also see {@link #getDegree()}. * @param status ICU error code. * @stable ICU 53 */ @@ -243,25 +292,89 @@ class U_I18N_API MeasureUnit: public UObject { #ifndef U_HIDE_DRAFT_API /** - * Returns unit of angle: radian. + * Returns by value, unit of angle: degree. + * Also see {@link #createDegree()}. + * @draft ICU 64 + */ + static MeasureUnit getDegree(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of angle: radian. * Caller owns returned value and must free it. + * Also see {@link #getRadian()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ static MeasureUnit *createRadian(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of angle: radian. + * Also see {@link #createRadian()}. + * @draft ICU 64 + */ + static MeasureUnit getRadian(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of angle: revolution. + * Caller owns returned value and must free it. + * Also see {@link #getRevolutionAngle()}. + * @param status ICU error code. + * @stable ICU 56 + */ + static MeasureUnit *createRevolutionAngle(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of angle: revolution. + * Also see {@link #createRevolutionAngle()}. + * @draft ICU 64 + */ + static MeasureUnit getRevolutionAngle(); +#endif /* U_HIDE_DRAFT_API */ + /** - * Returns unit of area: acre. + * Returns by pointer, unit of area: acre. * Caller owns returned value and must free it. + * Also see {@link #getAcre()}. * @param status ICU error code. * @stable ICU 53 */ static MeasureUnit *createAcre(UErrorCode &status); +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of area: acre. + * Also see {@link #createAcre()}. + * @draft ICU 64 + */ + static MeasureUnit getAcre(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of area: dunam. + * Caller owns returned value and must free it. + * Also see {@link #getDunam()}. + * @param status ICU error code. + * @draft ICU 64 + */ + static MeasureUnit *createDunam(UErrorCode &status); + + /** + * Returns by value, unit of area: dunam. + * Also see {@link #createDunam()}. + * @draft ICU 64 + */ + static MeasureUnit getDunam(); +#endif /* U_HIDE_DRAFT_API */ + /** - * Returns unit of area: hectare. + * Returns by pointer, unit of area: hectare. * Caller owns returned value and must free it. + * Also see {@link #getHectare()}. * @param status ICU error code. * @stable ICU 53 */ @@ -269,17 +382,35 @@ class U_I18N_API MeasureUnit: public UObject { #ifndef U_HIDE_DRAFT_API /** - * Returns unit of area: square-centimeter. + * Returns by value, unit of area: hectare. + * Also see {@link #createHectare()}. + * @draft ICU 64 + */ + static MeasureUnit getHectare(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of area: square-centimeter. * Caller owns returned value and must free it. + * Also see {@link #getSquareCentimeter()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ static MeasureUnit *createSquareCentimeter(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of area: square-centimeter. + * Also see {@link #createSquareCentimeter()}. + * @draft ICU 64 + */ + static MeasureUnit getSquareCentimeter(); +#endif /* U_HIDE_DRAFT_API */ + /** - * Returns unit of area: square-foot. + * Returns by pointer, unit of area: square-foot. * Caller owns returned value and must free it. + * Also see {@link #getSquareFoot()}. * @param status ICU error code. * @stable ICU 53 */ @@ -287,33 +418,71 @@ class U_I18N_API MeasureUnit: public UObject { #ifndef U_HIDE_DRAFT_API /** - * Returns unit of area: square-inch. + * Returns by value, unit of area: square-foot. + * Also see {@link #createSquareFoot()}. + * @draft ICU 64 + */ + static MeasureUnit getSquareFoot(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of area: square-inch. * Caller owns returned value and must free it. + * Also see {@link #getSquareInch()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ static MeasureUnit *createSquareInch(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of area: square-inch. + * Also see {@link #createSquareInch()}. + * @draft ICU 64 + */ + static MeasureUnit getSquareInch(); +#endif /* U_HIDE_DRAFT_API */ + /** - * Returns unit of area: square-kilometer. + * Returns by pointer, unit of area: square-kilometer. * Caller owns returned value and must free it. + * Also see {@link #getSquareKilometer()}. * @param status ICU error code. * @stable ICU 53 */ static MeasureUnit *createSquareKilometer(UErrorCode &status); +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of area: square-kilometer. + * Also see {@link #createSquareKilometer()}. + * @draft ICU 64 + */ + static MeasureUnit getSquareKilometer(); +#endif /* U_HIDE_DRAFT_API */ + /** - * Returns unit of area: square-meter. + * Returns by pointer, unit of area: square-meter. * Caller owns returned value and must free it. + * Also see {@link #getSquareMeter()}. * @param status ICU error code. * @stable ICU 53 */ static MeasureUnit *createSquareMeter(UErrorCode &status); +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of area: square-meter. + * Also see {@link #createSquareMeter()}. + * @draft ICU 64 + */ + static MeasureUnit getSquareMeter(); +#endif /* U_HIDE_DRAFT_API */ + /** - * Returns unit of area: square-mile. + * Returns by pointer, unit of area: square-mile. * Caller owns returned value and must free it. + * Also see {@link #getSquareMile()}. * @param status ICU error code. * @stable ICU 53 */ @@ -321,948 +490,2499 @@ class U_I18N_API MeasureUnit: public UObject { #ifndef U_HIDE_DRAFT_API /** - * Returns unit of area: square-yard. + * Returns by value, unit of area: square-mile. + * Also see {@link #createSquareMile()}. + * @draft ICU 64 + */ + static MeasureUnit getSquareMile(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of area: square-yard. * Caller owns returned value and must free it. + * Also see {@link #getSquareYard()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ static MeasureUnit *createSquareYard(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of consumption: liter-per-kilometer. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of area: square-yard. + * Also see {@link #createSquareYard()}. + * @draft ICU 64 */ - static MeasureUnit *createLiterPerKilometer(UErrorCode &status); + static MeasureUnit getSquareYard(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** - * Returns unit of consumption: mile-per-gallon. + * Returns by pointer, unit of concentr: karat. * Caller owns returned value and must free it. + * Also see {@link #getKarat()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ - static MeasureUnit *createMilePerGallon(UErrorCode &status); + static MeasureUnit *createKarat(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of digital: bit. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of concentr: karat. + * Also see {@link #createKarat()}. + * @draft ICU 64 */ - static MeasureUnit *createBit(UErrorCode &status); + static MeasureUnit getKarat(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** - * Returns unit of digital: byte. + * Returns by pointer, unit of concentr: milligram-per-deciliter. * Caller owns returned value and must free it. + * Also see {@link #getMilligramPerDeciliter()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 57 */ - static MeasureUnit *createByte(UErrorCode &status); + static MeasureUnit *createMilligramPerDeciliter(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of digital: gigabit. + * Returns by value, unit of concentr: milligram-per-deciliter. + * Also see {@link #createMilligramPerDeciliter()}. + * @draft ICU 64 + */ + static MeasureUnit getMilligramPerDeciliter(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of concentr: millimole-per-liter. * Caller owns returned value and must free it. + * Also see {@link #getMillimolePerLiter()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 57 */ - static MeasureUnit *createGigabit(UErrorCode &status); + static MeasureUnit *createMillimolePerLiter(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of digital: gigabyte. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of concentr: millimole-per-liter. + * Also see {@link #createMillimolePerLiter()}. + * @draft ICU 64 */ - static MeasureUnit *createGigabyte(UErrorCode &status); + static MeasureUnit getMillimolePerLiter(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of digital: kilobit. + * Returns by pointer, unit of concentr: mole. * Caller owns returned value and must free it. + * Also see {@link #getMole()}. * @param status ICU error code. - * @draft ICU 54 + * @draft ICU 64 */ - static MeasureUnit *createKilobit(UErrorCode &status); + static MeasureUnit *createMole(UErrorCode &status); + /** + * Returns by value, unit of concentr: mole. + * Also see {@link #createMole()}. + * @draft ICU 64 + */ + static MeasureUnit getMole(); #endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API + /** - * Returns unit of digital: kilobyte. + * Returns by pointer, unit of concentr: part-per-million. * Caller owns returned value and must free it. + * Also see {@link #getPartPerMillion()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 57 */ - static MeasureUnit *createKilobyte(UErrorCode &status); + static MeasureUnit *createPartPerMillion(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of digital: megabit. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of concentr: part-per-million. + * Also see {@link #createPartPerMillion()}. + * @draft ICU 64 */ - static MeasureUnit *createMegabit(UErrorCode &status); + static MeasureUnit getPartPerMillion(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of digital: megabyte. + * Returns by pointer, unit of concentr: percent. * Caller owns returned value and must free it. + * Also see {@link #getPercent()}. * @param status ICU error code. - * @draft ICU 54 + * @draft ICU 63 */ - static MeasureUnit *createMegabyte(UErrorCode &status); + static MeasureUnit *createPercent(UErrorCode &status); +#endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of concentr: percent. + * Also see {@link #createPercent()}. + * @draft ICU 64 + */ + static MeasureUnit getPercent(); #endif /* U_HIDE_DRAFT_API */ + #ifndef U_HIDE_DRAFT_API /** - * Returns unit of digital: terabit. + * Returns by pointer, unit of concentr: permille. * Caller owns returned value and must free it. + * Also see {@link #getPermille()}. * @param status ICU error code. - * @draft ICU 54 + * @draft ICU 63 */ - static MeasureUnit *createTerabit(UErrorCode &status); + static MeasureUnit *createPermille(UErrorCode &status); +#endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of concentr: permille. + * Also see {@link #createPermille()}. + * @draft ICU 64 + */ + static MeasureUnit getPermille(); #endif /* U_HIDE_DRAFT_API */ + #ifndef U_HIDE_DRAFT_API /** - * Returns unit of digital: terabyte. + * Returns by pointer, unit of concentr: permyriad. * Caller owns returned value and must free it. + * Also see {@link #getPermyriad()}. * @param status ICU error code. - * @draft ICU 54 + * @draft ICU 64 */ - static MeasureUnit *createTerabyte(UErrorCode &status); + static MeasureUnit *createPermyriad(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of duration: day. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @stable ICU 53 + * Returns by value, unit of concentr: permyriad. + * Also see {@link #createPermyriad()}. + * @draft ICU 64 */ - static MeasureUnit *createDay(UErrorCode &status); + static MeasureUnit getPermyriad(); +#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of duration: hour. + * Returns by pointer, unit of consumption: liter-per-100kilometers. * Caller owns returned value and must free it. + * Also see {@link #getLiterPer100Kilometers()}. * @param status ICU error code. - * @stable ICU 53 + * @stable ICU 56 */ - static MeasureUnit *createHour(UErrorCode &status); + static MeasureUnit *createLiterPer100Kilometers(UErrorCode &status); #ifndef U_HIDE_DRAFT_API /** - * Returns unit of duration: microsecond. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of consumption: liter-per-100kilometers. + * Also see {@link #createLiterPer100Kilometers()}. + * @draft ICU 64 */ - static MeasureUnit *createMicrosecond(UErrorCode &status); + static MeasureUnit getLiterPer100Kilometers(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of duration: millisecond. + * Returns by pointer, unit of consumption: liter-per-kilometer. * Caller owns returned value and must free it. + * Also see {@link #getLiterPerKilometer()}. * @param status ICU error code. - * @stable ICU 53 + * @stable ICU 54 */ - static MeasureUnit *createMillisecond(UErrorCode &status); + static MeasureUnit *createLiterPerKilometer(UErrorCode &status); +#ifndef U_HIDE_DRAFT_API /** - * Returns unit of duration: minute. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @stable ICU 53 + * Returns by value, unit of consumption: liter-per-kilometer. + * Also see {@link #createLiterPerKilometer()}. + * @draft ICU 64 */ - static MeasureUnit *createMinute(UErrorCode &status); + static MeasureUnit getLiterPerKilometer(); +#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of duration: month. + * Returns by pointer, unit of consumption: mile-per-gallon. * Caller owns returned value and must free it. + * Also see {@link #getMilePerGallon()}. * @param status ICU error code. - * @stable ICU 53 + * @stable ICU 54 */ - static MeasureUnit *createMonth(UErrorCode &status); + static MeasureUnit *createMilePerGallon(UErrorCode &status); #ifndef U_HIDE_DRAFT_API /** - * Returns unit of duration: nanosecond. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of consumption: mile-per-gallon. + * Also see {@link #createMilePerGallon()}. + * @draft ICU 64 */ - static MeasureUnit *createNanosecond(UErrorCode &status); + static MeasureUnit getMilePerGallon(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of duration: second. + * Returns by pointer, unit of consumption: mile-per-gallon-imperial. * Caller owns returned value and must free it. + * Also see {@link #getMilePerGallonImperial()}. * @param status ICU error code. - * @stable ICU 53 + * @stable ICU 57 */ - static MeasureUnit *createSecond(UErrorCode &status); + static MeasureUnit *createMilePerGallonImperial(UErrorCode &status); +#ifndef U_HIDE_DRAFT_API /** - * Returns unit of duration: week. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @stable ICU 53 + * Returns by value, unit of consumption: mile-per-gallon-imperial. + * Also see {@link #createMilePerGallonImperial()}. + * @draft ICU 64 */ - static MeasureUnit *createWeek(UErrorCode &status); + static MeasureUnit getMilePerGallonImperial(); +#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of duration: year. + * Returns by pointer, unit of digital: bit. * Caller owns returned value and must free it. + * Also see {@link #getBit()}. * @param status ICU error code. - * @stable ICU 53 + * @stable ICU 54 */ - static MeasureUnit *createYear(UErrorCode &status); + static MeasureUnit *createBit(UErrorCode &status); #ifndef U_HIDE_DRAFT_API /** - * Returns unit of electric: ampere. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of digital: bit. + * Also see {@link #createBit()}. + * @draft ICU 64 */ - static MeasureUnit *createAmpere(UErrorCode &status); + static MeasureUnit getBit(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** - * Returns unit of electric: milliampere. + * Returns by pointer, unit of digital: byte. * Caller owns returned value and must free it. + * Also see {@link #getByte()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ - static MeasureUnit *createMilliampere(UErrorCode &status); + static MeasureUnit *createByte(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of electric: ohm. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of digital: byte. + * Also see {@link #createByte()}. + * @draft ICU 64 */ - static MeasureUnit *createOhm(UErrorCode &status); + static MeasureUnit getByte(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** - * Returns unit of electric: volt. + * Returns by pointer, unit of digital: gigabit. * Caller owns returned value and must free it. + * Also see {@link #getGigabit()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ - static MeasureUnit *createVolt(UErrorCode &status); + static MeasureUnit *createGigabit(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of energy: calorie. + * Returns by value, unit of digital: gigabit. + * Also see {@link #createGigabit()}. + * @draft ICU 64 + */ + static MeasureUnit getGigabit(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of digital: gigabyte. * Caller owns returned value and must free it. + * Also see {@link #getGigabyte()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ - static MeasureUnit *createCalorie(UErrorCode &status); + static MeasureUnit *createGigabyte(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of energy: foodcalorie. + * Returns by value, unit of digital: gigabyte. + * Also see {@link #createGigabyte()}. + * @draft ICU 64 + */ + static MeasureUnit getGigabyte(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of digital: kilobit. * Caller owns returned value and must free it. + * Also see {@link #getKilobit()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ - static MeasureUnit *createFoodcalorie(UErrorCode &status); + static MeasureUnit *createKilobit(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of energy: joule. + * Returns by value, unit of digital: kilobit. + * Also see {@link #createKilobit()}. + * @draft ICU 64 + */ + static MeasureUnit getKilobit(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of digital: kilobyte. * Caller owns returned value and must free it. + * Also see {@link #getKilobyte()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ - static MeasureUnit *createJoule(UErrorCode &status); + static MeasureUnit *createKilobyte(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of energy: kilocalorie. + * Returns by value, unit of digital: kilobyte. + * Also see {@link #createKilobyte()}. + * @draft ICU 64 + */ + static MeasureUnit getKilobyte(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of digital: megabit. * Caller owns returned value and must free it. + * Also see {@link #getMegabit()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ - static MeasureUnit *createKilocalorie(UErrorCode &status); + static MeasureUnit *createMegabit(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of energy: kilojoule. + * Returns by value, unit of digital: megabit. + * Also see {@link #createMegabit()}. + * @draft ICU 64 + */ + static MeasureUnit getMegabit(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of digital: megabyte. * Caller owns returned value and must free it. + * Also see {@link #getMegabyte()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ - static MeasureUnit *createKilojoule(UErrorCode &status); + static MeasureUnit *createMegabyte(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of energy: kilowatt-hour. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of digital: megabyte. + * Also see {@link #createMegabyte()}. + * @draft ICU 64 */ - static MeasureUnit *createKilowattHour(UErrorCode &status); + static MeasureUnit getMegabyte(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of frequency: gigahertz. + * Returns by pointer, unit of digital: petabyte. * Caller owns returned value and must free it. + * Also see {@link #getPetabyte()}. * @param status ICU error code. - * @draft ICU 54 + * @draft ICU 63 */ - static MeasureUnit *createGigahertz(UErrorCode &status); + static MeasureUnit *createPetabyte(UErrorCode &status); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of frequency: hertz. + * Returns by value, unit of digital: petabyte. + * Also see {@link #createPetabyte()}. + * @draft ICU 64 + */ + static MeasureUnit getPetabyte(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of digital: terabit. * Caller owns returned value and must free it. + * Also see {@link #getTerabit()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ - static MeasureUnit *createHertz(UErrorCode &status); + static MeasureUnit *createTerabit(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of frequency: kilohertz. + * Returns by value, unit of digital: terabit. + * Also see {@link #createTerabit()}. + * @draft ICU 64 + */ + static MeasureUnit getTerabit(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of digital: terabyte. * Caller owns returned value and must free it. + * Also see {@link #getTerabyte()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ - static MeasureUnit *createKilohertz(UErrorCode &status); + static MeasureUnit *createTerabyte(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of frequency: megahertz. + * Returns by value, unit of digital: terabyte. + * Also see {@link #createTerabyte()}. + * @draft ICU 64 + */ + static MeasureUnit getTerabyte(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of duration: century. * Caller owns returned value and must free it. + * Also see {@link #getCentury()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 56 */ - static MeasureUnit *createMegahertz(UErrorCode &status); + static MeasureUnit *createCentury(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of length: astronomical-unit. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of duration: century. + * Also see {@link #createCentury()}. + * @draft ICU 64 */ - static MeasureUnit *createAstronomicalUnit(UErrorCode &status); + static MeasureUnit getCentury(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of length: centimeter. + * Returns by pointer, unit of duration: day. * Caller owns returned value and must free it. + * Also see {@link #getDay()}. * @param status ICU error code. * @stable ICU 53 */ - static MeasureUnit *createCentimeter(UErrorCode &status); + static MeasureUnit *createDay(UErrorCode &status); #ifndef U_HIDE_DRAFT_API /** - * Returns unit of length: decimeter. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of duration: day. + * Also see {@link #createDay()}. + * @draft ICU 64 */ - static MeasureUnit *createDecimeter(UErrorCode &status); + static MeasureUnit getDay(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of length: fathom. + * Returns by pointer, unit of duration: day-person. * Caller owns returned value and must free it. + * Also see {@link #getDayPerson()}. * @param status ICU error code. - * @draft ICU 54 + * @draft ICU 64 */ - static MeasureUnit *createFathom(UErrorCode &status); + static MeasureUnit *createDayPerson(UErrorCode &status); +#endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of duration: day-person. + * Also see {@link #createDayPerson()}. + * @draft ICU 64 + */ + static MeasureUnit getDayPerson(); #endif /* U_HIDE_DRAFT_API */ + /** - * Returns unit of length: foot. + * Returns by pointer, unit of duration: hour. * Caller owns returned value and must free it. + * Also see {@link #getHour()}. * @param status ICU error code. * @stable ICU 53 */ - static MeasureUnit *createFoot(UErrorCode &status); + static MeasureUnit *createHour(UErrorCode &status); #ifndef U_HIDE_DRAFT_API /** - * Returns unit of length: furlong. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of duration: hour. + * Also see {@link #createHour()}. + * @draft ICU 64 */ - static MeasureUnit *createFurlong(UErrorCode &status); + static MeasureUnit getHour(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of length: inch. + * Returns by pointer, unit of duration: microsecond. * Caller owns returned value and must free it. + * Also see {@link #getMicrosecond()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createMicrosecond(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of duration: microsecond. + * Also see {@link #createMicrosecond()}. + * @draft ICU 64 + */ + static MeasureUnit getMicrosecond(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of duration: millisecond. + * Caller owns returned value and must free it. + * Also see {@link #getMillisecond()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createMillisecond(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of duration: millisecond. + * Also see {@link #createMillisecond()}. + * @draft ICU 64 + */ + static MeasureUnit getMillisecond(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of duration: minute. + * Caller owns returned value and must free it. + * Also see {@link #getMinute()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createMinute(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of duration: minute. + * Also see {@link #createMinute()}. + * @draft ICU 64 + */ + static MeasureUnit getMinute(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of duration: month. + * Caller owns returned value and must free it. + * Also see {@link #getMonth()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createMonth(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of duration: month. + * Also see {@link #createMonth()}. + * @draft ICU 64 + */ + static MeasureUnit getMonth(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of duration: month-person. + * Caller owns returned value and must free it. + * Also see {@link #getMonthPerson()}. + * @param status ICU error code. + * @draft ICU 64 + */ + static MeasureUnit *createMonthPerson(UErrorCode &status); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of duration: month-person. + * Also see {@link #createMonthPerson()}. + * @draft ICU 64 + */ + static MeasureUnit getMonthPerson(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of duration: nanosecond. + * Caller owns returned value and must free it. + * Also see {@link #getNanosecond()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createNanosecond(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of duration: nanosecond. + * Also see {@link #createNanosecond()}. + * @draft ICU 64 + */ + static MeasureUnit getNanosecond(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of duration: second. + * Caller owns returned value and must free it. + * Also see {@link #getSecond()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createSecond(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of duration: second. + * Also see {@link #createSecond()}. + * @draft ICU 64 + */ + static MeasureUnit getSecond(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of duration: week. + * Caller owns returned value and must free it. + * Also see {@link #getWeek()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createWeek(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of duration: week. + * Also see {@link #createWeek()}. + * @draft ICU 64 + */ + static MeasureUnit getWeek(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of duration: week-person. + * Caller owns returned value and must free it. + * Also see {@link #getWeekPerson()}. + * @param status ICU error code. + * @draft ICU 64 + */ + static MeasureUnit *createWeekPerson(UErrorCode &status); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of duration: week-person. + * Also see {@link #createWeekPerson()}. + * @draft ICU 64 + */ + static MeasureUnit getWeekPerson(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of duration: year. + * Caller owns returned value and must free it. + * Also see {@link #getYear()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createYear(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of duration: year. + * Also see {@link #createYear()}. + * @draft ICU 64 + */ + static MeasureUnit getYear(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of duration: year-person. + * Caller owns returned value and must free it. + * Also see {@link #getYearPerson()}. + * @param status ICU error code. + * @draft ICU 64 + */ + static MeasureUnit *createYearPerson(UErrorCode &status); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of duration: year-person. + * Also see {@link #createYearPerson()}. + * @draft ICU 64 + */ + static MeasureUnit getYearPerson(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of electric: ampere. + * Caller owns returned value and must free it. + * Also see {@link #getAmpere()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createAmpere(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of electric: ampere. + * Also see {@link #createAmpere()}. + * @draft ICU 64 + */ + static MeasureUnit getAmpere(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of electric: milliampere. + * Caller owns returned value and must free it. + * Also see {@link #getMilliampere()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createMilliampere(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of electric: milliampere. + * Also see {@link #createMilliampere()}. + * @draft ICU 64 + */ + static MeasureUnit getMilliampere(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of electric: ohm. + * Caller owns returned value and must free it. + * Also see {@link #getOhm()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createOhm(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of electric: ohm. + * Also see {@link #createOhm()}. + * @draft ICU 64 + */ + static MeasureUnit getOhm(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of electric: volt. + * Caller owns returned value and must free it. + * Also see {@link #getVolt()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createVolt(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of electric: volt. + * Also see {@link #createVolt()}. + * @draft ICU 64 + */ + static MeasureUnit getVolt(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of energy: british-thermal-unit. + * Caller owns returned value and must free it. + * Also see {@link #getBritishThermalUnit()}. + * @param status ICU error code. + * @draft ICU 64 + */ + static MeasureUnit *createBritishThermalUnit(UErrorCode &status); + + /** + * Returns by value, unit of energy: british-thermal-unit. + * Also see {@link #createBritishThermalUnit()}. + * @draft ICU 64 + */ + static MeasureUnit getBritishThermalUnit(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of energy: calorie. + * Caller owns returned value and must free it. + * Also see {@link #getCalorie()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createCalorie(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of energy: calorie. + * Also see {@link #createCalorie()}. + * @draft ICU 64 + */ + static MeasureUnit getCalorie(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of energy: electronvolt. + * Caller owns returned value and must free it. + * Also see {@link #getElectronvolt()}. + * @param status ICU error code. + * @draft ICU 64 + */ + static MeasureUnit *createElectronvolt(UErrorCode &status); + + /** + * Returns by value, unit of energy: electronvolt. + * Also see {@link #createElectronvolt()}. + * @draft ICU 64 + */ + static MeasureUnit getElectronvolt(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of energy: foodcalorie. + * Caller owns returned value and must free it. + * Also see {@link #getFoodcalorie()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createFoodcalorie(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of energy: foodcalorie. + * Also see {@link #createFoodcalorie()}. + * @draft ICU 64 + */ + static MeasureUnit getFoodcalorie(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of energy: joule. + * Caller owns returned value and must free it. + * Also see {@link #getJoule()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createJoule(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of energy: joule. + * Also see {@link #createJoule()}. + * @draft ICU 64 + */ + static MeasureUnit getJoule(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of energy: kilocalorie. + * Caller owns returned value and must free it. + * Also see {@link #getKilocalorie()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createKilocalorie(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of energy: kilocalorie. + * Also see {@link #createKilocalorie()}. + * @draft ICU 64 + */ + static MeasureUnit getKilocalorie(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of energy: kilojoule. + * Caller owns returned value and must free it. + * Also see {@link #getKilojoule()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createKilojoule(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of energy: kilojoule. + * Also see {@link #createKilojoule()}. + * @draft ICU 64 + */ + static MeasureUnit getKilojoule(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of energy: kilowatt-hour. + * Caller owns returned value and must free it. + * Also see {@link #getKilowattHour()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createKilowattHour(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of energy: kilowatt-hour. + * Also see {@link #createKilowattHour()}. + * @draft ICU 64 + */ + static MeasureUnit getKilowattHour(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of force: newton. + * Caller owns returned value and must free it. + * Also see {@link #getNewton()}. + * @param status ICU error code. + * @draft ICU 64 + */ + static MeasureUnit *createNewton(UErrorCode &status); + + /** + * Returns by value, unit of force: newton. + * Also see {@link #createNewton()}. + * @draft ICU 64 + */ + static MeasureUnit getNewton(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of force: pound-force. + * Caller owns returned value and must free it. + * Also see {@link #getPoundForce()}. + * @param status ICU error code. + * @draft ICU 64 + */ + static MeasureUnit *createPoundForce(UErrorCode &status); + + /** + * Returns by value, unit of force: pound-force. + * Also see {@link #createPoundForce()}. + * @draft ICU 64 + */ + static MeasureUnit getPoundForce(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of frequency: gigahertz. + * Caller owns returned value and must free it. + * Also see {@link #getGigahertz()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createGigahertz(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of frequency: gigahertz. + * Also see {@link #createGigahertz()}. + * @draft ICU 64 + */ + static MeasureUnit getGigahertz(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of frequency: hertz. + * Caller owns returned value and must free it. + * Also see {@link #getHertz()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createHertz(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of frequency: hertz. + * Also see {@link #createHertz()}. + * @draft ICU 64 + */ + static MeasureUnit getHertz(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of frequency: kilohertz. + * Caller owns returned value and must free it. + * Also see {@link #getKilohertz()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createKilohertz(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of frequency: kilohertz. + * Also see {@link #createKilohertz()}. + * @draft ICU 64 + */ + static MeasureUnit getKilohertz(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of frequency: megahertz. + * Caller owns returned value and must free it. + * Also see {@link #getMegahertz()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createMegahertz(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of frequency: megahertz. + * Also see {@link #createMegahertz()}. + * @draft ICU 64 + */ + static MeasureUnit getMegahertz(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: astronomical-unit. + * Caller owns returned value and must free it. + * Also see {@link #getAstronomicalUnit()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createAstronomicalUnit(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: astronomical-unit. + * Also see {@link #createAstronomicalUnit()}. + * @draft ICU 64 + */ + static MeasureUnit getAstronomicalUnit(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: centimeter. + * Caller owns returned value and must free it. + * Also see {@link #getCentimeter()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createCentimeter(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: centimeter. + * Also see {@link #createCentimeter()}. + * @draft ICU 64 + */ + static MeasureUnit getCentimeter(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: decimeter. + * Caller owns returned value and must free it. + * Also see {@link #getDecimeter()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createDecimeter(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: decimeter. + * Also see {@link #createDecimeter()}. + * @draft ICU 64 + */ + static MeasureUnit getDecimeter(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: fathom. + * Caller owns returned value and must free it. + * Also see {@link #getFathom()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createFathom(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: fathom. + * Also see {@link #createFathom()}. + * @draft ICU 64 + */ + static MeasureUnit getFathom(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: foot. + * Caller owns returned value and must free it. + * Also see {@link #getFoot()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createFoot(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: foot. + * Also see {@link #createFoot()}. + * @draft ICU 64 + */ + static MeasureUnit getFoot(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: furlong. + * Caller owns returned value and must free it. + * Also see {@link #getFurlong()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createFurlong(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: furlong. + * Also see {@link #createFurlong()}. + * @draft ICU 64 + */ + static MeasureUnit getFurlong(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: inch. + * Caller owns returned value and must free it. + * Also see {@link #getInch()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createInch(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: inch. + * Also see {@link #createInch()}. + * @draft ICU 64 + */ + static MeasureUnit getInch(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: kilometer. + * Caller owns returned value and must free it. + * Also see {@link #getKilometer()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createKilometer(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: kilometer. + * Also see {@link #createKilometer()}. + * @draft ICU 64 + */ + static MeasureUnit getKilometer(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: light-year. + * Caller owns returned value and must free it. + * Also see {@link #getLightYear()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createLightYear(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: light-year. + * Also see {@link #createLightYear()}. + * @draft ICU 64 + */ + static MeasureUnit getLightYear(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: meter. + * Caller owns returned value and must free it. + * Also see {@link #getMeter()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createMeter(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: meter. + * Also see {@link #createMeter()}. + * @draft ICU 64 + */ + static MeasureUnit getMeter(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: micrometer. + * Caller owns returned value and must free it. + * Also see {@link #getMicrometer()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createMicrometer(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: micrometer. + * Also see {@link #createMicrometer()}. + * @draft ICU 64 + */ + static MeasureUnit getMicrometer(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: mile. + * Caller owns returned value and must free it. + * Also see {@link #getMile()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createMile(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: mile. + * Also see {@link #createMile()}. + * @draft ICU 64 + */ + static MeasureUnit getMile(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: mile-scandinavian. + * Caller owns returned value and must free it. + * Also see {@link #getMileScandinavian()}. + * @param status ICU error code. + * @stable ICU 56 + */ + static MeasureUnit *createMileScandinavian(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: mile-scandinavian. + * Also see {@link #createMileScandinavian()}. + * @draft ICU 64 + */ + static MeasureUnit getMileScandinavian(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: millimeter. + * Caller owns returned value and must free it. + * Also see {@link #getMillimeter()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createMillimeter(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: millimeter. + * Also see {@link #createMillimeter()}. + * @draft ICU 64 + */ + static MeasureUnit getMillimeter(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: nanometer. + * Caller owns returned value and must free it. + * Also see {@link #getNanometer()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createNanometer(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: nanometer. + * Also see {@link #createNanometer()}. + * @draft ICU 64 + */ + static MeasureUnit getNanometer(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: nautical-mile. + * Caller owns returned value and must free it. + * Also see {@link #getNauticalMile()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createNauticalMile(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: nautical-mile. + * Also see {@link #createNauticalMile()}. + * @draft ICU 64 + */ + static MeasureUnit getNauticalMile(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: parsec. + * Caller owns returned value and must free it. + * Also see {@link #getParsec()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createParsec(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: parsec. + * Also see {@link #createParsec()}. + * @draft ICU 64 + */ + static MeasureUnit getParsec(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: picometer. + * Caller owns returned value and must free it. + * Also see {@link #getPicometer()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createPicometer(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: picometer. + * Also see {@link #createPicometer()}. + * @draft ICU 64 + */ + static MeasureUnit getPicometer(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: point. + * Caller owns returned value and must free it. + * Also see {@link #getPoint()}. + * @param status ICU error code. + * @stable ICU 59 + */ + static MeasureUnit *createPoint(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: point. + * Also see {@link #createPoint()}. + * @draft ICU 64 + */ + static MeasureUnit getPoint(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of length: solar-radius. + * Caller owns returned value and must free it. + * Also see {@link #getSolarRadius()}. + * @param status ICU error code. + * @draft ICU 64 + */ + static MeasureUnit *createSolarRadius(UErrorCode &status); + + /** + * Returns by value, unit of length: solar-radius. + * Also see {@link #createSolarRadius()}. + * @draft ICU 64 + */ + static MeasureUnit getSolarRadius(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of length: yard. + * Caller owns returned value and must free it. + * Also see {@link #getYard()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createYard(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of length: yard. + * Also see {@link #createYard()}. + * @draft ICU 64 + */ + static MeasureUnit getYard(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of light: lux. + * Caller owns returned value and must free it. + * Also see {@link #getLux()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createLux(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of light: lux. + * Also see {@link #createLux()}. + * @draft ICU 64 + */ + static MeasureUnit getLux(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of light: solar-luminosity. + * Caller owns returned value and must free it. + * Also see {@link #getSolarLuminosity()}. + * @param status ICU error code. + * @draft ICU 64 + */ + static MeasureUnit *createSolarLuminosity(UErrorCode &status); + + /** + * Returns by value, unit of light: solar-luminosity. + * Also see {@link #createSolarLuminosity()}. + * @draft ICU 64 + */ + static MeasureUnit getSolarLuminosity(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of mass: carat. + * Caller owns returned value and must free it. + * Also see {@link #getCarat()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createCarat(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of mass: carat. + * Also see {@link #createCarat()}. + * @draft ICU 64 + */ + static MeasureUnit getCarat(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of mass: dalton. + * Caller owns returned value and must free it. + * Also see {@link #getDalton()}. + * @param status ICU error code. + * @draft ICU 64 + */ + static MeasureUnit *createDalton(UErrorCode &status); + + /** + * Returns by value, unit of mass: dalton. + * Also see {@link #createDalton()}. + * @draft ICU 64 + */ + static MeasureUnit getDalton(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of mass: earth-mass. + * Caller owns returned value and must free it. + * Also see {@link #getEarthMass()}. + * @param status ICU error code. + * @draft ICU 64 + */ + static MeasureUnit *createEarthMass(UErrorCode &status); + + /** + * Returns by value, unit of mass: earth-mass. + * Also see {@link #createEarthMass()}. + * @draft ICU 64 + */ + static MeasureUnit getEarthMass(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of mass: gram. + * Caller owns returned value and must free it. + * Also see {@link #getGram()}. * @param status ICU error code. * @stable ICU 53 */ - static MeasureUnit *createInch(UErrorCode &status); + static MeasureUnit *createGram(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of mass: gram. + * Also see {@link #createGram()}. + * @draft ICU 64 + */ + static MeasureUnit getGram(); +#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of length: kilometer. + * Returns by pointer, unit of mass: kilogram. * Caller owns returned value and must free it. + * Also see {@link #getKilogram()}. * @param status ICU error code. * @stable ICU 53 */ - static MeasureUnit *createKilometer(UErrorCode &status); + static MeasureUnit *createKilogram(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of mass: kilogram. + * Also see {@link #createKilogram()}. + * @draft ICU 64 + */ + static MeasureUnit getKilogram(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of mass: metric-ton. + * Caller owns returned value and must free it. + * Also see {@link #getMetricTon()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createMetricTon(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of mass: metric-ton. + * Also see {@link #createMetricTon()}. + * @draft ICU 64 + */ + static MeasureUnit getMetricTon(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of mass: microgram. + * Caller owns returned value and must free it. + * Also see {@link #getMicrogram()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createMicrogram(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of mass: microgram. + * Also see {@link #createMicrogram()}. + * @draft ICU 64 + */ + static MeasureUnit getMicrogram(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of mass: milligram. + * Caller owns returned value and must free it. + * Also see {@link #getMilligram()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createMilligram(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of mass: milligram. + * Also see {@link #createMilligram()}. + * @draft ICU 64 + */ + static MeasureUnit getMilligram(); +#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of length: light-year. + * Returns by pointer, unit of mass: ounce. * Caller owns returned value and must free it. + * Also see {@link #getOunce()}. * @param status ICU error code. * @stable ICU 53 */ - static MeasureUnit *createLightYear(UErrorCode &status); + static MeasureUnit *createOunce(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of mass: ounce. + * Also see {@link #createOunce()}. + * @draft ICU 64 + */ + static MeasureUnit getOunce(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of mass: ounce-troy. + * Caller owns returned value and must free it. + * Also see {@link #getOunceTroy()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createOunceTroy(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of mass: ounce-troy. + * Also see {@link #createOunceTroy()}. + * @draft ICU 64 + */ + static MeasureUnit getOunceTroy(); +#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of length: meter. + * Returns by pointer, unit of mass: pound. * Caller owns returned value and must free it. + * Also see {@link #getPound()}. * @param status ICU error code. * @stable ICU 53 */ - static MeasureUnit *createMeter(UErrorCode &status); + static MeasureUnit *createPound(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of mass: pound. + * Also see {@link #createPound()}. + * @draft ICU 64 + */ + static MeasureUnit getPound(); +#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of length: micrometer. + * Returns by pointer, unit of mass: solar-mass. * Caller owns returned value and must free it. + * Also see {@link #getSolarMass()}. * @param status ICU error code. - * @draft ICU 54 + * @draft ICU 64 */ - static MeasureUnit *createMicrometer(UErrorCode &status); + static MeasureUnit *createSolarMass(UErrorCode &status); + + /** + * Returns by value, unit of mass: solar-mass. + * Also see {@link #createSolarMass()}. + * @draft ICU 64 + */ + static MeasureUnit getSolarMass(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of mass: stone. + * Caller owns returned value and must free it. + * Also see {@link #getStone()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createStone(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of mass: stone. + * Also see {@link #createStone()}. + * @draft ICU 64 + */ + static MeasureUnit getStone(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of mass: ton. + * Caller owns returned value and must free it. + * Also see {@link #getTon()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createTon(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of mass: ton. + * Also see {@link #createTon()}. + * @draft ICU 64 + */ + static MeasureUnit getTon(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of power: gigawatt. + * Caller owns returned value and must free it. + * Also see {@link #getGigawatt()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createGigawatt(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of power: gigawatt. + * Also see {@link #createGigawatt()}. + * @draft ICU 64 + */ + static MeasureUnit getGigawatt(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of power: horsepower. + * Caller owns returned value and must free it. + * Also see {@link #getHorsepower()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createHorsepower(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of power: horsepower. + * Also see {@link #createHorsepower()}. + * @draft ICU 64 + */ + static MeasureUnit getHorsepower(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of power: kilowatt. + * Caller owns returned value and must free it. + * Also see {@link #getKilowatt()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createKilowatt(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of power: kilowatt. + * Also see {@link #createKilowatt()}. + * @draft ICU 64 + */ + static MeasureUnit getKilowatt(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of power: megawatt. + * Caller owns returned value and must free it. + * Also see {@link #getMegawatt()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createMegawatt(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of power: megawatt. + * Also see {@link #createMegawatt()}. + * @draft ICU 64 + */ + static MeasureUnit getMegawatt(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of power: milliwatt. + * Caller owns returned value and must free it. + * Also see {@link #getMilliwatt()}. + * @param status ICU error code. + * @stable ICU 54 + */ + static MeasureUnit *createMilliwatt(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of power: milliwatt. + * Also see {@link #createMilliwatt()}. + * @draft ICU 64 + */ + static MeasureUnit getMilliwatt(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of power: watt. + * Caller owns returned value and must free it. + * Also see {@link #getWatt()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createWatt(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of power: watt. + * Also see {@link #createWatt()}. + * @draft ICU 64 + */ + static MeasureUnit getWatt(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of pressure: atmosphere. + * Caller owns returned value and must free it. + * Also see {@link #getAtmosphere()}. + * @param status ICU error code. + * @draft ICU 63 + */ + static MeasureUnit *createAtmosphere(UErrorCode &status); +#endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of pressure: atmosphere. + * Also see {@link #createAtmosphere()}. + * @draft ICU 64 + */ + static MeasureUnit getAtmosphere(); #endif /* U_HIDE_DRAFT_API */ + /** - * Returns unit of length: mile. + * Returns by pointer, unit of pressure: hectopascal. * Caller owns returned value and must free it. + * Also see {@link #getHectopascal()}. * @param status ICU error code. * @stable ICU 53 */ - static MeasureUnit *createMile(UErrorCode &status); + static MeasureUnit *createHectopascal(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of pressure: hectopascal. + * Also see {@link #createHectopascal()}. + * @draft ICU 64 + */ + static MeasureUnit getHectopascal(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of pressure: inch-hg. + * Caller owns returned value and must free it. + * Also see {@link #getInchHg()}. + * @param status ICU error code. + * @stable ICU 53 + */ + static MeasureUnit *createInchHg(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of pressure: inch-hg. + * Also see {@link #createInchHg()}. + * @draft ICU 64 + */ + static MeasureUnit getInchHg(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of pressure: kilopascal. + * Caller owns returned value and must free it. + * Also see {@link #getKilopascal()}. + * @param status ICU error code. + * @draft ICU 64 + */ + static MeasureUnit *createKilopascal(UErrorCode &status); + + /** + * Returns by value, unit of pressure: kilopascal. + * Also see {@link #createKilopascal()}. + * @draft ICU 64 + */ + static MeasureUnit getKilopascal(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of pressure: megapascal. + * Caller owns returned value and must free it. + * Also see {@link #getMegapascal()}. + * @param status ICU error code. + * @draft ICU 64 + */ + static MeasureUnit *createMegapascal(UErrorCode &status); + + /** + * Returns by value, unit of pressure: megapascal. + * Also see {@link #createMegapascal()}. + * @draft ICU 64 + */ + static MeasureUnit getMegapascal(); +#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of length: millimeter. + * Returns by pointer, unit of pressure: millibar. * Caller owns returned value and must free it. + * Also see {@link #getMillibar()}. * @param status ICU error code. * @stable ICU 53 */ - static MeasureUnit *createMillimeter(UErrorCode &status); + static MeasureUnit *createMillibar(UErrorCode &status); #ifndef U_HIDE_DRAFT_API /** - * Returns unit of length: nanometer. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of pressure: millibar. + * Also see {@link #createMillibar()}. + * @draft ICU 64 */ - static MeasureUnit *createNanometer(UErrorCode &status); + static MeasureUnit getMillibar(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** - * Returns unit of length: nautical-mile. + * Returns by pointer, unit of pressure: millimeter-of-mercury. * Caller owns returned value and must free it. + * Also see {@link #getMillimeterOfMercury()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ - static MeasureUnit *createNauticalMile(UErrorCode &status); + static MeasureUnit *createMillimeterOfMercury(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of length: parsec. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of pressure: millimeter-of-mercury. + * Also see {@link #createMillimeterOfMercury()}. + * @draft ICU 64 */ - static MeasureUnit *createParsec(UErrorCode &status); + static MeasureUnit getMillimeterOfMercury(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of length: picometer. + * Returns by pointer, unit of pressure: pound-per-square-inch. * Caller owns returned value and must free it. + * Also see {@link #getPoundPerSquareInch()}. * @param status ICU error code. - * @stable ICU 53 + * @stable ICU 54 */ - static MeasureUnit *createPicometer(UErrorCode &status); + static MeasureUnit *createPoundPerSquareInch(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of pressure: pound-per-square-inch. + * Also see {@link #createPoundPerSquareInch()}. + * @draft ICU 64 + */ + static MeasureUnit getPoundPerSquareInch(); +#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of length: yard. + * Returns by pointer, unit of speed: kilometer-per-hour. * Caller owns returned value and must free it. + * Also see {@link #getKilometerPerHour()}. * @param status ICU error code. * @stable ICU 53 */ - static MeasureUnit *createYard(UErrorCode &status); + static MeasureUnit *createKilometerPerHour(UErrorCode &status); #ifndef U_HIDE_DRAFT_API /** - * Returns unit of light: lux. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of speed: kilometer-per-hour. + * Also see {@link #createKilometerPerHour()}. + * @draft ICU 64 */ - static MeasureUnit *createLux(UErrorCode &status); + static MeasureUnit getKilometerPerHour(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** - * Returns unit of mass: carat. + * Returns by pointer, unit of speed: knot. * Caller owns returned value and must free it. + * Also see {@link #getKnot()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 56 */ - static MeasureUnit *createCarat(UErrorCode &status); + static MeasureUnit *createKnot(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DRAFT_API /** - * Returns unit of mass: gram. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @stable ICU 53 + * Returns by value, unit of speed: knot. + * Also see {@link #createKnot()}. + * @draft ICU 64 */ - static MeasureUnit *createGram(UErrorCode &status); + static MeasureUnit getKnot(); +#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of mass: kilogram. + * Returns by pointer, unit of speed: meter-per-second. * Caller owns returned value and must free it. + * Also see {@link #getMeterPerSecond()}. * @param status ICU error code. * @stable ICU 53 */ - static MeasureUnit *createKilogram(UErrorCode &status); + static MeasureUnit *createMeterPerSecond(UErrorCode &status); #ifndef U_HIDE_DRAFT_API /** - * Returns unit of mass: metric-ton. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of speed: meter-per-second. + * Also see {@link #createMeterPerSecond()}. + * @draft ICU 64 */ - static MeasureUnit *createMetricTon(UErrorCode &status); + static MeasureUnit getMeterPerSecond(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** - * Returns unit of mass: microgram. + * Returns by pointer, unit of speed: mile-per-hour. * Caller owns returned value and must free it. + * Also see {@link #getMilePerHour()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 53 */ - static MeasureUnit *createMicrogram(UErrorCode &status); + static MeasureUnit *createMilePerHour(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of mass: milligram. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of speed: mile-per-hour. + * Also see {@link #createMilePerHour()}. + * @draft ICU 64 */ - static MeasureUnit *createMilligram(UErrorCode &status); + static MeasureUnit getMilePerHour(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of mass: ounce. + * Returns by pointer, unit of temperature: celsius. * Caller owns returned value and must free it. + * Also see {@link #getCelsius()}. * @param status ICU error code. * @stable ICU 53 */ - static MeasureUnit *createOunce(UErrorCode &status); + static MeasureUnit *createCelsius(UErrorCode &status); #ifndef U_HIDE_DRAFT_API /** - * Returns unit of mass: ounce-troy. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of temperature: celsius. + * Also see {@link #createCelsius()}. + * @draft ICU 64 */ - static MeasureUnit *createOunceTroy(UErrorCode &status); + static MeasureUnit getCelsius(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of mass: pound. + * Returns by pointer, unit of temperature: fahrenheit. * Caller owns returned value and must free it. + * Also see {@link #getFahrenheit()}. * @param status ICU error code. * @stable ICU 53 */ - static MeasureUnit *createPound(UErrorCode &status); + static MeasureUnit *createFahrenheit(UErrorCode &status); #ifndef U_HIDE_DRAFT_API /** - * Returns unit of mass: stone. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of temperature: fahrenheit. + * Also see {@link #createFahrenheit()}. + * @draft ICU 64 */ - static MeasureUnit *createStone(UErrorCode &status); + static MeasureUnit getFahrenheit(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** - * Returns unit of mass: ton. + * Returns by pointer, unit of temperature: generic. * Caller owns returned value and must free it. + * Also see {@link #getGenericTemperature()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 56 */ - static MeasureUnit *createTon(UErrorCode &status); + static MeasureUnit *createGenericTemperature(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of power: gigawatt. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of temperature: generic. + * Also see {@link #createGenericTemperature()}. + * @draft ICU 64 */ - static MeasureUnit *createGigawatt(UErrorCode &status); + static MeasureUnit getGenericTemperature(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of power: horsepower. + * Returns by pointer, unit of temperature: kelvin. * Caller owns returned value and must free it. + * Also see {@link #getKelvin()}. * @param status ICU error code. - * @stable ICU 53 + * @stable ICU 54 */ - static MeasureUnit *createHorsepower(UErrorCode &status); + static MeasureUnit *createKelvin(UErrorCode &status); +#ifndef U_HIDE_DRAFT_API /** - * Returns unit of power: kilowatt. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @stable ICU 53 + * Returns by value, unit of temperature: kelvin. + * Also see {@link #createKelvin()}. + * @draft ICU 64 */ - static MeasureUnit *createKilowatt(UErrorCode &status); + static MeasureUnit getKelvin(); +#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of power: megawatt. + * Returns by pointer, unit of torque: newton-meter. * Caller owns returned value and must free it. + * Also see {@link #getNewtonMeter()}. * @param status ICU error code. - * @draft ICU 54 + * @draft ICU 64 */ - static MeasureUnit *createMegawatt(UErrorCode &status); + static MeasureUnit *createNewtonMeter(UErrorCode &status); + /** + * Returns by value, unit of torque: newton-meter. + * Also see {@link #createNewtonMeter()}. + * @draft ICU 64 + */ + static MeasureUnit getNewtonMeter(); #endif /* U_HIDE_DRAFT_API */ + #ifndef U_HIDE_DRAFT_API /** - * Returns unit of power: milliwatt. + * Returns by pointer, unit of torque: pound-foot. * Caller owns returned value and must free it. + * Also see {@link #getPoundFoot()}. * @param status ICU error code. - * @draft ICU 54 + * @draft ICU 64 */ - static MeasureUnit *createMilliwatt(UErrorCode &status); + static MeasureUnit *createPoundFoot(UErrorCode &status); + /** + * Returns by value, unit of torque: pound-foot. + * Also see {@link #createPoundFoot()}. + * @draft ICU 64 + */ + static MeasureUnit getPoundFoot(); #endif /* U_HIDE_DRAFT_API */ + /** - * Returns unit of power: watt. + * Returns by pointer, unit of volume: acre-foot. * Caller owns returned value and must free it. + * Also see {@link #getAcreFoot()}. * @param status ICU error code. - * @stable ICU 53 + * @stable ICU 54 */ - static MeasureUnit *createWatt(UErrorCode &status); + static MeasureUnit *createAcreFoot(UErrorCode &status); +#ifndef U_HIDE_DRAFT_API /** - * Returns unit of pressure: hectopascal. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @stable ICU 53 + * Returns by value, unit of volume: acre-foot. + * Also see {@link #createAcreFoot()}. + * @draft ICU 64 */ - static MeasureUnit *createHectopascal(UErrorCode &status); + static MeasureUnit getAcreFoot(); +#endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DRAFT_API /** - * Returns unit of pressure: inch-hg. + * Returns by pointer, unit of volume: barrel. * Caller owns returned value and must free it. + * Also see {@link #getBarrel()}. * @param status ICU error code. - * @stable ICU 53 + * @draft ICU 64 */ - static MeasureUnit *createInchHg(UErrorCode &status); + static MeasureUnit *createBarrel(UErrorCode &status); + + /** + * Returns by value, unit of volume: barrel. + * Also see {@link #createBarrel()}. + * @draft ICU 64 + */ + static MeasureUnit getBarrel(); +#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of pressure: millibar. + * Returns by pointer, unit of volume: bushel. * Caller owns returned value and must free it. + * Also see {@link #getBushel()}. * @param status ICU error code. - * @stable ICU 53 + * @stable ICU 54 */ - static MeasureUnit *createMillibar(UErrorCode &status); + static MeasureUnit *createBushel(UErrorCode &status); #ifndef U_HIDE_DRAFT_API /** - * Returns unit of pressure: millimeter-of-mercury. + * Returns by value, unit of volume: bushel. + * Also see {@link #createBushel()}. + * @draft ICU 64 + */ + static MeasureUnit getBushel(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of volume: centiliter. * Caller owns returned value and must free it. + * Also see {@link #getCentiliter()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ - static MeasureUnit *createMillimeterOfMercury(UErrorCode &status); + static MeasureUnit *createCentiliter(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of pressure: pound-per-square-inch. + * Returns by value, unit of volume: centiliter. + * Also see {@link #createCentiliter()}. + * @draft ICU 64 + */ + static MeasureUnit getCentiliter(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of volume: cubic-centimeter. * Caller owns returned value and must free it. + * Also see {@link #getCubicCentimeter()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ - static MeasureUnit *createPoundPerSquareInch(UErrorCode &status); + static MeasureUnit *createCubicCentimeter(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of proportion: karat. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of volume: cubic-centimeter. + * Also see {@link #createCubicCentimeter()}. + * @draft ICU 64 */ - static MeasureUnit *createKarat(UErrorCode &status); + static MeasureUnit getCubicCentimeter(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of speed: kilometer-per-hour. + * Returns by pointer, unit of volume: cubic-foot. * Caller owns returned value and must free it. + * Also see {@link #getCubicFoot()}. * @param status ICU error code. - * @stable ICU 53 + * @stable ICU 54 */ - static MeasureUnit *createKilometerPerHour(UErrorCode &status); + static MeasureUnit *createCubicFoot(UErrorCode &status); +#ifndef U_HIDE_DRAFT_API /** - * Returns unit of speed: meter-per-second. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @stable ICU 53 + * Returns by value, unit of volume: cubic-foot. + * Also see {@link #createCubicFoot()}. + * @draft ICU 64 */ - static MeasureUnit *createMeterPerSecond(UErrorCode &status); + static MeasureUnit getCubicFoot(); +#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of speed: mile-per-hour. + * Returns by pointer, unit of volume: cubic-inch. * Caller owns returned value and must free it. + * Also see {@link #getCubicInch()}. * @param status ICU error code. - * @stable ICU 53 + * @stable ICU 54 */ - static MeasureUnit *createMilePerHour(UErrorCode &status); + static MeasureUnit *createCubicInch(UErrorCode &status); +#ifndef U_HIDE_DRAFT_API /** - * Returns unit of temperature: celsius. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @stable ICU 53 + * Returns by value, unit of volume: cubic-inch. + * Also see {@link #createCubicInch()}. + * @draft ICU 64 */ - static MeasureUnit *createCelsius(UErrorCode &status); + static MeasureUnit getCubicInch(); +#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of temperature: fahrenheit. + * Returns by pointer, unit of volume: cubic-kilometer. * Caller owns returned value and must free it. + * Also see {@link #getCubicKilometer()}. * @param status ICU error code. * @stable ICU 53 */ - static MeasureUnit *createFahrenheit(UErrorCode &status); + static MeasureUnit *createCubicKilometer(UErrorCode &status); #ifndef U_HIDE_DRAFT_API /** - * Returns unit of temperature: kelvin. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of volume: cubic-kilometer. + * Also see {@link #createCubicKilometer()}. + * @draft ICU 64 */ - static MeasureUnit *createKelvin(UErrorCode &status); + static MeasureUnit getCubicKilometer(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** - * Apple-specific for now - * Returns unit of temperature: generic temperature. + * Returns by pointer, unit of volume: cubic-meter. * Caller owns returned value and must free it. + * Also see {@link #getCubicMeter()}. * @param status ICU error code. - * @internal + * @stable ICU 54 */ - static MeasureUnit *createGenericTemperature(UErrorCode &status); + static MeasureUnit *createCubicMeter(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: acre-foot. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of volume: cubic-meter. + * Also see {@link #createCubicMeter()}. + * @draft ICU 64 */ - static MeasureUnit *createAcreFoot(UErrorCode &status); + static MeasureUnit getCubicMeter(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: bushel. + * Returns by pointer, unit of volume: cubic-mile. * Caller owns returned value and must free it. + * Also see {@link #getCubicMile()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 53 */ - static MeasureUnit *createBushel(UErrorCode &status); + static MeasureUnit *createCubicMile(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: centiliter. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of volume: cubic-mile. + * Also see {@link #createCubicMile()}. + * @draft ICU 64 */ - static MeasureUnit *createCentiliter(UErrorCode &status); + static MeasureUnit getCubicMile(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: cubic-centimeter. + * Returns by pointer, unit of volume: cubic-yard. * Caller owns returned value and must free it. + * Also see {@link #getCubicYard()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ - static MeasureUnit *createCubicCentimeter(UErrorCode &status); + static MeasureUnit *createCubicYard(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: cubic-foot. + * Returns by value, unit of volume: cubic-yard. + * Also see {@link #createCubicYard()}. + * @draft ICU 64 + */ + static MeasureUnit getCubicYard(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of volume: cup. * Caller owns returned value and must free it. + * Also see {@link #getCup()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ - static MeasureUnit *createCubicFoot(UErrorCode &status); + static MeasureUnit *createCup(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: cubic-inch. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of volume: cup. + * Also see {@link #createCup()}. + * @draft ICU 64 */ - static MeasureUnit *createCubicInch(UErrorCode &status); + static MeasureUnit getCup(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of volume: cubic-kilometer. + * Returns by pointer, unit of volume: cup-metric. * Caller owns returned value and must free it. + * Also see {@link #getCupMetric()}. * @param status ICU error code. - * @stable ICU 53 + * @stable ICU 56 */ - static MeasureUnit *createCubicKilometer(UErrorCode &status); + static MeasureUnit *createCupMetric(UErrorCode &status); #ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: cubic-meter. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of volume: cup-metric. + * Also see {@link #createCupMetric()}. + * @draft ICU 64 */ - static MeasureUnit *createCubicMeter(UErrorCode &status); + static MeasureUnit getCupMetric(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ /** - * Returns unit of volume: cubic-mile. + * Returns by pointer, unit of volume: deciliter. * Caller owns returned value and must free it. + * Also see {@link #getDeciliter()}. * @param status ICU error code. - * @stable ICU 53 + * @stable ICU 54 */ - static MeasureUnit *createCubicMile(UErrorCode &status); + static MeasureUnit *createDeciliter(UErrorCode &status); #ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: cubic-yard. + * Returns by value, unit of volume: deciliter. + * Also see {@link #createDeciliter()}. + * @draft ICU 64 + */ + static MeasureUnit getDeciliter(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of volume: fluid-ounce. * Caller owns returned value and must free it. + * Also see {@link #getFluidOunce()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ - static MeasureUnit *createCubicYard(UErrorCode &status); + static MeasureUnit *createFluidOunce(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: cup. - * Caller owns returned value and must free it. - * @param status ICU error code. - * @draft ICU 54 + * Returns by value, unit of volume: fluid-ounce. + * Also see {@link #createFluidOunce()}. + * @draft ICU 64 */ - static MeasureUnit *createCup(UErrorCode &status); + static MeasureUnit getFluidOunce(); +#endif /* U_HIDE_DRAFT_API */ -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: deciliter. + * Returns by pointer, unit of volume: fluid-ounce-imperial. * Caller owns returned value and must free it. + * Also see {@link #getFluidOunceImperial()}. * @param status ICU error code. - * @draft ICU 54 + * @draft ICU 64 */ - static MeasureUnit *createDeciliter(UErrorCode &status); + static MeasureUnit *createFluidOunceImperial(UErrorCode &status); + /** + * Returns by value, unit of volume: fluid-ounce-imperial. + * Also see {@link #createFluidOunceImperial()}. + * @draft ICU 64 + */ + static MeasureUnit getFluidOunceImperial(); #endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API + /** - * Returns unit of volume: fluid-ounce. + * Returns by pointer, unit of volume: gallon. * Caller owns returned value and must free it. + * Also see {@link #getGallon()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ - static MeasureUnit *createFluidOunce(UErrorCode &status); + static MeasureUnit *createGallon(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: gallon. + * Returns by value, unit of volume: gallon. + * Also see {@link #createGallon()}. + * @draft ICU 64 + */ + static MeasureUnit getGallon(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of volume: gallon-imperial. * Caller owns returned value and must free it. + * Also see {@link #getGallonImperial()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 57 */ - static MeasureUnit *createGallon(UErrorCode &status); + static MeasureUnit *createGallonImperial(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: hectoliter. + * Returns by value, unit of volume: gallon-imperial. + * Also see {@link #createGallonImperial()}. + * @draft ICU 64 + */ + static MeasureUnit getGallonImperial(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of volume: hectoliter. * Caller owns returned value and must free it. + * Also see {@link #getHectoliter()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ static MeasureUnit *createHectoliter(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of volume: hectoliter. + * Also see {@link #createHectoliter()}. + * @draft ICU 64 + */ + static MeasureUnit getHectoliter(); +#endif /* U_HIDE_DRAFT_API */ + /** - * Returns unit of volume: liter. + * Returns by pointer, unit of volume: liter. * Caller owns returned value and must free it. + * Also see {@link #getLiter()}. * @param status ICU error code. * @stable ICU 53 */ @@ -1270,64 +2990,139 @@ class U_I18N_API MeasureUnit: public UObject { #ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: megaliter. + * Returns by value, unit of volume: liter. + * Also see {@link #createLiter()}. + * @draft ICU 64 + */ + static MeasureUnit getLiter(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of volume: megaliter. * Caller owns returned value and must free it. + * Also see {@link #getMegaliter()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ static MeasureUnit *createMegaliter(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: milliliter. + * Returns by value, unit of volume: megaliter. + * Also see {@link #createMegaliter()}. + * @draft ICU 64 + */ + static MeasureUnit getMegaliter(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of volume: milliliter. * Caller owns returned value and must free it. + * Also see {@link #getMilliliter()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ static MeasureUnit *createMilliliter(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: pint. + * Returns by value, unit of volume: milliliter. + * Also see {@link #createMilliliter()}. + * @draft ICU 64 + */ + static MeasureUnit getMilliliter(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of volume: pint. * Caller owns returned value and must free it. + * Also see {@link #getPint()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ static MeasureUnit *createPint(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: quart. + * Returns by value, unit of volume: pint. + * Also see {@link #createPint()}. + * @draft ICU 64 + */ + static MeasureUnit getPint(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of volume: pint-metric. + * Caller owns returned value and must free it. + * Also see {@link #getPintMetric()}. + * @param status ICU error code. + * @stable ICU 56 + */ + static MeasureUnit *createPintMetric(UErrorCode &status); + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of volume: pint-metric. + * Also see {@link #createPintMetric()}. + * @draft ICU 64 + */ + static MeasureUnit getPintMetric(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of volume: quart. * Caller owns returned value and must free it. + * Also see {@link #getQuart()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ static MeasureUnit *createQuart(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: tablespoon. + * Returns by value, unit of volume: quart. + * Also see {@link #createQuart()}. + * @draft ICU 64 + */ + static MeasureUnit getQuart(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of volume: tablespoon. * Caller owns returned value and must free it. + * Also see {@link #getTablespoon()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ static MeasureUnit *createTablespoon(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** - * Returns unit of volume: teaspoon. + * Returns by value, unit of volume: tablespoon. + * Also see {@link #createTablespoon()}. + * @draft ICU 64 + */ + static MeasureUnit getTablespoon(); +#endif /* U_HIDE_DRAFT_API */ + + /** + * Returns by pointer, unit of volume: teaspoon. * Caller owns returned value and must free it. + * Also see {@link #getTeaspoon()}. * @param status ICU error code. - * @draft ICU 54 + * @stable ICU 54 */ static MeasureUnit *createTeaspoon(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DRAFT_API + /** + * Returns by value, unit of volume: teaspoon. + * Also see {@link #createTeaspoon()}. + * @draft ICU 64 + */ + static MeasureUnit getTeaspoon(); +#endif /* U_HIDE_DRAFT_API */ + // End generated createXXX methods @@ -1346,6 +3141,12 @@ class U_I18N_API MeasureUnit: public UObject { */ void initCurrency(const char *isoCurrency); + /** + * For ICU use only. + * @internal + */ + void initNoUnit(const char *subtype); + #endif /* U_HIDE_INTERNAL_API */ private: @@ -1362,6 +3163,7 @@ class U_I18N_API MeasureUnit: public UObject { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // !UNCONFIG_NO_FORMATTING #endif // __MEASUREUNIT_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/measure.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/measure.h index c0f88bbdaa..a5a82f26b9 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/measure.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/measure.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2004-2015, International Business Machines @@ -22,6 +24,7 @@ #include "unicode/fmtable.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class MeasureUnit; @@ -154,6 +157,7 @@ inline const MeasureUnit& Measure::getUnit() const { } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // !UCONFIG_NO_FORMATTING #endif // __MEASURE_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/messagepattern.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/messagepattern.h index f8b8dfb43f..396f96e3bb 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/messagepattern.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/messagepattern.h @@ -1,10 +1,12 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2011-2013, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* * file name: messagepattern.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -294,6 +296,7 @@ enum { */ #define UMSGPAT_NO_NUMERIC_VALUE ((double)(-123456789)) +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class MessagePatternDoubleList; @@ -769,8 +772,8 @@ class U_COMMON_API MessagePattern : public UObject { * @stable ICU 4.8 */ UMessagePatternArgType getArgType() const { - UMessagePatternPartType type=getType(); - if(type==UMSGPAT_PART_TYPE_ARG_START || type==UMSGPAT_PART_TYPE_ARG_LIMIT) { + UMessagePatternPartType msgType=getType(); + if(msgType ==UMSGPAT_PART_TYPE_ARG_START || msgType ==UMSGPAT_PART_TYPE_ARG_LIMIT) { return (UMessagePatternArgType)value; } else { return UMSGPAT_ARG_TYPE_NONE; @@ -937,6 +940,7 @@ class U_COMMON_API MessagePattern : public UObject { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // !UCONFIG_NO_FORMATTING diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/module.private.modulemap b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/module.private.modulemap new file mode 100644 index 0000000000..3a445b39c2 --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/module.private.modulemap @@ -0,0 +1,90 @@ +module ICU_Private [extern_c] [system] { + header "icudataver.h" + header "icuplug.h" + header "localpointer.h" + header "parseerr.h" + header "platform.h" + header "ptypes.h" + header "putil.h" + header "ualoc.h" + header "uameasureformat.h" + header "uatimeunitformat.h" + header "ubidi.h" + header "ubiditransform.h" + header "ubrk.h" + header "ucal.h" + header "ucasemap.h" + header "ucat.h" + header "uchar.h" + header "uclean.h" + header "ucnv.h" + header "ucnv_cb.h" + header "ucnv_err.h" + header "ucnvsel.h" + header "ucol.h" + header "ucoleitr.h" + header "uconfig.h" + header "ucpmap.h" + header "ucptrie.h" + header "ucsdet.h" + header "ucurr.h" + header "udat.h" + header "udata.h" + header "udateintervalformat.h" + header "udatintv.h" + header "udatpg.h" + header "udisplaycontext.h" + header "uenum.h" + header "ufieldpositer.h" + header "uformattable.h" + header "uformattedvalue.h" + header "ugender.h" + header "uidna.h" + header "uiter.h" + header "uldnames.h" + header "ulistformatter.h" + header "uloc.h" + header "ulocdata.h" + header "umachine.h" + header "umisc.h" + header "umsg.h" + header "umutablecptrie.h" + header "unorm.h" + header "unorm2.h" + header "unum.h" + header "unumberformatter.h" + header "unumsys.h" + header "uplrule.h" + header "upluralrules.h" + header "urbtok.h" + header "uregex.h" + header "uregion.h" + header "ureldatefmt.h" + header "urename.h" + header "urep.h" + header "ures.h" + header "uscript.h" + header "usearch.h" + header "uset.h" + header "ushape.h" + header "uspoof.h" + header "usprep.h" + header "ustdio.h" + header "ustring.h" + header "ustringtrie.h" + header "utext.h" + header "utf.h" + header "utf16.h" + header "utf8.h" + header "utf_old.h" + header "utmscale.h" + header "utrace.h" + header "utrans.h" + header "utypes.h" + header "uvernum.h" + header "uversion.h" + + link "icucore" + + export * +} diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/msgfmt.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/msgfmt.h index 5de91e41ff..382a317b0e 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/msgfmt.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/msgfmt.h @@ -1,3 +1,5 @@ +// © 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. @@ -39,6 +41,7 @@ struct UHashtable; typedef struct UHashtable UHashtable; /**< @internal */ U_CDECL_END +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class AppendableWrapper; @@ -67,9 +70,8 @@ class NumberFormat; * if the pattern has named arguments (see {@link #usesNamedArguments()}). * *

    An argument might not specify any format type. In this case, - * a Number value is formatted with a default (for the locale) NumberFormat, - * a Date value is formatted with a default (for the locale) DateFormat, - * and for any other value its toString() value is used. + * a numeric value is formatted with a default (for the locale) NumberFormat, + * and a date/time value is formatted with a default (for the locale) DateFormat. * *

    An argument might specify a "simple" type for which the specified * Format object is created, cached and used. @@ -122,7 +124,7 @@ class NumberFormat; * argNumber = '0' | ('1'..'9' ('0'..'9')*) * * argType = "number" | "date" | "time" | "spellout" | "ordinal" | "duration" - * argStyle = "short" | "medium" | "long" | "full" | "integer" | "currency" | "percent" | argStyleText + * argStyle = "short" | "medium" | "long" | "full" | "integer" | "currency" | "percent" | argStyleText | "::" argSkeletonText * * *

      @@ -164,7 +166,7 @@ class NumberFormat; * (none) * null * - * number + * number * (none) * NumberFormat.createInstance(getLocale(), status) * @@ -180,6 +182,9 @@ class NumberFormat; * argStyleText * new DecimalFormat(argStyleText, new DecimalFormatSymbols(getLocale(), status), status) * + * argSkeletonText + * NumberFormatter::forSkeleton(argSkeletonText, status).locale(getLocale()).toFormat(status) + * * date * (none) * DateFormat.createDateInstance(kDefault, getLocale(), status) @@ -197,7 +202,10 @@ class NumberFormat; * DateFormat.createDateInstance(kFull, getLocale(), status) * * argStyleText - * new SimpleDateFormat(argStyleText, getLocale(), status) + * new SimpleDateFormat(argStyleText, getLocale(), status) + * + * argSkeletonText + * DateFormat::createInstanceForSkeleton(argSkeletonText, getLocale(), status) * * time * (none) @@ -216,7 +224,7 @@ class NumberFormat; * DateFormat.createTimeInstance(kFull, getLocale(), status) * * argStyleText - * new SimpleDateFormat(argStyleText, getLocale(), status) + * new SimpleDateFormat(argStyleText, getLocale(), status) * * spellout * argStyleText (optional) @@ -235,6 +243,19 @@ class NumberFormat; * *

      * + *

      Argument formatting

      + * + *

      Arguments are formatted according to their type, using the default + * ICU formatters for those types, unless otherwise specified.

      + * + *

      There are also several ways to control the formatting.

      + * + *

      We recommend you use default styles, predefined style values, skeletons, + * or preformatted values, but not pattern strings or custom format objects.

      + * + *

      For more details, see the + * ICU User Guide.

      + * *

      Usage Information

      * *

      Here are some examples of usage: @@ -252,11 +273,11 @@ class NumberFormat; * * UnicodeString result; * MessageFormat::format( - * "At {1,time} on {1,date}, there was {2} on planet {0,number}.", + * "At {1,time,::jmm} on {1,date,::dMMMM}, there was {2} on planet {0,number}.", * arguments, 3, result, success ); * * cout << "result: " << result << endl; - * //: At 4:34:20 PM on 23-Mar-98, there was a disturbance + * //: At 4:34 PM on March 23, there was a disturbance * // in the Force on planet 7. * \endcode * @@ -937,7 +958,7 @@ class U_I18N_API MessageFormat : public Format { * @return the index of the list which matches the keyword s. */ static int32_t findKeyword( const UnicodeString& s, - const UChar * const *list); + const char16_t * const *list); /** * Thin wrapper around the format(... AppendableWrapper ...) variant. @@ -989,6 +1010,8 @@ class U_I18N_API MessageFormat : public Format { void cacheExplicitFormats(UErrorCode& status); + int32_t skipLeadingSpaces(UnicodeString& style); + Format* createAppropriateFormat(UnicodeString& type, UnicodeString& style, Formattable::Type& formattableType, @@ -1086,6 +1109,7 @@ class U_I18N_API MessageFormat : public Format { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/normalizer2.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/normalizer2.h index c03cba39e9..0581f6bba1 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/normalizer2.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/normalizer2.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -6,7 +8,7 @@ * ******************************************************************************* * file name: normalizer2.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -26,12 +28,16 @@ #if !UCONFIG_NO_NORMALIZATION +#include "unicode/stringpiece.h" #include "unicode/uniset.h" #include "unicode/unistr.h" #include "unicode/unorm2.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN +class ByteSink; + /** * Unicode normalization functionality for standard Unicode normalization or * for using custom mapping tables. @@ -213,6 +219,35 @@ class U_COMMON_API Normalizer2 : public UObject { normalize(const UnicodeString &src, UnicodeString &dest, UErrorCode &errorCode) const = 0; + + /** + * Normalizes a UTF-8 string and optionally records how source substrings + * relate to changed and unchanged result substrings. + * + * Currently implemented completely only for "compose" modes, + * such as for NFC, NFKC, and NFKC_Casefold + * (UNORM2_COMPOSE and UNORM2_COMPOSE_CONTIGUOUS). + * Otherwise currently converts to & from UTF-16 and does not support edits. + * + * @param options Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET. + * @param src Source UTF-8 string. + * @param sink A ByteSink to which the normalized UTF-8 result string is written. + * sink.Flush() is called at the end. + * @param edits Records edits for index mapping, working with styled text, + * and getting only changes (if any). + * The Edits contents is undefined if any error occurs. + * This function calls edits->reset() first unless + * options includes U_EDITS_NO_RESET. edits can be nullptr. + * @param errorCode Standard ICU error code. Its input value must + * pass the U_SUCCESS() test, or else the function returns + * immediately. Check for U_FAILURE() on output or use with + * function chaining. (See User Guide for details.) + * @stable ICU 60 + */ + virtual void + normalizeUTF8(uint32_t options, StringPiece src, ByteSink &sink, + Edits *edits, UErrorCode &errorCode) const; + /** * Appends the normalized form of the second string to the first string * (merging them at the boundary) and returns the first string. @@ -280,7 +315,7 @@ class U_COMMON_API Normalizer2 : public UObject { * * When used on a standard NFC Normalizer2 instance, * it returns the Decomposition_Mapping only if the Decomposition_Type (dt) is Canonical (Can); - * in this case, the result contains either one or two code points (=1..4 UChars). + * in this case, the result contains either one or two code points (=1..4 char16_ts). * * This function is independent of the mode of the Normalizer2. * The default implementation returns FALSE. @@ -338,6 +373,30 @@ class U_COMMON_API Normalizer2 : public UObject { */ virtual UBool isNormalized(const UnicodeString &s, UErrorCode &errorCode) const = 0; + /** + * Tests if the UTF-8 string is normalized. + * Internally, in cases where the quickCheck() method would return "maybe" + * (which is only possible for the two COMPOSE modes) this method + * resolves to "yes" or "no" to provide a definitive result, + * at the cost of doing more work in those cases. + * + * This works for all normalization modes, + * but it is currently optimized for UTF-8 only for "compose" modes, + * such as for NFC, NFKC, and NFKC_Casefold + * (UNORM2_COMPOSE and UNORM2_COMPOSE_CONTIGUOUS). + * For other modes it currently converts to UTF-16 and calls isNormalized(). + * + * @param s UTF-8 input string + * @param errorCode Standard ICU error code. Its input value must + * pass the U_SUCCESS() test, or else the function returns + * immediately. Check for U_FAILURE() on output or use with + * function chaining. (See User Guide for details.) + * @return TRUE if s is normalized + * @stable ICU 60 + */ + virtual UBool + isNormalizedUTF8(StringPiece s, UErrorCode &errorCode) const; + /** * Tests if the string is normalized. @@ -477,7 +536,36 @@ class U_COMMON_API FilteredNormalizer2 : public Normalizer2 { virtual UnicodeString & normalize(const UnicodeString &src, UnicodeString &dest, - UErrorCode &errorCode) const; + UErrorCode &errorCode) const U_OVERRIDE; + + /** + * Normalizes a UTF-8 string and optionally records how source substrings + * relate to changed and unchanged result substrings. + * + * Currently implemented completely only for "compose" modes, + * such as for NFC, NFKC, and NFKC_Casefold + * (UNORM2_COMPOSE and UNORM2_COMPOSE_CONTIGUOUS). + * Otherwise currently converts to & from UTF-16 and does not support edits. + * + * @param options Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET. + * @param src Source UTF-8 string. + * @param sink A ByteSink to which the normalized UTF-8 result string is written. + * sink.Flush() is called at the end. + * @param edits Records edits for index mapping, working with styled text, + * and getting only changes (if any). + * The Edits contents is undefined if any error occurs. + * This function calls edits->reset() first unless + * options includes U_EDITS_NO_RESET. edits can be nullptr. + * @param errorCode Standard ICU error code. Its input value must + * pass the U_SUCCESS() test, or else the function returns + * immediately. Check for U_FAILURE() on output or use with + * function chaining. (See User Guide for details.) + * @stable ICU 60 + */ + virtual void + normalizeUTF8(uint32_t options, StringPiece src, ByteSink &sink, + Edits *edits, UErrorCode &errorCode) const U_OVERRIDE; + /** * Appends the normalized form of the second string to the first string * (merging them at the boundary) and returns the first string. @@ -495,7 +583,7 @@ class U_COMMON_API FilteredNormalizer2 : public Normalizer2 { virtual UnicodeString & normalizeSecondAndAppend(UnicodeString &first, const UnicodeString &second, - UErrorCode &errorCode) const; + UErrorCode &errorCode) const U_OVERRIDE; /** * Appends the second string to the first string * (merging them at the boundary) and returns the first string. @@ -513,7 +601,7 @@ class U_COMMON_API FilteredNormalizer2 : public Normalizer2 { virtual UnicodeString & append(UnicodeString &first, const UnicodeString &second, - UErrorCode &errorCode) const; + UErrorCode &errorCode) const U_OVERRIDE; /** * Gets the decomposition mapping of c. @@ -527,7 +615,7 @@ class U_COMMON_API FilteredNormalizer2 : public Normalizer2 { * @stable ICU 4.6 */ virtual UBool - getDecomposition(UChar32 c, UnicodeString &decomposition) const; + getDecomposition(UChar32 c, UnicodeString &decomposition) const U_OVERRIDE; /** * Gets the raw decomposition mapping of c. @@ -541,7 +629,7 @@ class U_COMMON_API FilteredNormalizer2 : public Normalizer2 { * @stable ICU 49 */ virtual UBool - getRawDecomposition(UChar32 c, UnicodeString &decomposition) const; + getRawDecomposition(UChar32 c, UnicodeString &decomposition) const U_OVERRIDE; /** * Performs pairwise composition of a & b and returns the composite if there is one. @@ -554,7 +642,7 @@ class U_COMMON_API FilteredNormalizer2 : public Normalizer2 { * @stable ICU 49 */ virtual UChar32 - composePair(UChar32 a, UChar32 b) const; + composePair(UChar32 a, UChar32 b) const U_OVERRIDE; /** * Gets the combining class of c. @@ -565,7 +653,7 @@ class U_COMMON_API FilteredNormalizer2 : public Normalizer2 { * @stable ICU 49 */ virtual uint8_t - getCombiningClass(UChar32 c) const; + getCombiningClass(UChar32 c) const U_OVERRIDE; /** * Tests if the string is normalized. @@ -579,7 +667,30 @@ class U_COMMON_API FilteredNormalizer2 : public Normalizer2 { * @stable ICU 4.4 */ virtual UBool - isNormalized(const UnicodeString &s, UErrorCode &errorCode) const; + isNormalized(const UnicodeString &s, UErrorCode &errorCode) const U_OVERRIDE; + /** + * Tests if the UTF-8 string is normalized. + * Internally, in cases where the quickCheck() method would return "maybe" + * (which is only possible for the two COMPOSE modes) this method + * resolves to "yes" or "no" to provide a definitive result, + * at the cost of doing more work in those cases. + * + * This works for all normalization modes, + * but it is currently optimized for UTF-8 only for "compose" modes, + * such as for NFC, NFKC, and NFKC_Casefold + * (UNORM2_COMPOSE and UNORM2_COMPOSE_CONTIGUOUS). + * For other modes it currently converts to UTF-16 and calls isNormalized(). + * + * @param s UTF-8 input string + * @param errorCode Standard ICU error code. Its input value must + * pass the U_SUCCESS() test, or else the function returns + * immediately. Check for U_FAILURE() on output or use with + * function chaining. (See User Guide for details.) + * @return TRUE if s is normalized + * @stable ICU 60 + */ + virtual UBool + isNormalizedUTF8(StringPiece s, UErrorCode &errorCode) const U_OVERRIDE; /** * Tests if the string is normalized. * For details see the Normalizer2 base class documentation. @@ -592,7 +703,7 @@ class U_COMMON_API FilteredNormalizer2 : public Normalizer2 { * @stable ICU 4.4 */ virtual UNormalizationCheckResult - quickCheck(const UnicodeString &s, UErrorCode &errorCode) const; + quickCheck(const UnicodeString &s, UErrorCode &errorCode) const U_OVERRIDE; /** * Returns the end of the normalized substring of the input string. * For details see the Normalizer2 base class documentation. @@ -605,7 +716,7 @@ class U_COMMON_API FilteredNormalizer2 : public Normalizer2 { * @stable ICU 4.4 */ virtual int32_t - spanQuickCheckYes(const UnicodeString &s, UErrorCode &errorCode) const; + spanQuickCheckYes(const UnicodeString &s, UErrorCode &errorCode) const U_OVERRIDE; /** * Tests if the character always has a normalization boundary before it, @@ -615,7 +726,7 @@ class U_COMMON_API FilteredNormalizer2 : public Normalizer2 { * @return TRUE if c has a normalization boundary before it * @stable ICU 4.4 */ - virtual UBool hasBoundaryBefore(UChar32 c) const; + virtual UBool hasBoundaryBefore(UChar32 c) const U_OVERRIDE; /** * Tests if the character always has a normalization boundary after it, @@ -625,7 +736,7 @@ class U_COMMON_API FilteredNormalizer2 : public Normalizer2 { * @return TRUE if c has a normalization boundary after it * @stable ICU 4.4 */ - virtual UBool hasBoundaryAfter(UChar32 c) const; + virtual UBool hasBoundaryAfter(UChar32 c) const U_OVERRIDE; /** * Tests if the character is normalization-inert. @@ -634,7 +745,7 @@ class U_COMMON_API FilteredNormalizer2 : public Normalizer2 { * @return TRUE if c is normalization-inert * @stable ICU 4.4 */ - virtual UBool isInert(UChar32 c) const; + virtual UBool isInert(UChar32 c) const U_OVERRIDE; private: UnicodeString & normalize(const UnicodeString &src, @@ -642,6 +753,12 @@ class U_COMMON_API FilteredNormalizer2 : public Normalizer2 { USetSpanCondition spanCondition, UErrorCode &errorCode) const; + void + normalizeUTF8(uint32_t options, const char *src, int32_t length, + ByteSink &sink, Edits *edits, + USetSpanCondition spanCondition, + UErrorCode &errorCode) const; + UnicodeString & normalizeSecondAndAppend(UnicodeString &first, const UnicodeString &second, @@ -653,6 +770,7 @@ class U_COMMON_API FilteredNormalizer2 : public Normalizer2 { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // !UCONFIG_NO_NORMALIZATION #endif // __NORMALIZER2_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/normlzr.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/normlzr.h index 06cbfd477e..eceb6e6b9d 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/normlzr.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/normlzr.h @@ -1,7 +1,9 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************** * COPYRIGHT: - * Copyright (c) 1996-2011, International Business Machines Corporation and + * Copyright (c) 1996-2015, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************** */ @@ -24,16 +26,19 @@ #include "unicode/unorm.h" #include "unicode/uobject.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** - * The Normalizer class supports the standard normalization forms described in - * - * Unicode Standard Annex #15: Unicode Normalization Forms. + * Old Unicode normalization API. * - * Note: This API has been replaced by the Normalizer2 class and is only available + * This API has been replaced by the Normalizer2 class and is only available * for backward compatibility. This class simply delegates to the Normalizer2 class. * There is one exception: The new API does not provide a replacement for Normalizer::compare(). * + * The Normalizer class supports the standard normalization forms described in + * + * Unicode Standard Annex #15: Unicode Normalization Forms. + * * The Normalizer class consists of two parts: * - static functions that normalize strings or test if strings are normalized * - a Normalizer object is an iterator that takes any kind of text and @@ -129,10 +134,11 @@ U_NAMESPACE_BEGIN */ class U_COMMON_API Normalizer : public UObject { public: +#ifndef U_HIDE_DEPRECATED_API /** * If DONE is returned from an iteration function that returns a code point, * then there are no more normalization results available. - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ enum { DONE=0xffff @@ -148,7 +154,7 @@ class U_COMMON_API Normalizer : public UObject { * will start at the beginning of the string. * * @param mode The normalization mode. - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ Normalizer(const UnicodeString& str, UNormalizationMode mode); @@ -161,9 +167,9 @@ class U_COMMON_API Normalizer : public UObject { * * @param length Length of the string, or -1 if NUL-terminated. * @param mode The normalization mode. - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ - Normalizer(const UChar* str, int32_t length, UNormalizationMode mode); + Normalizer(ConstChar16Ptr str, int32_t length, UNormalizationMode mode); /** * Creates a new Normalizer object for iterating over the @@ -173,20 +179,21 @@ class U_COMMON_API Normalizer : public UObject { * will start at the beginning of the string. * * @param mode The normalization mode. - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ Normalizer(const CharacterIterator& iter, UNormalizationMode mode); +#endif /* U_HIDE_DEPRECATED_API */ /** * Copy constructor. * @param copy The object to be copied. - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ Normalizer(const Normalizer& copy); /** * Destructor - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ virtual ~Normalizer(); @@ -195,6 +202,7 @@ class U_COMMON_API Normalizer : public UObject { // Static utility methods //------------------------------------------------------------------------- +#ifndef U_HIDE_DEPRECATED_API /** * Normalizes a UnicodeString according to the specified normalization mode. * This is a wrapper for unorm_normalize(), using UnicodeString's. @@ -207,7 +215,7 @@ class U_COMMON_API Normalizer : public UObject { * @param options the optional features to be enabled (0 for no options) * @param result The normalized string (on output). * @param status The error code. - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ static void U_EXPORT2 normalize(const UnicodeString& source, UNormalizationMode mode, int32_t options, @@ -229,7 +237,7 @@ class U_COMMON_API Normalizer : public UObject { * @param options the optional features to be enabled (0 for no options) * @param result The composed string (on output). * @param status The error code. - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ static void U_EXPORT2 compose(const UnicodeString& source, UBool compat, int32_t options, @@ -251,7 +259,7 @@ class U_COMMON_API Normalizer : public UObject { * @param options the optional features to be enabled (0 for no options) * @param result The decomposed string (on output). * @param status The error code. - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ static void U_EXPORT2 decompose(const UnicodeString& source, UBool compat, int32_t options, @@ -276,7 +284,7 @@ class U_COMMON_API Normalizer : public UObject { * @return UNORM_YES, UNORM_NO or UNORM_MAYBE * * @see isNormalized - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ static inline UNormalizationCheckResult quickCheck(const UnicodeString &source, UNormalizationMode mode, UErrorCode &status); @@ -292,7 +300,7 @@ class U_COMMON_API Normalizer : public UObject { * @return UNORM_YES, UNORM_NO or UNORM_MAYBE * * @see isNormalized - * @stable ICU 2.6 + * @deprecated ICU 56 Use Normalizer2 instead. */ static UNormalizationCheckResult quickCheck(const UnicodeString &source, UNormalizationMode mode, int32_t options, UErrorCode &status); @@ -315,7 +323,7 @@ class U_COMMON_API Normalizer : public UObject { * "mode" normalization form. * * @see quickCheck - * @stable ICU 2.2 + * @deprecated ICU 56 Use Normalizer2 instead. */ static inline UBool isNormalized(const UnicodeString &src, UNormalizationMode mode, UErrorCode &errorCode); @@ -333,7 +341,7 @@ class U_COMMON_API Normalizer : public UObject { * "mode" normalization form. * * @see quickCheck - * @stable ICU 2.6 + * @deprecated ICU 56 Use Normalizer2 instead. */ static UBool isNormalized(const UnicodeString &src, UNormalizationMode mode, int32_t options, UErrorCode &errorCode); @@ -365,13 +373,14 @@ class U_COMMON_API Normalizer : public UObject { * @see unorm_next * @see unorm_previous * - * @stable ICU 2.1 + * @deprecated ICU 56 Use Normalizer2 instead. */ static UnicodeString & U_EXPORT2 concatenate(const UnicodeString &left, const UnicodeString &right, UnicodeString &result, UNormalizationMode mode, int32_t options, UErrorCode &errorCode); +#endif /* U_HIDE_DEPRECATED_API */ /** * Compare two strings for canonical equivalence. @@ -442,6 +451,7 @@ class U_COMMON_API Normalizer : public UObject { uint32_t options, UErrorCode &errorCode); +#ifndef U_HIDE_DEPRECATED_API //------------------------------------------------------------------------- // Iteration API //------------------------------------------------------------------------- @@ -452,7 +462,7 @@ class U_COMMON_API Normalizer : public UObject { * The getIndex() is not changed. * * @return the current normalized code point - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ UChar32 current(void); @@ -462,7 +472,7 @@ class U_COMMON_API Normalizer : public UObject { * (Post-increment semantics.) * * @return the first normalized code point - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ UChar32 first(void); @@ -472,7 +482,7 @@ class U_COMMON_API Normalizer : public UObject { * (Pre-decrement semantics.) * * @return the last normalized code point - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ UChar32 last(void); @@ -488,7 +498,7 @@ class U_COMMON_API Normalizer : public UObject { * The C API unorm_next() is more efficient and does not have this ambiguity. * * @return the next normalized code point - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ UChar32 next(void); @@ -504,7 +514,7 @@ class U_COMMON_API Normalizer : public UObject { * The C API unorm_previous() is more efficient and does not have this ambiguity. * * @return the previous normalized code point - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ UChar32 previous(void); @@ -515,14 +525,14 @@ class U_COMMON_API Normalizer : public UObject { * specified here. * * @param index the desired index in the input text. - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ void setIndexOnly(int32_t index); /** * Reset the index to the beginning of the text. * This is equivalent to setIndexOnly(startIndex)). - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ void reset(void); @@ -538,7 +548,7 @@ class U_COMMON_API Normalizer : public UObject { * was returned from with previous(). * * @return the current index in the input text - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ int32_t getIndex(void) const; @@ -548,7 +558,7 @@ class U_COMMON_API Normalizer : public UObject { * over which this Normalizer is iterating. * * @return the smallest index in the input text where the Normalizer operates - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ int32_t startIndex(void) const; @@ -560,7 +570,7 @@ class U_COMMON_API Normalizer : public UObject { * before this index. * * @return the first index in the input text where the Normalizer does not operate - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ int32_t endIndex(void) const; @@ -570,7 +580,7 @@ class U_COMMON_API Normalizer : public UObject { * * @param that a Normalizer object to compare this one to * @return comparison result - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ UBool operator==(const Normalizer& that) const; @@ -580,7 +590,7 @@ class U_COMMON_API Normalizer : public UObject { * * @param that a Normalizer object to compare this one to * @return comparison result - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ inline UBool operator!=(const Normalizer& that) const; @@ -588,7 +598,7 @@ class U_COMMON_API Normalizer : public UObject { * Returns a pointer to a new Normalizer that is a clone of this one. * The caller is responsible for deleting the new clone. * @return a pointer to a new Normalizer - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ Normalizer* clone(void) const; @@ -596,7 +606,7 @@ class U_COMMON_API Normalizer : public UObject { * Generates a hash code for this iterator. * * @return the hash code - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ int32_t hashCode(void) const; @@ -617,7 +627,7 @@ class U_COMMON_API Normalizer : public UObject { *

      * @param newMode the new mode for this Normalizer. * @see #getUMode - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ void setMode(UNormalizationMode newMode); @@ -629,7 +639,7 @@ class U_COMMON_API Normalizer : public UObject { * * @return the mode for this Normalizer * @see #setMode - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ UNormalizationMode getUMode(void) const; @@ -647,7 +657,7 @@ class U_COMMON_API Normalizer : public UObject { * turn the option(s) on and FALSE to turn it/them off. * * @see #getOption - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ void setOption(int32_t option, UBool value); @@ -660,7 +670,7 @@ class U_COMMON_API Normalizer : public UObject { * @param option the option(s) that are to be checked * @return TRUE if any of the option(s) are set * @see #setOption - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ UBool getOption(int32_t option) const; @@ -670,7 +680,7 @@ class U_COMMON_API Normalizer : public UObject { * * @param newText a string that replaces the current input text * @param status a UErrorCode - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ void setText(const UnicodeString& newText, UErrorCode &status); @@ -681,7 +691,7 @@ class U_COMMON_API Normalizer : public UObject { * * @param newText a CharacterIterator object that replaces the current input text * @param status a UErrorCode - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ void setText(const CharacterIterator& newText, UErrorCode &status); @@ -693,30 +703,31 @@ class U_COMMON_API Normalizer : public UObject { * @param newText a string that replaces the current input text * @param length the length of the string, or -1 if NUL-terminated * @param status a UErrorCode - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ - void setText(const UChar* newText, + void setText(ConstChar16Ptr newText, int32_t length, UErrorCode &status); /** * Copies the input text into the UnicodeString argument. * * @param result Receives a copy of the text under iteration. - * @stable ICU 2.0 + * @deprecated ICU 56 Use Normalizer2 instead. */ void getText(UnicodeString& result); /** * ICU "poor man's RTTI", returns a UClassID for this class. * @returns a UClassID for this class. - * @stable ICU 2.2 + * @deprecated ICU 56 Use Normalizer2 instead. */ static UClassID U_EXPORT2 getStaticClassID(); +#endif /* U_HIDE_DEPRECATED_API */ /** * ICU "poor man's RTTI", returns a UClassID for the actual class. * @return a UClassID for the actual class. - * @stable ICU 2.2 + * @deprecated ICU 56 Use Normalizer2 instead. */ virtual UClassID getDynamicClassID() const; @@ -742,7 +753,7 @@ class U_COMMON_API Normalizer : public UObject { FilteredNormalizer2*fFilteredNorm2; // owned if not NULL const Normalizer2 *fNorm2; // not owned; may be equal to fFilteredNorm2 - UNormalizationMode fUMode; + UNormalizationMode fUMode; // deprecated int32_t fOptions; // The input text and our position in it @@ -761,6 +772,7 @@ class U_COMMON_API Normalizer : public UObject { // Inline implementations //------------------------------------------------------------------------- +#ifndef U_HIDE_DEPRECATED_API inline UBool Normalizer::operator!= (const Normalizer& other) const { return ! operator==(other); } @@ -778,19 +790,21 @@ Normalizer::isNormalized(const UnicodeString& source, UErrorCode &status) { return isNormalized(source, mode, 0, status); } +#endif /* U_HIDE_DEPRECATED_API */ inline int32_t Normalizer::compare(const UnicodeString &s1, const UnicodeString &s2, uint32_t options, UErrorCode &errorCode) { // all argument checking is done in unorm_compare - return unorm_compare(s1.getBuffer(), s1.length(), - s2.getBuffer(), s2.length(), + return unorm_compare(toUCharPtr(s1.getBuffer()), s1.length(), + toUCharPtr(s2.getBuffer()), s2.length(), options, &errorCode); } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_NORMALIZATION */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/nounit.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/nounit.h new file mode 100644 index 0000000000..879849b16b --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/nounit.h @@ -0,0 +1,111 @@ +// © 2017 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* + ******************************************************************************* + * Copyright (C) 2009-2017, International Business Machines Corporation, * + * Google, and others. All Rights Reserved. * + ******************************************************************************* + */ + +#ifndef __NOUNIT_H__ +#define __NOUNIT_H__ + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING +#ifndef U_HIDE_DRAFT_API + +#include "unicode/measunit.h" + +/** + * \file + * \brief C++ API: units for percent and permille + */ + +U_NAMESPACE_BEGIN + +/** + * Dimensionless unit for percent and permille. + * @see NumberFormatter + * @draft ICU 60 + */ +class U_I18N_API NoUnit: public MeasureUnit { +public: + /** + * Returns an instance for the base unit (dimensionless and no scaling). + * + * @return a NoUnit instance + * @draft ICU 60 + */ + static NoUnit U_EXPORT2 base(); + + /** + * Returns an instance for percent, or 1/100 of a base unit. + * + * @return a NoUnit instance + * @draft ICU 60 + */ + static NoUnit U_EXPORT2 percent(); + + /** + * Returns an instance for permille, or 1/1000 of a base unit. + * + * @return a NoUnit instance + * @draft ICU 60 + */ + static NoUnit U_EXPORT2 permille(); + + /** + * Copy operator. + * @draft ICU 60 + */ + NoUnit(const NoUnit& other); + + /** + * Destructor. + * @draft ICU 60 + */ + virtual ~NoUnit(); + + /** + * Return a polymorphic clone of this object. The result will + * have the same class as returned by getDynamicClassID(). + * @draft ICU 60 + */ + virtual UObject* clone() const; + + /** + * Returns a unique class ID for this object POLYMORPHICALLY. + * This method implements a simple form of RTTI used by ICU. + * @return The class ID for this object. All objects of a given + * class have the same class ID. Objects of other classes have + * different class IDs. + * @draft ICU 60 + */ + virtual UClassID getDynamicClassID() const; + + /** + * Returns the class ID for this class. This is used to compare to + * the return value of getDynamicClassID(). + * @return The class ID for all objects of this class. + * @draft ICU 60 + */ + static UClassID U_EXPORT2 getStaticClassID(); + +private: + /** + * Constructor + * @internal (private) + */ + NoUnit(const char* subtype); + +}; + +U_NAMESPACE_END + +#endif /* U_HIDE_DRAFT_API */ +#endif /* #if !UCONFIG_NO_FORMATTING */ + +#endif // __NOUNIT_H__ +//eof +// diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/numberformatter.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/numberformatter.h new file mode 100644 index 0000000000..56c3a5a9d8 --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/numberformatter.h @@ -0,0 +1,2667 @@ +// © 2017 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING +#ifndef __NUMBERFORMATTER_H__ +#define __NUMBERFORMATTER_H__ + +#include "unicode/appendable.h" +#include "unicode/dcfmtsym.h" +#include "unicode/currunit.h" +#include "unicode/fieldpos.h" +#include "unicode/formattedvalue.h" +#include "unicode/fpositer.h" +#include "unicode/measunit.h" +#include "unicode/nounit.h" +#include "unicode/parseerr.h" +#include "unicode/plurrule.h" +#include "unicode/ucurr.h" +#include "unicode/unum.h" +#include "unicode/unumberformatter.h" +#include "unicode/uobject.h" + +#ifndef U_HIDE_DRAFT_API + +/** + * \file + * \brief C++ API: Library for localized number formatting introduced in ICU 60. + * + * This library was introduced in ICU 60 to simplify the process of formatting localized number strings. + * Basic usage examples: + * + *

      + * // Most basic usage:
      + * NumberFormatter::withLocale(...).format(123).toString();  // 1,234 in en-US
      + *
      + * // Custom notation, unit, and rounding precision:
      + * NumberFormatter::with()
      + *     .notation(Notation::compactShort())
      + *     .unit(CurrencyUnit("EUR", status))
      + *     .precision(Precision::maxDigits(2))
      + *     .locale(...)
      + *     .format(1234)
      + *     .toString();  // €1.2K in en-US
      + *
      + * // Create a formatter in a singleton by value for use later:
      + * static const LocalizedNumberFormatter formatter = NumberFormatter::withLocale(...)
      + *     .unit(NoUnit::percent())
      + *     .precision(Precision::fixedFraction(3));
      + * formatter.format(5.9831).toString();  // 5.983% in en-US
      + *
      + * // Create a "template" in a singleton unique_ptr but without setting a locale until the call site:
      + * std::unique_ptr template = NumberFormatter::with()
      + *     .sign(UNumberSignDisplay::UNUM_SIGN_ALWAYS)
      + *     .unit(MeasureUnit::getMeter())
      + *     .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME)
      + *     .clone();
      + * template->locale(...).format(1234).toString();  // +1,234 meters in en-US
      + * 
      + * + *

      + * This API offers more features than DecimalFormat and is geared toward new users of ICU. + * + *

      + * NumberFormatter instances (i.e., LocalizedNumberFormatter and UnlocalizedNumberFormatter) + * are immutable and thread safe. This means that invoking a configuration method has no + * effect on the receiving instance; you must store and use the new number formatter instance it returns instead. + * + *

      + * UnlocalizedNumberFormatter formatter = UnlocalizedNumberFormatter::with().notation(Notation::scientific());
      + * formatter.precision(Precision.maxFraction(2)); // does nothing!
      + * formatter.locale(Locale.getEnglish()).format(9.8765).toString(); // prints "9.8765E0", not "9.88E0"
      + * 
      + * + *

      + * This API is based on the fluent design pattern popularized by libraries such as Google's Guava. For + * extensive details on the design of this API, read the design doc. + * + * @author Shane Carr + */ + +U_NAMESPACE_BEGIN + +// Forward declarations: +class IFixedDecimal; +class FieldPositionIteratorHandler; + +namespace numparse { +namespace impl { + +// Forward declarations: +class NumberParserImpl; +class MultiplierParseHandler; + +} +} + +namespace number { // icu::number + +// Forward declarations: +class UnlocalizedNumberFormatter; +class LocalizedNumberFormatter; +class FormattedNumber; +class Notation; +class ScientificNotation; +class Precision; +class FractionPrecision; +class CurrencyPrecision; +class IncrementPrecision; +class IntegerWidth; + +namespace impl { + +// can't be #ifndef U_HIDE_INTERNAL_API; referenced throughout this file in public classes +/** + * Datatype for minimum/maximum fraction digits. Must be able to hold kMaxIntFracSig. + * + * @internal + */ +typedef int16_t digits_t; + +// can't be #ifndef U_HIDE_INTERNAL_API; needed for struct initialization +/** + * Use a default threshold of 3. This means that the third time .format() is called, the data structures get built + * using the "safe" code path. The first two calls to .format() will trigger the unsafe code path. + * + * @internal + */ +static constexpr int32_t kInternalDefaultThreshold = 3; + +// Forward declarations: +class Padder; +struct MacroProps; +struct MicroProps; +class DecimalQuantity; +class UFormattedNumberData; +class NumberFormatterImpl; +struct ParsedPatternInfo; +class ScientificModifier; +class MultiplierProducer; +class RoundingImpl; +class ScientificHandler; +class Modifier; +class NumberStringBuilder; +class AffixPatternProvider; +class NumberPropertyMapper; +struct DecimalFormatProperties; +class MultiplierFormatHandler; +class CurrencySymbols; +class GeneratorHelpers; +class DecNum; +class NumberRangeFormatterImpl; +struct RangeMacroProps; +struct UFormattedNumberImpl; + +/** + * Used for NumberRangeFormatter and implemented in numrange_fluent.cpp. + * Declared here so it can be friended. + * + * @internal + */ +void touchRangeLocales(impl::RangeMacroProps& macros); + +} // namespace impl + +/** + * Extra name reserved in case it is needed in the future. + * + * @draft ICU 63 + */ +typedef Notation CompactNotation; + +/** + * Extra name reserved in case it is needed in the future. + * + * @draft ICU 63 + */ +typedef Notation SimpleNotation; + +/** + * A class that defines the notation style to be used when formatting numbers in NumberFormatter. + * + * @draft ICU 60 + */ +class U_I18N_API Notation : public UMemory { + public: + /** + * Print the number using scientific notation (also known as scientific form, standard index form, or standard form + * in the UK). The format for scientific notation varies by locale; for example, many Western locales display the + * number in the form "#E0", where the number is displayed with one digit before the decimal separator, zero or more + * digits after the decimal separator, and the corresponding power of 10 displayed after the "E". + * + *

      + * Example outputs in en-US when printing 8.765E4 through 8.765E-3: + * + *

      +     * 8.765E4
      +     * 8.765E3
      +     * 8.765E2
      +     * 8.765E1
      +     * 8.765E0
      +     * 8.765E-1
      +     * 8.765E-2
      +     * 8.765E-3
      +     * 0E0
      +     * 
      + * + * @return A ScientificNotation for chaining or passing to the NumberFormatter notation() setter. + * @draft ICU 60 + */ + static ScientificNotation scientific(); + + /** + * Print the number using engineering notation, a variant of scientific notation in which the exponent must be + * divisible by 3. + * + *

      + * Example outputs in en-US when printing 8.765E4 through 8.765E-3: + * + *

      +     * 87.65E3
      +     * 8.765E3
      +     * 876.5E0
      +     * 87.65E0
      +     * 8.765E0
      +     * 876.5E-3
      +     * 87.65E-3
      +     * 8.765E-3
      +     * 0E0
      +     * 
      + * + * @return A ScientificNotation for chaining or passing to the NumberFormatter notation() setter. + * @draft ICU 60 + */ + static ScientificNotation engineering(); + + /** + * Print the number using short-form compact notation. + * + *

      + * Compact notation, defined in Unicode Technical Standard #35 Part 3 Section 2.4.1, prints numbers with + * localized prefixes or suffixes corresponding to different powers of ten. Compact notation is similar to + * engineering notation in how it scales numbers. + * + *

      + * Compact notation is ideal for displaying large numbers (over ~1000) to humans while at the same time minimizing + * screen real estate. + * + *

      + * In short form, the powers of ten are abbreviated. In en-US, the abbreviations are "K" for thousands, "M" + * for millions, "B" for billions, and "T" for trillions. Example outputs in en-US when printing 8.765E7 + * through 8.765E0: + * + *

      +     * 88M
      +     * 8.8M
      +     * 876K
      +     * 88K
      +     * 8.8K
      +     * 876
      +     * 88
      +     * 8.8
      +     * 
      + * + *

      + * When compact notation is specified without an explicit rounding precision, numbers are rounded off to the closest + * integer after scaling the number by the corresponding power of 10, but with a digit shown after the decimal + * separator if there is only one digit before the decimal separator. The default compact notation rounding precision + * is equivalent to: + * + *

      +     * Precision::integer().withMinDigits(2)
      +     * 
      + * + * @return A CompactNotation for passing to the NumberFormatter notation() setter. + * @draft ICU 60 + */ + static CompactNotation compactShort(); + + /** + * Print the number using long-form compact notation. For more information on compact notation, see + * {@link #compactShort}. + * + *

      + * In long form, the powers of ten are spelled out fully. Example outputs in en-US when printing 8.765E7 + * through 8.765E0: + * + *

      +     * 88 million
      +     * 8.8 million
      +     * 876 thousand
      +     * 88 thousand
      +     * 8.8 thousand
      +     * 876
      +     * 88
      +     * 8.8
      +     * 
      + * + * @return A CompactNotation for passing to the NumberFormatter notation() setter. + * @draft ICU 60 + */ + static CompactNotation compactLong(); + + /** + * Print the number using simple notation without any scaling by powers of ten. This is the default behavior. + * + *

      + * Since this is the default behavior, this method needs to be called only when it is necessary to override a + * previous setting. + * + *

      + * Example outputs in en-US when printing 8.765E7 through 8.765E0: + * + *

      +     * 87,650,000
      +     * 8,765,000
      +     * 876,500
      +     * 87,650
      +     * 8,765
      +     * 876.5
      +     * 87.65
      +     * 8.765
      +     * 
      + * + * @return A SimpleNotation for passing to the NumberFormatter notation() setter. + * @draft ICU 60 + */ + static SimpleNotation simple(); + + private: + enum NotationType { + NTN_SCIENTIFIC, NTN_COMPACT, NTN_SIMPLE, NTN_ERROR + } fType; + + union NotationUnion { + // For NTN_SCIENTIFIC + /** @internal */ + struct ScientificSettings { + /** @internal */ + int8_t fEngineeringInterval; + /** @internal */ + bool fRequireMinInt; + /** @internal */ + impl::digits_t fMinExponentDigits; + /** @internal */ + UNumberSignDisplay fExponentSignDisplay; + } scientific; + + // For NTN_COMPACT + UNumberCompactStyle compactStyle; + + // For NTN_ERROR + UErrorCode errorCode; + } fUnion; + + typedef NotationUnion::ScientificSettings ScientificSettings; + + Notation(const NotationType &type, const NotationUnion &union_) : fType(type), fUnion(union_) {} + + Notation(UErrorCode errorCode) : fType(NTN_ERROR) { + fUnion.errorCode = errorCode; + } + + Notation() : fType(NTN_SIMPLE), fUnion() {} + + UBool copyErrorTo(UErrorCode &status) const { + if (fType == NTN_ERROR) { + status = fUnion.errorCode; + return TRUE; + } + return FALSE; + } + + // To allow MacroProps to initialize empty instances: + friend struct impl::MacroProps; + friend class ScientificNotation; + + // To allow implementation to access internal types: + friend class impl::NumberFormatterImpl; + friend class impl::ScientificModifier; + friend class impl::ScientificHandler; + + // To allow access to the skeleton generation code: + friend class impl::GeneratorHelpers; +}; + +/** + * A class that defines the scientific notation style to be used when formatting numbers in NumberFormatter. + * + *

      + * To create a ScientificNotation, use one of the factory methods in {@link Notation}. + * + * @draft ICU 60 + */ +class U_I18N_API ScientificNotation : public Notation { + public: + /** + * Sets the minimum number of digits to show in the exponent of scientific notation, padding with zeros if + * necessary. Useful for fixed-width display. + * + *

      + * For example, with minExponentDigits=2, the number 123 will be printed as "1.23E02" in en-US instead of + * the default "1.23E2". + * + * @param minExponentDigits + * The minimum number of digits to show in the exponent. + * @return A ScientificNotation, for chaining. + * @draft ICU 60 + */ + ScientificNotation withMinExponentDigits(int32_t minExponentDigits) const; + + /** + * Sets whether to show the sign on positive and negative exponents in scientific notation. The default is AUTO, + * showing the minus sign but not the plus sign. + * + *

      + * For example, with exponentSignDisplay=ALWAYS, the number 123 will be printed as "1.23E+2" in en-US + * instead of the default "1.23E2". + * + * @param exponentSignDisplay + * The strategy for displaying the sign in the exponent. + * @return A ScientificNotation, for chaining. + * @draft ICU 60 + */ + ScientificNotation withExponentSignDisplay(UNumberSignDisplay exponentSignDisplay) const; + + private: + // Inherit constructor + using Notation::Notation; + + // Raw constructor for NumberPropertyMapper + ScientificNotation(int8_t fEngineeringInterval, bool fRequireMinInt, impl::digits_t fMinExponentDigits, + UNumberSignDisplay fExponentSignDisplay); + + friend class Notation; + + // So that NumberPropertyMapper can create instances + friend class impl::NumberPropertyMapper; +}; + +/** + * Extra name reserved in case it is needed in the future. + * + * @draft ICU 63 + */ +typedef Precision SignificantDigitsPrecision; + +/** + * A class that defines the rounding precision to be used when formatting numbers in NumberFormatter. + * + *

      + * To create a Precision, use one of the factory methods. + * + * @draft ICU 60 + */ +class U_I18N_API Precision : public UMemory { + + public: + /** + * Show all available digits to full precision. + * + *

      + * NOTE: When formatting a double, this method, along with {@link #minFraction} and + * {@link #minSignificantDigits}, will trigger complex algorithm similar to Dragon4 to determine the + * low-order digits and the number of digits to display based on the value of the double. + * If the number of fraction places or significant digits can be bounded, consider using {@link #maxFraction} + * or {@link #maxSignificantDigits} instead to maximize performance. + * For more information, read the following blog post. + * + *

      + * http://www.serpentine.com/blog/2011/06/29/here-be-dragons-advances-in-problems-you-didnt-even-know-you-had/ + * + * @return A Precision for chaining or passing to the NumberFormatter precision() setter. + * @draft ICU 60 + */ + static Precision unlimited(); + + /** + * Show numbers rounded if necessary to the nearest integer. + * + * @return A FractionPrecision for chaining or passing to the NumberFormatter precision() setter. + * @draft ICU 60 + */ + static FractionPrecision integer(); + + /** + * Show numbers rounded if necessary to a certain number of fraction places (numerals after the decimal separator). + * Additionally, pad with zeros to ensure that this number of places are always shown. + * + *

      + * Example output with minMaxFractionPlaces = 3: + * + *

      + * 87,650.000
      + * 8,765.000
      + * 876.500
      + * 87.650
      + * 8.765
      + * 0.876
      + * 0.088
      + * 0.009
      + * 0.000 (zero) + * + *

      + * This method is equivalent to {@link #minMaxFraction} with both arguments equal. + * + * @param minMaxFractionPlaces + * The minimum and maximum number of numerals to display after the decimal separator (rounding if too + * long or padding with zeros if too short). + * @return A FractionPrecision for chaining or passing to the NumberFormatter precision() setter. + * @draft ICU 60 + */ + static FractionPrecision fixedFraction(int32_t minMaxFractionPlaces); + + /** + * Always show at least a certain number of fraction places after the decimal separator, padding with zeros if + * necessary. Do not perform rounding (display numbers to their full precision). + * + *

      + * NOTE: If you are formatting doubles, see the performance note in {@link #unlimited}. + * + * @param minFractionPlaces + * The minimum number of numerals to display after the decimal separator (padding with zeros if + * necessary). + * @return A FractionPrecision for chaining or passing to the NumberFormatter precision() setter. + * @draft ICU 60 + */ + static FractionPrecision minFraction(int32_t minFractionPlaces); + + /** + * Show numbers rounded if necessary to a certain number of fraction places (numerals after the decimal separator). + * Unlike the other fraction rounding strategies, this strategy does not pad zeros to the end of the + * number. + * + * @param maxFractionPlaces + * The maximum number of numerals to display after the decimal mark (rounding if necessary). + * @return A FractionPrecision for chaining or passing to the NumberFormatter precision() setter. + * @draft ICU 60 + */ + static FractionPrecision maxFraction(int32_t maxFractionPlaces); + + /** + * Show numbers rounded if necessary to a certain number of fraction places (numerals after the decimal separator); + * in addition, always show at least a certain number of places after the decimal separator, padding with zeros if + * necessary. + * + * @param minFractionPlaces + * The minimum number of numerals to display after the decimal separator (padding with zeros if + * necessary). + * @param maxFractionPlaces + * The maximum number of numerals to display after the decimal separator (rounding if necessary). + * @return A FractionPrecision for chaining or passing to the NumberFormatter precision() setter. + * @draft ICU 60 + */ + static FractionPrecision minMaxFraction(int32_t minFractionPlaces, int32_t maxFractionPlaces); + + /** + * Show numbers rounded if necessary to a certain number of significant digits or significant figures. Additionally, + * pad with zeros to ensure that this number of significant digits/figures are always shown. + * + *

      + * This method is equivalent to {@link #minMaxSignificantDigits} with both arguments equal. + * + * @param minMaxSignificantDigits + * The minimum and maximum number of significant digits to display (rounding if too long or padding with + * zeros if too short). + * @return A precision for chaining or passing to the NumberFormatter precision() setter. + * @draft ICU 62 + */ + static SignificantDigitsPrecision fixedSignificantDigits(int32_t minMaxSignificantDigits); + + /** + * Always show at least a certain number of significant digits/figures, padding with zeros if necessary. Do not + * perform rounding (display numbers to their full precision). + * + *

      + * NOTE: If you are formatting doubles, see the performance note in {@link #unlimited}. + * + * @param minSignificantDigits + * The minimum number of significant digits to display (padding with zeros if too short). + * @return A precision for chaining or passing to the NumberFormatter precision() setter. + * @draft ICU 62 + */ + static SignificantDigitsPrecision minSignificantDigits(int32_t minSignificantDigits); + + /** + * Show numbers rounded if necessary to a certain number of significant digits/figures. + * + * @param maxSignificantDigits + * The maximum number of significant digits to display (rounding if too long). + * @return A precision for chaining or passing to the NumberFormatter precision() setter. + * @draft ICU 62 + */ + static SignificantDigitsPrecision maxSignificantDigits(int32_t maxSignificantDigits); + + /** + * Show numbers rounded if necessary to a certain number of significant digits/figures; in addition, always show at + * least a certain number of significant digits, padding with zeros if necessary. + * + * @param minSignificantDigits + * The minimum number of significant digits to display (padding with zeros if necessary). + * @param maxSignificantDigits + * The maximum number of significant digits to display (rounding if necessary). + * @return A precision for chaining or passing to the NumberFormatter precision() setter. + * @draft ICU 62 + */ + static SignificantDigitsPrecision minMaxSignificantDigits(int32_t minSignificantDigits, + int32_t maxSignificantDigits); + + /** + * Show numbers rounded if necessary to the closest multiple of a certain rounding increment. For example, if the + * rounding increment is 0.5, then round 1.2 to 1 and round 1.3 to 1.5. + * + *

      + * In order to ensure that numbers are padded to the appropriate number of fraction places, call + * withMinFraction() on the return value of this method. + * For example, to round to the nearest 0.5 and always display 2 numerals after the + * decimal separator (to display 1.2 as "1.00" and 1.3 as "1.50"), you can run: + * + *

      +     * Precision::increment(0.5).withMinFraction(2)
      +     * 
      + * + * @param roundingIncrement + * The increment to which to round numbers. + * @return A precision for chaining or passing to the NumberFormatter precision() setter. + * @draft ICU 60 + */ + static IncrementPrecision increment(double roundingIncrement); + + /** + * Show numbers rounded and padded according to the rules for the currency unit. The most common + * rounding precision settings for currencies include Precision::fixedFraction(2), + * Precision::integer(), and Precision::increment(0.05) for cash transactions + * ("nickel rounding"). + * + *

      + * The exact rounding details will be resolved at runtime based on the currency unit specified in the + * NumberFormatter chain. To round according to the rules for one currency while displaying the symbol for another + * currency, the withCurrency() method can be called on the return value of this method. + * + * @param currencyUsage + * Either STANDARD (for digital transactions) or CASH (for transactions where the rounding increment may + * be limited by the available denominations of cash or coins). + * @return A CurrencyPrecision for chaining or passing to the NumberFormatter precision() setter. + * @draft ICU 60 + */ + static CurrencyPrecision currency(UCurrencyUsage currencyUsage); + + private: + enum PrecisionType { + RND_BOGUS, + RND_NONE, + RND_FRACTION, + RND_SIGNIFICANT, + RND_FRACTION_SIGNIFICANT, + + // Used for strange increments like 3.14. + RND_INCREMENT, + + // Used for increments with 1 as the only digit. This is different than fraction + // rounding because it supports having additional trailing zeros. For example, this + // class is used to round with the increment 0.010. + RND_INCREMENT_ONE, + + // Used for increments with 5 as the only digit (nickel rounding). + RND_INCREMENT_FIVE, + + RND_CURRENCY, + RND_INCREMENT_SIGNIFICANT, // Apple addition rdar://52538227 + RND_ERROR + } fType; + + union PrecisionUnion { + /** @internal */ + struct FractionSignificantSettings { + // For RND_FRACTION, RND_SIGNIFICANT, and RND_FRACTION_SIGNIFICANT + /** @internal */ + impl::digits_t fMinFrac; + /** @internal */ + impl::digits_t fMaxFrac; + /** @internal */ + impl::digits_t fMinSig; + /** @internal */ + impl::digits_t fMaxSig; + } fracSig; + /** @internal */ + struct IncrementSettings { + // For RND_INCREMENT, RND_INCREMENT_ONE, and RND_INCREMENT_FIVE + /** @internal */ + double fIncrement; + /** @internal */ + impl::digits_t fMinFrac; + /** @internal */ + impl::digits_t fMaxFrac; + } increment; + /** @internal */ + struct IncrementSignificantSettings { // Apple addition rdar://52538227 + // For // Apple addition rdar://52538227 + /** @internal */ + double fIncrement; + /** @internal */ + impl::digits_t fMinSig; + /** @internal */ + impl::digits_t fMaxSig; + } incrSig; + UCurrencyUsage currencyUsage; // For RND_CURRENCY + UErrorCode errorCode; // For RND_ERROR + } fUnion; + + typedef PrecisionUnion::FractionSignificantSettings FractionSignificantSettings; + typedef PrecisionUnion::IncrementSettings IncrementSettings; + typedef PrecisionUnion::IncrementSignificantSettings IncrementSignificantSettings; + + /** The Precision encapsulates the RoundingMode when used within the implementation. */ + UNumberFormatRoundingMode fRoundingMode; + + Precision(const PrecisionType& type, const PrecisionUnion& union_, + UNumberFormatRoundingMode roundingMode) + : fType(type), fUnion(union_), fRoundingMode(roundingMode) {} + + Precision(UErrorCode errorCode) : fType(RND_ERROR) { + fUnion.errorCode = errorCode; + } + + Precision() : fType(RND_BOGUS) {} + + bool isBogus() const { + return fType == RND_BOGUS; + } + + UBool copyErrorTo(UErrorCode &status) const { + if (fType == RND_ERROR) { + status = fUnion.errorCode; + return TRUE; + } + return FALSE; + } + + // On the parent type so that this method can be called internally on Precision instances. + Precision withCurrency(const CurrencyUnit ¤cy, UErrorCode &status) const; + + static FractionPrecision constructFraction(int32_t minFrac, int32_t maxFrac); + + static Precision constructSignificant(int32_t minSig, int32_t maxSig); + + static Precision constructIncrementSignificant(double increment, int32_t minSig, int32_t maxSig); // Apple + + static Precision + constructFractionSignificant(const FractionPrecision &base, int32_t minSig, int32_t maxSig); + + static IncrementPrecision constructIncrement(double increment, int32_t minFrac); + + static CurrencyPrecision constructCurrency(UCurrencyUsage usage); + + static Precision constructPassThrough(); + + // To allow MacroProps/MicroProps to initialize bogus instances: + friend struct impl::MacroProps; + friend struct impl::MicroProps; + + // To allow NumberFormatterImpl to access isBogus() and other internal methods: + friend class impl::NumberFormatterImpl; + + // To allow NumberPropertyMapper to create instances from DecimalFormatProperties: + friend class impl::NumberPropertyMapper; + + // To allow access to the main implementation class: + friend class impl::RoundingImpl; + + // To allow child classes to call private methods: + friend class FractionPrecision; + friend class CurrencyPrecision; + friend class IncrementPrecision; + + // To allow access to the skeleton generation code: + friend class impl::GeneratorHelpers; +}; + +/** + * A class that defines a rounding precision based on a number of fraction places and optionally significant digits to be + * used when formatting numbers in NumberFormatter. + * + *

      + * To create a FractionPrecision, use one of the factory methods on Precision. + * + * @draft ICU 60 + */ +class U_I18N_API FractionPrecision : public Precision { + public: + /** + * Ensure that no less than this number of significant digits are retained when rounding according to fraction + * rules. + * + *

      + * For example, with integer rounding, the number 3.141 becomes "3". However, with minimum figures set to 2, 3.141 + * becomes "3.1" instead. + * + *

      + * This setting does not affect the number of trailing zeros. For example, 3.01 would print as "3", not "3.0". + * + * @param minSignificantDigits + * The number of significant figures to guarantee. + * @return A precision for chaining or passing to the NumberFormatter precision() setter. + * @draft ICU 60 + */ + Precision withMinDigits(int32_t minSignificantDigits) const; + + /** + * Ensure that no more than this number of significant digits are retained when rounding according to fraction + * rules. + * + *

      + * For example, with integer rounding, the number 123.4 becomes "123". However, with maximum figures set to 2, 123.4 + * becomes "120" instead. + * + *

      + * This setting does not affect the number of trailing zeros. For example, with fixed fraction of 2, 123.4 would + * become "120.00". + * + * @param maxSignificantDigits + * Round the number to no more than this number of significant figures. + * @return A precision for chaining or passing to the NumberFormatter precision() setter. + * @draft ICU 60 + */ + Precision withMaxDigits(int32_t maxSignificantDigits) const; + + private: + // Inherit constructor + using Precision::Precision; + + // To allow parent class to call this class's constructor: + friend class Precision; +}; + +/** + * A class that defines a rounding precision parameterized by a currency to be used when formatting numbers in + * NumberFormatter. + * + *

      + * To create a CurrencyPrecision, use one of the factory methods on Precision. + * + * @draft ICU 60 + */ +class U_I18N_API CurrencyPrecision : public Precision { + public: + /** + * Associates a currency with this rounding precision. + * + *

      + * Calling this method is not required, because the currency specified in unit() + * is automatically applied to currency rounding precisions. However, + * this method enables you to override that automatic association. + * + *

      + * This method also enables numbers to be formatted using currency rounding rules without explicitly using a + * currency format. + * + * @param currency + * The currency to associate with this rounding precision. + * @return A precision for chaining or passing to the NumberFormatter precision() setter. + * @draft ICU 60 + */ + Precision withCurrency(const CurrencyUnit ¤cy) const; + + private: + // Inherit constructor + using Precision::Precision; + + // To allow parent class to call this class's constructor: + friend class Precision; +}; + +/** + * A class that defines a rounding precision parameterized by a rounding increment to be used when formatting numbers in + * NumberFormatter. + * + *

      + * To create an IncrementPrecision, use one of the factory methods on Precision. + * + * @draft ICU 60 + */ +class U_I18N_API IncrementPrecision : public Precision { + public: + /** + * Specifies the minimum number of fraction digits to render after the decimal separator, padding with zeros if + * necessary. By default, no trailing zeros are added. + * + *

      + * For example, if the rounding increment is 0.5 and minFrac is 2, then the resulting strings include "0.00", + * "0.50", "1.00", and "1.50". + * + *

      + * Note: In ICU4J, this functionality is accomplished via the scale of the BigDecimal rounding increment. + * + * @param minFrac The minimum number of digits after the decimal separator. + * @return A precision for chaining or passing to the NumberFormatter precision() setter. + * @draft ICU 60 + */ + Precision withMinFraction(int32_t minFrac) const; + + private: + // Inherit constructor + using Precision::Precision; + + // To allow parent class to call this class's constructor: + friend class Precision; +}; + +/** + * A class that defines the strategy for padding and truncating integers before the decimal separator. + * + *

      + * To create an IntegerWidth, use one of the factory methods. + * + * @draft ICU 60 + * @see NumberFormatter + */ +class U_I18N_API IntegerWidth : public UMemory { + public: + /** + * Pad numbers at the beginning with zeros to guarantee a certain number of numerals before the decimal separator. + * + *

      + * For example, with minInt=3, the number 55 will get printed as "055". + * + * @param minInt + * The minimum number of places before the decimal separator. + * @return An IntegerWidth for chaining or passing to the NumberFormatter integerWidth() setter. + * @draft ICU 60 + */ + static IntegerWidth zeroFillTo(int32_t minInt); + + /** + * Truncate numbers exceeding a certain number of numerals before the decimal separator. + * + * For example, with maxInt=3, the number 1234 will get printed as "234". + * + * @param maxInt + * The maximum number of places before the decimal separator. maxInt == -1 means no + * truncation. + * @return An IntegerWidth for passing to the NumberFormatter integerWidth() setter. + * @draft ICU 60 + */ + IntegerWidth truncateAt(int32_t maxInt); + + private: + union { + struct { + impl::digits_t fMinInt; + impl::digits_t fMaxInt; + bool fFormatFailIfMoreThanMaxDigits; + } minMaxInt; + UErrorCode errorCode; + } fUnion; + bool fHasError = false; + + IntegerWidth(impl::digits_t minInt, impl::digits_t maxInt, bool formatFailIfMoreThanMaxDigits); + + IntegerWidth(UErrorCode errorCode) { // NOLINT + fUnion.errorCode = errorCode; + fHasError = true; + } + + IntegerWidth() { // NOLINT + fUnion.minMaxInt.fMinInt = -1; + } + + /** Returns the default instance. */ + static IntegerWidth standard() { + return IntegerWidth::zeroFillTo(1); + } + + bool isBogus() const { + return !fHasError && fUnion.minMaxInt.fMinInt == -1; + } + + UBool copyErrorTo(UErrorCode &status) const { + if (fHasError) { + status = fUnion.errorCode; + return TRUE; + } + return FALSE; + } + + void apply(impl::DecimalQuantity &quantity, UErrorCode &status) const; + + bool operator==(const IntegerWidth& other) const; + + // To allow MacroProps/MicroProps to initialize empty instances: + friend struct impl::MacroProps; + friend struct impl::MicroProps; + + // To allow NumberFormatterImpl to access isBogus() and perform other operations: + friend class impl::NumberFormatterImpl; + + // So that NumberPropertyMapper can create instances + friend class impl::NumberPropertyMapper; + + // To allow access to the skeleton generation code: + friend class impl::GeneratorHelpers; +}; + +/** + * A class that defines a quantity by which a number should be multiplied when formatting. + * + *

      + * To create a Scale, use one of the factory methods. + * + * @draft ICU 62 + */ +class U_I18N_API Scale : public UMemory { + public: + /** + * Do not change the value of numbers when formatting or parsing. + * + * @return A Scale to prevent any multiplication. + * @draft ICU 62 + */ + static Scale none(); + + /** + * Multiply numbers by a power of ten before formatting. Useful for combining with a percent unit: + * + *

      +     * NumberFormatter::with().unit(NoUnit::percent()).multiplier(Scale::powerOfTen(2))
      +     * 
      + * + * @return A Scale for passing to the setter in NumberFormatter. + * @draft ICU 62 + */ + static Scale powerOfTen(int32_t power); + + /** + * Multiply numbers by an arbitrary value before formatting. Useful for unit conversions. + * + * This method takes a string in a decimal number format with syntax + * as defined in the Decimal Arithmetic Specification, available at + * http://speleotrove.com/decimal + * + * Also see the version of this method that takes a double. + * + * @return A Scale for passing to the setter in NumberFormatter. + * @draft ICU 62 + */ + static Scale byDecimal(StringPiece multiplicand); + + /** + * Multiply numbers by an arbitrary value before formatting. Useful for unit conversions. + * + * This method takes a double; also see the version of this method that takes an exact decimal. + * + * @return A Scale for passing to the setter in NumberFormatter. + * @draft ICU 62 + */ + static Scale byDouble(double multiplicand); + + /** + * Multiply a number by both a power of ten and by an arbitrary double value. + * + * @return A Scale for passing to the setter in NumberFormatter. + * @draft ICU 62 + */ + static Scale byDoubleAndPowerOfTen(double multiplicand, int32_t power); + + // We need a custom destructor for the DecNum, which means we need to declare + // the copy/move constructor/assignment quartet. + + /** @draft ICU 62 */ + Scale(const Scale& other); + + /** @draft ICU 62 */ + Scale& operator=(const Scale& other); + + /** @draft ICU 62 */ + Scale(Scale&& src) U_NOEXCEPT; + + /** @draft ICU 62 */ + Scale& operator=(Scale&& src) U_NOEXCEPT; + + /** @draft ICU 62 */ + ~Scale(); + +#ifndef U_HIDE_INTERNAL_API + /** @internal */ + Scale(int32_t magnitude, impl::DecNum* arbitraryToAdopt); +#endif /* U_HIDE_INTERNAL_API */ + + private: + int32_t fMagnitude; + impl::DecNum* fArbitrary; + UErrorCode fError; + + Scale(UErrorCode error) : fMagnitude(0), fArbitrary(nullptr), fError(error) {} + + Scale() : fMagnitude(0), fArbitrary(nullptr), fError(U_ZERO_ERROR) {} + + bool isValid() const { + return fMagnitude != 0 || fArbitrary != nullptr; + } + + UBool copyErrorTo(UErrorCode &status) const { + if (fError != U_ZERO_ERROR) { + status = fError; + return TRUE; + } + return FALSE; + } + + void applyTo(impl::DecimalQuantity& quantity) const; + + void applyReciprocalTo(impl::DecimalQuantity& quantity) const; + + // To allow MacroProps/MicroProps to initialize empty instances: + friend struct impl::MacroProps; + friend struct impl::MicroProps; + + // To allow NumberFormatterImpl to access isBogus() and perform other operations: + friend class impl::NumberFormatterImpl; + + // To allow the helper class MultiplierFormatHandler access to private fields: + friend class impl::MultiplierFormatHandler; + + // To allow access to the skeleton generation code: + friend class impl::GeneratorHelpers; + + // To allow access to parsing code: + friend class ::icu::numparse::impl::NumberParserImpl; + friend class ::icu::numparse::impl::MultiplierParseHandler; +}; + +namespace impl { + +// Do not enclose entire SymbolsWrapper with #ifndef U_HIDE_INTERNAL_API, needed for a protected field +/** @internal */ +class U_I18N_API SymbolsWrapper : public UMemory { + public: + /** @internal */ + SymbolsWrapper() : fType(SYMPTR_NONE), fPtr{nullptr} {} + + /** @internal */ + SymbolsWrapper(const SymbolsWrapper &other); + + /** @internal */ + SymbolsWrapper &operator=(const SymbolsWrapper &other); + + /** @internal */ + SymbolsWrapper(SymbolsWrapper&& src) U_NOEXCEPT; + + /** @internal */ + SymbolsWrapper &operator=(SymbolsWrapper&& src) U_NOEXCEPT; + + /** @internal */ + ~SymbolsWrapper(); + +#ifndef U_HIDE_INTERNAL_API + + /** + * Set whether DecimalFormatSymbols copy is deep (clone) + * or shallow (pointer copy). Apple + * @internal + */ + void setDFSShallowCopy(UBool shallow); + + /** + * The provided object is copied, but we do not adopt it. + * @internal + */ + void setTo(const DecimalFormatSymbols &dfs); + + /** + * Adopt the provided object. + * @internal + */ + void setTo(const NumberingSystem *ns); + + /** + * Whether the object is currently holding a DecimalFormatSymbols. + * @internal + */ + bool isDecimalFormatSymbols() const; + + /** + * Whether the object is currently holding a NumberingSystem. + * @internal + */ + bool isNumberingSystem() const; + + /** + * Get the DecimalFormatSymbols pointer. No ownership change. + * @internal + */ + const DecimalFormatSymbols *getDecimalFormatSymbols() const; + + /** + * Get the NumberingSystem pointer. No ownership change. + * @internal + */ + const NumberingSystem *getNumberingSystem() const; + +#endif // U_HIDE_INTERNAL_API + + /** @internal */ + UBool copyErrorTo(UErrorCode &status) const { + if ((fType == SYMPTR_DFS || fType == SYMPTR_DFS_SHALLOWCOPY) && fPtr.dfs == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return TRUE; + } else if (fType == SYMPTR_NS && fPtr.ns == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return TRUE; + } + return FALSE; + } + + private: + enum SymbolsPointerType { + SYMPTR_NONE, SYMPTR_DFS, SYMPTR_NS, SYMPTR_DFS_SHALLOWCOPY // Apple add SHALLOWCOPY + } fType; + + union { + const DecimalFormatSymbols *dfs; + const NumberingSystem *ns; + } fPtr; + + void doCopyFrom(const SymbolsWrapper &other); + + void doMoveFrom(SymbolsWrapper&& src); + + void doCleanup(); +}; + +// Do not enclose entire Grouper with #ifndef U_HIDE_INTERNAL_API, needed for a protected field +/** @internal */ +class U_I18N_API Grouper : public UMemory { + public: +#ifndef U_HIDE_INTERNAL_API + /** @internal */ + static Grouper forStrategy(UNumberGroupingStrategy grouping); + + /** + * Resolve the values in Properties to a Grouper object. + * @internal + */ + static Grouper forProperties(const DecimalFormatProperties& properties); + + // Future: static Grouper forProperties(DecimalFormatProperties& properties); + + /** @internal */ + Grouper(int16_t grouping1, int16_t grouping2, int16_t minGrouping, UNumberGroupingStrategy strategy) + : fGrouping1(grouping1), + fGrouping2(grouping2), + fMinGrouping(minGrouping), + fStrategy(strategy) {} +#endif // U_HIDE_INTERNAL_API + + /** @internal */ + int16_t getPrimary() const; + + /** @internal */ + int16_t getSecondary() const; + + private: + /** + * The grouping sizes, with the following special values: + *
        + *
      • -1 = no grouping + *
      • -2 = needs locale data + *
      • -4 = fall back to Western grouping if not in locale + *
      + */ + int16_t fGrouping1; + int16_t fGrouping2; + + /** + * The minimum grouping size, with the following special values: + *
        + *
      • -2 = needs locale data + *
      • -3 = no less than 2 + *
      + */ + int16_t fMinGrouping; + + /** + * The UNumberGroupingStrategy that was used to create this Grouper, or UNUM_GROUPING_COUNT if this + * was not created from a UNumberGroupingStrategy. + */ + UNumberGroupingStrategy fStrategy; + + Grouper() : fGrouping1(-3) {} + + bool isBogus() const { + return fGrouping1 == -3; + } + + /** NON-CONST: mutates the current instance. */ + void setLocaleData(const impl::ParsedPatternInfo &patternInfo, const Locale& locale); + + bool groupAtPosition(int32_t position, const impl::DecimalQuantity &value) const; + + // To allow MacroProps/MicroProps to initialize empty instances: + friend struct MacroProps; + friend struct MicroProps; + + // To allow NumberFormatterImpl to access isBogus() and perform other operations: + friend class NumberFormatterImpl; + + // To allow NumberParserImpl to perform setLocaleData(): + friend class ::icu::numparse::impl::NumberParserImpl; + + // To allow access to the skeleton generation code: + friend class impl::GeneratorHelpers; +}; + +// Do not enclose entire Padder with #ifndef U_HIDE_INTERNAL_API, needed for a protected field +/** @internal */ +class U_I18N_API Padder : public UMemory { + public: +#ifndef U_HIDE_INTERNAL_API + /** @internal */ + static Padder none(); + + /** @internal */ + static Padder codePoints(UChar32 cp, int32_t targetWidth, UNumberFormatPadPosition position); +#endif // U_HIDE_INTERNAL_API + + /** @internal */ + static Padder forProperties(const DecimalFormatProperties& properties); + + private: + UChar32 fWidth; // -3 = error; -2 = bogus; -1 = no padding + union { + struct { + int32_t fCp; + UNumberFormatPadPosition fPosition; + } padding; + UErrorCode errorCode; + } fUnion; + + Padder(UChar32 cp, int32_t width, UNumberFormatPadPosition position); + + Padder(int32_t width); + + Padder(UErrorCode errorCode) : fWidth(-3) { // NOLINT + fUnion.errorCode = errorCode; + } + + Padder() : fWidth(-2) {} // NOLINT + + bool isBogus() const { + return fWidth == -2; + } + + UBool copyErrorTo(UErrorCode &status) const { + if (fWidth == -3) { + status = fUnion.errorCode; + return TRUE; + } + return FALSE; + } + + bool isValid() const { + return fWidth > 0; + } + + int32_t padAndApply(const impl::Modifier &mod1, const impl::Modifier &mod2, + impl::NumberStringBuilder &string, int32_t leftIndex, int32_t rightIndex, + UErrorCode &status) const; + + // To allow MacroProps/MicroProps to initialize empty instances: + friend struct MacroProps; + friend struct MicroProps; + + // To allow NumberFormatterImpl to access isBogus() and perform other operations: + friend class impl::NumberFormatterImpl; + + // To allow access to the skeleton generation code: + friend class impl::GeneratorHelpers; +}; + +// Do not enclose entire MacroProps with #ifndef U_HIDE_INTERNAL_API, needed for a protected field +/** @internal */ +struct U_I18N_API MacroProps : public UMemory { + /** @internal */ + Notation notation; + + /** @internal */ + MeasureUnit unit; // = NoUnit::base(); + + /** @internal */ + MeasureUnit perUnit; // = NoUnit::base(); + + /** @internal */ + Precision precision; // = Precision(); (bogus) + + /** @internal */ + UNumberFormatRoundingMode roundingMode = UNUM_ROUND_HALFEVEN; + + /** @internal */ + Grouper grouper; // = Grouper(); (bogus) + + /** @internal */ + Padder padder; // = Padder(); (bogus) + + /** @internal */ + IntegerWidth integerWidth; // = IntegerWidth(); (bogus) + + /** @internal */ + SymbolsWrapper symbols; + + // UNUM_XYZ_COUNT denotes null (bogus) values. + + /** @internal */ + UNumberUnitWidth unitWidth = UNUM_UNIT_WIDTH_COUNT; + + /** @internal */ + UNumberSignDisplay sign = UNUM_SIGN_COUNT; + + /** @internal */ + UNumberDecimalSeparatorDisplay decimal = UNUM_DECIMAL_SEPARATOR_COUNT; + + /** @internal */ + Scale scale; // = Scale(); (benign value) + + /** @internal */ + const AffixPatternProvider* affixProvider = nullptr; // no ownership + + /** @internal */ + const PluralRules* rules = nullptr; // no ownership + + /** @internal */ + const CurrencySymbols* currencySymbols = nullptr; // no ownership + + /** @internal */ + int32_t threshold = kInternalDefaultThreshold; + + /** @internal Apple addition for */ + bool adjustDoublePrecision = false; + + /** @internal */ + Locale locale; + + // NOTE: Uses default copy and move constructors. + + /** + * Check all members for errors. + * @internal + */ + bool copyErrorTo(UErrorCode &status) const { + return notation.copyErrorTo(status) || precision.copyErrorTo(status) || + padder.copyErrorTo(status) || integerWidth.copyErrorTo(status) || + symbols.copyErrorTo(status) || scale.copyErrorTo(status); + } +}; + +} // namespace impl + +/** + * An abstract base class for specifying settings related to number formatting. This class is implemented by + * {@link UnlocalizedNumberFormatter} and {@link LocalizedNumberFormatter}. This class is not intended for + * public subclassing. + */ +template +class U_I18N_API NumberFormatterSettings { + public: + /** + * Specifies the notation style (simple, scientific, or compact) for rendering numbers. + * + *
        + *
      • Simple notation: "12,300" + *
      • Scientific notation: "1.23E4" + *
      • Compact notation: "12K" + *
      + * + *

      + * All notation styles will be properly localized with locale data, and all notation styles are compatible with + * units, rounding precisions, and other number formatter settings. + * + *

      + * Pass this method the return value of a {@link Notation} factory method. For example: + * + *

      +     * NumberFormatter::with().notation(Notation::compactShort())
      +     * 
      + * + * The default is to use simple notation. + * + * @param notation + * The notation strategy to use. + * @return The fluent chain. + * @see Notation + * @draft ICU 60 + */ + Derived notation(const Notation ¬ation) const &; + + /** + * Overload of notation() for use on an rvalue reference. + * + * @param notation + * The notation strategy to use. + * @return The fluent chain. + * @see #notation + * @draft ICU 62 + */ + Derived notation(const Notation ¬ation) &&; + + /** + * Specifies the unit (unit of measure, currency, or percent) to associate with rendered numbers. + * + *
        + *
      • Unit of measure: "12.3 meters" + *
      • Currency: "$12.30" + *
      • Percent: "12.3%" + *
      + * + * All units will be properly localized with locale data, and all units are compatible with notation styles, + * rounding precisions, and other number formatter settings. + * + * Pass this method any instance of {@link MeasureUnit}. For units of measure: + * + *
      +     * NumberFormatter::with().unit(MeasureUnit::getMeter())
      +     * 
      + * + * Currency: + * + *
      +     * NumberFormatter::with().unit(CurrencyUnit(u"USD", status))
      +     * 
      + * + * Percent: + * + *
      +     * NumberFormatter::with().unit(NoUnit.percent())
      +     * 
      + * + * See {@link #perUnit} for information on how to format strings like "5 meters per second". + * + * The default is to render without units (equivalent to NoUnit.base()). + * + * @param unit + * The unit to render. + * @return The fluent chain. + * @see MeasureUnit + * @see Currency + * @see NoUnit + * @see #perUnit + * @draft ICU 60 + */ + Derived unit(const icu::MeasureUnit &unit) const &; + + /** + * Overload of unit() for use on an rvalue reference. + * + * @param unit + * The unit to render. + * @return The fluent chain. + * @see #unit + * @draft ICU 62 + */ + Derived unit(const icu::MeasureUnit &unit) &&; + + /** + * Like unit(), but takes ownership of a pointer. Convenient for use with the MeasureFormat factory + * methods that return pointers that need ownership. + * + * Note: consider using the MeasureFormat factory methods that return by value. + * + * @param unit + * The unit to render. + * @return The fluent chain. + * @see #unit + * @see MeasureUnit + * @draft ICU 60 + */ + Derived adoptUnit(icu::MeasureUnit *unit) const &; + + /** + * Overload of adoptUnit() for use on an rvalue reference. + * + * @param unit + * The unit to render. + * @return The fluent chain. + * @see #adoptUnit + * @draft ICU 62 + */ + Derived adoptUnit(icu::MeasureUnit *unit) &&; + + /** + * Sets a unit to be used in the denominator. For example, to format "3 m/s", pass METER to the unit and SECOND to + * the perUnit. + * + * Pass this method any instance of {@link MeasureUnit}. Example: + * + *
      +     * NumberFormatter::with()
      +     *      .unit(MeasureUnit::getMeter())
      +     *      .perUnit(MeasureUnit::getSecond())
      +     * 
      + * + * The default is not to display any unit in the denominator. + * + * If a per-unit is specified without a primary unit via {@link #unit}, the behavior is undefined. + * + * @param perUnit + * The unit to render in the denominator. + * @return The fluent chain + * @see #unit + * @draft ICU 61 + */ + Derived perUnit(const icu::MeasureUnit &perUnit) const &; + + /** + * Overload of perUnit() for use on an rvalue reference. + * + * @param perUnit + * The unit to render in the denominator. + * @return The fluent chain. + * @see #perUnit + * @draft ICU 62 + */ + Derived perUnit(const icu::MeasureUnit &perUnit) &&; + + /** + * Like perUnit(), but takes ownership of a pointer. Convenient for use with the MeasureFormat factory + * methods that return pointers that need ownership. + * + * Note: consider using the MeasureFormat factory methods that return by value. + * + * @param perUnit + * The unit to render in the denominator. + * @return The fluent chain. + * @see #perUnit + * @see MeasureUnit + * @draft ICU 61 + */ + Derived adoptPerUnit(icu::MeasureUnit *perUnit) const &; + + /** + * Overload of adoptPerUnit() for use on an rvalue reference. + * + * @param perUnit + * The unit to render in the denominator. + * @return The fluent chain. + * @see #adoptPerUnit + * @draft ICU 62 + */ + Derived adoptPerUnit(icu::MeasureUnit *perUnit) &&; + + /** + * Specifies the rounding precision to use when formatting numbers. + * + *
        + *
      • Round to 3 decimal places: "3.142" + *
      • Round to 3 significant figures: "3.14" + *
      • Round to the closest nickel: "3.15" + *
      • Do not perform rounding: "3.1415926..." + *
      + * + *

      + * Pass this method the return value of one of the factory methods on {@link Precision}. For example: + * + *

      +     * NumberFormatter::with().precision(Precision::fixedFraction(2))
      +     * 
      + * + *

      + * In most cases, the default rounding strategy is to round to 6 fraction places; i.e., + * Precision.maxFraction(6). The exceptions are if compact notation is being used, then the compact + * notation rounding strategy is used (see {@link Notation#compactShort} for details), or if the unit is a currency, + * then standard currency rounding is used, which varies from currency to currency (see {@link Precision#currency} for + * details). + * + * @param precision + * The rounding precision to use. + * @return The fluent chain. + * @see Precision + * @draft ICU 62 + */ + Derived precision(const Precision& precision) const &; + + /** + * Overload of precision() for use on an rvalue reference. + * + * @param precision + * The rounding precision to use. + * @return The fluent chain. + * @see #precision + * @draft ICU 62 + */ + Derived precision(const Precision& precision) &&; + + /** + * Specifies how to determine the direction to round a number when it has more digits than fit in the + * desired precision. When formatting 1.235: + * + *

        + *
      • Ceiling rounding mode with integer precision: "2" + *
      • Half-down rounding mode with 2 fixed fraction digits: "1.23" + *
      • Half-up rounding mode with 2 fixed fraction digits: "1.24" + *
      + * + * The default is HALF_EVEN. For more information on rounding mode, see the ICU userguide here: + * + * http://userguide.icu-project.org/formatparse/numbers/rounding-modes + * + * @param roundingMode The rounding mode to use. + * @return The fluent chain. + * @draft ICU 62 + */ + Derived roundingMode(UNumberFormatRoundingMode roundingMode) const &; + + /** + * Overload of roundingMode() for use on an rvalue reference. + * + * @param roundingMode The rounding mode to use. + * @return The fluent chain. + * @see #roundingMode + * @draft ICU 62 + */ + Derived roundingMode(UNumberFormatRoundingMode roundingMode) &&; + + /** + * Specifies the grouping strategy to use when formatting numbers. + * + *
        + *
      • Default grouping: "12,300" and "1,230" + *
      • Grouping with at least 2 digits: "12,300" and "1230" + *
      • No grouping: "12300" and "1230" + *
      + * + *

      + * The exact grouping widths will be chosen based on the locale. + * + *

      + * Pass this method an element from the {@link UNumberGroupingStrategy} enum. For example: + * + *

      +     * NumberFormatter::with().grouping(UNUM_GROUPING_MIN2)
      +     * 
      + * + * The default is to perform grouping according to locale data; most locales, but not all locales, + * enable it by default. + * + * @param strategy + * The grouping strategy to use. + * @return The fluent chain. + * @draft ICU 61 + */ + Derived grouping(UNumberGroupingStrategy strategy) const &; + + /** + * Overload of grouping() for use on an rvalue reference. + * + * @param strategy + * The grouping strategy to use. + * @return The fluent chain. + * @see #grouping + * @draft ICU 62 + */ + Derived grouping(UNumberGroupingStrategy strategy) &&; + + /** + * Specifies the minimum and maximum number of digits to render before the decimal mark. + * + *
        + *
      • Zero minimum integer digits: ".08" + *
      • One minimum integer digit: "0.08" + *
      • Two minimum integer digits: "00.08" + *
      + * + *

      + * Pass this method the return value of {@link IntegerWidth#zeroFillTo}. For example: + * + *

      +     * NumberFormatter::with().integerWidth(IntegerWidth::zeroFillTo(2))
      +     * 
      + * + * The default is to have one minimum integer digit. + * + * @param style + * The integer width to use. + * @return The fluent chain. + * @see IntegerWidth + * @draft ICU 60 + */ + Derived integerWidth(const IntegerWidth &style) const &; + + /** + * Overload of integerWidth() for use on an rvalue reference. + * + * @param style + * The integer width to use. + * @return The fluent chain. + * @see #integerWidth + * @draft ICU 62 + */ + Derived integerWidth(const IntegerWidth &style) &&; + + /** + * Specifies the symbols (decimal separator, grouping separator, percent sign, numerals, etc.) to use when rendering + * numbers. + * + *
        + *
      • en_US symbols: "12,345.67" + *
      • fr_FR symbols: "12 345,67" + *
      • de_CH symbols: "12’345.67" + *
      • my_MY symbols: "၁၂,၃၄၅.၆၇" + *
      + * + *

      + * Pass this method an instance of {@link DecimalFormatSymbols}. For example: + * + *

      +     * NumberFormatter::with().symbols(DecimalFormatSymbols(Locale("de_CH"), status))
      +     * 
      + * + *

      + * Note: DecimalFormatSymbols automatically chooses the best numbering system based on the locale. + * In the examples above, the first three are using the Latin numbering system, and the fourth is using the Myanmar + * numbering system. + * + *

      + * Note: The instance of DecimalFormatSymbols will be copied: changes made to the symbols object + * after passing it into the fluent chain will not be seen. + * + *

      + * Note: Calling this method will override any previously specified DecimalFormatSymbols + * or NumberingSystem. + * + *

      + * The default is to choose the symbols based on the locale specified in the fluent chain. + * + * @param symbols + * The DecimalFormatSymbols to use. + * @return The fluent chain. + * @see DecimalFormatSymbols + * @draft ICU 60 + */ + Derived symbols(const DecimalFormatSymbols &symbols) const &; + + /** + * Overload of symbols() for use on an rvalue reference. + * + * @param symbols + * The DecimalFormatSymbols to use. + * @return The fluent chain. + * @see #symbols + * @draft ICU 62 + */ + Derived symbols(const DecimalFormatSymbols &symbols) &&; + + /** + * Specifies that the given numbering system should be used when fetching symbols. + * + *

        + *
      • Latin numbering system: "12,345" + *
      • Myanmar numbering system: "၁၂,၃၄၅" + *
      • Math Sans Bold numbering system: "𝟭𝟮,𝟯𝟰𝟱" + *
      + * + *

      + * Pass this method an instance of {@link NumberingSystem}. For example, to force the locale to always use the Latin + * alphabet numbering system (ASCII digits): + * + *

      +     * NumberFormatter::with().adoptSymbols(NumberingSystem::createInstanceByName("latn", status))
      +     * 
      + * + *

      + * Note: Calling this method will override any previously specified DecimalFormatSymbols + * or NumberingSystem. + * + *

      + * The default is to choose the best numbering system for the locale. + * + *

      + * This method takes ownership of a pointer in order to work nicely with the NumberingSystem factory methods. + * + * @param symbols + * The NumberingSystem to use. + * @return The fluent chain. + * @see NumberingSystem + * @draft ICU 60 + */ + Derived adoptSymbols(NumberingSystem *symbols) const &; + + /** + * Overload of adoptSymbols() for use on an rvalue reference. + * + * @param symbols + * The NumberingSystem to use. + * @return The fluent chain. + * @see #adoptSymbols + * @draft ICU 62 + */ + Derived adoptSymbols(NumberingSystem *symbols) &&; + + /** + * Sets the width of the unit (measure unit or currency). Most common values: + * + *

        + *
      • Short: "$12.00", "12 m" + *
      • ISO Code: "USD 12.00" + *
      • Full name: "12.00 US dollars", "12 meters" + *
      + * + *

      + * Pass an element from the {@link UNumberUnitWidth} enum to this setter. For example: + * + *

      +     * NumberFormatter::with().unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME)
      +     * 
      + * + *

      + * The default is the SHORT width. + * + * @param width + * The width to use when rendering numbers. + * @return The fluent chain + * @see UNumberUnitWidth + * @draft ICU 60 + */ + Derived unitWidth(UNumberUnitWidth width) const &; + + /** + * Overload of unitWidth() for use on an rvalue reference. + * + * @param width + * The width to use when rendering numbers. + * @return The fluent chain. + * @see #unitWidth + * @draft ICU 62 + */ + Derived unitWidth(UNumberUnitWidth width) &&; + + /** + * Sets the plus/minus sign display strategy. Most common values: + * + *

        + *
      • Auto: "123", "-123" + *
      • Always: "+123", "-123" + *
      • Accounting: "$123", "($123)" + *
      + * + *

      + * Pass an element from the {@link UNumberSignDisplay} enum to this setter. For example: + * + *

      +     * NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ALWAYS)
      +     * 
      + * + *

      + * The default is AUTO sign display. + * + * @param style + * The sign display strategy to use when rendering numbers. + * @return The fluent chain + * @see UNumberSignDisplay + * @draft ICU 60 + */ + Derived sign(UNumberSignDisplay style) const &; + + /** + * Overload of sign() for use on an rvalue reference. + * + * @param style + * The sign display strategy to use when rendering numbers. + * @return The fluent chain. + * @see #sign + * @draft ICU 62 + */ + Derived sign(UNumberSignDisplay style) &&; + + /** + * Sets the decimal separator display strategy. This affects integer numbers with no fraction part. Most common + * values: + * + *

        + *
      • Auto: "1" + *
      • Always: "1." + *
      + * + *

      + * Pass an element from the {@link UNumberDecimalSeparatorDisplay} enum to this setter. For example: + * + *

      +     * NumberFormatter::with().decimal(UNumberDecimalSeparatorDisplay::UNUM_DECIMAL_SEPARATOR_ALWAYS)
      +     * 
      + * + *

      + * The default is AUTO decimal separator display. + * + * @param style + * The decimal separator display strategy to use when rendering numbers. + * @return The fluent chain + * @see UNumberDecimalSeparatorDisplay + * @draft ICU 60 + */ + Derived decimal(UNumberDecimalSeparatorDisplay style) const &; + + /** + * Overload of decimal() for use on an rvalue reference. + * + * @param style + * The decimal separator display strategy to use when rendering numbers. + * @return The fluent chain. + * @see #decimal + * @draft ICU 62 + */ + Derived decimal(UNumberDecimalSeparatorDisplay style) &&; + + /** + * Sets a scale (multiplier) to be used to scale the number by an arbitrary amount before formatting. + * Most common values: + * + *

        + *
      • Multiply by 100: useful for percentages. + *
      • Multiply by an arbitrary value: useful for unit conversions. + *
      + * + *

      + * Pass an element from a {@link Scale} factory method to this setter. For example: + * + *

      +     * NumberFormatter::with().scale(Scale::powerOfTen(2))
      +     * 
      + * + *

      + * The default is to not apply any multiplier. + * + * @param scale + * The scale to apply when rendering numbers. + * @return The fluent chain + * @draft ICU 62 + */ + Derived scale(const Scale &scale) const &; + + /** + * Overload of scale() for use on an rvalue reference. + * + * @param scale + * The scale to apply when rendering numbers. + * @return The fluent chain. + * @see #scale + * @draft ICU 62 + */ + Derived scale(const Scale &scale) &&; + +#ifndef U_HIDE_INTERNAL_API + + /** + * Set the padding strategy. May be added in the future; see #13338. + * + * @internal ICU 60: This API is ICU internal only. + */ + Derived padding(const impl::Padder &padder) const &; + + /** @internal */ + Derived padding(const impl::Padder &padder) &&; + + /** + * Internal fluent setter to support a custom regulation threshold. A threshold of 1 causes the data structures to + * be built right away. A threshold of 0 prevents the data structures from being built. + * + * @internal ICU 60: This API is ICU internal only. + */ + Derived threshold(int32_t threshold) const &; + + /** @internal */ + Derived threshold(int32_t threshold) &&; + + /** + * Internal fluent setter to overwrite the entire macros object. + * + * @internal ICU 60: This API is ICU internal only. + */ + Derived macros(const impl::MacroProps& macros) const &; + + /** @internal */ + Derived macros(const impl::MacroProps& macros) &&; + + /** @internal */ + Derived macros(impl::MacroProps&& macros) const &; + + /** @internal */ + Derived macros(impl::MacroProps&& macros) &&; + +#endif /* U_HIDE_INTERNAL_API */ + + /** + * Creates a skeleton string representation of this number formatter. A skeleton string is a + * locale-agnostic serialized form of a number formatter. + * + * Not all options are capable of being represented in the skeleton string; for example, a + * DecimalFormatSymbols object. If any such option is encountered, the error code is set to + * U_UNSUPPORTED_ERROR. + * + * The returned skeleton is in normalized form, such that two number formatters with equivalent + * behavior should produce the same skeleton. + * + * @return A number skeleton string with behavior corresponding to this number formatter. + * @draft ICU 62 + */ + UnicodeString toSkeleton(UErrorCode& status) const; + + /** + * Returns the current (Un)LocalizedNumberFormatter as a LocalPointer + * wrapping a heap-allocated copy of the current object. + * + * This is equivalent to new-ing the move constructor with a value object + * as the argument. + * + * @return A wrapped (Un)LocalizedNumberFormatter pointer, or a wrapped + * nullptr on failure. + * @draft ICU 64 + */ + LocalPointer clone() const &; + + /** + * Overload of clone for use on an rvalue reference. + * + * @return A wrapped (Un)LocalizedNumberFormatter pointer, or a wrapped + * nullptr on failure. + * @draft ICU 64 + */ + LocalPointer clone() &&; + + /** + * Sets the UErrorCode if an error occurred in the fluent chain. + * Preserves older error codes in the outErrorCode. + * @return TRUE if U_FAILURE(outErrorCode) + * @draft ICU 60 + */ + UBool copyErrorTo(UErrorCode &outErrorCode) const { + if (U_FAILURE(outErrorCode)) { + // Do not overwrite the older error code + return TRUE; + } + fMacros.copyErrorTo(outErrorCode); + return U_FAILURE(outErrorCode); + } + + // NOTE: Uses default copy and move constructors. + + private: + impl::MacroProps fMacros; + + // Don't construct me directly! Use (Un)LocalizedNumberFormatter. + NumberFormatterSettings() = default; + + friend class LocalizedNumberFormatter; + friend class UnlocalizedNumberFormatter; + + // Give NumberRangeFormatter access to the MacroProps + friend void impl::touchRangeLocales(impl::RangeMacroProps& macros); + friend class impl::NumberRangeFormatterImpl; +}; + +/** + * A NumberFormatter that does not yet have a locale. In order to format numbers, a locale must be specified. + * + * Instances of this class are immutable and thread-safe. + * + * @see NumberFormatter + * @draft ICU 60 + */ +class U_I18N_API UnlocalizedNumberFormatter + : public NumberFormatterSettings, public UMemory { + + public: + /** + * Associate the given locale with the number formatter. The locale is used for picking the appropriate symbols, + * formats, and other data for number display. + * + * @param locale + * The locale to use when loading data for number formatting. + * @return The fluent chain. + * @draft ICU 60 + */ + LocalizedNumberFormatter locale(const icu::Locale &locale) const &; + + /** + * Overload of locale() for use on an rvalue reference. + * + * @param locale + * The locale to use when loading data for number formatting. + * @return The fluent chain. + * @see #locale + * @draft ICU 62 + */ + LocalizedNumberFormatter locale(const icu::Locale &locale) &&; + + /** + * Default constructor: puts the formatter into a valid but undefined state. + * + * @draft ICU 62 + */ + UnlocalizedNumberFormatter() = default; + + /** + * Returns a copy of this UnlocalizedNumberFormatter. + * @draft ICU 60 + */ + UnlocalizedNumberFormatter(const UnlocalizedNumberFormatter &other); + + /** + * Move constructor: + * The source UnlocalizedNumberFormatter will be left in a valid but undefined state. + * @draft ICU 62 + */ + UnlocalizedNumberFormatter(UnlocalizedNumberFormatter&& src) U_NOEXCEPT; + + /** + * Copy assignment operator. + * @draft ICU 62 + */ + UnlocalizedNumberFormatter& operator=(const UnlocalizedNumberFormatter& other); + + /** + * Move assignment operator: + * The source UnlocalizedNumberFormatter will be left in a valid but undefined state. + * @draft ICU 62 + */ + UnlocalizedNumberFormatter& operator=(UnlocalizedNumberFormatter&& src) U_NOEXCEPT; + + private: + explicit UnlocalizedNumberFormatter(const NumberFormatterSettings& other); + + explicit UnlocalizedNumberFormatter( + NumberFormatterSettings&& src) U_NOEXCEPT; + + // To give the fluent setters access to this class's constructor: + friend class NumberFormatterSettings; + + // To give NumberFormatter::with() access to this class's constructor: + friend class NumberFormatter; +}; + +/** + * A NumberFormatter that has a locale associated with it; this means .format() methods are available. + * + * Instances of this class are immutable and thread-safe. + * + * @see NumberFormatter + * @draft ICU 60 + */ +class U_I18N_API LocalizedNumberFormatter + : public NumberFormatterSettings, public UMemory { + public: + /** + * Format the given integer number to a string using the settings specified in the NumberFormatter fluent + * setting chain. + * + * @param value + * The number to format. + * @param status + * Set to an ErrorCode if one occurred in the setter chain or during formatting. + * @return A FormattedNumber object; call .toString() to get the string. + * @draft ICU 60 + */ + FormattedNumber formatInt(int64_t value, UErrorCode &status) const; + + /** + * Format the given float or double to a string using the settings specified in the NumberFormatter fluent setting + * chain. + * + * @param value + * The number to format. + * @param status + * Set to an ErrorCode if one occurred in the setter chain or during formatting. + * @return A FormattedNumber object; call .toString() to get the string. + * @draft ICU 60 + */ + FormattedNumber formatDouble(double value, UErrorCode &status) const; + + /** + * Format the given decimal number to a string using the settings + * specified in the NumberFormatter fluent setting chain. + * The syntax of the unformatted number is a "numeric string" + * as defined in the Decimal Arithmetic Specification, available at + * http://speleotrove.com/decimal + * + * @param value + * The number to format. + * @param status + * Set to an ErrorCode if one occurred in the setter chain or during formatting. + * @return A FormattedNumber object; call .toString() to get the string. + * @draft ICU 60 + */ + FormattedNumber formatDecimal(StringPiece value, UErrorCode& status) const; + +#ifndef U_HIDE_INTERNAL_API + + /** + * Set whether DecimalFormatSymbols copy is deep (clone) + * or shallow (pointer copy). Apple + * @internal + */ + void setDFSShallowCopy(UBool shallow); + + /** Internal method. + * @internal + */ + FormattedNumber formatDecimalQuantity(const impl::DecimalQuantity& dq, UErrorCode& status) const; + + /** Internal method for DecimalFormat compatibility. + * @internal + */ + void getAffixImpl(bool isPrefix, bool isNegative, UnicodeString& result, UErrorCode& status) const; + + /** + * Internal method for testing. + * @internal + */ + const impl::NumberFormatterImpl* getCompiled() const; + + /** + * Internal method for testing. + * @internal + */ + int32_t getCallCount() const; + +#endif /* U_HIDE_INTERNAL_API */ + + /** + * Creates a representation of this LocalizedNumberFormat as an icu::Format, enabling the use + * of this number formatter with APIs that need an object of that type, such as MessageFormat. + * + * This API is not intended to be used other than for enabling API compatibility. The formatDouble, + * formatInt, and formatDecimal methods should normally be used when formatting numbers, not the Format + * object returned by this method. + * + * The caller owns the returned object and must delete it when finished. + * + * @return A Format wrapping this LocalizedNumberFormatter. + * @draft ICU 62 + */ + Format* toFormat(UErrorCode& status) const; + + /** + * Default constructor: puts the formatter into a valid but undefined state. + * + * @draft ICU 62 + */ + LocalizedNumberFormatter() = default; + + /** + * Returns a copy of this LocalizedNumberFormatter. + * @draft ICU 60 + */ + LocalizedNumberFormatter(const LocalizedNumberFormatter &other); + + /** + * Move constructor: + * The source LocalizedNumberFormatter will be left in a valid but undefined state. + * @draft ICU 62 + */ + LocalizedNumberFormatter(LocalizedNumberFormatter&& src) U_NOEXCEPT; + + /** + * Copy assignment operator. + * @draft ICU 62 + */ + LocalizedNumberFormatter& operator=(const LocalizedNumberFormatter& other); + + /** + * Move assignment operator: + * The source LocalizedNumberFormatter will be left in a valid but undefined state. + * @draft ICU 62 + */ + LocalizedNumberFormatter& operator=(LocalizedNumberFormatter&& src) U_NOEXCEPT; + +#ifndef U_HIDE_INTERNAL_API + + /** + * This is the core entrypoint to the number formatting pipeline. It performs self-regulation: a static code path + * for the first few calls, and compiling a more efficient data structure if called repeatedly. + * + *

      + * This function is very hot, being called in every call to the number formatting pipeline. + * + * @param results + * The results object. This method will mutate it to save the results. + * @param status + * @internal + */ + void formatImpl(impl::UFormattedNumberData *results, UErrorCode &status) const; + +#endif /* U_HIDE_INTERNAL_API */ + + /** + * Destruct this LocalizedNumberFormatter, cleaning up any memory it might own. + * @draft ICU 60 + */ + ~LocalizedNumberFormatter(); + + private: + // Note: fCompiled can't be a LocalPointer because impl::NumberFormatterImpl is defined in an internal + // header, and LocalPointer needs the full class definition in order to delete the instance. + const impl::NumberFormatterImpl* fCompiled {nullptr}; + char fUnsafeCallCount[8] {}; // internally cast to u_atomic_int32_t + + explicit LocalizedNumberFormatter(const NumberFormatterSettings& other); + + explicit LocalizedNumberFormatter(NumberFormatterSettings&& src) U_NOEXCEPT; + + LocalizedNumberFormatter(const impl::MacroProps ¯os, const Locale &locale); + + LocalizedNumberFormatter(impl::MacroProps &¯os, const Locale &locale); + + void clear(); + + void lnfMoveHelper(LocalizedNumberFormatter&& src); + + /** + * @return true if the compiled formatter is available. + */ + bool computeCompiled(UErrorCode& status) const; + + // To give the fluent setters access to this class's constructor: + friend class NumberFormatterSettings; + friend class NumberFormatterSettings; + + // To give UnlocalizedNumberFormatter::locale() access to this class's constructor: + friend class UnlocalizedNumberFormatter; +}; + +/** + * The result of a number formatting operation. This class allows the result to be exported in several data types, + * including a UnicodeString and a FieldPositionIterator. + * + * Instances of this class are immutable and thread-safe. + * + * @draft ICU 60 + */ +class U_I18N_API FormattedNumber : public UMemory, public FormattedValue { + public: + + /** + * Default constructor; makes an empty FormattedNumber. + * @draft ICU 64 + */ + FormattedNumber() + : fData(nullptr), fErrorCode(U_INVALID_STATE_ERROR) {} + + /** + * Move constructor: Leaves the source FormattedNumber in an undefined state. + * @draft ICU 62 + */ + FormattedNumber(FormattedNumber&& src) U_NOEXCEPT; + + /** + * Destruct an instance of FormattedNumber. + * @draft ICU 60 + */ + virtual ~FormattedNumber() U_OVERRIDE; + + /** Copying not supported; use move constructor instead. */ + FormattedNumber(const FormattedNumber&) = delete; + + /** Copying not supported; use move assignment instead. */ + FormattedNumber& operator=(const FormattedNumber&) = delete; + + /** + * Move assignment: Leaves the source FormattedNumber in an undefined state. + * @draft ICU 62 + */ + FormattedNumber& operator=(FormattedNumber&& src) U_NOEXCEPT; + + // Copybrief: this method is older than the parent method + /** + * @copybrief FormattedValue::toString() + * + * For more information, see FormattedValue::toString() + * + * @draft ICU 62 + */ + UnicodeString toString(UErrorCode& status) const U_OVERRIDE; + + // Copydoc: this method is new in ICU 64 + /** @copydoc FormattedValue::toTempString() */ + UnicodeString toTempString(UErrorCode& status) const U_OVERRIDE; + + // Copybrief: this method is older than the parent method + /** + * @copybrief FormattedValue::appendTo() + * + * For more information, see FormattedValue::appendTo() + * + * @draft ICU 62 + */ + Appendable &appendTo(Appendable& appendable, UErrorCode& status) const U_OVERRIDE; + + // Copydoc: this method is new in ICU 64 + /** @copydoc FormattedValue::nextPosition() */ + UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE; + + /** + * Determines the start (inclusive) and end (exclusive) indices of the next occurrence of the given + * field in the output string. This allows you to determine the locations of, for example, + * the integer part, fraction part, or symbols. + * + * This is a simpler but less powerful alternative to {@link #nextPosition}. + * + * If a field occurs just once, calling this method will find that occurrence and return it. If a + * field occurs multiple times, this method may be called repeatedly with the following pattern: + * + *

      +     * FieldPosition fpos(UNUM_GROUPING_SEPARATOR_FIELD);
      +     * while (formattedNumber.nextFieldPosition(fpos, status)) {
      +     *   // do something with fpos.
      +     * }
      +     * 
      + * + * This method is useful if you know which field to query. If you want all available field position + * information, use {@link #nextPosition} or {@link #getAllFieldPositions}. + * + * @param fieldPosition + * Input+output variable. On input, the "field" property determines which field to look + * up, and the "beginIndex" and "endIndex" properties determine where to begin the search. + * On output, the "beginIndex" is set to the beginning of the first occurrence of the + * field with either begin or end indices after the input indices; "endIndex" is set to + * the end of that occurrence of the field (exclusive index). If a field position is not + * found, the method returns FALSE and the FieldPosition may or may not be changed. + * @param status + * Set if an error occurs while populating the FieldPosition. + * @return TRUE if a new occurrence of the field was found; FALSE otherwise. + * @draft ICU 62 + * @see UNumberFormatFields + */ + UBool nextFieldPosition(FieldPosition& fieldPosition, UErrorCode& status) const; + + /** + * Export the formatted number to a FieldPositionIterator. This allows you to determine which characters in + * the output string correspond to which fields, such as the integer part, fraction part, and sign. + * + * This is an alternative to the more powerful #nextPosition() API. + * + * If information on only one field is needed, use #nextPosition() or #nextFieldPosition() instead. + * + * @param iterator + * The FieldPositionIterator to populate with all of the fields present in the formatted number. + * @param status + * Set if an error occurs while populating the FieldPositionIterator. + * @draft ICU 62 + * @see UNumberFormatFields + */ + void getAllFieldPositions(FieldPositionIterator &iterator, UErrorCode &status) const; + +#ifndef U_HIDE_INTERNAL_API + + /** + * Gets the raw DecimalQuantity for plural rule selection. + * @internal + */ + void getDecimalQuantity(impl::DecimalQuantity& output, UErrorCode& status) const; + + /** + * Populates the mutable builder type FieldPositionIteratorHandler. + * @internal + */ + void getAllFieldPositionsImpl(FieldPositionIteratorHandler& fpih, UErrorCode& status) const; + +#endif /* U_HIDE_INTERNAL_API */ + + private: + // Can't use LocalPointer because UFormattedNumberData is forward-declared + const impl::UFormattedNumberData *fData; + + // Error code for the terminal methods + UErrorCode fErrorCode; + + /** + * Internal constructor from data type. Adopts the data pointer. + * @internal + */ + explicit FormattedNumber(impl::UFormattedNumberData *results) + : fData(results), fErrorCode(U_ZERO_ERROR) {} + + explicit FormattedNumber(UErrorCode errorCode) + : fData(nullptr), fErrorCode(errorCode) {} + + // To give LocalizedNumberFormatter format methods access to this class's constructor: + friend class LocalizedNumberFormatter; + + // To give C API access to internals + friend struct impl::UFormattedNumberImpl; +}; + +/** + * See the main description in numberformatter.h for documentation and examples. + * + * @draft ICU 60 + */ +class U_I18N_API NumberFormatter final { + public: + /** + * Call this method at the beginning of a NumberFormatter fluent chain in which the locale is not currently known at + * the call site. + * + * @return An {@link UnlocalizedNumberFormatter}, to be used for chaining. + * @draft ICU 60 + */ + static UnlocalizedNumberFormatter with(); + + /** + * Call this method at the beginning of a NumberFormatter fluent chain in which the locale is known at the call + * site. + * + * @param locale + * The locale from which to load formats and symbols for number formatting. + * @return A {@link LocalizedNumberFormatter}, to be used for chaining. + * @draft ICU 60 + */ + static LocalizedNumberFormatter withLocale(const Locale &locale); + + /** + * Call this method at the beginning of a NumberFormatter fluent chain to create an instance based + * on a given number skeleton string. + * + * It is possible for an error to occur while parsing. See the overload of this method if you are + * interested in the location of a possible parse error. + * + * @param skeleton + * The skeleton string off of which to base this NumberFormatter. + * @param status + * Set to U_NUMBER_SKELETON_SYNTAX_ERROR if the skeleton was invalid. + * @return An UnlocalizedNumberFormatter, to be used for chaining. + * @draft ICU 62 + */ + static UnlocalizedNumberFormatter forSkeleton(const UnicodeString& skeleton, UErrorCode& status); + + /** + * Call this method at the beginning of a NumberFormatter fluent chain to create an instance based + * on a given number skeleton string. + * + * If an error occurs while parsing the skeleton string, the offset into the skeleton string at + * which the error occurred will be saved into the UParseError, if provided. + * + * @param skeleton + * The skeleton string off of which to base this NumberFormatter. + * @param perror + * A parse error struct populated if an error occurs when parsing. + * If no error occurs, perror.offset will be set to -1. + * @param status + * Set to U_NUMBER_SKELETON_SYNTAX_ERROR if the skeleton was invalid. + * @return An UnlocalizedNumberFormatter, to be used for chaining. + * @draft ICU 64 + */ + static UnlocalizedNumberFormatter forSkeleton(const UnicodeString& skeleton, + UParseError& perror, UErrorCode& status); + + /** + * Use factory methods instead of the constructor to create a NumberFormatter. + */ + NumberFormatter() = delete; +}; + +} // namespace number +U_NAMESPACE_END + +#endif // U_HIDE_DRAFT_API + +#endif // __NUMBERFORMATTER_H__ + +#endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/numberrangeformatter.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/numberrangeformatter.h new file mode 100644 index 0000000000..35b95d88af --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/numberrangeformatter.h @@ -0,0 +1,909 @@ +// © 2018 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#if !UCONFIG_NO_FORMATTING +#ifndef __NUMBERRANGEFORMATTER_H__ +#define __NUMBERRANGEFORMATTER_H__ + +#include +#include "unicode/appendable.h" +#include "unicode/fieldpos.h" +#include "unicode/formattedvalue.h" +#include "unicode/fpositer.h" +#include "unicode/numberformatter.h" + +#ifndef U_HIDE_DRAFT_API + +/** + * \file + * \brief C++ API: Library for localized formatting of number, currency, and unit ranges. + * + * The main entrypoint to the formatting of ranges of numbers, including currencies and other units of measurement. + *

      + * Usage example: + *

      + *

      + * NumberRangeFormatter::with()
      + *     .identityFallback(UNUM_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE)
      + *     .numberFormatterFirst(NumberFormatter::with().adoptUnit(MeasureUnit::createMeter()))
      + *     .numberFormatterSecond(NumberFormatter::with().adoptUnit(MeasureUnit::createKilometer()))
      + *     .locale("en-GB")
      + *     .formatRange(750, 1.2, status)
      + *     .toString(status);
      + * // => "750 m - 1.2 km"
      + * 
      + *

      + * Like NumberFormatter, NumberRangeFormatter instances (i.e., LocalizedNumberRangeFormatter + * and UnlocalizedNumberRangeFormatter) are immutable and thread-safe. This API is based on the + * fluent design pattern popularized by libraries such as Google's Guava. + * + * @author Shane Carr + */ + + +/** + * Defines how to merge fields that are identical across the range sign. + * + * @draft ICU 63 + */ +typedef enum UNumberRangeCollapse { + /** + * Use locale data and heuristics to determine how much of the string to collapse. Could end up collapsing none, + * some, or all repeated pieces in a locale-sensitive way. + * + * The heuristics used for this option are subject to change over time. + * + * @draft ICU 63 + */ + UNUM_RANGE_COLLAPSE_AUTO, + + /** + * Do not collapse any part of the number. Example: "3.2 thousand kilograms – 5.3 thousand kilograms" + * + * @draft ICU 63 + */ + UNUM_RANGE_COLLAPSE_NONE, + + /** + * Collapse the unit part of the number, but not the notation, if present. Example: "3.2 thousand – 5.3 thousand + * kilograms" + * + * @draft ICU 63 + */ + UNUM_RANGE_COLLAPSE_UNIT, + + /** + * Collapse any field that is equal across the range sign. May introduce ambiguity on the magnitude of the + * number. Example: "3.2 – 5.3 thousand kilograms" + * + * @draft ICU 63 + */ + UNUM_RANGE_COLLAPSE_ALL +} UNumberRangeCollapse; + +/** + * Defines the behavior when the two numbers in the range are identical after rounding. To programmatically detect + * when the identity fallback is used, compare the lower and upper BigDecimals via FormattedNumber. + * + * @draft ICU 63 + * @see NumberRangeFormatter + */ +typedef enum UNumberRangeIdentityFallback { + /** + * Show the number as a single value rather than a range. Example: "$5" + * + * @draft ICU 63 + */ + UNUM_IDENTITY_FALLBACK_SINGLE_VALUE, + + /** + * Show the number using a locale-sensitive approximation pattern. If the numbers were the same before rounding, + * show the single value. Example: "~$5" or "$5" + * + * @draft ICU 63 + */ + UNUM_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, + + /** + * Show the number using a locale-sensitive approximation pattern. Use the range pattern always, even if the + * inputs are the same. Example: "~$5" + * + * @draft ICU 63 + */ + UNUM_IDENTITY_FALLBACK_APPROXIMATELY, + + /** + * Show the number as the range of two equal values. Use the range pattern always, even if the inputs are the + * same. Example (with RangeCollapse.NONE): "$5 – $5" + * + * @draft ICU 63 + */ + UNUM_IDENTITY_FALLBACK_RANGE +} UNumberRangeIdentityFallback; + +/** + * Used in the result class FormattedNumberRange to indicate to the user whether the numbers formatted in the range + * were equal or not, and whether or not the identity fallback was applied. + * + * @draft ICU 63 + * @see NumberRangeFormatter + */ +typedef enum UNumberRangeIdentityResult { + /** + * Used to indicate that the two numbers in the range were equal, even before any rounding rules were applied. + * + * @draft ICU 63 + * @see NumberRangeFormatter + */ + UNUM_IDENTITY_RESULT_EQUAL_BEFORE_ROUNDING, + + /** + * Used to indicate that the two numbers in the range were equal, but only after rounding rules were applied. + * + * @draft ICU 63 + * @see NumberRangeFormatter + */ + UNUM_IDENTITY_RESULT_EQUAL_AFTER_ROUNDING, + + /** + * Used to indicate that the two numbers in the range were not equal, even after rounding rules were applied. + * + * @draft ICU 63 + * @see NumberRangeFormatter + */ + UNUM_IDENTITY_RESULT_NOT_EQUAL, + +#ifndef U_HIDE_INTERNAL_API + /** + * The number of entries in this enum. + * @internal + */ + UNUM_IDENTITY_RESULT_COUNT +#endif + +} UNumberRangeIdentityResult; + +#if U_SHOW_CPLUSPLUS_API +U_NAMESPACE_BEGIN + +namespace number { // icu::number + +// Forward declarations: +class UnlocalizedNumberRangeFormatter; +class LocalizedNumberRangeFormatter; +class FormattedNumberRange; + +namespace impl { + +// Forward declarations: +struct RangeMacroProps; +class DecimalQuantity; +class UFormattedNumberRangeData; +class NumberRangeFormatterImpl; + +} // namespace impl + +/** + * \cond + * Export an explicit template instantiation. See datefmt.h + * (When building DLLs for Windows this is required.) + */ +#if U_PLATFORM == U_PF_WINDOWS && !defined(U_IN_DOXYGEN) +} // namespace icu::number +U_NAMESPACE_END + +template struct U_I18N_API std::atomic< U_NAMESPACE_QUALIFIER number::impl::NumberRangeFormatterImpl*>; + +U_NAMESPACE_BEGIN +namespace number { // icu::number +#endif +/** \endcond */ + +// Other helper classes would go here, but there are none. + +namespace impl { // icu::number::impl + +// Do not enclose entire MacroProps with #ifndef U_HIDE_INTERNAL_API, needed for a protected field +/** @internal */ +struct U_I18N_API RangeMacroProps : public UMemory { + /** @internal */ + UnlocalizedNumberFormatter formatter1; // = NumberFormatter::with(); + + /** @internal */ + UnlocalizedNumberFormatter formatter2; // = NumberFormatter::with(); + + /** @internal */ + bool singleFormatter = true; + + /** @internal */ + UNumberRangeCollapse collapse = UNUM_RANGE_COLLAPSE_AUTO; + + /** @internal */ + UNumberRangeIdentityFallback identityFallback = UNUM_IDENTITY_FALLBACK_APPROXIMATELY; + + /** @internal */ + Locale locale; + + // NOTE: Uses default copy and move constructors. + + /** + * Check all members for errors. + * @internal + */ + bool copyErrorTo(UErrorCode &status) const { + return formatter1.copyErrorTo(status) || formatter2.copyErrorTo(status); + } +}; + +} // namespace impl + +/** + * An abstract base class for specifying settings related to number formatting. This class is implemented by + * {@link UnlocalizedNumberRangeFormatter} and {@link LocalizedNumberRangeFormatter}. This class is not intended for + * public subclassing. + */ +template +class U_I18N_API NumberRangeFormatterSettings { + public: + /** + * Sets the NumberFormatter instance to use for the numbers in the range. The same formatter is applied to both + * sides of the range. + *

      + * The NumberFormatter instances must not have a locale applied yet; the locale specified on the + * NumberRangeFormatter will be used. + * + * @param formatter + * The formatter to use for both numbers in the range. + * @return The fluent chain. + * @draft ICU 63 + */ + Derived numberFormatterBoth(const UnlocalizedNumberFormatter &formatter) const &; + + /** + * Overload of numberFormatterBoth() for use on an rvalue reference. + * + * @param formatter + * The formatter to use for both numbers in the range. + * @return The fluent chain. + * @see #numberFormatterBoth + * @draft ICU 63 + */ + Derived numberFormatterBoth(const UnlocalizedNumberFormatter &formatter) &&; + + /** + * Overload of numberFormatterBoth() for use on an rvalue reference. + * + * @param formatter + * The formatter to use for both numbers in the range. + * @return The fluent chain. + * @see #numberFormatterBoth + * @draft ICU 63 + */ + Derived numberFormatterBoth(UnlocalizedNumberFormatter &&formatter) const &; + + /** + * Overload of numberFormatterBoth() for use on an rvalue reference. + * + * @param formatter + * The formatter to use for both numbers in the range. + * @return The fluent chain. + * @see #numberFormatterBoth + * @draft ICU 63 + */ + Derived numberFormatterBoth(UnlocalizedNumberFormatter &&formatter) &&; + + /** + * Sets the NumberFormatter instance to use for the first number in the range. + *

      + * The NumberFormatter instances must not have a locale applied yet; the locale specified on the + * NumberRangeFormatter will be used. + * + * @param formatterFirst + * The formatter to use for the first number in the range. + * @return The fluent chain. + * @draft ICU 63 + */ + Derived numberFormatterFirst(const UnlocalizedNumberFormatter &formatterFirst) const &; + + /** + * Overload of numberFormatterFirst() for use on an rvalue reference. + * + * @param formatterFirst + * The formatter to use for the first number in the range. + * @return The fluent chain. + * @see #numberFormatterFirst + * @draft ICU 63 + */ + Derived numberFormatterFirst(const UnlocalizedNumberFormatter &formatterFirst) &&; + + /** + * Overload of numberFormatterFirst() for use on an rvalue reference. + * + * @param formatterFirst + * The formatter to use for the first number in the range. + * @return The fluent chain. + * @see #numberFormatterFirst + * @draft ICU 63 + */ + Derived numberFormatterFirst(UnlocalizedNumberFormatter &&formatterFirst) const &; + + /** + * Overload of numberFormatterFirst() for use on an rvalue reference. + * + * @param formatterFirst + * The formatter to use for the first number in the range. + * @return The fluent chain. + * @see #numberFormatterFirst + * @draft ICU 63 + */ + Derived numberFormatterFirst(UnlocalizedNumberFormatter &&formatterFirst) &&; + + /** + * Sets the NumberFormatter instance to use for the second number in the range. + *

      + * The NumberFormatter instances must not have a locale applied yet; the locale specified on the + * NumberRangeFormatter will be used. + * + * @param formatterSecond + * The formatter to use for the second number in the range. + * @return The fluent chain. + * @draft ICU 63 + */ + Derived numberFormatterSecond(const UnlocalizedNumberFormatter &formatterSecond) const &; + + /** + * Overload of numberFormatterSecond() for use on an rvalue reference. + * + * @param formatterSecond + * The formatter to use for the second number in the range. + * @return The fluent chain. + * @see #numberFormatterSecond + * @draft ICU 63 + */ + Derived numberFormatterSecond(const UnlocalizedNumberFormatter &formatterSecond) &&; + + /** + * Overload of numberFormatterSecond() for use on an rvalue reference. + * + * @param formatterSecond + * The formatter to use for the second number in the range. + * @return The fluent chain. + * @see #numberFormatterSecond + * @draft ICU 63 + */ + Derived numberFormatterSecond(UnlocalizedNumberFormatter &&formatterSecond) const &; + + /** + * Overload of numberFormatterSecond() for use on an rvalue reference. + * + * @param formatterSecond + * The formatter to use for the second number in the range. + * @return The fluent chain. + * @see #numberFormatterSecond + * @draft ICU 63 + */ + Derived numberFormatterSecond(UnlocalizedNumberFormatter &&formatterSecond) &&; + + /** + * Sets the aggressiveness of "collapsing" fields across the range separator. Possible values: + *

      + *

        + *
      • ALL: "3-5K miles"
      • + *
      • UNIT: "3K - 5K miles"
      • + *
      • NONE: "3K miles - 5K miles"
      • + *
      • AUTO: usually UNIT or NONE, depending on the locale and formatter settings
      • + *
      + *

      + * The default value is AUTO. + * + * @param collapse + * The collapsing strategy to use for this range. + * @return The fluent chain. + * @draft ICU 63 + */ + Derived collapse(UNumberRangeCollapse collapse) const &; + + /** + * Overload of collapse() for use on an rvalue reference. + * + * @param collapse + * The collapsing strategy to use for this range. + * @return The fluent chain. + * @see #collapse + * @draft ICU 63 + */ + Derived collapse(UNumberRangeCollapse collapse) &&; + + /** + * Sets the behavior when the two sides of the range are the same. This could happen if the same two numbers are + * passed to the formatRange function, or if different numbers are passed to the function but they become the same + * after rounding rules are applied. Possible values: + *

      + *

        + *
      • SINGLE_VALUE: "5 miles"
      • + *
      • APPROXIMATELY_OR_SINGLE_VALUE: "~5 miles" or "5 miles", depending on whether the number was the same before + * rounding was applied
      • + *
      • APPROXIMATELY: "~5 miles"
      • + *
      • RANGE: "5-5 miles" (with collapse=UNIT)
      • + *
      + *

      + * The default value is APPROXIMATELY. + * + * @param identityFallback + * The strategy to use when formatting two numbers that end up being the same. + * @return The fluent chain. + * @draft ICU 63 + */ + Derived identityFallback(UNumberRangeIdentityFallback identityFallback) const &; + + /** + * Overload of identityFallback() for use on an rvalue reference. + * + * @param identityFallback + * The strategy to use when formatting two numbers that end up being the same. + * @return The fluent chain. + * @see #identityFallback + * @draft ICU 63 + */ + Derived identityFallback(UNumberRangeIdentityFallback identityFallback) &&; + + /** + * Returns the current (Un)LocalizedNumberRangeFormatter as a LocalPointer + * wrapping a heap-allocated copy of the current object. + * + * This is equivalent to new-ing the move constructor with a value object + * as the argument. + * + * @return A wrapped (Un)LocalizedNumberRangeFormatter pointer, or a wrapped + * nullptr on failure. + * @draft ICU 64 + */ + LocalPointer clone() const &; + + /** + * Overload of clone for use on an rvalue reference. + * + * @return A wrapped (Un)LocalizedNumberRangeFormatter pointer, or a wrapped + * nullptr on failure. + * @draft ICU 64 + */ + LocalPointer clone() &&; + + /** + * Sets the UErrorCode if an error occurred in the fluent chain. + * Preserves older error codes in the outErrorCode. + * @return TRUE if U_FAILURE(outErrorCode) + * @draft ICU 63 + */ + UBool copyErrorTo(UErrorCode &outErrorCode) const { + if (U_FAILURE(outErrorCode)) { + // Do not overwrite the older error code + return TRUE; + } + fMacros.copyErrorTo(outErrorCode); + return U_FAILURE(outErrorCode); + } + + // NOTE: Uses default copy and move constructors. + + private: + impl::RangeMacroProps fMacros; + + // Don't construct me directly! Use (Un)LocalizedNumberFormatter. + NumberRangeFormatterSettings() = default; + + friend class LocalizedNumberRangeFormatter; + friend class UnlocalizedNumberRangeFormatter; +}; + +/** + * A NumberRangeFormatter that does not yet have a locale. In order to format, a locale must be specified. + * + * Instances of this class are immutable and thread-safe. + * + * @see NumberRangeFormatter + * @draft ICU 63 + */ +class U_I18N_API UnlocalizedNumberRangeFormatter + : public NumberRangeFormatterSettings, public UMemory { + + public: + /** + * Associate the given locale with the number range formatter. The locale is used for picking the + * appropriate symbols, formats, and other data for number display. + * + * @param locale + * The locale to use when loading data for number formatting. + * @return The fluent chain. + * @draft ICU 63 + */ + LocalizedNumberRangeFormatter locale(const icu::Locale &locale) const &; + + /** + * Overload of locale() for use on an rvalue reference. + * + * @param locale + * The locale to use when loading data for number formatting. + * @return The fluent chain. + * @see #locale + * @draft ICU 63 + */ + LocalizedNumberRangeFormatter locale(const icu::Locale &locale) &&; + + /** + * Default constructor: puts the formatter into a valid but undefined state. + * + * @draft ICU 63 + */ + UnlocalizedNumberRangeFormatter() = default; + + /** + * Returns a copy of this UnlocalizedNumberRangeFormatter. + * @draft ICU 63 + */ + UnlocalizedNumberRangeFormatter(const UnlocalizedNumberRangeFormatter &other); + + /** + * Move constructor: + * The source UnlocalizedNumberRangeFormatter will be left in a valid but undefined state. + * @draft ICU 63 + */ + UnlocalizedNumberRangeFormatter(UnlocalizedNumberRangeFormatter&& src) U_NOEXCEPT; + + /** + * Copy assignment operator. + * @draft ICU 63 + */ + UnlocalizedNumberRangeFormatter& operator=(const UnlocalizedNumberRangeFormatter& other); + + /** + * Move assignment operator: + * The source UnlocalizedNumberRangeFormatter will be left in a valid but undefined state. + * @draft ICU 63 + */ + UnlocalizedNumberRangeFormatter& operator=(UnlocalizedNumberRangeFormatter&& src) U_NOEXCEPT; + + private: + explicit UnlocalizedNumberRangeFormatter( + const NumberRangeFormatterSettings& other); + + explicit UnlocalizedNumberRangeFormatter( + NumberRangeFormatterSettings&& src) U_NOEXCEPT; + + // To give the fluent setters access to this class's constructor: + friend class NumberRangeFormatterSettings; + + // To give NumberRangeFormatter::with() access to this class's constructor: + friend class NumberRangeFormatter; +}; + +/** + * A NumberRangeFormatter that has a locale associated with it; this means .formatRange() methods are available. + * + * Instances of this class are immutable and thread-safe. + * + * @see NumberFormatter + * @draft ICU 63 + */ +class U_I18N_API LocalizedNumberRangeFormatter + : public NumberRangeFormatterSettings, public UMemory { + public: + /** + * Format the given Formattables to a string using the settings specified in the NumberRangeFormatter fluent setting + * chain. + * + * @param first + * The first number in the range, usually to the left in LTR locales. + * @param second + * The second number in the range, usually to the right in LTR locales. + * @param status + * Set if an error occurs while formatting. + * @return A FormattedNumberRange object; call .toString() to get the string. + * @draft ICU 63 + */ + FormattedNumberRange formatFormattableRange( + const Formattable& first, const Formattable& second, UErrorCode& status) const; + + /** + * Default constructor: puts the formatter into a valid but undefined state. + * + * @draft ICU 63 + */ + LocalizedNumberRangeFormatter() = default; + + /** + * Returns a copy of this LocalizedNumberRangeFormatter. + * @draft ICU 63 + */ + LocalizedNumberRangeFormatter(const LocalizedNumberRangeFormatter &other); + + /** + * Move constructor: + * The source LocalizedNumberRangeFormatter will be left in a valid but undefined state. + * @draft ICU 63 + */ + LocalizedNumberRangeFormatter(LocalizedNumberRangeFormatter&& src) U_NOEXCEPT; + + /** + * Copy assignment operator. + * @draft ICU 63 + */ + LocalizedNumberRangeFormatter& operator=(const LocalizedNumberRangeFormatter& other); + + /** + * Move assignment operator: + * The source LocalizedNumberRangeFormatter will be left in a valid but undefined state. + * @draft ICU 63 + */ + LocalizedNumberRangeFormatter& operator=(LocalizedNumberRangeFormatter&& src) U_NOEXCEPT; + +#ifndef U_HIDE_INTERNAL_API + + /** + * @param results + * The results object. This method will mutate it to save the results. + * @param equalBeforeRounding + * Whether the number was equal before copying it into a DecimalQuantity. + * Used for determining the identity fallback behavior. + * @param status + * Set if an error occurs while formatting. + * @internal + */ + void formatImpl(impl::UFormattedNumberRangeData& results, bool equalBeforeRounding, + UErrorCode& status) const; + +#endif + + /** + * Destruct this LocalizedNumberRangeFormatter, cleaning up any memory it might own. + * @draft ICU 63 + */ + ~LocalizedNumberRangeFormatter(); + + private: + std::atomic fAtomicFormatter = {}; + + const impl::NumberRangeFormatterImpl* getFormatter(UErrorCode& stauts) const; + + explicit LocalizedNumberRangeFormatter( + const NumberRangeFormatterSettings& other); + + explicit LocalizedNumberRangeFormatter( + NumberRangeFormatterSettings&& src) U_NOEXCEPT; + + LocalizedNumberRangeFormatter(const impl::RangeMacroProps ¯os, const Locale &locale); + + LocalizedNumberRangeFormatter(impl::RangeMacroProps &¯os, const Locale &locale); + + void clear(); + + // To give the fluent setters access to this class's constructor: + friend class NumberRangeFormatterSettings; + friend class NumberRangeFormatterSettings; + + // To give UnlocalizedNumberRangeFormatter::locale() access to this class's constructor: + friend class UnlocalizedNumberRangeFormatter; +}; + +/** + * The result of a number range formatting operation. This class allows the result to be exported in several data types, + * including a UnicodeString and a FieldPositionIterator. + * + * Instances of this class are immutable and thread-safe. + * + * @draft ICU 63 + */ +class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue { + public: + // Copybrief: this method is older than the parent method + /** + * @copybrief FormattedValue::toString() + * + * For more information, see FormattedValue::toString() + * + * @draft ICU 63 + */ + UnicodeString toString(UErrorCode& status) const U_OVERRIDE; + + // Copydoc: this method is new in ICU 64 + /** @copydoc FormattedValue::toTempString() */ + UnicodeString toTempString(UErrorCode& status) const U_OVERRIDE; + + // Copybrief: this method is older than the parent method + /** + * @copybrief FormattedValue::appendTo() + * + * For more information, see FormattedValue::appendTo() + * + * @draft ICU 63 + */ + Appendable &appendTo(Appendable &appendable, UErrorCode& status) const U_OVERRIDE; + + // Copydoc: this method is new in ICU 64 + /** @copydoc FormattedValue::nextPosition() */ + UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE; + + /** + * Determines the start (inclusive) and end (exclusive) indices of the next occurrence of the given + * field in the output string. This allows you to determine the locations of, for example, + * the integer part, fraction part, or symbols. + * + * If both sides of the range have the same field, the field will occur twice, once before the + * range separator and once after the range separator, if applicable. + * + * If a field occurs just once, calling this method will find that occurrence and return it. If a + * field occurs multiple times, this method may be called repeatedly with the following pattern: + * + *

      +     * FieldPosition fpos(UNUM_INTEGER_FIELD);
      +     * while (formattedNumberRange.nextFieldPosition(fpos, status)) {
      +     *   // do something with fpos.
      +     * }
      +     * 
      + * + * This method is useful if you know which field to query. If you want all available field position + * information, use #getAllFieldPositions(). + * + * @param fieldPosition + * Input+output variable. See {@link FormattedNumber#nextFieldPosition}. + * @param status + * Set if an error occurs while populating the FieldPosition. + * @return TRUE if a new occurrence of the field was found; FALSE otherwise. + * @draft ICU 63 + * @see UNumberFormatFields + */ + UBool nextFieldPosition(FieldPosition& fieldPosition, UErrorCode& status) const; + + /** + * Export the formatted number range to a FieldPositionIterator. This allows you to determine which characters in + * the output string correspond to which fields, such as the integer part, fraction part, and sign. + * + * If information on only one field is needed, use #nextFieldPosition() instead. + * + * @param iterator + * The FieldPositionIterator to populate with all of the fields present in the formatted number. + * @param status + * Set if an error occurs while populating the FieldPositionIterator. + * @draft ICU 63 + * @see UNumberFormatFields + */ + void getAllFieldPositions(FieldPositionIterator &iterator, UErrorCode &status) const; + + /** + * Export the first formatted number as a decimal number. This endpoint + * is useful for obtaining the exact number being printed after scaling + * and rounding have been applied by the number range formatting pipeline. + * + * The syntax of the unformatted number is a "numeric string" + * as defined in the Decimal Arithmetic Specification, available at + * http://speleotrove.com/decimal + * + * @return A decimal representation of the first formatted number. + * @draft ICU 63 + * @see NumberRangeFormatter + * @see #getSecondDecimal + */ + UnicodeString getFirstDecimal(UErrorCode& status) const; + + /** + * Export the second formatted number as a decimal number. This endpoint + * is useful for obtaining the exact number being printed after scaling + * and rounding have been applied by the number range formatting pipeline. + * + * The syntax of the unformatted number is a "numeric string" + * as defined in the Decimal Arithmetic Specification, available at + * http://speleotrove.com/decimal + * + * @return A decimal representation of the second formatted number. + * @draft ICU 63 + * @see NumberRangeFormatter + * @see #getFirstDecimal + */ + UnicodeString getSecondDecimal(UErrorCode& status) const; + + /** + * Returns whether the pair of numbers was successfully formatted as a range or whether an identity fallback was + * used. For example, if the first and second number were the same either before or after rounding occurred, an + * identity fallback was used. + * + * @return An indication the resulting identity situation in the formatted number range. + * @draft ICU 63 + * @see UNumberRangeIdentityFallback + */ + UNumberRangeIdentityResult getIdentityResult(UErrorCode& status) const; + + /** + * Copying not supported; use move constructor instead. + */ + FormattedNumberRange(const FormattedNumberRange&) = delete; + + /** + * Copying not supported; use move assignment instead. + */ + FormattedNumberRange& operator=(const FormattedNumberRange&) = delete; + + /** + * Move constructor: + * Leaves the source FormattedNumberRange in an undefined state. + * @draft ICU 63 + */ + FormattedNumberRange(FormattedNumberRange&& src) U_NOEXCEPT; + + /** + * Move assignment: + * Leaves the source FormattedNumberRange in an undefined state. + * @draft ICU 63 + */ + FormattedNumberRange& operator=(FormattedNumberRange&& src) U_NOEXCEPT; + + /** + * Destruct an instance of FormattedNumberRange, cleaning up any memory it might own. + * @draft ICU 63 + */ + ~FormattedNumberRange(); + + private: + // Can't use LocalPointer because UFormattedNumberRangeData is forward-declared + const impl::UFormattedNumberRangeData *fData; + + // Error code for the terminal methods + UErrorCode fErrorCode; + + /** + * Internal constructor from data type. Adopts the data pointer. + * @internal + */ + explicit FormattedNumberRange(impl::UFormattedNumberRangeData *results) + : fData(results), fErrorCode(U_ZERO_ERROR) {} + + explicit FormattedNumberRange(UErrorCode errorCode) + : fData(nullptr), fErrorCode(errorCode) {} + + void getAllFieldPositionsImpl(FieldPositionIteratorHandler& fpih, UErrorCode& status) const; + + // To give LocalizedNumberRangeFormatter format methods access to this class's constructor: + friend class LocalizedNumberRangeFormatter; +}; + +/** + * See the main description in numberrangeformatter.h for documentation and examples. + * + * @draft ICU 63 + */ +class U_I18N_API NumberRangeFormatter final { + public: + /** + * Call this method at the beginning of a NumberRangeFormatter fluent chain in which the locale is not currently + * known at the call site. + * + * @return An {@link UnlocalizedNumberRangeFormatter}, to be used for chaining. + * @draft ICU 63 + */ + static UnlocalizedNumberRangeFormatter with(); + + /** + * Call this method at the beginning of a NumberRangeFormatter fluent chain in which the locale is known at the call + * site. + * + * @param locale + * The locale from which to load formats and symbols for number range formatting. + * @return A {@link LocalizedNumberRangeFormatter}, to be used for chaining. + * @draft ICU 63 + */ + static LocalizedNumberRangeFormatter withLocale(const Locale &locale); + + /** + * Use factory methods instead of the constructor to create a NumberFormatter. + */ + NumberRangeFormatter() = delete; +}; + +} // namespace number +U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API + +#endif // U_HIDE_DRAFT_API + +#endif // __NUMBERRANGEFORMATTER_H__ + +#endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/numfmt.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/numfmt.h index 164c65769f..cf188eef99 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/numfmt.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/numfmt.h @@ -1,6 +1,8 @@ +// © 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. +* Copyright (C) 1997-2016, International Business Machines Corporation and others. * All Rights Reserved. ******************************************************************************** * @@ -26,7 +28,7 @@ /** * \file - * \brief C++ API: Abstract base class for all number formats. + * \brief C++ API: Compatibility APIs for number formatting. */ #if !UCONFIG_NO_FORMATTING @@ -41,6 +43,7 @@ class NumberFormatTest; +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class SharedNumberFormat; @@ -51,11 +54,16 @@ class StringEnumeration; #endif /** + *

      IMPORTANT: New users are strongly encouraged to see if + * numberformatter.h fits their use case. Although not deprecated, this header + * is provided for backwards compatibility only. * * Abstract base class for all number formats. Provides interface for * formatting and parsing a number. Also provides methods for * determining which locales have number formats, and what their names * are. + * + * \headerfile unicode/numfmt.h "unicode/numfmt.h" *

      * NumberFormat helps you to format and parse numbers for any locale. * Your code can be completely independent of the locale conventions @@ -64,16 +72,22 @@ class StringEnumeration; *

      * To format a number for the current Locale, use one of the static * factory methods: - *

        * \code
      - *    double myNumber = 7.0;
      - *    UnicodeString myString;
      - *    UErrorCode success = U_ZERO_ERROR;
      - *    NumberFormat* nf = NumberFormat::createInstance(success)
      - *    nf->format(myNumber, myString);
      - *    cout << " Example 1: " << myString << endl;
      + *    #include 
      + *    #include "unicode/numfmt.h"
      + *    #include "unicode/unistr.h"
      + *    #include "unicode/ustream.h"
      + *    using namespace std;
      + *    
      + *    int main() {
      + *        double myNumber = 7.0;
      + *        UnicodeString myString;
      + *        UErrorCode success = U_ZERO_ERROR;
      + *        NumberFormat* nf = NumberFormat::createInstance(success);
      + *        nf->format(myNumber, myString);
      + *        cout << " Example 1: " << myString << endl;
      + *    }
        * \endcode
      - * 
      * Note that there are additional factory methods within subclasses of * NumberFormat. *

      @@ -81,68 +95,56 @@ class StringEnumeration; * the format and use it multiple times so that the system doesn't * have to fetch the information about the local language and country * conventions multiple times. - *

        * \code
        *     UnicodeString myString;
        *     UErrorCode success = U_ZERO_ERROR;
      - *     nf = NumberFormat::createInstance( success );
      - *     int32_t a[] = { 123, 3333, -1234567 };
      - *     const int32_t a_len = sizeof(a) / sizeof(a[0]);
      - *     myString.remove();
      - *     for (int32_t i = 0; i < a_len; i++) {
      - *         nf->format(a[i], myString);
      - *         myString += " ; ";
      + *     NumberFormat *nf = NumberFormat::createInstance( success );
      + *     for (int32_t number: {123, 3333, -1234567}) {
      + *         nf->format(number, myString);
      + *         myString += "; ";
        *     }
        *     cout << " Example 2: " << myString << endl;
        * \endcode
      - * 
      * To format a number for a different Locale, specify it in the - * call to createInstance(). - *
      + * call to \c createInstance().
        * \code
      - *     nf = NumberFormat::createInstance( Locale::FRENCH, success );
      + *     nf = NumberFormat::createInstance(Locale::getFrench(), success);
        * \endcode
      - * 
      - * You can use a NumberFormat to parse also. - *
      + * You can use a \c NumberFormat to parse also.
        * \code
        *    UErrorCode success;
        *    Formattable result(-999);  // initialized with error code
        *    nf->parse(myString, result, success);
        * \endcode
      - * 
      - * Use createInstance to get the normal number format for that country. - * There are other static factory methods available. Use getCurrency - * to get the currency number format for that country. Use getPercent + * Use \c createInstance() to get the normal number format for a \c Locale. + * There are other static factory methods available. Use \c createCurrencyInstance() + * to get the currency number format for that country. Use \c createPercentInstance() * to get a format for displaying percentages. With this format, a * fraction from 0.53 is displayed as 53%. *

      - * Starting from ICU 4.2, you can use createInstance() by passing in a 'style' - * as parameter to get the correct instance. - * For example, - * use createInstance(...kNumberStyle...) to get the normal number format, - * createInstance(...kPercentStyle...) to get a format for displaying - * percentage, - * createInstance(...kScientificStyle...) to get a format for displaying - * scientific number, - * createInstance(...kCurrencyStyle...) to get the currency number format, - * in which the currency is represented by its symbol, for example, "$3.00". - * createInstance(...kIsoCurrencyStyle...) to get the currency number format, - * in which the currency is represented by its ISO code, for example "USD3.00". - * createInstance(...kPluralCurrencyStyle...) to get the currency number format, + * The type of number formatting can be specified by passing a 'style' parameter to \c createInstance(). + * For example, use\n + * \c createInstance(locale, UNUM_DECIMAL, errorCode) to get the normal number format,\n + * \c createInstance(locale, UNUM_PERCENT, errorCode) to get a format for displaying percentage,\n + * \c createInstance(locale, UNUM_SCIENTIFIC, errorCode) to get a format for displaying scientific number,\n + * \c createInstance(locale, UNUM_CURRENCY, errorCode) to get the currency number format, + * in which the currency is represented by its symbol, for example, "$3.00".\n + * \c createInstance(locale, UNUM_CURRENCY_ISO, errorCode) to get the currency number format, + * in which the currency is represented by its ISO code, for example "USD3.00".\n + * \c createInstance(locale, UNUM_CURRENCY_PLURAL, errorCode) to get the currency number format, * in which the currency is represented by its full name in plural format, * for example, "3.00 US dollars" or "1.00 US dollar". *

      * You can also control the display of numbers with such methods as - * getMinimumFractionDigits. If you want even more control over the + * \c getMinimumFractionDigits(). If you want even more control over the * format or parsing, or want to give your users more control, you can - * try casting the NumberFormat you get from the factory methods to a - * DecimalNumberFormat. This will work for the vast majority of - * countries; just remember to put it in a try block in case you + * try dynamic_casting the \c NumberFormat you get from the factory methods to a + * \c DecimalFormat. This will work for the vast majority of + * countries; just remember to test for NULL in case you * encounter an unusual one. *

      * You can also use forms of the parse and format methods with - * ParsePosition and FieldPosition to allow you to: + * \c ParsePosition and \c FieldPosition to allow you to: *

        *
      • (a) progressively parse through pieces of a string. *
      • (b) align the decimal point and other areas. @@ -150,8 +152,8 @@ class StringEnumeration; * For example, you can align numbers in two ways. *

        * If you are using a monospaced font with spacing for alignment, you - * can pass the FieldPosition in your format call, with field = - * INTEGER_FIELD. On output, getEndIndex will be set to the offset + * can pass the \c FieldPosition in your format call, with field = + * \c UNUM_INTEGER_FIELD. On output, \c getEndIndex will be set to the offset * between the last character of the integer and the decimal. Add * (desiredSpaceCount - getEndIndex) spaces at the front of the * string. @@ -171,6 +173,33 @@ class StringEnumeration; */ class U_I18N_API NumberFormat : public Format { public: + /** + * Rounding mode. + * + *

        + * For more detail on rounding modes, see: + * http://userguide.icu-project.org/formatparse/numbers/rounding-modes + * + * @stable ICU 2.4 + */ + enum ERoundingMode { + kRoundCeiling, /**< Round towards positive infinity */ + kRoundFloor, /**< Round towards negative infinity */ + kRoundDown, /**< Round towards zero */ + kRoundUp, /**< Round away from zero */ + kRoundHalfEven, /**< Round towards the nearest integer, or + towards the nearest even integer if equidistant */ + kRoundHalfDown, /**< Round towards the nearest integer, or + towards zero if equidistant */ + kRoundHalfUp, /**< Round towards the nearest integer, or + away from zero if equidistant */ + /** + * Return U_FORMAT_INEXACT_ERROR if number does not format exactly. + * @stable ICU 4.8 + */ + kRoundUnnecessary + }; + /** * Alignment Field constants used to construct a FieldPosition object. * Signifies that the position of the integer part or fraction part of @@ -209,6 +238,12 @@ class U_I18N_API NumberFormat : public Format { kPermillField = UNUM_PERMILL_FIELD, /** @stable ICU 2.0 */ kSignField = UNUM_SIGN_FIELD, +#ifndef U_HIDE_DRAFT_API + /** @draft ICU 64 */ + kMeasureUnitField = UNUM_MEASURE_UNIT_FIELD, + /** @draft ICU 64 */ + kCompactField = UNUM_COMPACT_FIELD, +#endif // U_HIDE_DRAFT_API /** * These constants are provided for backwards compatibility only. @@ -271,7 +306,7 @@ class U_I18N_API NumberFormat : public Format { * 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, @@ -394,7 +429,7 @@ class U_I18N_API NumberFormat : public Format { * 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, @@ -446,7 +481,7 @@ class U_I18N_API NumberFormat : public Format { * 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, @@ -479,6 +514,7 @@ class U_I18N_API NumberFormat : public Format { * Result is appended to existing contents. * @param pos On input: an alignment field, if desired. * On output: the offsets of the alignment field. + * @param status Output param filled with success/failure status. * @return Reference to 'appendTo' parameter. * @internal */ @@ -498,7 +534,7 @@ class U_I18N_API NumberFormat : public Format { * 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, @@ -519,22 +555,24 @@ class U_I18N_API NumberFormat : public Format { * 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; -public: + +// Can't use #ifndef U_HIDE_INTERNAL_API because these are virtual methods + /** - * Format a decimal number. - * The number is a DigitList wrapper onto a floating point decimal number. + * Format a decimal number. + * The number is a DecimalQuantity wrapper onto a floating point decimal number. * The default implementation in NumberFormat converts the decimal number * to a double and formats that. Subclasses of NumberFormat that want * to specifically handle big decimal numbers must override this method. * class DecimalFormat does so. * - * @param number The number, a DigitList format Decimal Floating Point. + * @param number The number, a DecimalQuantity format Decimal Floating Point. * @param appendTo Output parameter to receive result. * Result is appended to existing contents. * @param posIter On return, can be used to iterate over positions @@ -543,20 +581,20 @@ class U_I18N_API NumberFormat : public Format { * @return Reference to 'appendTo' parameter. * @internal */ - virtual UnicodeString& format(const DigitList &number, + virtual UnicodeString& format(const number::impl::DecimalQuantity &number, UnicodeString& appendTo, FieldPositionIterator* posIter, UErrorCode& status) const; /** - * Format a decimal number. - * The number is a DigitList wrapper onto a floating point decimal number. + * Format a decimal number. + * The number is a DecimalQuantity wrapper onto a floating point decimal number. * The default implementation in NumberFormat converts the decimal number * to a double and formats that. Subclasses of NumberFormat that want * to specifically handle big decimal numbers must override this method. * class DecimalFormat does so. * - * @param number The number, a DigitList format Decimal Floating Point. + * @param number The number, a DecimalQuantity format Decimal Floating Point. * @param appendTo Output parameter to receive result. * Result is appended to existing contents. * @param pos On input: an alignment field, if desired. @@ -565,13 +603,11 @@ class U_I18N_API NumberFormat : public Format { * @return Reference to 'appendTo' parameter. * @internal */ - virtual UnicodeString& format(const DigitList &number, + virtual UnicodeString& format(const number::impl::DecimalQuantity &number, UnicodeString& appendTo, FieldPosition& pos, UErrorCode& status) const; -public: - /** * Return a long if possible (e.g. within range LONG_MAX, * LONG_MAX], and with no decimals), otherwise a double. If @@ -659,8 +695,8 @@ class U_I18N_API NumberFormat : public Format { /** * Sets whether lenient parsing should be enabled (it is off by default). * - * @param enable TRUE if lenient parsing should be used, - * FALSE otherwise. + * @param enable \c TRUE if lenient parsing should be used, + * \c FALSE otherwise. * @stable ICU 4.8 */ virtual void setLenient(UBool enable); @@ -668,36 +704,40 @@ class U_I18N_API NumberFormat : public Format { /** * Returns whether lenient parsing is enabled (it is off by default). * - * @return TRUE if lenient parsing is enabled, - * FALSE otherwise. + * @return \c TRUE if lenient parsing is enabled, + * \c FALSE otherwise. * @see #setLenient * @stable ICU 4.8 */ virtual UBool isLenient(void) const; /** - * Returns the default number format for the current default - * locale. The default format is one of the styles provided by - * the other factory methods: getNumberInstance, - * getCurrencyInstance or getPercentInstance. Exactly which one - * is locale dependant. + * Create a default style NumberFormat for the current default locale. + * The default formatting style is locale dependent. + *

        + * NOTE: New users are strongly encouraged to use + * {@link icu::number::NumberFormatter} instead of NumberFormat. * @stable ICU 2.0 */ static NumberFormat* U_EXPORT2 createInstance(UErrorCode&); /** - * Returns the default number format for the specified locale. - * The default format is one of the styles provided by the other - * factory methods: getNumberInstance, getCurrencyInstance or - * getPercentInstance. Exactly which one is locale dependant. + * Create a default style NumberFormat for the specified locale. + * The default formatting style is locale dependent. * @param inLocale the given locale. + *

        + * NOTE: New users are strongly encouraged to use + * {@link icu::number::NumberFormatter} instead of NumberFormat. * @stable ICU 2.0 */ static NumberFormat* U_EXPORT2 createInstance(const Locale& inLocale, UErrorCode&); /** - * Creates the specified decimal format style of the desired locale. + * Create a specific style NumberFormat for the specified locale. + *

        + * NOTE: New users are strongly encouraged to use + * {@link icu::number::NumberFormatter} instead of NumberFormat. * @param desiredLocale the given locale. * @param style the given style. * @param errorCode Output param filled with success/failure status. @@ -734,12 +774,18 @@ class U_I18N_API NumberFormat : public Format { /** * Returns a currency format for the current default locale. + *

        + * NOTE: New users are strongly encouraged to use + * {@link icu::number::NumberFormatter} instead of NumberFormat. * @stable ICU 2.0 */ static NumberFormat* U_EXPORT2 createCurrencyInstance(UErrorCode&); /** * Returns a currency format for the specified locale. + *

        + * NOTE: New users are strongly encouraged to use + * {@link icu::number::NumberFormatter} instead of NumberFormat. * @param inLocale the given locale. * @stable ICU 2.0 */ @@ -748,12 +794,18 @@ class U_I18N_API NumberFormat : public Format { /** * Returns a percentage format for the current default locale. + *

        + * NOTE: New users are strongly encouraged to use + * {@link icu::number::NumberFormatter} instead of NumberFormat. * @stable ICU 2.0 */ static NumberFormat* U_EXPORT2 createPercentInstance(UErrorCode&); /** * Returns a percentage format for the specified locale. + *

        + * NOTE: New users are strongly encouraged to use + * {@link icu::number::NumberFormatter} instead of NumberFormat. * @param inLocale the given locale. * @stable ICU 2.0 */ @@ -762,12 +814,18 @@ class U_I18N_API NumberFormat : public Format { /** * Returns a scientific format for the current default locale. + *

        + * NOTE: New users are strongly encouraged to use + * {@link icu::number::NumberFormatter} instead of NumberFormat. * @stable ICU 2.0 */ static NumberFormat* U_EXPORT2 createScientificInstance(UErrorCode&); /** * Returns a scientific format for the specified locale. + *

        + * NOTE: New users are strongly encouraged to use + * {@link icu::number::NumberFormatter} instead of NumberFormat. * @param inLocale the given locale. * @stable ICU 2.0 */ @@ -821,7 +879,7 @@ class U_I18N_API NumberFormat : public Format { * Returns true if grouping is used in this format. For example, * in the English locale, with grouping on, the number 1234567 * might be formatted as "1,234,567". The grouping separator as - * well as the size of each group is locale dependant and is + * well as the size of each group is locale dependent and is * determined by sub-classes of NumberFormat. * @see setGroupingUsed * @stable ICU 2.0 @@ -938,7 +996,7 @@ class U_I18N_API NumberFormat : public Format { * @param ec input-output error code * @stable ICU 3.0 */ - virtual void setCurrency(const UChar* theCurrency, UErrorCode& ec); + virtual void setCurrency(const char16_t* theCurrency, UErrorCode& ec); /** * Gets the currency used to display currency @@ -947,15 +1005,15 @@ class U_I18N_API NumberFormat : public Format { * the currency in use, or a pointer to the empty string. * @stable ICU 2.6 */ - const UChar* getCurrency() const; - + const char16_t* getCurrency() const; + /** * Set a particular UDisplayContext value in the formatter, such as * UDISPCTX_CAPITALIZATION_FOR_STANDALONE. * @param value The UDisplayContext value to set. * @param status Input/output status. If at entry this indicates a failure * status, the function will do nothing; otherwise this will be - * updated with any new status from the function. + * updated with any new status from the function. * @stable ICU 53 */ virtual void setContext(UDisplayContext value, UErrorCode& status); @@ -966,12 +1024,37 @@ class U_I18N_API NumberFormat : public Format { * @param type The UDisplayContextType whose value to return * @param status Input/output status. If at entry this indicates a failure * status, the function will do nothing; otherwise this will be - * updated with any new status from the function. + * updated with any new status from the function. * @return The UDisplayContextValue for the specified type. * @stable ICU 53 */ virtual UDisplayContext getContext(UDisplayContextType type, UErrorCode& status) const; + /** + * Get the rounding mode. This will always return NumberFormat::ERoundingMode::kRoundUnnecessary + * if the subclass does not support rounding. + * @return A rounding mode + * @stable ICU 60 + */ + virtual ERoundingMode getRoundingMode(void) const; + + /** + * Set the rounding mode. If a subclass does not support rounding, this will do nothing. + * @param roundingMode A rounding mode + * @stable ICU 60 + */ + virtual void setRoundingMode(ERoundingMode roundingMode); + + /** + * Group-set several settings used for numbers in date formats. + * Equivalent to: + * setGroupingUsed(FALSE); + * setParseIntegerOnly(TRUE); + * setMinimumFractionDigits(0); + * @internal + */ + virtual void setDateSettings(void); + public: /** @@ -1025,7 +1108,7 @@ class U_I18N_API NumberFormat : public Format { * have a capacity of at least 4 * @internal */ - virtual void getEffectiveCurrency(UChar* result, UErrorCode& ec) const; + virtual void getEffectiveCurrency(char16_t* result, UErrorCode& ec) const; #ifndef U_HIDE_INTERNAL_API /** @@ -1062,15 +1145,17 @@ class U_I18N_API NumberFormat : public Format { int32_t fMinFractionDigits; protected: + /** \internal */ static const int32_t gDefaultMaxIntegerDigits; + /** \internal */ static const int32_t gDefaultMinIntegerDigits; - + private: UBool fParseIntegerOnly; UBool fLenient; // TRUE => lenient parse is enabled // ISO currency code - UChar fCurrency[4]; + char16_t fCurrency[4]; UDisplayContext fCapitalizationContext; @@ -1178,6 +1263,7 @@ NumberFormat::isLenient() const } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/numsys.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/numsys.h index deeda2cabc..fc74fce797 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/numsys.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/numsys.h @@ -1,3 +1,5 @@ +// © 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 @@ -18,14 +20,6 @@ #include "unicode/utypes.h" -/** - * \def NUMSYS_NAME_CAPACITY - * Size of a numbering system name. - * @internal - */ -#define NUMSYS_NAME_CAPACITY 8 - - /** * \file * \brief C++ API: NumberingSystem object @@ -33,12 +27,19 @@ #if !UCONFIG_NO_FORMATTING - #include "unicode/format.h" #include "unicode/uobject.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN +// can't be #ifndef U_HIDE_INTERNAL_API; needed for char[] field size +/** + * Size of a numbering system name. + * @internal + */ +constexpr const size_t kInternalNumSysNameCapacity = 8; + /** * Defines numbering systems. A numbering system describes the scheme by which * numbers are to be presented to the end user. In its simplest form, a numbering @@ -104,9 +105,13 @@ class U_I18N_API NumberingSystem : public UObject { /** * Return a StringEnumeration over all the names of numbering systems known to ICU. + * The numbering system names will be in alphabetical (invariant) order. + * + * The returned StringEnumeration is owned by the caller, who must delete it when + * finished with it. + * * @stable ICU 4.2 */ - static StringEnumeration * U_EXPORT2 getAvailableNames(UErrorCode& status); /** @@ -117,8 +122,10 @@ class U_I18N_API NumberingSystem : public UObject { * default, native, traditional, finance - do not identify specific numbering systems, * but rather key values that may only be used as part of a locale, which in turn * defines how they are mapped to a specific numbering system such as "latn" or "hant". + * * @param name The name of the numbering system. - * @param status ICU status + * @param status ICU status; set to U_UNSUPPORTED_ERROR if numbering system not found. + * @return The NumberingSystem instance, or nullptr if not found. * @stable ICU 4.2 */ static NumberingSystem* U_EXPORT2 createInstanceByName(const char* name, UErrorCode& status); @@ -185,13 +192,13 @@ class U_I18N_API NumberingSystem : public UObject { UnicodeString desc; int32_t radix; UBool algorithmic; - char name[NUMSYS_NAME_CAPACITY+1]; + char name[kInternalNumSysNameCapacity+1]; void setRadix(int32_t radix); void setAlgorithmic(UBool algorithmic); - void setDesc(UnicodeString desc); + void setDesc(const UnicodeString &desc); void setName(const char* name); @@ -201,6 +208,7 @@ class U_I18N_API NumberingSystem : public UObject { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/parseerr.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/parseerr.h index 44ff00811d..c23cc273b8 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/parseerr.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/parseerr.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2005, International Business Machines @@ -56,9 +58,9 @@ enum { U_PARSE_CONTEXT_LEN = 16 }; typedef struct UParseError { /** - * The line on which the error occured. If the parser uses this + * The line on which the error occurred. If the parser uses this * field, it sets it to the line number of the source text line on - * which the error appears, which will be be a value >= 1. If the + * which the error appears, which will be a value >= 1. If the * parse does not support line numbers, the value will be <= 0. * @stable ICU 2.0 */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/parsepos.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/parsepos.h index cdf49e04ec..e3d7d778ac 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/parsepos.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/parsepos.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) 1997-2005, International Business Machines Corporation and others. All Rights Reserved. ******************************************************************************* @@ -20,6 +22,7 @@ #include "unicode/uobject.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -88,21 +91,21 @@ class U_COMMON_API ParsePosition : public UObject { * Assignment operator * @stable ICU 2.0 */ - ParsePosition& operator=(const ParsePosition& copy); + inline ParsePosition& operator=(const ParsePosition& copy); /** * Equality operator. * @return TRUE if the two parse positions are equal, FALSE otherwise. * @stable ICU 2.0 */ - UBool operator==(const ParsePosition& that) const; + inline UBool operator==(const ParsePosition& that) const; /** * Equality operator. * @return TRUE if the two parse positions are not equal, FALSE otherwise. * @stable ICU 2.0 */ - UBool operator!=(const ParsePosition& that) const; + inline UBool operator!=(const ParsePosition& that) const; /** * Clone this object. @@ -124,14 +127,14 @@ class U_COMMON_API ParsePosition : public UObject { * @return the current index. * @stable ICU 2.0 */ - int32_t getIndex(void) const; + inline int32_t getIndex(void) const; /** * Set the current parse position. * @param index the new index. * @stable ICU 2.0 */ - void setIndex(int32_t index); + inline void setIndex(int32_t index); /** * Set the index at which a parse error occurred. Formatters @@ -140,14 +143,14 @@ class U_COMMON_API ParsePosition : public UObject { * set. * @stable ICU 2.0 */ - void setErrorIndex(int32_t ei); + inline void setErrorIndex(int32_t ei); /** * Retrieve the index at which an error occurred, or -1 if the * error index has not been set. * @stable ICU 2.0 */ - int32_t getErrorIndex(void) const; + inline int32_t getErrorIndex(void) const; /** * ICU "poor man's RTTI", returns a UClassID for this class. @@ -226,5 +229,6 @@ ParsePosition::setErrorIndex(int32_t ei) this->errorIndex = ei; } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/platform.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/platform.h index 482900069d..a3623f5da6 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/platform.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/platform.h @@ -1,7 +1,9 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * -* Copyright (C) 1997-2015, International Business Machines +* Copyright (C) 1997-2016, International Business Machines * Corporation and others. All Rights Reserved. * ****************************************************************************** @@ -36,7 +38,7 @@ * and/or from other macros that are predefined by the compiler * or defined in standard (POSIX or platform or compiler) headers. * - * As a temporary workaround, you can add an explicit #define for some macros + * As a temporary workaround, you can add an explicit \#define for some macros * before it is first tested, or add an equivalent -D macro definition * to the compiler's command line. * @@ -130,6 +132,8 @@ #define U_PF_BROWSER_NATIVE_CLIENT 4020 /** Android is based on Linux. @internal */ #define U_PF_ANDROID 4050 +/** Fuchsia is a POSIX-ish platform. @internal */ +#define U_PF_FUCHSIA 4100 /* Maximum value for Linux-based platform is 4499 */ /** z/OS is the successor to OS/390 which was the successor to MVS. @internal */ #define U_PF_OS390 9000 @@ -148,8 +152,10 @@ # define U_PLATFORM U_PF_ANDROID /* Android wchar_t support depends on the API level. */ # include -#elif defined(__native_client__) +#elif defined(__pnacl__) || defined(__native_client__) # define U_PLATFORM U_PF_BROWSER_NATIVE_CLIENT +#elif defined(__Fuchsia__) +# define U_PLATFORM U_PF_FUCHSIA #elif defined(linux) || defined(__linux__) || defined(__linux) # define U_PLATFORM U_PF_LINUX #elif defined(__APPLE__) && defined(__MACH__) @@ -160,6 +166,9 @@ # define U_PLATFORM U_PF_DARWIN # endif #elif defined(BSD) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__MirBSD__) +# if defined(__FreeBSD__) +# include +# endif # define U_PLATFORM U_PF_BSD #elif defined(sun) || defined(__sun) /* Check defined(__SVR4) || defined(__svr4__) to distinguish Solaris from SunOS? */ @@ -198,6 +207,9 @@ # define CYGWINMSVC #endif */ +#ifdef U_IN_DOXYGEN +# define CYGWINMSVC +#endif /** * \def U_PLATFORM_USES_ONLY_WIN32_API @@ -228,6 +240,18 @@ # define U_PLATFORM_HAS_WIN32_API 0 #endif +/** + * \def U_PLATFORM_HAS_WINUWP_API + * Defines whether target is intended for Universal Windows Platform API + * Set to 1 for Windows10 Release Solution Configuration + * @internal + */ +#ifdef U_PLATFORM_HAS_WINUWP_API + /* Use the predefined value. */ +#else +# define U_PLATFORM_HAS_WINUWP_API 0 +#endif + /** * \def U_PLATFORM_IMPLEMENTS_POSIX * Defines whether the platform implements (most of) the POSIX API. @@ -313,42 +337,6 @@ # define U_HAVE_INTTYPES_H U_HAVE_STDINT_H #endif -/** - * \def U_IOSTREAM_SOURCE - * Defines what support for C++ streams is available. - * - * If U_IOSTREAM_SOURCE is set to 199711, then <iostream> is available - * (the ISO/IEC C++ FDIS was published in November 1997), and then - * one should qualify streams using the std namespace in ICU header - * files. - * Starting with ICU 49, this is the only supported version. - * - * If U_IOSTREAM_SOURCE is set to 198506, then <iostream.h> is - * available instead (in June 1985 Stroustrup published - * "An Extensible I/O Facility for C++" at the summer USENIX conference). - * Starting with ICU 49, this version is not supported any more. - * - * If U_IOSTREAM_SOURCE is 0 (or any value less than 199711), - * then C++ streams are not available and - * support for them will be silently suppressed in ICU. - * - * @internal - */ -#ifndef U_IOSTREAM_SOURCE -#define U_IOSTREAM_SOURCE 199711 -#endif - -/** - * \def U_HAVE_STD_STRING - * Defines whether the standard C++ (STL) <string> header is available. - * @internal - */ -#ifdef U_HAVE_STD_STRING - /* Use the predefined value. */ -#else -# define U_HAVE_STD_STRING 1 -#endif - /*===========================================================================*/ /** @{ Compiler and environment features */ /*===========================================================================*/ @@ -425,10 +413,28 @@ # define U_HAVE_DEBUG_LOCATION_NEW 0 #endif -/* Compatibility with non clang compilers */ +/* Compatibility with compilers other than clang: http://clang.llvm.org/docs/LanguageExtensions.html */ #ifndef __has_attribute # define __has_attribute(x) 0 #endif +#ifndef __has_cpp_attribute +# define __has_cpp_attribute(x) 0 +#endif +#ifndef __has_declspec_attribute +# define __has_declspec_attribute(x) 0 +#endif +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif +#ifndef __has_feature +# define __has_feature(x) 0 +#endif +#ifndef __has_extension +# define __has_extension(x) 0 +#endif +#ifndef __has_warning +# define __has_warning(x) 0 +#endif /** * \def U_MALLOC_ATTR @@ -454,6 +460,74 @@ # define U_ALLOC_SIZE_ATTR2(X,Y) #endif +/** + * \def U_CPLUSPLUS_VERSION + * 0 if no C++; 1, 11, 14, ... if C++. + * Support for specific features cannot always be determined by the C++ version alone. + * @internal + */ +#ifdef U_CPLUSPLUS_VERSION +# if U_CPLUSPLUS_VERSION != 0 && !defined(__cplusplus) +# undef U_CPLUSPLUS_VERSION +# define U_CPLUSPLUS_VERSION 0 +# endif + /* Otherwise use the predefined value. */ +#elif !defined(__cplusplus) +# define U_CPLUSPLUS_VERSION 0 +#elif __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) +# define U_CPLUSPLUS_VERSION 14 +#elif __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L) +# define U_CPLUSPLUS_VERSION 11 +#else + // C++98 or C++03 +# define U_CPLUSPLUS_VERSION 1 +#endif + +#if (U_PLATFORM == U_PF_AIX || U_PLATFORM == U_PF_OS390) && defined(__cplusplus) &&(U_CPLUSPLUS_VERSION < 11) +// add in std::nullptr_t +namespace std { + typedef decltype(nullptr) nullptr_t; +}; +#endif + +/** + * \def U_NOEXCEPT + * "noexcept" if supported, otherwise empty. + * Some code, especially STL containers, uses move semantics of objects only + * if the move constructor and the move operator are declared as not throwing exceptions. + * @internal + */ +#ifdef U_NOEXCEPT + /* Use the predefined value. */ +#else +# define U_NOEXCEPT noexcept +#endif + +/** + * \def U_FALLTHROUGH + * Annotate intentional fall-through between switch labels. + * http://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough + * @internal + */ +#ifndef __cplusplus + // Not for C. +#elif defined(U_FALLTHROUGH) + // Use the predefined value. +#elif defined(__clang__) + // Test for compiler vs. feature separately. + // Other compilers might choke on the feature test. +# if __has_cpp_attribute(clang::fallthrough) || \ + (__has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")) +# define U_FALLTHROUGH [[clang::fallthrough]] +# endif +#elif defined(__GNUC__) && (__GNUC__ >= 7) +# define U_FALLTHROUGH __attribute__((fallthrough)) +#endif + +#ifndef U_FALLTHROUGH +# define U_FALLTHROUGH +#endif + /** @} */ /*===========================================================================*/ @@ -546,7 +620,7 @@ */ #ifdef U_CHARSET_IS_UTF8 /* Use the predefined value. */ -#elif U_PLATFORM == U_PF_ANDROID || U_PLATFORM_IS_DARWIN_BASED +#elif U_PLATFORM_IS_LINUX_BASED || U_PLATFORM_IS_DARWIN_BASED # define U_CHARSET_IS_UTF8 1 #else # define U_CHARSET_IS_UTF8 0 @@ -664,13 +738,16 @@ #else /* * Notes: - * Visual Studio 10 (_MSC_VER>=1600) defines char16_t but - * does not support u"abc" string literals. + * Visual Studio 2010 (_MSC_VER==1600) defines char16_t as a typedef + * and does not support u"abc" string literals. + * Visual Studio 2015 (_MSC_VER>=1900) and above adds support for + * both char16_t and u"abc" string literals. * gcc 4.4 defines the __CHAR16_TYPE__ macro to a usable type but * does not support u"abc" string literals. * C++11 and C11 require support for UTF-16 literals + * TODO: Fix for plain C. Doesn't work on Mac. */ -# if (defined(__cplusplus) && __cplusplus >= 201103L) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) +# if U_CPLUSPLUS_VERSION >= 11 || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) # define U_HAVE_CHAR16_T 1 # else # define U_HAVE_CHAR16_T 0 @@ -689,7 +766,8 @@ #elif U_HAVE_CHAR16_T \ || (defined(__xlC__) && defined(__IBM_UTF_LITERAL) && U_SIZEOF_WCHAR_T != 2) \ || (defined(__HP_aCC) && __HP_aCC >= 035000) \ - || (defined(__HP_cc) && __HP_cc >= 111106) + || (defined(__HP_cc) && __HP_cc >= 111106) \ + || (defined(U_IN_DOXYGEN)) # define U_DECLARE_UTF16(string) u ## string #elif U_SIZEOF_WCHAR_T == 2 \ && (U_CHARSET_FAMILY == 0 || (U_PF_OS390 <= U_PLATFORM && U_PLATFORM <= U_PF_OS400 && defined(__UCS2__))) @@ -708,6 +786,8 @@ /* Use the predefined value. */ #elif defined(U_STATIC_IMPLEMENTATION) # define U_EXPORT +#elif defined(_MSC_VER) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport)) +# define U_EXPORT __declspec(dllexport) #elif defined(__GNUC__) # define U_EXPORT __attribute__((visibility("default"))) #elif (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x550) \ @@ -715,8 +795,6 @@ # define U_EXPORT __global /*#elif defined(__HP_aCC) || defined(__HP_cc) # define U_EXPORT __declspec(dllexport)*/ -#elif defined(_MSC_VER) -# define U_EXPORT __declspec(dllexport) #else # define U_EXPORT #endif @@ -732,7 +810,7 @@ #ifdef U_IMPORT /* Use the predefined value. */ -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport)) /* Windows needs to export/import data. */ # define U_IMPORT __declspec(dllimport) #else @@ -748,6 +826,12 @@ * This is only used for non-ICU-API functions. * When a function is a public ICU API, * you must use the U_CAPI and U_EXPORT2 qualifiers. + * + * Please note, you need to use U_CALLCONV after the *. + * + * NO : "static const char U_CALLCONV *func( . . . )" + * YES: "static const char* U_CALLCONV func( . . . )" + * * @stable ICU 2.0 */ #if U_PLATFORM == U_PF_OS390 && defined(__cplusplus) @@ -756,6 +840,16 @@ # define U_CALLCONV U_EXPORT2 #endif +/** + * \def U_CALLCONV_FPTR + * Similar to U_CALLCONV, but only used on function pointers. + * @internal + */ +#if U_PLATFORM == U_PF_OS390 && defined(__cplusplus) +# define U_CALLCONV_FPTR U_CALLCONV +#else +# define U_CALLCONV_FPTR +#endif /* @} */ #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/plurfmt.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/plurfmt.h index f7099d81e2..566c57cbe9 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/plurfmt.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/plurfmt.h @@ -1,3 +1,5 @@ +// © 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 @@ -25,6 +27,7 @@ #include "unicode/numfmt.h" #include "unicode/plurrule.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class Hashtable; @@ -518,15 +521,7 @@ class U_I18N_API PluralFormat : public Format { */ virtual UClassID getDynamicClassID() const; -#if (defined(__xlC__) && (__xlC__ < 0x0C00)) || (U_PLATFORM == U_PF_OS390) || (U_PLATFORM ==U_PF_OS400) -// Work around a compiler bug on xlC 11.1 on AIX 7.1 that would -// prevent PluralSelectorAdapter from implementing private PluralSelector. -// xlC error message: -// 1540-0300 (S) The "private" member "class icu_49::PluralFormat::PluralSelector" cannot be accessed. -public: -#else private: -#endif /** * @internal */ @@ -562,10 +557,6 @@ class U_I18N_API PluralFormat : public Format { PluralRules* pluralRules; }; -#if defined(__xlC__) -// End of xlC bug workaround, keep remaining definitions private. -private: -#endif Locale locale; MessagePattern msgPattern; NumberFormat* numberFormat; @@ -608,6 +599,7 @@ class U_I18N_API PluralFormat : public Format { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/plurrule.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/plurrule.h index 6d219fb2f7..d3c3bd56ba 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/plurrule.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/plurrule.h @@ -1,3 +1,5 @@ +// © 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 @@ -27,6 +29,9 @@ #include "unicode/format.h" #include "unicode/upluralrules.h" +#ifndef U_HIDE_INTERNAL_API +#include "unicode/numfmt.h" +#endif /* U_HIDE_INTERNAL_API */ /** * Value returned by PluralRules::getUniqueKeywordValue() when there is no @@ -35,16 +40,21 @@ */ #define UPLRULES_NO_UNIQUE_VALUE ((double)-0.00123456777) +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class Hashtable; -class FixedDecimal; +class IFixedDecimal; class RuleChain; class PluralRuleParser; class PluralKeywordEnumeration; class AndConstraint; class SharedPluralRules; +namespace number { +class FormattedNumber; +} + /** * Defines rules for mapping non-negative numeric values onto a small set of * keywords. Rules are constructed from a text description, consisting @@ -113,7 +123,6 @@ class SharedPluralRules; * Examples are in the following table: *

        * - * * * * @@ -150,7 +159,6 @@ class SharedPluralRules; * * * - * *
        ni232
        *

        * The difference between 'in' and 'within' is that 'in' only includes integers in the specified range, while 'within' @@ -320,9 +328,9 @@ class U_I18N_API PluralRules : public UObject { #endif /* U_HIDE_INTERNAL_API */ /** - * Given a number, returns the keyword of the first rule that applies to - * the number. This function can be used with isKeyword* functions to - * determine the keyword for default plural rules. + * Given an integer, returns the keyword of the first rule + * that applies to the number. This function can be used with + * isKeyword* functions to determine the keyword for default plural rules. * * @param number The number for which the rule has to be determined. * @return The keyword of the selected rule. @@ -331,9 +339,9 @@ class U_I18N_API PluralRules : public UObject { UnicodeString select(int32_t number) const; /** - * Given a number, returns the keyword of the first rule that applies to - * the number. This function can be used with isKeyword* functions to - * determine the keyword for default plural rules. + * Given a floating-point number, returns the keyword of the first rule + * that applies to the number. This function can be used with + * isKeyword* functions to determine the keyword for default plural rules. * * @param number The number for which the rule has to be determined. * @return The keyword of the selected rule. @@ -341,11 +349,30 @@ class U_I18N_API PluralRules : public UObject { */ UnicodeString select(double number) const; +#ifndef U_HIDE_DRAFT_API + /** + * Given a formatted number, returns the keyword of the first rule + * that applies to the number. This function can be used with + * isKeyword* functions to determine the keyword for default plural rules. + * + * A FormattedNumber allows you to specify an exponent or trailing zeros, + * which can affect the plural category. To get a FormattedNumber, see + * NumberFormatter. + * + * @param number The number for which the rule has to be determined. + * @param status Set if an error occurs while selecting plural keyword. + * This could happen if the FormattedNumber is invalid. + * @return The keyword of the selected rule. + * @draft ICU 64 + */ + UnicodeString select(const number::FormattedNumber& number, UErrorCode& status) const; +#endif /* U_HIDE_DRAFT_API */ + #ifndef U_HIDE_INTERNAL_API /** * @internal */ - UnicodeString select(const FixedDecimal &number) const; + UnicodeString select(const IFixedDecimal &number) const; #endif /* U_HIDE_INTERNAL_API */ /** @@ -376,7 +403,7 @@ class U_I18N_API PluralRules : public UObject { /** * Deprecated Function, does not produce useful results. * - * Orginally intended to return all the values for which select() would return the keyword. + * Originally intended to return all the values for which select() would return the keyword. * If the keyword is unknown, returns no values, but this is not an error. If * the number of values is unlimited, returns no values and -1 as the * count. @@ -494,10 +521,17 @@ class U_I18N_API PluralRules : public UObject { UnicodeString getRuleFromResource(const Locale& locale, UPluralType type, UErrorCode& status); RuleChain *rulesForKeyword(const UnicodeString &keyword) const; + /** + * An internal status variable used to indicate that the object is in an 'invalid' state. + * Used by copy constructor, the assignment operator and the clone method. + */ + UErrorCode mInternalStatus; + friend class PluralRuleParser; }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ptypes.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ptypes.h index b7f7116032..70324ffee3 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ptypes.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ptypes.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * @@ -81,6 +83,7 @@ typedef unsigned char uint8_t; #else /* neither U_HAVE_STDINT_H nor U_HAVE_INTTYPES_H */ +/// \cond #if ! U_HAVE_INT8_T typedef signed char int8_t; #endif @@ -120,6 +123,7 @@ typedef unsigned int uint32_t; typedef unsigned long long uint64_t; #endif #endif +/// \endcond #endif /* U_HAVE_STDINT_H / U_HAVE_INTTYPES_H */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/putil.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/putil.h index df1b17bad0..759b136c13 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/putil.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/putil.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * @@ -36,7 +38,7 @@ /** * Platform utilities isolates the platform dependencies of the - * libarary. For each platform which this code is ported to, these + * library. For each platform which this code is ported to, these * functions may have to be re-implemented. */ @@ -51,7 +53,7 @@ * The data directory is determined as follows: * If u_setDataDirectory() has been called, that is it, otherwise * if the ICU_DATA environment variable is set, use that, otherwise - * If a data directory was specifed at ICU build time + * If a data directory was specified at ICU build time * * \code * #define ICU_DATA_DIR "path" @@ -91,7 +93,7 @@ U_STABLE void U_EXPORT2 u_setDataDirectory(const char *directory); #ifndef U_HIDE_INTERNAL_API /** * Return the time zone files override directory, or an empty string if - * no directory was specified. Certain time zone resources will be preferrentially + * no directory was specified. Certain time zone resources will be preferentially * loaded from individual files in this directory. * * @return the time zone data override directory. diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/rbbi.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/rbbi.h index d47598a50e..9b086ffcca 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/rbbi.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/rbbi.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* *************************************************************************** -* Copyright (C) 1999-2014 International Business Machines Corporation * +* Copyright (C) 1999-2016 International Business Machines Corporation * * and others. All rights reserved. * *************************************************************************** @@ -27,25 +29,18 @@ #include "unicode/udata.h" #include "unicode/parseerr.h" #include "unicode/schriter.h" -#include "unicode/uchriter.h" - - -struct UTrie; +// for Apple addition: +#include "unicode/urbtok.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @internal */ +class LanguageBreakEngine; struct RBBIDataHeader; -class RuleBasedBreakIteratorTables; -class BreakIterator; class RBBIDataWrapper; -class UStack; -class LanguageBreakEngine; class UnhandledEngine; -struct RBBIStateTable; - - - +class UStack; /** * @@ -56,133 +51,109 @@ struct RBBIStateTable; * *

        See the ICU User Guide for information on Break Iterator Rules.

        * - *

        This class is not intended to be subclassed. (Class DictionaryBasedBreakIterator - * is a subclass, but that relationship is effectively internal to the ICU - * implementation. The subclassing interface to RulesBasedBreakIterator is - * not part of the ICU API, and may not remain stable.

        - * + *

        This class is not intended to be subclassed.

        */ class U_COMMON_API RuleBasedBreakIterator /*U_FINAL*/ : public BreakIterator { -protected: +private: /** * The UText through which this BreakIterator accesses the text - * @internal + * @internal (private) */ - UText *fText; - - /** - * A character iterator that refers to the same text as the UText, above. - * Only included for compatibility with old API, which was based on CharacterIterators. - * Value may be adopted from outside, or one of fSCharIter or fDCharIter, below. - */ - CharacterIterator *fCharIter; - - /** - * When the input text is provided by a UnicodeString, this will point to - * a characterIterator that wraps that data. Needed only for the - * implementation of getText(), a backwards compatibility issue. - */ - StringCharacterIterator *fSCharIter; - - /** - * When the input text is provided by a UText, this - * dummy CharacterIterator over an empty string will - * be returned from getText() - */ - UCharCharacterIterator *fDCharIter; + UText fText; +#ifndef U_HIDE_INTERNAL_API +public: +#endif /* U_HIDE_INTERNAL_API */ /** - * The rule data for this BreakIterator instance + * The rule data for this BreakIterator instance. + * Not for general use; Public only for testing purposes. * @internal */ RBBIDataWrapper *fData; - - /** Index of the Rule {tag} values for the most recent match. - * @internal - */ - int32_t fLastRuleStatusIndex; +private: /** - * Rule tag value valid flag. - * Some iterator operations don't intrinsically set the correct tag value. - * This flag lets us lazily compute the value if we are ever asked for it. - * @internal + * Character categories for the Latin1 subset of Unicode + * @internal Apple-only */ - UBool fLastStatusIndexValid; + uint16_t *fLatin1Cat; /** - * Counter for the number of characters encountered with the "dictionary" - * flag set. - * @internal - */ - uint32_t fDictionaryCharCount; + * The current position of the iterator. Pinned, 0 < fPosition <= text.length. + * Never has the value UBRK_DONE (-1). + */ + int32_t fPosition; /** - * When a range of characters is divided up using the dictionary, the break - * positions that are discovered are stored here, preventing us from having - * to use either the dictionary or the state table again until the iterator - * leaves this range of text. Has the most impact for line breaking. - * @internal - */ - int32_t* fCachedBreakPositions; + * TODO: + */ + int32_t fRuleStatusIndex; /** - * The number of elements in fCachedBreakPositions - * @internal + * Cache of previously determined boundary positions. */ - int32_t fNumCachedBreakPositions; + class BreakCache; + BreakCache *fBreakCache; /** - * if fCachedBreakPositions is not null, this indicates which item in the - * cache the current iteration position refers to - * @internal + * Cache of boundary positions within a region of text that has been + * sub-divided by dictionary based breaking. */ - int32_t fPositionInCache; - + class DictionaryCache; + DictionaryCache *fDictionaryCache; + /** * * If present, UStack of LanguageBreakEngine objects that might handle * dictionary characters. Searched from top to bottom to find an object to * handle a given character. - * @internal + * @internal (private) */ UStack *fLanguageBreakEngines; - + /** * * If present, the special LanguageBreakEngine used for handling * characters that are in the dictionary set, but not handled by any - * LangugageBreakEngine. - * @internal + * LanguageBreakEngine. + * @internal (private) */ UnhandledEngine *fUnhandledBreakEngine; - + /** - * - * The type of the break iterator, or -1 if it has not been set. - * @internal + * Counter for the number of characters encountered with the "dictionary" + * flag set. + * @internal (private) */ - int32_t fBreakType; - -protected: - //======================================================================= - // constructors - //======================================================================= + uint32_t fDictionaryCharCount; -#ifndef U_HIDE_INTERNAL_API /** - * Constant to be used in the constructor - * RuleBasedBreakIterator(RBBIDataHeader*, EDontAdopt, UErrorCode &); - * which does not adopt the memory indicated by the RBBIDataHeader* - * parameter. - * - * @internal + * A character iterator that refers to the same text as the UText, above. + * Only included for compatibility with old API, which was based on CharacterIterators. + * Value may be adopted from outside, or one of fSCharIter or fDCharIter, below. */ - enum EDontAdopt { - kDontAdopt - }; + CharacterIterator *fCharIter; + /** + * When the input text is provided by a UnicodeString, this will point to + * a characterIterator that wraps that data. Needed only for the + * implementation of getText(), a backwards compatibility issue. + */ + StringCharacterIterator fSCharIter; + + /** + * True when iteration has run off the end, and iterator functions should return UBRK_DONE. + */ + UBool fDone; + + //======================================================================= + // constructors + //======================================================================= + +// The following is intended to be private in open-source. +// However Apple needs it to be public for urbtok.cpp +public: /** * Constructor from a flattened set of RBBI data in malloced memory. * RulesBasedBreakIterators built from a custom set of rules @@ -191,28 +162,16 @@ class U_COMMON_API RuleBasedBreakIterator /*U_FINAL*/ : public BreakIterator { * * The break iterator adopts the memory, and will * free it when done. - * @internal + * @internal (private) */ RuleBasedBreakIterator(RBBIDataHeader* data, UErrorCode &status); +private: - /** - * Constructor from a flattened set of RBBI data in memory which need not - * be malloced (e.g. it may be a memory-mapped file, etc.). - * - * This version does not adopt the memory, and does not - * free it when done. - * @internal - */ - RuleBasedBreakIterator(const RBBIDataHeader* data, enum EDontAdopt dontAdopt, UErrorCode &status); -#endif /* U_HIDE_INTERNAL_API */ - - + /** @internal */ friend class RBBIRuleBuilder; /** @internal */ friend class BreakIterator; - - public: /** Default constructor. Creates an empty shell of an iterator, with no @@ -242,17 +201,17 @@ class U_COMMON_API RuleBasedBreakIterator /*U_FINAL*/ : public BreakIterator { UErrorCode &status); /** - * Contruct a RuleBasedBreakIterator from a set of precompiled binary rules. + * Construct a RuleBasedBreakIterator from a set of precompiled binary rules. * Binary rules are obtained from RulesBasedBreakIterator::getBinaryRules(). * Construction of a break iterator in this way is substantially faster than - * constuction from source rules. + * construction from source rules. * * Ownership of the storage containing the compiled rules remains with the - * caller of this function. The compiled rules must not be modified or + * caller of this function. The compiled rules must not be modified or * deleted during the life of the break iterator. * * The compiled rules are not compatible across different major versions of ICU. - * The compiled rules are comaptible only between machines with the same + * The compiled rules are compatible only between machines with the same * byte ordering (little or big endian) and the same base character set family * (ASCII or EBCDIC). * @@ -314,14 +273,14 @@ class U_COMMON_API RuleBasedBreakIterator /*U_FINAL*/ : public BreakIterator { * @return TRUE if both BreakIterators are not same. * @stable ICU 2.0 */ - UBool operator!=(const BreakIterator& that) const; + inline UBool operator!=(const BreakIterator& that) const; /** * Returns a newly-constructed RuleBasedBreakIterator with the same * behavior, and iterating over the same text, as this one. * Differs from the copy constructor in that it is polymorphic, and * will correctly clone (copy) a derived class. - * clone() is thread safe. Multiple threads may simultaeneously + * clone() is thread safe. Multiple threads may simultaneously * clone the same source break iterator. * @return a newly-constructed RuleBasedBreakIterator * @stable ICU 2.0 @@ -402,6 +361,11 @@ class U_COMMON_API RuleBasedBreakIterator /*U_FINAL*/ : public BreakIterator { /** * Set the iterator to analyze a new piece of text. This function resets * the current iteration position to the beginning of the text. + * + * The BreakIterator will retain a reference to the supplied string. + * The caller must not modify or delete the text while the BreakIterator + * retains the reference. + * * @param newText The text to analyze. * @stable ICU 2.0 */ @@ -481,7 +445,7 @@ class U_COMMON_API RuleBasedBreakIterator /*U_FINAL*/ : public BreakIterator { virtual int32_t preceding(int32_t offset); /** - * Returns true if the specfied position is a boundary position. As a side + * Returns true if the specified position is a boundary position. As a side * effect, leaves the iterator pointing to the first boundary position at * or after "offset". * @param offset the offset to check. @@ -491,7 +455,10 @@ class U_COMMON_API RuleBasedBreakIterator /*U_FINAL*/ : public BreakIterator { virtual UBool isBoundary(int32_t offset); /** - * Returns the current iteration position. + * Returns the current iteration position. Note that UBRK_DONE is never + * returned from this function; if iteration has run to the end of a + * string, current() will return the length of the string while + * next() will return UBRK_DONE). * @return The current iteration position. * @stable ICU 2.0 */ @@ -499,8 +466,8 @@ class U_COMMON_API RuleBasedBreakIterator /*U_FINAL*/ : public BreakIterator { /** - * Return the status tag from the break rule that determined the most recently - * returned break position. For break rules that do not specify a + * Return the status tag from the break rule that determined the boundary at + * the current iteration position. For break rules that do not specify a * status, a default value of 0 is returned. If more than one break rule * would cause a boundary to be located at some position in the text, * the numerically largest of the applicable status values is returned. @@ -517,15 +484,14 @@ class U_COMMON_API RuleBasedBreakIterator /*U_FINAL*/ : public BreakIterator { * position from next(), previous(), or * any other break iterator functions that returns a boundary position. *

        + * Note that getRuleStatus() returns the value corresponding to + * current() index even after next() has returned DONE. + *

        * When creating custom break rules, one is free to define whatever * status values may be convenient for the application. *

        - * Note: this function is not thread safe. It should not have been - * declared const, and the const remains only for compatibility - * reasons. (The function is logically const, but not bit-wise const). - *

        - * @return the status from the break rule that determined the most recently - * returned break position. + * @return the status from the break rule that determined the boundary + * at the current iteration position. * * @see UWordBreak * @stable ICU 2.2 @@ -533,8 +499,8 @@ class U_COMMON_API RuleBasedBreakIterator /*U_FINAL*/ : public BreakIterator { virtual int32_t getRuleStatus() const; /** - * Get the status (tag) values from the break rule(s) that determined the most - * recently returned break position. + * Get the status (tag) values from the break rule(s) that determined the boundary + * at the current iteration position. *

        * The returned status value(s) are stored into an array provided by the caller. * The values are stored in sorted (ascending) order. @@ -545,10 +511,10 @@ class U_COMMON_API RuleBasedBreakIterator /*U_FINAL*/ : public BreakIterator { * @param fillInVec an array to be filled in with the status values. * @param capacity the length of the supplied vector. A length of zero causes * the function to return the number of status values, in the - * normal way, without attemtping to store any values. + * normal way, without attempting to store any values. * @param status receives error codes. - * @return The number of rule status values from rules that determined - * the most recent boundary returned by the break iterator. + * @return The number of rule status values from the rules that determined + * the boundary at the current iteration position. * In the event of a U_BUFFER_OVERFLOW_ERROR, the return value * is the total number of status values that were available, * not the reduced number that were actually returned. @@ -557,6 +523,23 @@ class U_COMMON_API RuleBasedBreakIterator /*U_FINAL*/ : public BreakIterator { */ virtual int32_t getRuleStatusVec(int32_t *fillInVec, int32_t capacity, UErrorCode &status); + /** + * Apple custom extension + * Initializes Latin1 category + * @internal + */ + void initLatin1Cat(void); + + /** + * Apple custom extension + * Fetch the next set of tokens. + * @param maxTokens The maximum number of tokens to return. + * @param outTokenRanges Pointer to output array of token ranges. + * @param outTokenFlags (optional) pointer to output array of token flags. + * @internal + */ + int32_t tokenize(int32_t maxTokens, RuleBasedTokenRange *outTokenRanges, unsigned long *outTokenFlags); + /** * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. * This method is to implement a simple version of RTTI, since not all @@ -588,7 +571,7 @@ class U_COMMON_API RuleBasedBreakIterator /*U_FINAL*/ : public BreakIterator { * * Create a clone (copy) of this break iterator in memory provided * by the caller. The idea is to increase performance by avoiding - * a storage allocation. Use of this functoin is NOT RECOMMENDED. + * a storage allocation. Use of this function is NOT RECOMMENDED. * Performance gains are minimal, and correct buffer management is * tricky. Use clone() instead. * @@ -601,7 +584,7 @@ class U_COMMON_API RuleBasedBreakIterator /*U_FINAL*/ : public BreakIterator { * storage for the cloned object. * * @param status Error status. U_SAFECLONE_ALLOCATED_WARNING will be - * returned if the the provided buffer was too small, and + * returned if the provided buffer was too small, and * the clone was therefore put on the heap. * * @return Pointer to the clone object. This may differ from the stackBuffer @@ -624,7 +607,7 @@ class U_COMMON_API RuleBasedBreakIterator /*U_FINAL*/ : public BreakIterator { * The binary data can only be used with the same version of ICU * and on the same platform type (processor endian-ness) * - * @param length Returns the length of the binary data. (Out paramter.) + * @param length Returns the length of the binary data. (Out parameter.) * * @return A pointer to the binary (compiled) rule data. The storage * belongs to the RulesBasedBreakIterator object, not the @@ -661,108 +644,73 @@ class U_COMMON_API RuleBasedBreakIterator /*U_FINAL*/ : public BreakIterator { virtual RuleBasedBreakIterator &refreshInputText(UText *input, UErrorCode &status); -protected: +private: //======================================================================= // implementation //======================================================================= /** * Dumps caches and performs other actions associated with a complete change * in text or iteration position. - * @internal + * @internal (private) */ - virtual void reset(void); + void reset(void); -#if 0 - /** - * Return true if the category lookup for this char - * indicates that it is in the set of dictionary lookup chars. - * This function is intended for use by dictionary based break iterators. - * @return true if the category lookup for this char - * indicates that it is in the set of dictionary lookup chars. - * @internal - */ - virtual UBool isDictionaryChar(UChar32); - - /** - * Get the type of the break iterator. - * @internal - */ - virtual int32_t getBreakType() const; -#endif - - /** - * Set the type of the break iterator. - * @internal - */ - virtual void setBreakType(int32_t type); - -#ifndef U_HIDE_INTERNAL_API /** * Common initialization function, used by constructors and bufferClone. - * @internal + * @internal (private) */ - void init(); -#endif /* U_HIDE_INTERNAL_API */ - -private: - - /** - * This method backs the iterator back up to a "safe position" in the text. - * This is a position that we know, without any context, must be a break position. - * The various calling methods then iterate forward from this safe position to - * the appropriate position to return. (For more information, see the description - * of buildBackwardsStateTable() in RuleBasedBreakIterator.Builder.) - * @param statetable state table used of moving backwards - * @internal - */ - int32_t handlePrevious(const RBBIStateTable *statetable); + void init(UErrorCode &status); /** - * This method is the actual implementation of the next() method. All iteration - * vectors through here. This method initializes the state machine to state 1 - * and advances through the text character by character until we reach the end - * of the text or the state machine transitions to state 0. We update our return - * value every time the state machine passes through a possible end state. - * @param statetable state table used of moving forwards - * @internal + * Iterate backwards from an arbitrary position in the input text using the + * synthesized Safe Reverse rules. + * This locates a "Safe Position" from which the forward break rules + * will operate correctly. A Safe Position is not necessarily a boundary itself. + * + * @param fromPosition the position in the input text to begin the iteration. + * @internal (private) */ - int32_t handleNext(const RBBIStateTable *statetable); - -protected: + int32_t handleSafePrevious(int32_t fromPosition); -#ifndef U_HIDE_INTERNAL_API /** - * This is the function that actually implements dictionary-based - * breaking. Covering at least the range from startPos to endPos, - * it checks for dictionary characters, and if it finds them determines - * the appropriate object to deal with them. It may cache found breaks in - * fCachedBreakPositions as it goes. It may well also look at text outside - * the range startPos to endPos. - * If going forward, endPos is the normal Unicode break result, and - * if goind in reverse, startPos is the normal Unicode break result - * @param startPos The start position of a range of text - * @param endPos The end position of a range of text - * @param reverse The call is for the reverse direction - * @internal + * Find a rule-based boundary by running the state machine. + * Input + * fPosition, the position in the text to begin from. + * Output + * fPosition: the boundary following the starting position. + * fDictionaryCharCount the number of dictionary characters encountered. + * If > 0, the segment will be further subdivided + * fRuleStatusIndex Info from the state table indicating which rules caused the boundary. + * + * @internal (private) */ - int32_t checkDictionary(int32_t startPos, int32_t endPos, UBool reverse); -#endif /* U_HIDE_INTERNAL_API */ + int32_t handleNext(); + int32_t handleNextInternal(); -private: /** * This function returns the appropriate LanguageBreakEngine for a * given character c. * @param c A character in the dictionary set - * @internal + * @internal (private) */ const LanguageBreakEngine *getLanguageBreakEngine(UChar32 c); + public: +#ifndef U_HIDE_INTERNAL_API + /** + * Debugging function only. + * @internal + */ + void dumpCache(); + /** - * @internal + * Debugging function only. + * @internal */ - void makeRuleStatusValid(); + void dumpTables(); +#endif /* U_HIDE_INTERNAL_API */ }; //------------------------------------------------------------------------------ @@ -776,6 +724,7 @@ inline UBool RuleBasedBreakIterator::operator!=(const BreakIterator& that) const } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_BREAK_ITERATION */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/rbnf.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/rbnf.h index 7058c9671c..6befb43781 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/rbnf.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/rbnf.h @@ -1,3 +1,5 @@ +// © 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. @@ -36,8 +38,10 @@ #include "unicode/brkiter.h" #include "unicode/upluralrules.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN +class NFRule; class NFRuleSet; class LocalizationInfo; class PluralFormat; @@ -53,7 +57,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 }; /** @@ -264,15 +274,44 @@ enum URBNFRuleSetTag { * * * x.x: - * The rule is an improper fraction rule. + * The rule is an improper fraction rule. If the full stop in + * the middle of the rule name is replaced with the decimal point + * that is used in the language or DecimalFormatSymbols, then that rule will + * have precedence when formatting and parsing this rule. For example, some + * languages use the comma, and can thus be written as x,x instead. For example, + * you can use "x.x: << point >>;x,x: << comma >>;" to + * handle the decimal point that matches the language's natural spelling of + * the punctuation of either the full stop or comma. * * * 0.x: - * The rule is a proper fraction rule. + * The rule is a proper fraction rule. If the full stop in + * the middle of the rule name is replaced with the decimal point + * that is used in the language or DecimalFormatSymbols, then that rule will + * have precedence when formatting and parsing this rule. For example, some + * languages use the comma, and can thus be written as 0,x instead. For example, + * you can use "0.x: point >>;0,x: comma >>;" to + * handle the decimal point that matches the language's natural spelling of + * the punctuation of either the full stop or comma. * * * x.0: - * The rule is a master rule. + * The rule is a master rule. If the full stop in + * the middle of the rule name is replaced with the decimal point + * that is used in the language or DecimalFormatSymbols, then that rule will + * have precedence when formatting and parsing this rule. For example, some + * languages use the comma, and can thus be written as x,0 instead. For example, + * you can use "x.0: << point;x,0: << comma;" to + * handle the decimal point that matches the language's natural spelling of + * the punctuation of either the full stop or comma. + * + * + * Inf: + * The rule for infinity. + * + * + * NaN: + * The rule for an IEEE 754 NaN (not a number). * * * nothing @@ -827,6 +866,52 @@ class U_I18N_API RuleBasedNumberFormat : public NumberFormat { FieldPosition& pos, UErrorCode& status) const; +protected: + /** + * Format a decimal number. + * The number is a DigitList wrapper onto a floating point decimal number. + * The default implementation in NumberFormat converts the decimal number + * to a double and formats that. Subclasses of NumberFormat that want + * to specifically handle big decimal numbers must override this method. + * class DecimalFormat does so. + * + * @param number The number, a DigitList format Decimal Floating Point. + * @param appendTo Output parameter to receive result. + * Result is appended to existing contents. + * @param posIter On return, can be used to iterate over positions + * of fields generated by this format call. + * @param status Output param filled with success/failure status. + * @return Reference to 'appendTo' parameter. + * @internal + */ + virtual UnicodeString& format(const number::impl::DecimalQuantity &number, + UnicodeString& appendTo, + FieldPositionIterator* posIter, + UErrorCode& status) const; + + /** + * Format a decimal number. + * The number is a DigitList wrapper onto a floating point decimal number. + * The default implementation in NumberFormat converts the decimal number + * to a double and formats that. Subclasses of NumberFormat that want + * to specifically handle big decimal numbers must override this method. + * class DecimalFormat does so. + * + * @param number The number, a DigitList format Decimal Floating Point. + * @param appendTo Output parameter to receive result. + * Result is appended to existing contents. + * @param pos On input: an alignment field, if desired. + * On output: the offsets of the alignment field. + * @param status Output param filled with success/failure status. + * @return Reference to 'appendTo' parameter. + * @internal + */ + virtual UnicodeString& format(const number::impl::DecimalQuantity &number, + UnicodeString& appendTo, + FieldPosition& pos, + UErrorCode& status) const; +public: + using NumberFormat::parse; /** @@ -925,6 +1010,20 @@ class U_I18N_API RuleBasedNumberFormat : public NumberFormat { */ virtual void setContext(UDisplayContext value, UErrorCode& status); + /** + * Get the rounding mode. + * @return A rounding mode + * @stable ICU 60 + */ + virtual ERoundingMode getRoundingMode(void) const; + + /** + * Set the rounding mode. + * @param roundingMode A rounding mode + * @stable ICU 60 + */ + virtual void setRoundingMode(ERoundingMode roundingMode); + public: /** * ICU "poor man's RTTI", returns a UClassID for this class. @@ -974,28 +1073,38 @@ class U_I18N_API RuleBasedNumberFormat : public NumberFormat { void dispose(); void stripWhitespace(UnicodeString& src); void initDefaultRuleSet(); - void format(double number, NFRuleSet& ruleSet); NFRuleSet* findRuleSet(const UnicodeString& name, UErrorCode& status) const; /* friend access */ friend class NFSubstitution; friend class NFRule; + friend class NFRuleSet; friend class FractionalPartSubstitution; inline NFRuleSet * getDefaultRuleSet() const; const RuleBasedCollator * getCollator() const; - DecimalFormatSymbols * getDecimalFormatSymbols() const; + DecimalFormatSymbols * initializeDecimalFormatSymbols(UErrorCode &status); + const DecimalFormatSymbols * getDecimalFormatSymbols() const; + NFRule * initializeDefaultInfinityRule(UErrorCode &status); + const NFRule * getDefaultInfinityRule() const; + NFRule * initializeDefaultNaNRule(UErrorCode &status); + const NFRule * getDefaultNaNRule() const; PluralFormat *createPluralFormat(UPluralType pluralType, const UnicodeString &pattern, UErrorCode& status) const; - UnicodeString& adjustForCapitalizationContext(int32_t startPos, UnicodeString& currentResult) const; + UnicodeString& adjustForCapitalizationContext(int32_t startPos, UnicodeString& currentResult, UErrorCode& status) const; + UnicodeString& format(int64_t number, NFRuleSet *ruleSet, UnicodeString& toAppendTo, UErrorCode& status) const; + void format(double number, NFRuleSet& rs, UnicodeString& toAppendTo, UErrorCode& status) const; private: - NFRuleSet **ruleSets; + NFRuleSet **fRuleSets; UnicodeString* ruleSetDescriptions; int32_t numRuleSets; NFRuleSet *defaultRuleSet; Locale locale; RuleBasedCollator* collator; DecimalFormatSymbols* decimalFormatSymbols; + NFRule *defaultInfinityRule; + NFRule *defaultNaNRule; + ERoundingMode fRoundingMode; UBool lenient; UnicodeString* lenientParseRules; LocalizationInfo* localizations; @@ -1023,6 +1132,7 @@ RuleBasedNumberFormat::getDefaultRuleSet() const { } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API /* U_HAVE_RBNF */ #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/rbtz.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/rbtz.h index f20fc81a4e..b6dda4974e 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/rbtz.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/rbtz.h @@ -1,3 +1,5 @@ +// © 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 * @@ -19,6 +21,7 @@ #include "unicode/basictz.h" #include "unicode/unistr.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN // forward declaration @@ -354,6 +357,7 @@ class U_I18N_API RuleBasedTimeZone : public BasicTimeZone { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/regex.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/regex.h index c3c6441b6f..5fb6db06bb 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/regex.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/regex.h @@ -1,10 +1,12 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** -* Copyright (C) 2002-2015, International Business Machines +* Copyright (C) 2002-2016, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * file name: regex.h -* encoding: US-ASCII +* encoding: UTF-8 * indentation:4 * * created on: 2002oct22 @@ -22,24 +24,22 @@ * \file * \brief C++ API: Regular Expressions * - *

        Regular Expression API

        - * - *

        The ICU API for processing regular expressions consists of two classes, - * RegexPattern and RegexMatcher. - * RegexPattern objects represent a pre-processed, or compiled + * The ICU API for processing regular expressions consists of two classes, + * `RegexPattern` and `RegexMatcher`. + * `RegexPattern` objects represent a pre-processed, or compiled * regular expression. They are created from a regular expression pattern string, - * and can be used to create RegexMatcher objects for the pattern.

        + * and can be used to create `RegexMatcher` objects for the pattern. * - *

        Class RegexMatcher bundles together a regular expression + * Class `RegexMatcher` bundles together a regular expression * pattern and a target string to which the search pattern will be applied. - * RegexMatcher includes API for doing plain find or search + * `RegexMatcher` includes API for doing plain find or search * operations, for search and replace operations, and for obtaining detailed - * information about bounds of a match.

        + * information about bounds of a match. * - *

        Note that by constructing RegexMatcher objects directly from regular + * Note that by constructing `RegexMatcher` objects directly from regular * expression pattern strings application code can be simplified and the explicit - * need for RegexPattern objects can usually be eliminated. - *

        + * need for `RegexPattern` objects can usually be eliminated. + * */ #include "unicode/utypes.h" @@ -57,6 +57,7 @@ struct UHashtable; +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN struct Regex8BitSet; @@ -72,13 +73,13 @@ class UVector64; /** - * Class RegexPattern represents a compiled regular expression. It includes + * Class `RegexPattern` represents a compiled regular expression. It includes * factory methods for creating a RegexPattern object from the source (string) form * of a regular expression, methods for creating RegexMatchers that allow the pattern * to be applied to input text, and a few convenience methods for simple common * uses of regular expressions. * - *

        Class RegexPattern is not intended to be subclassed.

        + * Class RegexPattern is not intended to be subclassed. * * @stable ICU 2.4 */ @@ -88,7 +89,7 @@ class U_I18N_API RegexPattern U_FINAL : public UObject { /** * default constructor. Create a RegexPattern object that refers to no actual * pattern. Not normally needed; RegexPattern objects are usually - * created using the factory method compile(). + * created using the factory method `compile()`. * * @stable ICU 2.4 */ @@ -111,7 +112,7 @@ class U_I18N_API RegexPattern U_FINAL : public UObject { /** * Comparison operator. Two RegexPattern objects are considered equal if they - * were constructed from identical source patterns using the same match flag + * were constructed from identical source patterns using the same #URegexpFlag * settings. * @param that a RegexPattern object to compare with "this". * @return TRUE if the objects are equivalent. @@ -121,7 +122,7 @@ class U_I18N_API RegexPattern U_FINAL : public UObject { /** * Comparison operator. Two RegexPattern objects are considered equal if they - * were constructed from identical source patterns using the same match flag + * were constructed from identical source patterns using the same #URegexpFlag * settings. * @param that a RegexPattern object to compare with "this". * @return TRUE if the objects are different. @@ -151,16 +152,16 @@ class U_I18N_API RegexPattern U_FINAL : public UObject { * object. These compile methods, rather than the constructors, are the usual * way that RegexPattern objects are created. * - *

        Note that RegexPattern objects must not be deleted while RegexMatcher + * Note that RegexPattern objects must not be deleted while RegexMatcher * objects created from the pattern are active. RegexMatchers keep a pointer * back to their pattern, so premature deletion of the pattern is a - * catastrophic error.

        + * catastrophic error. * - *

        All pattern match mode flags are set to their default values.

        + * All #URegexpFlag pattern match mode flags are set to their default values. * - *

        Note that it is often more convenient to construct a RegexMatcher directly + * Note that it is often more convenient to construct a RegexMatcher directly * from a pattern string rather than separately compiling the pattern and - * then creating a RegexMatcher object from the pattern.

        + * then creating a RegexMatcher object from the pattern. * * @param regex The regular expression to be compiled. * @param pe Receives the position (line and column nubers) of any error @@ -179,16 +180,16 @@ class U_I18N_API RegexPattern U_FINAL : public UObject { * object. These compile methods, rather than the constructors, are the usual * way that RegexPattern objects are created. * - *

        Note that RegexPattern objects must not be deleted while RegexMatcher + * Note that RegexPattern objects must not be deleted while RegexMatcher * objects created from the pattern are active. RegexMatchers keep a pointer * back to their pattern, so premature deletion of the pattern is a - * catastrophic error.

        + * catastrophic error. * - *

        All pattern match mode flags are set to their default values.

        + * All #URegexpFlag pattern match mode flags are set to their default values. * - *

        Note that it is often more convenient to construct a RegexMatcher directly + * Note that it is often more convenient to construct a RegexMatcher directly * from a pattern string rather than separately compiling the pattern and - * then creating a RegexMatcher object from the pattern.

        + * then creating a RegexMatcher object from the pattern. * * @param regex The regular expression to be compiled. Note, the text referred * to by this UText must not be deleted during the lifetime of the @@ -206,21 +207,21 @@ class U_I18N_API RegexPattern U_FINAL : public UObject { /** * Compiles the regular expression in string form into a RegexPattern - * object using the specified match mode flags. These compile methods, + * object using the specified #URegexpFlag match mode flags. These compile methods, * rather than the constructors, are the usual way that RegexPattern objects * are created. * - *

        Note that RegexPattern objects must not be deleted while RegexMatcher + * Note that RegexPattern objects must not be deleted while RegexMatcher * objects created from the pattern are active. RegexMatchers keep a pointer * back to their pattern, so premature deletion of the pattern is a - * catastrophic error.

        + * catastrophic error. * - *

        Note that it is often more convenient to construct a RegexMatcher directly + * Note that it is often more convenient to construct a RegexMatcher directly * from a pattern string instead of than separately compiling the pattern and - * then creating a RegexMatcher object from the pattern.

        + * then creating a RegexMatcher object from the pattern. * * @param regex The regular expression to be compiled. - * @param flags The match mode flags to be used. + * @param flags The #URegexpFlag match mode flags to be used, e.g. #UREGEX_CASE_INSENSITIVE. * @param pe Receives the position (line and column numbers) of any error * within the regular expression.) * @param status A reference to a UErrorCode to receive any errors. @@ -235,23 +236,23 @@ class U_I18N_API RegexPattern U_FINAL : public UObject { /** * Compiles the regular expression in string form into a RegexPattern - * object using the specified match mode flags. These compile methods, + * object using the specified #URegexpFlag match mode flags. These compile methods, * rather than the constructors, are the usual way that RegexPattern objects * are created. * - *

        Note that RegexPattern objects must not be deleted while RegexMatcher + * Note that RegexPattern objects must not be deleted while RegexMatcher * objects created from the pattern are active. RegexMatchers keep a pointer * back to their pattern, so premature deletion of the pattern is a - * catastrophic error.

        + * catastrophic error. * - *

        Note that it is often more convenient to construct a RegexMatcher directly + * Note that it is often more convenient to construct a RegexMatcher directly * from a pattern string instead of than separately compiling the pattern and - * then creating a RegexMatcher object from the pattern.

        + * then creating a RegexMatcher object from the pattern. * * @param regex The regular expression to be compiled. Note, the text referred * to by this UText must not be deleted during the lifetime of the * RegexPattern object or any RegexMatcher object created from it. - * @param flags The match mode flags to be used. + * @param flags The #URegexpFlag match mode flags to be used, e.g. #UREGEX_CASE_INSENSITIVE. * @param pe Receives the position (line and column numbers) of any error * within the regular expression.) * @param status A reference to a UErrorCode to receive any errors. @@ -266,21 +267,21 @@ class U_I18N_API RegexPattern U_FINAL : public UObject { /** * Compiles the regular expression in string form into a RegexPattern - * object using the specified match mode flags. These compile methods, + * object using the specified #URegexpFlag match mode flags. These compile methods, * rather than the constructors, are the usual way that RegexPattern objects * are created. * - *

        Note that RegexPattern objects must not be deleted while RegexMatcher + * Note that RegexPattern objects must not be deleted while RegexMatcher * objects created from the pattern are active. RegexMatchers keep a pointer * back to their pattern, so premature deletion of the pattern is a - * catastrophic error.

        + * catastrophic error. * - *

        Note that it is often more convenient to construct a RegexMatcher directly + * Note that it is often more convenient to construct a RegexMatcher directly * from a pattern string instead of than separately compiling the pattern and - * then creating a RegexMatcher object from the pattern.

        + * then creating a RegexMatcher object from the pattern. * * @param regex The regular expression to be compiled. - * @param flags The match mode flags to be used. + * @param flags The #URegexpFlag match mode flags to be used, e.g. #UREGEX_CASE_INSENSITIVE. * @param status A reference to a UErrorCode to receive any errors. * @return A regexPattern object for the compiled pattern. * @@ -292,23 +293,23 @@ class U_I18N_API RegexPattern U_FINAL : public UObject { /** * Compiles the regular expression in string form into a RegexPattern - * object using the specified match mode flags. These compile methods, + * object using the specified #URegexpFlag match mode flags. These compile methods, * rather than the constructors, are the usual way that RegexPattern objects * are created. * - *

        Note that RegexPattern objects must not be deleted while RegexMatcher + * Note that RegexPattern objects must not be deleted while RegexMatcher * objects created from the pattern are active. RegexMatchers keep a pointer * back to their pattern, so premature deletion of the pattern is a - * catastrophic error.

        + * catastrophic error. * - *

        Note that it is often more convenient to construct a RegexMatcher directly + * Note that it is often more convenient to construct a RegexMatcher directly * from a pattern string instead of than separately compiling the pattern and - * then creating a RegexMatcher object from the pattern.

        + * then creating a RegexMatcher object from the pattern. * * @param regex The regular expression to be compiled. Note, the text referred * to by this UText must not be deleted during the lifetime of the * RegexPattern object or any RegexMatcher object created from it. - * @param flags The match mode flags to be used. + * @param flags The #URegexpFlag match mode flags to be used, e.g. #UREGEX_CASE_INSENSITIVE. * @param status A reference to a UErrorCode to receive any errors. * @return A regexPattern object for the compiled pattern. * @@ -319,8 +320,8 @@ class U_I18N_API RegexPattern U_FINAL : public UObject { UErrorCode &status); /** - * Get the match mode flags that were used when compiling this pattern. - * @return the match mode flags + * Get the #URegexpFlag match mode flags that were used when compiling this pattern. + * @return the #URegexpFlag match mode flags * @stable ICU 2.4 */ virtual uint32_t flags() const; @@ -330,7 +331,7 @@ class U_I18N_API RegexPattern U_FINAL : public UObject { * RegexMatcher can then be used to perform match, find or replace operations * on the input. Note that a RegexPattern object must not be deleted while * RegexMatchers created from it still exist and might possibly be used again. - *

        + * * The matcher will retain a reference to the supplied input string, and all regexp * pattern matching operations happen directly on this original string. It is * critical that the string not be altered or deleted before use by the regular @@ -348,17 +349,17 @@ class U_I18N_API RegexPattern U_FINAL : public UObject { private: /** * Cause a compilation error if an application accidentally attempts to - * create a matcher with a (UChar *) string as input rather than + * create a matcher with a (char16_t *) string as input rather than * a UnicodeString. Avoids a dangling reference to a temporary string. - *

        - * To efficiently work with UChar *strings, wrap the data in a UnicodeString + * + * To efficiently work with char16_t *strings, wrap the data in a UnicodeString * using one of the aliasing constructors, such as - * UnicodeString(UBool isTerminated, const UChar *text, int32_t textLength); + * `UnicodeString(UBool isTerminated, const char16_t *text, int32_t textLength);` * or in a UText, using - * utext_openUChars(UText *ut, const UChar *text, int64_t textLength, UErrorCode *status); + * `utext_openUChars(UText *ut, const char16_t *text, int64_t textLength, UErrorCode *status);` * */ - RegexMatcher *matcher(const UChar *input, + RegexMatcher *matcher(const char16_t *input, UErrorCode &status) const; public: @@ -450,7 +451,7 @@ class U_I18N_API RegexPattern U_FINAL : public UObject { * @param groupName The capture group name. * @param status A UErrorCode to receive any errors. * - * @draft ICU 55 + * @stable ICU 55 */ virtual int32_t groupNumberFromName(const UnicodeString &groupName, UErrorCode &status) const; @@ -469,7 +470,7 @@ class U_I18N_API RegexPattern U_FINAL : public UObject { * nul-terminated. * @param status A UErrorCode to receive any errors. * - * @draft ICU 55 + * @stable ICU 55 */ virtual int32_t groupNumberFromName(const char *groupName, int32_t nameLength, UErrorCode &status) const; @@ -519,7 +520,7 @@ class U_I18N_API RegexPattern U_FINAL : public UObject { /** - * Split a string into fields. Somewhat like split() from Perl or Java. + * Split a string into fields. Somewhat like %split() from Perl or Java. * Pattern matches identify delimiters that separate the input * into fields. The input data between the delimiters becomes the * fields themselves. @@ -538,7 +539,7 @@ class U_I18N_API RegexPattern U_FINAL : public UObject { * This behavior differs from Java, which ignores capture groups. * * For the best performance on split() operations, - * RegexMatcher::split is preferable to this function + * `RegexMatcher::split()` is preferable to this function * * @param input The string to be split into fields. The field delimiters * match the pattern (in the "this" object) @@ -671,8 +672,7 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * its matcher() method to create the RegexMatcher objects. * * @param regexp The Regular Expression to be compiled. - * @param flags Regular expression options, such as case insensitive matching. - * @see UREGEX_CASE_INSENSITIVE + * @param flags #URegexpFlag options, such as #UREGEX_CASE_INSENSITIVE. * @param status Any errors are reported by setting this UErrorCode variable. * @stable ICU 2.6 */ @@ -687,8 +687,7 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * its matcher() method to create the RegexMatcher objects. * * @param regexp The regular expression to be compiled. - * @param flags Regular expression options, such as case insensitive matching. - * @see UREGEX_CASE_INSENSITIVE + * @param flags #URegexpFlag options, such as #UREGEX_CASE_INSENSITIVE. * @param status Any errors are reported by setting this UErrorCode variable. * * @stable ICU 4.6 @@ -702,7 +701,7 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * created for the same expression, it will be more efficient to * separately create and cache a RegexPattern object, and use * its matcher() method to create the RegexMatcher objects. - *

        + * * The matcher will retain a reference to the supplied input string, and all regexp * pattern matching operations happen directly on the original string. It is * critical that the string not be altered or deleted before use by the regular @@ -711,8 +710,7 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * @param regexp The Regular Expression to be compiled. * @param input The string to match. The matcher retains a reference to the * caller's string; mo copy is made. - * @param flags Regular expression options, such as case insensitive matching. - * @see UREGEX_CASE_INSENSITIVE + * @param flags #URegexpFlag options, such as #UREGEX_CASE_INSENSITIVE. * @param status Any errors are reported by setting this UErrorCode variable. * @stable ICU 2.6 */ @@ -726,7 +724,7 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * created for the same expression, it will be more efficient to * separately create and cache a RegexPattern object, and use * its matcher() method to create the RegexMatcher objects. - *

        + * * The matcher will make a shallow clone of the supplied input text, and all regexp * pattern matching operations happen on this clone. While read-only operations on * the supplied text are permitted, it is critical that the underlying string not be @@ -734,8 +732,7 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * * @param regexp The Regular Expression to be compiled. * @param input The string to match. The matcher retains a shallow clone of the text. - * @param flags Regular expression options, such as case insensitive matching. - * @see UREGEX_CASE_INSENSITIVE + * @param flags #URegexpFlag options, such as #UREGEX_CASE_INSENSITIVE. * @param status Any errors are reported by setting this UErrorCode variable. * * @stable ICU 4.6 @@ -746,17 +743,16 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { private: /** * Cause a compilation error if an application accidentally attempts to - * create a matcher with a (UChar *) string as input rather than + * create a matcher with a (char16_t *) string as input rather than * a UnicodeString. Avoids a dangling reference to a temporary string. - *

        - * To efficiently work with UChar *strings, wrap the data in a UnicodeString + * + * To efficiently work with char16_t *strings, wrap the data in a UnicodeString * using one of the aliasing constructors, such as - * UnicodeString(UBool isTerminated, const UChar *text, int32_t textLength); + * `UnicodeString(UBool isTerminated, const char16_t *text, int32_t textLength);` * or in a UText, using - * utext_openUChars(UText *ut, const UChar *text, int64_t textLength, UErrorCode *status); - * + * `utext_openUChars(UText *ut, const char16_t *text, int64_t textLength, UErrorCode *status);` */ - RegexMatcher(const UnicodeString ®exp, const UChar *input, + RegexMatcher(const UnicodeString ®exp, const char16_t *input, uint32_t flags, UErrorCode &status); public: @@ -797,8 +793,8 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * always starts at the beginning of the input region; * unlike that function, it does not require that the entire region be matched. * - *

        If the match succeeds then more information can be obtained via the start(), - * end(), and group() functions.

        + * If the match succeeds then more information can be obtained via the start(), + * end(), and group() functions. * * @param status A reference to a UErrorCode to receive any errors. * @return TRUE if there is a match at the start of the input string. @@ -812,8 +808,8 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * The match may be of any length, and is not required to extend to the end * of the input string. Contrast with match(). * - *

        If the match succeeds then more information can be obtained via the start(), - * end(), and group() functions.

        + * If the match succeeds then more information can be obtained via the start(), + * end(), and group() functions. * * @param startIndex The input string (native) index at which to begin matching. * @param status A reference to a UErrorCode to receive any errors. @@ -827,11 +823,11 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * Find the next pattern match in the input string. * The find begins searching the input at the location following the end of * the previous match, or at the start of the string if there is no previous match. - * If a match is found, start(), end() and group() + * If a match is found, `start()`, `end()` and `group()` * will provide more information regarding the match. - *

        Note that if the input string is changed by the application, + * Note that if the input string is changed by the application, * use find(startPos, status) instead of find(), because the saved starting - * position may not be valid with the altered input string.

        + * position may not be valid with the altered input string. * @return TRUE if a match is found. * @stable ICU 2.4 */ @@ -842,14 +838,15 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * Find the next pattern match in the input string. * The find begins searching the input at the location following the end of * the previous match, or at the start of the string if there is no previous match. - * If a match is found, start(), end() and group() + * If a match is found, `start()`, `end()` and `group()` * will provide more information regarding the match. - *

        Note that if the input string is changed by the application, - * use find(startPos, status) instead of find(), because the saved starting - * position may not be valid with the altered input string.

        + * + * Note that if the input string is changed by the application, + * use find(startPos, status) instead of find(), because the saved starting + * position may not be valid with the altered input string. * @param status A reference to a UErrorCode to receive any errors. * @return TRUE if a match is found. - * @draft ICU 55 + * @stable ICU 55 */ virtual UBool find(UErrorCode &status); @@ -881,6 +878,11 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * Returns a string containing the text captured by the given group * during the previous match operation. Group(0) is the entire match. * + * A zero length string is returned both for capture groups that did not + * participate in the match and for actual zero length matches. + * To distinguish between these two cases use the function start(), + * which returns -1 for non-participating groups. + * * @param groupNum the capture group number * @param status A reference to a UErrorCode to receive any errors. * Possible errors are U_REGEX_INVALID_STATE if no match @@ -919,6 +921,11 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * Returns a shallow clone of the entire live input string with the UText current native index * set to the beginning of the requested group. * + * A group length of zero is returned both for capture groups that did not + * participate in the match and for actual zero length matches. + * To distinguish between these two cases use the function start(), + * which returns -1 for non-participating groups. + * * @param groupNum The capture group number. * @param dest The UText into which the input should be cloned, or NULL to create a new UText. * @param group_len A reference to receive the length of the desired capture group @@ -1066,10 +1073,10 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * The effect is to remove any memory of previous matches, * and to cause subsequent find() operations to begin at * the specified (native) position in the input string. - *

        + * * The matcher's region is reset to its default, which is the entire * input string. - *

        + * * An alternative to this function is to set a match region * beginning at the desired index. * @@ -1144,17 +1151,17 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { private: /** * Cause a compilation error if an application accidentally attempts to - * reset a matcher with a (UChar *) string as input rather than + * reset a matcher with a (char16_t *) string as input rather than * a UnicodeString. Avoids a dangling reference to a temporary string. - *

        - * To efficiently work with UChar *strings, wrap the data in a UnicodeString + * + * To efficiently work with char16_t *strings, wrap the data in a UnicodeString * using one of the aliasing constructors, such as - * UnicodeString(UBool isTerminated, const UChar *text, int32_t textLength); + * `UnicodeString(UBool isTerminated, const char16_t *text, int32_t textLength);` * or in a UText, using - * utext_openUChars(UText *ut, const UChar *text, int64_t textLength, UErrorCode *status); + * `utext_openUChars(UText *ut, const char16_t *text, int64_t textLength, UErrorCode *status);` * */ - RegexMatcher &reset(const UChar *input); + RegexMatcher &reset(const char16_t *input); public: /** @@ -1400,15 +1407,15 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * the pattern with the replacement string. This is a convenience * function that provides a complete find-and-replace operation. * - *

        This function first resets this RegexMatcher. It then scans the input string + * This function first resets this RegexMatcher. It then scans the input string * looking for a match of the pattern. Input that is not part * of the match is appended directly to the result string; the match is replaced * in the result by the replacement string. The replacement string may contain - * references to captured groups.

        + * references to captured groups. * - *

        The state of the matcher (the position at which a subsequent find() + * The state of the matcher (the position at which a subsequent find() * would begin) after completing a replaceFirst() is not specified. The - * RegexMatcher should be reset before doing additional find() operations.

        + * RegexMatcher should be reset before doing additional find() operations. * * @param replacement a string containing the replacement text. * @param status a reference to a UErrorCode to receive any errors. @@ -1423,15 +1430,15 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * the pattern with the replacement string. This is a convenience * function that provides a complete find-and-replace operation. * - *

        This function first resets this RegexMatcher. It then scans the input string + * This function first resets this RegexMatcher. It then scans the input string * looking for a match of the pattern. Input that is not part * of the match is appended directly to the result string; the match is replaced * in the result by the replacement string. The replacement string may contain - * references to captured groups.

        + * references to captured groups. * - *

        The state of the matcher (the position at which a subsequent find() + * The state of the matcher (the position at which a subsequent find() * would begin) after completing a replaceFirst() is not specified. The - * RegexMatcher should be reset before doing additional find() operations.

        + * RegexMatcher should be reset before doing additional find() operations. * * @param replacement a string containing the replacement text. * @param dest a mutable UText in which the results are placed. @@ -1449,13 +1456,13 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * Implements a replace operation intended to be used as part of an * incremental find-and-replace. * - *

        The input string, starting from the end of the previous replacement and ending at + * The input string, starting from the end of the previous replacement and ending at * the start of the current match, is appended to the destination string. Then the * replacement string is appended to the output string, - * including handling any substitutions of captured text.

        + * including handling any substitutions of captured text. * - *

        For simple, prepackaged, non-incremental find-and-replace - * operations, see replaceFirst() or replaceAll().

        + * For simple, prepackaged, non-incremental find-and-replace + * operations, see replaceFirst() or replaceAll(). * * @param dest A UnicodeString to which the results of the find-and-replace are appended. * @param replacement A UnicodeString that provides the text to be substituted for @@ -1480,13 +1487,13 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * Implements a replace operation intended to be used as part of an * incremental find-and-replace. * - *

        The input string, starting from the end of the previous replacement and ending at + * The input string, starting from the end of the previous replacement and ending at * the start of the current match, is appended to the destination string. Then the * replacement string is appended to the output string, - * including handling any substitutions of captured text.

        + * including handling any substitutions of captured text. * - *

        For simple, prepackaged, non-incremental find-and-replace - * operations, see replaceFirst() or replaceAll().

        + * For simple, prepackaged, non-incremental find-and-replace + * operations, see replaceFirst() or replaceAll(). * * @param dest A mutable UText to which the results of the find-and-replace are appended. * Must not be NULL. @@ -1510,8 +1517,8 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { /** * As the final step in a find-and-replace operation, append the remainder * of the input string, starting at the position following the last appendReplacement(), - * to the destination string. appendTail() is intended to be invoked after one - * or more invocations of the RegexMatcher::appendReplacement(). + * to the destination string. `appendTail()` is intended to be invoked after one + * or more invocations of the `RegexMatcher::appendReplacement()`. * * @param dest A UnicodeString to which the results of the find-and-replace are appended. * @return the destination string. @@ -1523,8 +1530,8 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { /** * As the final step in a find-and-replace operation, append the remainder * of the input string, starting at the position following the last appendReplacement(), - * to the destination string. appendTail() is intended to be invoked after one - * or more invocations of the RegexMatcher::appendReplacement(). + * to the destination string. `appendTail()` is intended to be invoked after one + * or more invocations of the `RegexMatcher::appendReplacement()`. * * @param dest A mutable UText to which the results of the find-and-replace are appended. * Must not be NULL. @@ -1537,7 +1544,7 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { /** - * Split a string into fields. Somewhat like split() from Perl. + * Split a string into fields. Somewhat like %split() from Perl. * The pattern matches identify delimiters that separate the input * into fields. The input data between the matches becomes the * fields themselves. @@ -1566,7 +1573,7 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { /** - * Split a string into fields. Somewhat like split() from Perl. + * Split a string into fields. Somewhat like %split() from Perl. * The pattern matches identify delimiters that separate the input * into fields. The input data between the matches becomes the * fields themselves. @@ -1601,14 +1608,14 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { * infinite loop. * When a limit is set a match operation will fail with an error if the * limit is exceeded. - *

        + * * The units of the limit are steps of the match engine. * Correspondence with actual processor time will depend on the speed * of the processor and the details of the specific pattern, but will * typically be on the order of milliseconds. - *

        + * * By default, the matching time is not limited. - *

        + * * * @param limit The limit value, or 0 for no limit. * @param status A reference to a UErrorCode to receive any errors. @@ -1627,16 +1634,16 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { /** * Set the amount of heap storage available for use by the match backtracking stack. * The matcher is also reset, discarding any results from previous matches. - *

        + * * ICU uses a backtracking regular expression engine, with the backtrack stack * maintained on the heap. This function sets the limit to the amount of memory - * that can be used for this purpose. A backtracking stack overflow will + * that can be used for this purpose. A backtracking stack overflow will * result in an error from the match operation that caused it. - *

        + * * A limit is desirable because a malicious or poorly designed pattern can use * excessive memory, potentially crashing the process. A limit is enabled * by default. - *

        + * * @param limit The maximum size, in bytes, of the matching backtrack stack. * A value of zero means no limit. * The limit must be greater or equal to zero. @@ -1869,5 +1876,7 @@ class U_I18N_API RegexMatcher U_FINAL : public UObject { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API + #endif // UCONFIG_NO_REGULAR_EXPRESSIONS #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/region.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/region.h index cb75234bf9..d180129fb6 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/region.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/region.h @@ -1,6 +1,8 @@ +// © 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 others. + * Copyright (C) 2014-2016, International Business Machines Corporation and others. * All Rights Reserved. ******************************************************************************* */ @@ -23,6 +25,7 @@ #include "unicode/unistr.h" #include "unicode/strenum.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -101,13 +104,11 @@ class U_I18N_API Region : public UObject { */ static const Region* U_EXPORT2 getInstance (int32_t code, UErrorCode &status); -#ifndef U_HIDE_DRAFT_API /** * Returns an enumeration over the IDs of all known regions that match the given type. - * @draft ICU 55 + * @stable ICU 55 */ static StringEnumeration* U_EXPORT2 getAvailable(URegionType type, UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ /** * Returns a pointer to the region that contains this region. Returns NULL if this region is code "001" (World) @@ -127,7 +128,6 @@ class U_I18N_API Region : public UObject { */ const Region* getContainingRegion(URegionType type) const; -#ifndef U_HIDE_DRAFT_API /** * Return an enumeration over the IDs of all the regions that are immediate children of this region in the * region hierarchy. These returned regions could be either macro regions, territories, or a mixture of the two, @@ -135,7 +135,7 @@ class U_I18N_API Region : public UObject { * any sub-regions. For example, calling this method with region "150" (Europe) returns an enumeration containing * the various sub regions of Europe - "039" (Southern Europe) - "151" (Eastern Europe) - "154" (Northern Europe) * and "155" (Western Europe). - * @draft ICU 55 + * @stable ICU 55 */ StringEnumeration* getContainedRegions(UErrorCode &status) const; @@ -144,10 +144,9 @@ class U_I18N_API Region : public UObject { * hierarchy and match the given type. This API may return an empty enumeration if this region doesn't have any * sub-regions that match the given type. For example, calling this method with region "150" (Europe) and type * "URGN_TERRITORY" returns a set containing all the territories in Europe ( "FR" (France) - "IT" (Italy) - "DE" (Germany) etc. ) - * @draft ICU 55 + * @stable ICU 55 */ StringEnumeration* getContainedRegions( URegionType type, UErrorCode &status ) const; -#endif /* U_HIDE_DRAFT_API */ /** * Returns true if this region contains the supplied other region anywhere in the region hierarchy. @@ -155,15 +154,13 @@ class U_I18N_API Region : public UObject { */ UBool contains(const Region &other) const; -#ifndef U_HIDE_DRAFT_API /** * For deprecated regions, return an enumeration over the IDs of the regions that are the preferred replacement * regions for this region. Returns null for a non-deprecated region. For example, calling this method with region * "SU" (Soviet Union) would return a list of the regions containing "RU" (Russia), "AM" (Armenia), "AZ" (Azerbaijan), etc... - * @draft ICU 55 + * @stable ICU 55 */ StringEnumeration* getPreferredValues(UErrorCode &status) const; -#endif /* U_HIDE_DRAFT_API */ /** * Return this region's canonical region code. @@ -196,7 +193,7 @@ class U_I18N_API Region : public UObject { char id[4]; UnicodeString idStr; int32_t code; - URegionType type; + URegionType fType; Region *containingRegion; UVector *containedRegions; UVector *preferredValues; @@ -216,11 +213,12 @@ class U_I18N_API Region : public UObject { * anything meaningful. */ - static void loadRegionData(UErrorCode &status); + static void U_CALLCONV loadRegionData(UErrorCode &status); }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ #endif // REGION_H diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/reldatefmt.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/reldatefmt.h index 7b416cfcf6..c1eca271cc 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/reldatefmt.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/reldatefmt.h @@ -1,6 +1,8 @@ +// © 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. ***************************************************************************** @@ -15,49 +17,16 @@ #include "unicode/utypes.h" #include "unicode/uobject.h" #include "unicode/udisplaycontext.h" +#include "unicode/ureldatefmt.h" #include "unicode/locid.h" +#include "unicode/formattedvalue.h" /** * \file * \brief C++ API: Formats relative dates such as "1 day ago" or "tomorrow" */ -#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION - -#ifndef U_HIDE_DRAFT_API - -/** - * The formatting style - * @draft ICU 54 - */ -typedef enum UDateRelativeDateTimeFormatterStyle { - - /** - * Everything spelled out. - * @draft ICU 54 - */ - UDAT_STYLE_LONG, - - /** - * Abbreviations used when possible. - * @draft ICU 54 - */ - UDAT_STYLE_SHORT, - - /** - * Use the shortest possible form. - * @draft ICU 54 - */ - UDAT_STYLE_NARROW, - - /** - * The number of styles. - * @draft ICU 54 - */ - UDAT_STYLE_COUNT -} UDateRelativeDateTimeFormatterStyle; - -#endif /* U_HIDE_DRAFT_API */ +#if !UCONFIG_NO_FORMATTING /** * Represents the unit for formatting a relative date. e.g "in 5 days" @@ -108,11 +77,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; /** @@ -195,11 +166,21 @@ typedef enum UDateAbsoluteUnit { */ UDAT_ABSOLUTE_NOW, +#ifndef U_HIDE_DRAFT_API /** - * Count of items in this enum. - * @stable ICU 53 + * Quarter + * @draft ICU 63 */ - UDAT_ABSOLUTE_UNIT_COUNT + UDAT_ABSOLUTE_QUARTER, +#endif // U_HIDE_DRAFT_API + +#ifndef U_HIDE_DEPRECATED_API + /** + * 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 = UDAT_ABSOLUTE_NOW + 2 +#endif // U_HIDE_DEPRECATED_API } UDateAbsoluteUnit; /** @@ -245,22 +226,93 @@ 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 +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN +class BreakIterator; class RelativeDateTimeCacheData; class SharedNumberFormat; class SharedPluralRules; class SharedBreakIterator; class NumberFormat; class UnicodeString; +class FormattedRelativeDateTimeData; + +#ifndef U_HIDE_DRAFT_API +/** + * An immutable class containing the result of a relative datetime formatting operation. + * + * Instances of this class are immutable and thread-safe. + * + * Not intended for public subclassing. + * + * @draft ICU 64 + */ +class U_I18N_API FormattedRelativeDateTime : public UMemory, public FormattedValue { + public: + /** + * Default constructor; makes an empty FormattedRelativeDateTime. + * @draft ICU 64 + */ + FormattedRelativeDateTime() : fData(nullptr), fErrorCode(U_INVALID_STATE_ERROR) {} + + /** + * Move constructor: Leaves the source FormattedRelativeDateTime in an undefined state. + * @draft ICU 64 + */ + FormattedRelativeDateTime(FormattedRelativeDateTime&& src) U_NOEXCEPT; + + /** + * Destruct an instance of FormattedRelativeDateTime. + * @draft ICU 64 + */ + virtual ~FormattedRelativeDateTime() U_OVERRIDE; + + /** Copying not supported; use move constructor instead. */ + FormattedRelativeDateTime(const FormattedRelativeDateTime&) = delete; + + /** Copying not supported; use move assignment instead. */ + FormattedRelativeDateTime& operator=(const FormattedRelativeDateTime&) = delete; + + /** + * Move assignment: Leaves the source FormattedRelativeDateTime in an undefined state. + * @draft ICU 64 + */ + FormattedRelativeDateTime& operator=(FormattedRelativeDateTime&& src) U_NOEXCEPT; + + /** @copydoc FormattedValue::toString() */ + UnicodeString toString(UErrorCode& status) const U_OVERRIDE; + + /** @copydoc FormattedValue::toTempString() */ + UnicodeString toTempString(UErrorCode& status) const U_OVERRIDE; + + /** @copydoc FormattedValue::appendTo() */ + Appendable &appendTo(Appendable& appendable, UErrorCode& status) const U_OVERRIDE; + + /** @copydoc FormattedValue::nextPosition() */ + UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE; + + private: + FormattedRelativeDateTimeData *fData; + UErrorCode fErrorCode; + explicit FormattedRelativeDateTime(FormattedRelativeDateTimeData *results) + : fData(results), fErrorCode(U_ZERO_ERROR) {} + explicit FormattedRelativeDateTime(UErrorCode errorCode) + : fData(nullptr), fErrorCode(errorCode) {} + friend class RelativeDateTimeFormatter; +}; +#endif /* U_HIDE_DRAFT_API */ /** * Formats simple relative dates. There are two types of relative dates that @@ -352,13 +404,12 @@ class U_I18N_API RelativeDateTimeFormatter : public UObject { * @param nfToAdopt Constructed object takes ownership of this pointer. * It is an error for caller to delete this pointer or change its * contents after calling this constructor. - * @status Any error is returned here. + * @param status Any error is returned here. * @stable ICU 53 */ RelativeDateTimeFormatter( const Locale& locale, NumberFormat *nfToAdopt, UErrorCode& status); -#ifndef U_HIDE_DRAFT_API /** * Create RelativeDateTimeFormatter with given locale, NumberFormat, * and capitalization context. @@ -371,8 +422,8 @@ class U_I18N_API RelativeDateTimeFormatter : public UObject { * @param style the format style. The UDAT_RELATIVE bit field has no effect. * @param capitalizationContext A value from UDisplayContext that pertains to * capitalization. - * @status Any error is returned here. - * @draft ICU 54 + * @param status Any error is returned here. + * @stable ICU 54 */ RelativeDateTimeFormatter( const Locale& locale, @@ -380,7 +431,6 @@ class U_I18N_API RelativeDateTimeFormatter : public UObject { UDateRelativeDateTimeFormatterStyle style, UDisplayContext capitalizationContext, UErrorCode& status); -#endif /* U_HIDE_DRAFT_API */ /** * Copy constructor. @@ -404,6 +454,10 @@ class U_I18N_API RelativeDateTimeFormatter : public UObject { /** * Formats a relative date with a quantity such as "in 5 days" or * "3 months ago" + * + * This method returns a String. To get more information about the + * formatting result, use formatToValue(). + * * @param quantity The numerical amount e.g 5. This value is formatted * according to this object's NumberFormat object. * @param direction NEXT means a future relative date; LAST means a past @@ -423,8 +477,37 @@ class U_I18N_API RelativeDateTimeFormatter : public UObject { UnicodeString& appendTo, UErrorCode& status) const; +#ifndef U_HIDE_DRAFT_API + /** + * Formats a relative date with a quantity such as "in 5 days" or + * "3 months ago" + * + * This method returns a FormattedRelativeDateTime, which exposes more + * information than the String returned by format(). + * + * @param quantity The numerical amount e.g 5. This value is formatted + * according to this object's NumberFormat object. + * @param direction NEXT means a future relative date; LAST means a past + * relative date. If direction is anything else, this method sets + * status to U_ILLEGAL_ARGUMENT_ERROR. + * @param unit the unit e.g day? month? year? + * @param status ICU error code returned here. + * @return The formatted relative datetime + * @draft ICU 64 + */ + FormattedRelativeDateTime formatToValue( + double quantity, + UDateDirection direction, + UDateRelativeUnit unit, + UErrorCode& status) const; +#endif /* U_HIDE_DRAFT_API */ + /** * Formats a relative date without a quantity. + * + * This method returns a String. To get more information about the + * formatting result, use formatToValue(). + * * @param direction NEXT, LAST, THIS, etc. * @param unit e.g SATURDAY, DAY, MONTH * @param appendTo The string to which the formatted result will be @@ -441,6 +524,130 @@ class U_I18N_API RelativeDateTimeFormatter : public UObject { UnicodeString& appendTo, UErrorCode& status) const; +#ifndef U_HIDE_DRAFT_API + /** + * Formats a relative date without a quantity. + * + * This method returns a FormattedRelativeDateTime, which exposes more + * information than the String returned by format(). + * + * If the string is not available in the requested locale, the return + * value will be empty (calling toString will give an empty string). + * + * @param direction NEXT, LAST, THIS, etc. + * @param unit e.g SATURDAY, DAY, MONTH + * @param status ICU error code returned here. + * @return The formatted relative datetime + * @draft ICU 64 + */ + FormattedRelativeDateTime formatToValue( + UDateDirection direction, + UDateAbsoluteUnit unit, + UErrorCode& status) const; +#endif /* U_HIDE_DRAFT_API */ + + /** + * Format a combination of URelativeDateTimeUnit and numeric offset + * using a numeric style, e.g. "1 week ago", "in 1 week", + * "5 weeks ago", "in 5 weeks". + * + * This method returns a String. To get more information about the + * formatting result, use formatNumericToValue(). + * + * @param offset The signed offset for the specified unit. This + * will be formatted according to this object's + * NumberFormat object. + * @param unit The unit to use when formatting the relative + * date, e.g. UDAT_REL_UNIT_WEEK, + * UDAT_REL_UNIT_FRIDAY. + * @param appendTo The string to which the formatted result will be + * appended. + * @param status ICU error code returned here. + * @return appendTo + * @stable ICU 57 + */ + UnicodeString& formatNumeric( + double offset, + URelativeDateTimeUnit unit, + UnicodeString& appendTo, + UErrorCode& status) const; + +#ifndef U_HIDE_DRAFT_API + /** + * Format a combination of URelativeDateTimeUnit and numeric offset + * using a numeric style, e.g. "1 week ago", "in 1 week", + * "5 weeks ago", "in 5 weeks". + * + * This method returns a FormattedRelativeDateTime, which exposes more + * information than the String returned by formatNumeric(). + * + * @param offset The signed offset for the specified unit. This + * will be formatted according to this object's + * NumberFormat object. + * @param unit The unit to use when formatting the relative + * date, e.g. UDAT_REL_UNIT_WEEK, + * UDAT_REL_UNIT_FRIDAY. + * @param status ICU error code returned here. + * @return The formatted relative datetime + * @draft ICU 64 + */ + FormattedRelativeDateTime formatNumericToValue( + double offset, + URelativeDateTimeUnit unit, + UErrorCode& status) const; +#endif /* U_HIDE_DRAFT_API */ + + /** + * Format a combination of URelativeDateTimeUnit and numeric offset + * using a text style if possible, e.g. "last week", "this week", + * "next week", "yesterday", "tomorrow". Falls back to numeric + * style if no appropriate text term is available for the specified + * offset in the object's locale. + * + * This method returns a String. To get more information about the + * formatting result, use formatToValue(). + * + * @param offset The signed offset for the specified unit. + * @param unit The unit to use when formatting the relative + * date, e.g. UDAT_REL_UNIT_WEEK, + * UDAT_REL_UNIT_FRIDAY. + * @param appendTo The string to which the formatted result will be + * appended. + * @param status ICU error code returned here. + * @return appendTo + * @stable ICU 57 + */ + UnicodeString& format( + double offset, + URelativeDateTimeUnit unit, + UnicodeString& appendTo, + UErrorCode& status) const; + +#ifndef U_HIDE_DRAFT_API + /** + * Format a combination of URelativeDateTimeUnit and numeric offset + * using a text style if possible, e.g. "last week", "this week", + * "next week", "yesterday", "tomorrow". Falls back to numeric + * style if no appropriate text term is available for the specified + * offset in the object's locale. + * + * This method returns a FormattedRelativeDateTime, which exposes more + * information than the String returned by format(). + * + * @param offset The signed offset for the specified unit. + * @param unit The unit to use when formatting the relative + * date, e.g. UDAT_REL_UNIT_WEEK, + * UDAT_REL_UNIT_FRIDAY. + * @param status ICU error code returned here. + * @return The formatted relative datetime + * @draft ICU 64 + */ + FormattedRelativeDateTime formatToValue( + double offset, + URelativeDateTimeUnit unit, + UErrorCode& status) const; +#endif /* U_HIDE_DRAFT_API */ + /** * Combines a relative date string and a time string in this object's * locale. This is done with the same date-time separator used for the @@ -466,21 +673,19 @@ class U_I18N_API RelativeDateTimeFormatter : public UObject { */ const NumberFormat& getNumberFormat() const; -#ifndef U_HIDE_DRAFT_API /** * Returns the capitalization context. * - * @draft ICU 54 + * @stable ICU 54 */ UDisplayContext getCapitalizationContext() const; /** * Returns the format style. * - * @draft ICU 54 + * @stable ICU 54 */ UDateRelativeDateTimeFormatterStyle getFormatStyle() const; -#endif /* U_HIDE_DRAFT_API */ private: const RelativeDateTimeCacheData* fCache; @@ -494,10 +699,50 @@ class U_I18N_API RelativeDateTimeFormatter : public UObject { NumberFormat *nfToAdopt, BreakIterator *brkIter, UErrorCode &status); - void adjustForContext(UnicodeString &) const; + UnicodeString& adjustForContext(UnicodeString &) const; + UBool checkNoAdjustForContext(UErrorCode& status) const; + + template + UnicodeString& doFormat( + F callback, + UnicodeString& appendTo, + UErrorCode& status, + Args... args) const; + +#ifndef U_HIDE_DRAFT_API // for FormattedRelativeDateTime + template + FormattedRelativeDateTime doFormatToValue( + F callback, + UErrorCode& status, + Args... args) const; +#endif // U_HIDE_DRAFT_API + + void formatImpl( + double quantity, + UDateDirection direction, + UDateRelativeUnit unit, + FormattedRelativeDateTimeData& output, + UErrorCode& status) const; + void formatAbsoluteImpl( + UDateDirection direction, + UDateAbsoluteUnit unit, + FormattedRelativeDateTimeData& output, + UErrorCode& status) const; + void formatNumericImpl( + double offset, + URelativeDateTimeUnit unit, + FormattedRelativeDateTimeData& output, + UErrorCode& status) const; + void formatRelativeImpl( + double offset, + URelativeDateTimeUnit unit, + FormattedRelativeDateTimeData& output, + UErrorCode& status) const; }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API -#endif /* !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION*/ -#endif +#endif /* !UCONFIG_NO_BREAK_ITERATION */ +#endif /* !UCONFIG_NO_FORMATTING */ +#endif /* __RELDATEFMT_H */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/rep.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/rep.h index 4c7eae1401..c831ee56ad 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/rep.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/rep.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ************************************************************************** * Copyright (C) 1999-2012, International Business Machines Corporation and @@ -21,6 +23,7 @@ * \brief C++ API: Replaceable String */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class UnicodeString; @@ -91,7 +94,7 @@ class U_COMMON_API Replaceable : public UObject { * @return 16-bit code unit of text at given offset * @stable ICU 1.8 */ - inline UChar charAt(int32_t offset) const; + inline char16_t charAt(int32_t offset) const; /** * Returns the 32-bit code point at the given 16-bit offset into @@ -228,7 +231,7 @@ class U_COMMON_API Replaceable : public UObject { * Virtual version of charAt(). * @stable ICU 2.4 */ - virtual UChar getCharAt(int32_t offset) const = 0; + virtual char16_t getCharAt(int32_t offset) const = 0; /** * Virtual version of char32At(). @@ -244,7 +247,7 @@ Replaceable::length() const { return getLength(); } -inline UChar +inline char16_t Replaceable::charAt(int32_t offset) const { return getCharAt(offset); } @@ -257,5 +260,6 @@ Replaceable::char32At(int32_t offset) const { // There is no rep.cpp, see unistr.cpp for Replaceable function implementations. U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/resbund.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/resbund.h index 6e3c1b2afc..4904b6e372 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/resbund.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/resbund.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * @@ -57,6 +59,7 @@ * \brief C++ API: Resource Bundle */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -130,7 +133,7 @@ class U_COMMON_API ResourceBundle : public UObject { ResourceBundle(UErrorCode &err); /** - * Standard constructor, onstructs a resource bundle for the locale-specific + * Standard constructor, constructs a resource bundle for the locale-specific * bundle in the specified package. * * @param packageName The packageName and locale together point to an ICU udata object, @@ -214,7 +217,7 @@ class U_COMMON_API ResourceBundle : public UObject { * could be U_MISSING_RESOURCE_ERROR if the key is not found * could be a warning * e.g.: U_USING_FALLBACK_WARNING,U_USING_DEFAULT_WARNING - * @return a pointer to a zero-terminated UChar array which lives in a memory mapped/DLL file. + * @return a pointer to a zero-terminated char16_t array which lives in a memory mapped/DLL file. * @stable ICU 2.0 */ UnicodeString @@ -487,4 +490,6 @@ class U_COMMON_API ResourceBundle : public UObject { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API + #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/schriter.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/schriter.h index d0b5e22503..29360e724a 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/schriter.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/schriter.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * @@ -27,6 +29,7 @@ * \brief C++ API: String Character Iterator */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** * A concrete subclass of CharacterIterator that iterates over the @@ -67,7 +70,7 @@ class U_COMMON_API StringCharacterIterator : public UCharCharacterIterator { * Create an iterator over the UnicodeString referred to by "textStr". * The UnicodeString object is copied. * The iteration range begins with the code unit specified by - * "textBegin" and ends with the code unit BEFORE the code unit specfied + * "textBegin" and ends with the code unit BEFORE the code unit specified * by "textEnd". The starting position is specified by "textPos". If * "textBegin" and "textEnd" don't form a valid range on "text" (i.e., * textBegin >= textEnd or either is negative or greater than text.size()), @@ -173,7 +176,7 @@ class U_COMMON_API StringCharacterIterator : public UCharCharacterIterator { * @param newTextLength The length of the String * @stable ICU 2.0 */ - void setText(const UChar* newText, int32_t newTextLength); + void setText(const char16_t* newText, int32_t newTextLength); /** * Copy of the iterated string object. @@ -184,4 +187,6 @@ class U_COMMON_API StringCharacterIterator : public UCharCharacterIterator { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API + #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/scientificnumberformatter.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/scientificnumberformatter.h index 700694cd24..ce1e6d2068 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/scientificnumberformatter.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/scientificnumberformatter.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** -* Copyright (c) 2014, International Business Machines +* Copyright (c) 2014-2016, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -11,7 +13,6 @@ #if !UCONFIG_NO_FORMATTING -#ifndef U_HIDE_DRAFT_API #include "unicode/unistr.h" @@ -20,10 +21,10 @@ * \brief C++ API: Formats in scientific notation. */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class FieldPositionIterator; -class DecimalFormatStaticSets; class DecimalFormatSymbols; class DecimalFormat; class Formattable; @@ -45,7 +46,7 @@ class Formattable; * fmt->format(1.23456e-78, appendTo, status); * * - * @draft ICU 55 + * @stable ICU 55 */ class U_I18N_API ScientificNumberFormatter : public UObject { public: @@ -58,7 +59,7 @@ class U_I18N_API ScientificNumberFormatter : public UObject { * @param status error returned here. * @return The new ScientificNumberFormatter instance. * - * @draft ICU 55 + * @stable ICU 55 */ static ScientificNumberFormatter *createSuperscriptInstance( DecimalFormat *fmtToAdopt, UErrorCode &status); @@ -70,7 +71,7 @@ class U_I18N_API ScientificNumberFormatter : public UObject { * @param status error returned here. * @return The ScientificNumberFormatter instance. * - * @draft ICU 55 + * @stable ICU 55 */ static ScientificNumberFormatter *createSuperscriptInstance( const Locale &locale, UErrorCode &status); @@ -86,7 +87,7 @@ class U_I18N_API ScientificNumberFormatter : public UObject { * @param status error returned here. * @return The new ScientificNumberFormatter instance. * - * @draft ICU 55 + * @stable ICU 55 */ static ScientificNumberFormatter *createMarkupInstance( DecimalFormat *fmtToAdopt, @@ -103,7 +104,7 @@ class U_I18N_API ScientificNumberFormatter : public UObject { * @param status error returned here. * @return The ScientificNumberFormatter instance. * - * @draft ICU 55 + * @stable ICU 55 */ static ScientificNumberFormatter *createMarkupInstance( const Locale &locale, @@ -114,7 +115,7 @@ class U_I18N_API ScientificNumberFormatter : public UObject { /** * Returns a copy of this object. Caller must free returned copy. - * @draft ICU 55 + * @stable ICU 55 */ ScientificNumberFormatter *clone() const { return new ScientificNumberFormatter(*this); @@ -122,7 +123,7 @@ class U_I18N_API ScientificNumberFormatter : public UObject { /** * Destructor. - * @draft ICU 55 + * @stable ICU 55 */ virtual ~ScientificNumberFormatter(); @@ -134,7 +135,7 @@ class U_I18N_API ScientificNumberFormatter : public UObject { * @param status any error returned here. * @return appendTo * - * @draft ICU 55 + * @stable ICU 55 */ UnicodeString &format( const Formattable &number, @@ -149,7 +150,6 @@ class U_I18N_API ScientificNumberFormatter : public UObject { const UnicodeString &original, FieldPositionIterator &fpi, const UnicodeString &preExponent, - const DecimalFormatStaticSets &decimalFormatSets, UnicodeString &appendTo, UErrorCode &status) const = 0; private: @@ -164,7 +164,6 @@ class U_I18N_API ScientificNumberFormatter : public UObject { const UnicodeString &original, FieldPositionIterator &fpi, const UnicodeString &preExponent, - const DecimalFormatStaticSets &decimalFormatSets, UnicodeString &appendTo, UErrorCode &status) const; }; @@ -183,7 +182,6 @@ class U_I18N_API ScientificNumberFormatter : public UObject { const UnicodeString &original, FieldPositionIterator &fpi, const UnicodeString &preExponent, - const DecimalFormatStaticSets &decimalFormatSets, UnicodeString &appendTo, UErrorCode &status) const; private: @@ -210,13 +208,12 @@ class U_I18N_API ScientificNumberFormatter : public UObject { UnicodeString fPreExponent; DecimalFormat *fDecimalFormat; Style *fStyle; - const DecimalFormatStaticSets *fStaticSets; }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API -#endif /* U_HIDE_DRAFT_API */ #endif /* !UCONFIG_NO_FORMATTING */ #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/search.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/search.h index 71bbf2dd52..403d3c5a91 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/search.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/search.h @@ -1,3 +1,5 @@ +// © 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. @@ -34,6 +36,7 @@ struct USearch; */ typedef struct USearch USearch; +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -568,6 +571,7 @@ inline UBool SearchIterator::operator!=(const SearchIterator &that) const return !operator==(that); } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_COLLATION */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/selfmt.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/selfmt.h index 635144bb9b..91e0e63135 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/selfmt.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/selfmt.h @@ -1,3 +1,5 @@ +// © 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 @@ -27,6 +29,7 @@ #if !UCONFIG_NO_FORMATTING +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class MessageFormat; @@ -360,6 +363,7 @@ class U_I18N_API SelectFormat : public Format { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/simpleformatter.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/simpleformatter.h new file mode 100644 index 0000000000..0b92a5b54e --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/simpleformatter.h @@ -0,0 +1,338 @@ +// © 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. All Rights Reserved. +****************************************************************************** +* simpleformatter.h +*/ + +#ifndef __SIMPLEFORMATTER_H__ +#define __SIMPLEFORMATTER_H__ + +/** + * \file + * \brief C++ API: Simple formatter, minimal subset of MessageFormat. + */ + +#include "unicode/utypes.h" +#include "unicode/unistr.h" + +#if U_SHOW_CPLUSPLUS_API +U_NAMESPACE_BEGIN + +// Forward declaration: +namespace number { +namespace impl { +class SimpleModifier; +} +} + +/** + * Formats simple patterns like "{1} was born in {0}". + * Minimal subset of MessageFormat; fast, simple, minimal dependencies. + * Supports only numbered arguments with no type nor style parameters, + * and formats only string values. + * Quoting via ASCII apostrophe compatible with ICU MessageFormat default behavior. + * + * Factory methods set error codes for syntax errors + * and for too few or too many arguments/placeholders. + * + * SimpleFormatter objects are thread-safe except for assignment and applying new patterns. + * + * Example: + *

        + * UErrorCode errorCode = U_ZERO_ERROR;
        + * SimpleFormatter fmt("{1} '{born}' in {0}", errorCode);
        + * UnicodeString result;
        + *
        + * // Output: "paul {born} in england"
        + * fmt.format("england", "paul", result, errorCode);
        + * 
        + * + * This class is not intended for public subclassing. + * + * @see MessageFormat + * @see UMessagePatternApostropheMode + * @stable ICU 57 + */ +class U_COMMON_API SimpleFormatter U_FINAL : public UMemory { +public: + /** + * Default constructor. + * @stable ICU 57 + */ + SimpleFormatter() : compiledPattern((char16_t)0) {} + + /** + * Constructs a formatter from the pattern string. + * + * @param pattern The pattern string. + * @param errorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax. + * @stable ICU 57 + */ + SimpleFormatter(const UnicodeString& pattern, UErrorCode &errorCode) { + applyPattern(pattern, errorCode); + } + + /** + * Constructs a formatter from the pattern string. + * The number of arguments checked against the given limits is the + * highest argument number plus one, not the number of occurrences of arguments. + * + * @param pattern The pattern string. + * @param min The pattern must have at least this many arguments. + * @param max The pattern must have at most this many arguments. + * @param errorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax and + * too few or too many arguments. + * @stable ICU 57 + */ + SimpleFormatter(const UnicodeString& pattern, int32_t min, int32_t max, + UErrorCode &errorCode) { + applyPatternMinMaxArguments(pattern, min, max, errorCode); + } + + /** + * Copy constructor. + * @stable ICU 57 + */ + SimpleFormatter(const SimpleFormatter& other) + : compiledPattern(other.compiledPattern) {} + + /** + * Assignment operator. + * @stable ICU 57 + */ + SimpleFormatter &operator=(const SimpleFormatter& other); + + /** + * Destructor. + * @stable ICU 57 + */ + ~SimpleFormatter(); + + /** + * Changes this object according to the new pattern. + * + * @param pattern The pattern string. + * @param errorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax. + * @return TRUE if U_SUCCESS(errorCode). + * @stable ICU 57 + */ + UBool applyPattern(const UnicodeString &pattern, UErrorCode &errorCode) { + return applyPatternMinMaxArguments(pattern, 0, INT32_MAX, errorCode); + } + + /** + * Changes this object according to the new pattern. + * The number of arguments checked against the given limits is the + * highest argument number plus one, not the number of occurrences of arguments. + * + * @param pattern The pattern string. + * @param min The pattern must have at least this many arguments. + * @param max The pattern must have at most this many arguments. + * @param errorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax and + * too few or too many arguments. + * @return TRUE if U_SUCCESS(errorCode). + * @stable ICU 57 + */ + UBool applyPatternMinMaxArguments(const UnicodeString &pattern, + int32_t min, int32_t max, UErrorCode &errorCode); + + /** + * @return The max argument number + 1. + * @stable ICU 57 + */ + int32_t getArgumentLimit() const { + return getArgumentLimit(compiledPattern.getBuffer(), compiledPattern.length()); + } + + /** + * Formats the given value, appending to the appendTo builder. + * The argument value must not be the same object as appendTo. + * getArgumentLimit() must be at most 1. + * + * @param value0 Value for argument {0}. + * @param appendTo Gets the formatted pattern and value appended. + * @param errorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return appendTo + * @stable ICU 57 + */ + UnicodeString &format( + const UnicodeString &value0, + UnicodeString &appendTo, UErrorCode &errorCode) const; + + /** + * Formats the given values, appending to the appendTo builder. + * An argument value must not be the same object as appendTo. + * getArgumentLimit() must be at most 2. + * + * @param value0 Value for argument {0}. + * @param value1 Value for argument {1}. + * @param appendTo Gets the formatted pattern and values appended. + * @param errorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return appendTo + * @stable ICU 57 + */ + UnicodeString &format( + const UnicodeString &value0, + const UnicodeString &value1, + UnicodeString &appendTo, UErrorCode &errorCode) const; + + /** + * Formats the given values, appending to the appendTo builder. + * An argument value must not be the same object as appendTo. + * getArgumentLimit() must be at most 3. + * + * @param value0 Value for argument {0}. + * @param value1 Value for argument {1}. + * @param value2 Value for argument {2}. + * @param appendTo Gets the formatted pattern and values appended. + * @param errorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return appendTo + * @stable ICU 57 + */ + UnicodeString &format( + const UnicodeString &value0, + const UnicodeString &value1, + const UnicodeString &value2, + UnicodeString &appendTo, UErrorCode &errorCode) const; + + /** + * Formats the given values, appending to the appendTo string. + * + * @param values The argument values. + * An argument value must not be the same object as appendTo. + * Can be NULL if valuesLength==getArgumentLimit()==0. + * @param valuesLength The length of the values array. + * Must be at least getArgumentLimit(). + * @param appendTo Gets the formatted pattern and values appended. + * @param offsets offsets[i] receives the offset of where + * values[i] replaced pattern argument {i}. + * Can be shorter or longer than values. Can be NULL if offsetsLength==0. + * If there is no {i} in the pattern, then offsets[i] is set to -1. + * @param offsetsLength The length of the offsets array. + * @param errorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return appendTo + * @stable ICU 57 + */ + UnicodeString &formatAndAppend( + const UnicodeString *const *values, int32_t valuesLength, + UnicodeString &appendTo, + int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const; + + /** + * Formats the given values, replacing the contents of the result string. + * May optimize by actually appending to the result if it is the same object + * as the value corresponding to the initial argument in the pattern. + * + * @param values The argument values. + * An argument value may be the same object as result. + * Can be NULL if valuesLength==getArgumentLimit()==0. + * @param valuesLength The length of the values array. + * Must be at least getArgumentLimit(). + * @param result Gets its contents replaced by the formatted pattern and values. + * @param offsets offsets[i] receives the offset of where + * values[i] replaced pattern argument {i}. + * Can be shorter or longer than values. Can be NULL if offsetsLength==0. + * If there is no {i} in the pattern, then offsets[i] is set to -1. + * @param offsetsLength The length of the offsets array. + * @param errorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return result + * @stable ICU 57 + */ + UnicodeString &formatAndReplace( + const UnicodeString *const *values, int32_t valuesLength, + UnicodeString &result, + int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const; + + /** + * Returns the pattern text with none of the arguments. + * Like formatting with all-empty string values. + * @stable ICU 57 + */ + UnicodeString getTextWithNoArguments() const { + return getTextWithNoArguments( + compiledPattern.getBuffer(), + compiledPattern.length(), + nullptr, + 0); + } + +#ifndef U_HIDE_INTERNAL_API + /** + * Returns the pattern text with none of the arguments. + * Like formatting with all-empty string values. + * + * TODO(ICU-20406): Replace this with an Iterator interface. + * + * @param offsets offsets[i] receives the offset of where {i} was located + * before it was replaced by an empty string. + * For example, "a{0}b{1}" produces offset 1 for i=0 and 2 for i=1. + * Can be nullptr if offsetsLength==0. + * If there is no {i} in the pattern, then offsets[i] is set to -1. + * @param offsetsLength The length of the offsets array. + * + * @internal + */ + UnicodeString getTextWithNoArguments(int32_t *offsets, int32_t offsetsLength) const { + return getTextWithNoArguments( + compiledPattern.getBuffer(), + compiledPattern.length(), + offsets, + offsetsLength); + } +#endif // U_HIDE_INTERNAL_API + +private: + /** + * Binary representation of the compiled pattern. + * Index 0: One more than the highest argument number. + * Followed by zero or more arguments or literal-text segments. + * + * An argument is stored as its number, less than ARG_NUM_LIMIT. + * A literal-text segment is stored as its length (at least 1) offset by ARG_NUM_LIMIT, + * followed by that many chars. + */ + UnicodeString compiledPattern; + + static inline int32_t getArgumentLimit(const char16_t *compiledPattern, + int32_t compiledPatternLength) { + return compiledPatternLength == 0 ? 0 : compiledPattern[0]; + } + + static UnicodeString getTextWithNoArguments( + const char16_t *compiledPattern, + int32_t compiledPatternLength, + int32_t *offsets, + int32_t offsetsLength); + + static UnicodeString &format( + const char16_t *compiledPattern, int32_t compiledPatternLength, + const UnicodeString *const *values, + UnicodeString &result, const UnicodeString *resultCopy, UBool forbidResultAsValue, + int32_t *offsets, int32_t offsetsLength, + UErrorCode &errorCode); + + // Give access to internals to SimpleModifier for number formatting + friend class number::impl::SimpleModifier; +}; + +U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API + +#endif // __SIMPLEFORMATTER_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/simpletz.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/simpletz.h index 4762f63995..f93d106304 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/simpletz.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/simpletz.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 1997-2013, International Business Machines * @@ -35,6 +37,7 @@ #include "unicode/basictz.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN // forward declaration @@ -645,7 +648,8 @@ class U_I18N_API SimpleTimeZone: public BasicTimeZone { * Sets the amount of time in ms that the clock is advanced during DST. * @param millisSavedDuringDST the number of milliseconds the time is * advanced with respect to standard time when the daylight savings rules - * are in effect. A positive number, typically one hour (3600000). + * are in effect. Typically one hour (+3600000). The amount could be negative, + * but not 0. * @param status An UErrorCode to receive the status. * @stable ICU 2.0 */ @@ -655,7 +659,8 @@ class U_I18N_API SimpleTimeZone: public BasicTimeZone { * Returns the amount of time in ms that the clock is advanced during DST. * @return the number of milliseconds the time is * advanced with respect to standard time when the daylight savings rules - * are in effect. A positive number, typically one hour (3600000). + * are in effect. Typically one hour (+3600000). The amount could be negative, + * but not 0. * @stable ICU 2.0 */ virtual int32_t getDSTSavings(void) const; @@ -922,6 +927,7 @@ SimpleTimeZone::getOffset(UDate date, UBool local, int32_t& rawOffsetRef, } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/smpdtfmt.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/smpdtfmt.h index ccdaff42ab..6aa58eef6b 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/smpdtfmt.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/smpdtfmt.h @@ -1,5 +1,7 @@ +// © 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. ******************************************************************************* * @@ -38,6 +40,7 @@ #include "unicode/tzfmt.h" /* for UTimeZoneFormatTimeType */ #include "unicode/brkiter.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class DateFormatSymbols; @@ -47,6 +50,11 @@ class FieldPositionHandler; class TimeZoneFormat; class SharedNumberFormat; class SimpleDateFormatMutableNFs; +class DateIntervalFormat; + +namespace number { +class LocalizedNumberFormatter; +} /** * @@ -89,7 +97,7 @@ class SimpleDateFormatMutableNFs; * G * 1..3 * AD - * Era - Replaced with the Era string for the current date. One to three letters for the + * Era - Replaced with the Era string for the current date. One to three letters for the * abbreviated form, four letters for the long (wide) form, five for the narrow form. * * @@ -218,7 +226,7 @@ class SimpleDateFormatMutableNFs; * q * 1..2 * 02 - * Stand-Alone Quarter - Use one or two for the numerical quarter, three for the abbreviation, + * Stand-Alone Quarter - Use one or two for the numerical quarter, three for the abbreviation, * or four for the full name (five for the narrow name is not yet supported). * * @@ -254,7 +262,7 @@ class SimpleDateFormatMutableNFs; * L * 1..2 * 09 - * Stand-Alone Month - Use one or two for the numerical month, three for the abbreviation, + * Stand-Alone Month - Use one or two for the numerical month, three for the abbreviation, * four for the full (wide) name, or 5 for the narrow name. With two ("LL"), the month number is zero-padded if * necessary (e.g. "08") * @@ -310,7 +318,7 @@ class SimpleDateFormatMutableNFs; * 2451334 * Modified Julian day. This is different from the conventional Julian day number in two regards. * First, it demarcates days at local zone midnight, rather than noon GMT. Second, it is a local number; - * that is, it depends on the local time zone. It can be thought of as a single number that encompasses + * that is, it depends on the local time zone. It can be thought of as a single number that encompasses * all the date-related fields. * * @@ -319,7 +327,7 @@ class SimpleDateFormatMutableNFs; * E * 1..3 * Tue - * Day of week - Use one through three letters for the short day, four for the full (wide) name, + * Day of week - Use one through three letters for the short day, four for the full (wide) name, * five for the narrow name, or six for the short name. * * @@ -539,7 +547,7 @@ class SimpleDateFormatMutableNFs; * The generic location format. * Where that is unavailable, falls back to the long localized GMT format ("OOOO"; * Note: Fallback is only necessary with a GMT-style Time Zone ID, like Etc/GMT-830.)
        - * This is especially useful when presenting possible timezone choices for user selection, + * This is especially useful when presenting possible timezone choices for user selection, * since the naming is more uniform than the "v" format. * * @@ -651,7 +659,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 +1007,12 @@ class U_I18N_API SimpleDateFormat: public DateFormat { * (Presumably, letters that would be more mnemonic in that locale's * language.) This function would produce a pattern using those * letters. + *

        + * Note: 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 @@ -1126,18 +1140,17 @@ class U_I18N_API SimpleDateFormat: public DateFormat { * @param value The UDisplayContext value to set. * @param status Input/output status. If at entry this indicates a failure * status, the function will do nothing; otherwise this will be - * updated with any new status from the function. + * updated with any new status from the function. * @stable ICU 53 */ virtual void setContext(UDisplayContext value, UErrorCode& status); - -#ifndef U_HIDE_DRAFT_API + /** * Overrides base class method and - * This method clears per field NumberFormat instances - * previously set by {@see adoptNumberFormat(const UnicodeString&, NumberFormat*, UErrorCode)} - * @param adoptNF the NumbeferFormat used - * @draft ICU 54 + * This method clears per field NumberFormat instances + * previously set by {@see adoptNumberFormat(const UnicodeString&, NumberFormat*, UErrorCode)} + * @param formatToAdopt the NumbeferFormat used + * @stable ICU 54 */ void adoptNumberFormat(NumberFormat *formatToAdopt); @@ -1145,26 +1158,25 @@ class U_I18N_API SimpleDateFormat: public DateFormat { * Allow the user to set the NumberFormat for several fields * It can be a single field like: "y"(year) or "M"(month) * It can be several field combined together: "yM"(year and month) - * Note: + * Note: * 1 symbol field is enough for multiple symbol field (so "y" will override "yy", "yyy") * If the field is not numeric, then override has no effect (like "MMM" will use abbreviation, not numerical field) * Per field NumberFormat can also be cleared in {@see DateFormat::setNumberFormat(const NumberFormat& newNumberFormat)} * * @param fields the fields to override(like y) - * @param adoptNF the NumbeferFormat used + * @param formatToAdopt the NumbeferFormat used * @param status Receives a status code, which will be U_ZERO_ERROR * if the operation succeeds. - * @draft ICU 54 + * @stable ICU 54 */ void adoptNumberFormat(const UnicodeString& fields, NumberFormat *formatToAdopt, UErrorCode &status); /** * Get the numbering system to be used for a particular field. * @param field The UDateFormatField to get - * @draft ICU 54 + * @stable ICU 54 */ - const NumberFormat * getNumberFormatForField(UChar field) const; -#endif /* U_HIDE_DRAFT_API */ + const NumberFormat * getNumberFormatForField(char16_t field) const; #ifndef U_HIDE_INTERNAL_API /** @@ -1203,10 +1215,23 @@ class U_I18N_API SimpleDateFormat: public DateFormat { * @internal ICU 4.0 */ const Locale& getSmpFmtLocale(void) const; + + /** + * Apple addition + * This is for ICU internal use only. Please do not use. + * Get the capitalization break iterator of this simple date formatter. + * Should be cloned before using it. + * It is used in udat. + * + * @return capitalization break iterator + * @internal + */ + BreakIterator* getCapitalizationBrkIter(void) const; #endif /* U_HIDE_INTERNAL_API */ private: friend class DateFormat; + friend class DateIntervalFormat; void initializeDefaultCentury(void); @@ -1256,13 +1281,12 @@ class U_I18N_API SimpleDateFormat: public DateFormat { * succeeds. */ void subFormat(UnicodeString &appendTo, - UChar ch, + char16_t ch, int32_t count, UDisplayContext capitalizationContext, int32_t fieldNum, FieldPositionHandler& handler, Calendar& cal, - SimpleDateFormatMutableNFs &mutableNFs, UErrorCode& status) const; // in case of illegal argument /** @@ -1271,14 +1295,14 @@ class U_I18N_API SimpleDateFormat: public DateFormat { * having a number of digits between "minDigits" and * "maxDigits". Uses the DateFormat's NumberFormat. * - * @param currentNumberFormat + * @param currentNumberFormat * @param appendTo Output parameter to receive result. * Formatted number is appended to existing contents. * @param value Value to format. * @param minDigits Minimum number of digits the result should have * @param maxDigits Maximum number of digits the result should have */ - void zeroPaddingNumber(NumberFormat *currentNumberFormat, + void zeroPaddingNumber(const NumberFormat *currentNumberFormat, UnicodeString &appendTo, int32_t value, int32_t minDigits, @@ -1288,7 +1312,7 @@ class U_I18N_API SimpleDateFormat: public DateFormat { * Return true if the given format character, occuring count * times, represents a numeric field. */ - static UBool isNumeric(UChar formatChar, int32_t count); + static UBool isNumeric(char16_t formatChar, int32_t count); /** * Returns TRUE if the patternOffset is at the start of a numeric field. @@ -1359,7 +1383,14 @@ class U_I18N_API SimpleDateFormat: public DateFormat { */ int32_t matchQuarterString(const UnicodeString& text, int32_t start, UCalendarDateFields field, const UnicodeString* stringArray, int32_t stringArrayCount, Calendar& cal) const; - + + /** + * Used by subParse() to match localized day period strings. + */ + int32_t matchDayPeriodStrings(const UnicodeString& text, int32_t start, + const UnicodeString* stringArray, int32_t stringArrayCount, + int32_t &dayPeriod) const; + /** * Private function used by subParse to match literal pattern text. * @@ -1376,9 +1407,9 @@ class U_I18N_API SimpleDateFormat: public DateFormat { * @return TRUE if the literal text could be matched, FALSE otherwise. */ static UBool matchLiterals(const UnicodeString &pattern, int32_t &patternOffset, - const UnicodeString &text, int32_t &textOffset, + const UnicodeString &text, int32_t &textOffset, UBool whitespaceLenient, UBool partialMatchLenient, UBool oldLeniency); - + /** * Private member function that converts the parsed date strings into * timeFields. Returns -start (for ParsePosition) if failed. @@ -1399,26 +1430,37 @@ class U_I18N_API SimpleDateFormat: public DateFormat { * @return the new start position if matching succeeded; a negative number * indicating matching failure, otherwise. */ - int32_t subParse(const UnicodeString& text, int32_t& start, UChar ch, int32_t count, + int32_t subParse(const UnicodeString& text, int32_t& start, char16_t ch, int32_t count, UBool obeyCount, UBool allowNegative, UBool ambiguousYear[], int32_t& saveHebrewMonth, Calendar& cal, - int32_t patLoc, MessageFormat * numericLeapMonthFormatter, UTimeZoneFormatTimeType *tzTimeType, SimpleDateFormatMutableNFs &mutableNFs) const; + int32_t patLoc, MessageFormat * numericLeapMonthFormatter, UTimeZoneFormatTimeType *tzTimeType, + int32_t *dayPeriod=NULL) const; void parseInt(const UnicodeString& text, Formattable& number, ParsePosition& pos, UBool allowNegative, - NumberFormat *fmt) const; + const NumberFormat *fmt) const; void parseInt(const UnicodeString& text, Formattable& number, int32_t maxDigits, ParsePosition& pos, UBool allowNegative, - NumberFormat *fmt) const; + const NumberFormat *fmt) const; int32_t checkIntSuffix(const UnicodeString& text, int32_t start, int32_t patLoc, UBool isNegative) const; + /** + * Counts number of digit code points in the specified text. + * + * @param text input text + * @param start start index, inclusive + * @param end end index, exclusive + * @return number of digits found in the text in the specified range. + */ + int32_t countDigits(const UnicodeString& text, int32_t start, int32_t end) const; + /** * Translate a pattern, mapping each character in the from string to the * corresponding character in the to string. Return an error if the original @@ -1471,6 +1513,16 @@ class U_I18N_API SimpleDateFormat: public DateFormat { */ int32_t skipUWhiteSpace(const UnicodeString& text, int32_t pos) const; + /** + * Initialize LocalizedNumberFormatter instances used for speedup. + */ + void initFastNumberFormatters(UErrorCode& status); + + /** + * Delete the LocalizedNumberFormatter instances used for speedup. + */ + void freeFastNumberFormatters(); + /** * Initialize NumberFormat instances used for numbering system overrides. */ @@ -1494,7 +1546,7 @@ class U_I18N_API SimpleDateFormat: public DateFormat { /** * Lazy TimeZoneFormat instantiation, semantically const */ - TimeZoneFormat *tzFormat() const; + TimeZoneFormat *tzFormat(UErrorCode &status) const; const NumberFormat* getNumberFormatByIndex(UDateFormatField index) const; @@ -1509,12 +1561,12 @@ class U_I18N_API SimpleDateFormat: public DateFormat { /** * Map calendar field letter into calendar field level. */ - static int32_t getLevelFromChar(UChar ch); + static int32_t getLevelFromChar(char16_t ch); /** * Tell if a character can be used to define a field in a format string. */ - static UBool isSyntaxChar(UChar ch); + static UBool isSyntaxChar(char16_t ch); /** * The formatting pattern for this formatter. @@ -1558,6 +1610,15 @@ class U_I18N_API SimpleDateFormat: public DateFormat { */ UDate fDefaultCenturyStart; + UBool fHasMinute; + UBool fHasSecond; + UBool fHasHanYearChar; // pattern contains the Han year character \u5E74 + + /** + * Sets fHasMinutes and fHasSeconds. + */ + void parsePattern(); + /** * See documentation for defaultCenturyStart. */ @@ -1579,6 +1640,20 @@ class U_I18N_API SimpleDateFormat: public DateFormat { */ const SharedNumberFormat **fSharedNumberFormatters; + enum NumberFormatterKey { + SMPDTFMT_NF_1x10, + SMPDTFMT_NF_2x10, + SMPDTFMT_NF_3x10, + SMPDTFMT_NF_4x10, + SMPDTFMT_NF_2x2, + SMPDTFMT_NF_COUNT + }; + + /** + * Number formatters pre-allocated for fast performance on the most common integer lengths. + */ + const number::LocalizedNumberFormatter* fFastNumberFormatters[SMPDTFMT_NF_COUNT] = {}; + UBool fHaveDefaultCentury; BreakIterator* fCapitalizationBrkIter; @@ -1590,7 +1665,14 @@ SimpleDateFormat::get2DigitYearStart(UErrorCode& /*status*/) const return fDefaultCenturyStart; } +inline BreakIterator* +SimpleDateFormat::getCapitalizationBrkIter() const +{ + return fCapitalizationBrkIter; +} + U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/sortkey.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/sortkey.h index c125eeecf0..5ac1fe1172 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/sortkey.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/sortkey.h @@ -1,3 +1,5 @@ +// © 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. @@ -34,6 +36,7 @@ #include "unicode/unistr.h" #include "unicode/coll.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /* forward declaration */ @@ -332,6 +335,7 @@ CollationKey::getByteArray(int32_t &count) const } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_COLLATION */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/std_string.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/std_string.h index 05955c5d1e..729c563995 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/std_string.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/std_string.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -6,7 +8,7 @@ * ******************************************************************************* * file name: std_string.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -25,13 +27,11 @@ #include "unicode/utypes.h" -#if U_HAVE_STD_STRING - -#if !defined(_MSC_VER) -namespace std { class type_info; } // WORKAROUND: http://llvm.org/bugs/show_bug.cgi?id=13364 +// Workaround for a libstdc++ bug before libstdc++4.6 (2011). +// https://bugs.llvm.org/show_bug.cgi?id=13364 +#if defined(__GLIBCXX__) +namespace std { class type_info; } #endif #include -#endif // U_HAVE_STD_STRING - #endif // __STD_STRING_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/strenum.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/strenum.h index 3dbe21c6b2..50dfe4f573 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/strenum.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/strenum.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -18,6 +20,7 @@ * \brief C++ API: String Enumeration */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -33,7 +36,7 @@ U_NAMESPACE_BEGIN * call, so the returned string still might not be 'valid' on * subsequent use.

        * - *

        Strings may take the form of const char*, const UChar*, or const + *

        Strings may take the form of const char*, const char16_t*, or const * UnicodeString*. The type you get is determine by the variant of * 'next' that you call. In general the StringEnumeration is * optimized for one of these types, but all StringEnumerations can @@ -110,7 +113,7 @@ class U_COMMON_API StringEnumeration : public UObject { *

        If the iterator is out of sync with its service, status is set * to U_ENUM_OUT_OF_SYNC_ERROR and NULL is returned.

        * - *

        If the native service string is a UChar* string, it is + *

        If the native service string is a char16_t* string, it is * converted to char* with the invariant converter. If the * conversion fails (because a character cannot be converted) then * status is set to U_INVARIANT_CONVERSION_ERROR and the return @@ -129,7 +132,7 @@ class U_COMMON_API StringEnumeration : public UObject { virtual const char* next(int32_t *resultLength, UErrorCode& status); /** - *

        Returns the next element as a NUL-terminated UChar*. If there + *

        Returns the next element as a NUL-terminated char16_t*. If there * are no more elements, returns NULL. If the resultLength pointer * is not NULL, the length of the string (not counting the * terminating NUL) is returned at that address. If an error @@ -151,7 +154,7 @@ class U_COMMON_API StringEnumeration : public UObject { * * @stable ICU 2.4 */ - virtual const UChar* unext(int32_t *resultLength, UErrorCode& status); + virtual const char16_t* unext(int32_t *resultLength, UErrorCode& status); /** *

        Returns the next element a UnicodeString*. If there are no @@ -271,6 +274,7 @@ class U_COMMON_API StringEnumeration : public UObject { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API /* STRENUM_H */ #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/stringoptions.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/stringoptions.h new file mode 100644 index 0000000000..7b9f70944f --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/stringoptions.h @@ -0,0 +1,190 @@ +// © 2017 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +// stringoptions.h +// created: 2017jun08 Markus W. Scherer + +#ifndef __STRINGOPTIONS_H__ +#define __STRINGOPTIONS_H__ + +#include "unicode/utypes.h" + +/** + * \file + * \brief C API: Bit set option bit constants for various string and character processing functions. + */ + +/** + * Option value for case folding: Use default mappings defined in CaseFolding.txt. + * + * @stable ICU 2.0 + */ +#define U_FOLD_CASE_DEFAULT 0 + +/** + * Option value for case folding: + * + * Use the modified set of mappings provided in CaseFolding.txt to handle dotted I + * and dotless i appropriately for Turkic languages (tr, az). + * + * Before Unicode 3.2, CaseFolding.txt contains mappings marked with 'I' that + * are to be included for default mappings and + * excluded for the Turkic-specific mappings. + * + * Unicode 3.2 CaseFolding.txt instead contains mappings marked with 'T' that + * are to be excluded for default mappings and + * included for the Turkic-specific mappings. + * + * @stable ICU 2.0 + */ +#define U_FOLD_CASE_EXCLUDE_SPECIAL_I 1 + +/** + * Titlecase the string as a whole rather than each word. + * (Titlecase only the character at index 0, possibly adjusted.) + * Option bits value for titlecasing APIs that take an options bit set. + * + * It is an error to specify multiple titlecasing iterator options together, + * including both an options bit and an explicit BreakIterator. + * + * @see U_TITLECASE_ADJUST_TO_CASED + * @stable ICU 60 + */ +#define U_TITLECASE_WHOLE_STRING 0x20 + +/** + * Titlecase sentences rather than words. + * (Titlecase only the first character of each sentence, possibly adjusted.) + * Option bits value for titlecasing APIs that take an options bit set. + * + * It is an error to specify multiple titlecasing iterator options together, + * including both an options bit and an explicit BreakIterator. + * + * @see U_TITLECASE_ADJUST_TO_CASED + * @stable ICU 60 + */ +#define U_TITLECASE_SENTENCES 0x40 + +/** + * Do not lowercase non-initial parts of words when titlecasing. + * Option bit for titlecasing APIs that take an options bit set. + * + * By default, titlecasing will titlecase the character at each + * (possibly adjusted) BreakIterator index and + * lowercase all other characters up to the next iterator index. + * With this option, the other characters will not be modified. + * + * @see U_TITLECASE_ADJUST_TO_CASED + * @see UnicodeString::toTitle + * @see CaseMap::toTitle + * @see ucasemap_setOptions + * @see ucasemap_toTitle + * @see ucasemap_utf8ToTitle + * @stable ICU 3.8 + */ +#define U_TITLECASE_NO_LOWERCASE 0x100 + +/** + * Do not adjust the titlecasing BreakIterator indexes; + * titlecase exactly the characters at breaks from the iterator. + * Option bit for titlecasing APIs that take an options bit set. + * + * By default, titlecasing will take each break iterator index, + * adjust it to the next relevant character (see U_TITLECASE_ADJUST_TO_CASED), + * and titlecase that one. + * + * Other characters are lowercased. + * + * It is an error to specify multiple titlecasing adjustment options together. + * + * @see U_TITLECASE_ADJUST_TO_CASED + * @see U_TITLECASE_NO_LOWERCASE + * @see UnicodeString::toTitle + * @see CaseMap::toTitle + * @see ucasemap_setOptions + * @see ucasemap_toTitle + * @see ucasemap_utf8ToTitle + * @stable ICU 3.8 + */ +#define U_TITLECASE_NO_BREAK_ADJUSTMENT 0x200 + +/** + * Adjust each titlecasing BreakIterator index to the next cased character. + * (See the Unicode Standard, chapter 3, Default Case Conversion, R3 toTitlecase(X).) + * Option bit for titlecasing APIs that take an options bit set. + * + * This used to be the default index adjustment in ICU. + * Since ICU 60, the default index adjustment is to the next character that is + * a letter, number, symbol, or private use code point. + * (Uncased modifier letters are skipped.) + * The difference in behavior is small for word titlecasing, + * but the new adjustment is much better for whole-string and sentence titlecasing: + * It yields "49ers" and "«丰(abc)»" instead of "49Ers" and "«丰(Abc)»". + * + * It is an error to specify multiple titlecasing adjustment options together. + * + * @see U_TITLECASE_NO_BREAK_ADJUSTMENT + * @stable ICU 60 + */ +#define U_TITLECASE_ADJUST_TO_CASED 0x400 + +/** + * Option for string transformation functions to not first reset the Edits object. + * Used for example in some case-mapping and normalization functions. + * + * @see CaseMap + * @see Edits + * @see Normalizer2 + * @stable ICU 60 + */ +#define U_EDITS_NO_RESET 0x2000 + +/** + * Omit unchanged text when recording how source substrings + * relate to changed and unchanged result substrings. + * Used for example in some case-mapping and normalization functions. + * + * @see CaseMap + * @see Edits + * @see Normalizer2 + * @stable ICU 60 + */ +#define U_OMIT_UNCHANGED_TEXT 0x4000 + +/** + * Option bit for u_strCaseCompare, u_strcasecmp, unorm_compare, etc: + * Compare strings in code point order instead of code unit order. + * @stable ICU 2.2 + */ +#define U_COMPARE_CODE_POINT_ORDER 0x8000 + +/** + * Option bit for unorm_compare: + * Perform case-insensitive comparison. + * @stable ICU 2.2 + */ +#define U_COMPARE_IGNORE_CASE 0x10000 + +/** + * Option bit for unorm_compare: + * Both input strings are assumed to fulfill FCD conditions. + * @stable ICU 2.2 + */ +#define UNORM_INPUT_IS_FCD 0x20000 + +// Related definitions elsewhere. +// Options that are not meaningful in the same functions +// can share the same bits. +// +// Public: +// unicode/unorm.h #define UNORM_COMPARE_NORM_OPTIONS_SHIFT 20 +// +// Internal: (may change or be removed) +// ucase.h #define _STRCASECMP_OPTIONS_MASK 0xffff +// ucase.h #define _FOLD_CASE_OPTIONS_MASK 7 +// ucasemap_imp.h #define U_TITLECASE_ITERATOR_MASK 0xe0 +// ucasemap_imp.h #define U_TITLECASE_ADJUSTMENT_MASK 0x600 +// ustr_imp.h #define _STRNCMP_STYLE 0x1000 +// unormcmp.cpp #define _COMPARE_EQUIV 0x80000 + +#endif // __STRINGOPTIONS_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/stringpiece.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/stringpiece.h index b29571d4ad..d525f43288 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/stringpiece.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/stringpiece.h @@ -1,3 +1,5 @@ +// © 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 others. All Rights Reserved. // @@ -31,6 +33,7 @@ // Arghh! I wish C++ literals were "string". +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -40,9 +43,9 @@ U_NAMESPACE_BEGIN * in a "const char*" or a "string" wherever a "StringPiece" is * expected. * - * Functions or methods may use const StringPiece& parameters to accept either - * a "const char*" or a "string" value that will be implicitly converted to - * a StringPiece. + * Functions or methods may use StringPiece parameters to accept either a + * "const char*" or a "string" value that will be implicitly converted to a + * StringPiece. * * Systematic usage of StringPiece is encouraged as it will reduce unnecessary * conversions from "const char*" to "string" and back again. @@ -66,14 +69,12 @@ class U_COMMON_API StringPiece : public UMemory { * @stable ICU 4.2 */ StringPiece(const char* str); -#if U_HAVE_STD_STRING /** * Constructs from a std::string. * @stable ICU 4.2 */ StringPiece(const std::string& str) : ptr_(str.data()), length_(static_cast(str.size())) { } -#endif /** * Constructs from a const char * pointer and a specified length. * @param offset a const char * pointer (need not be terminated) @@ -220,5 +221,6 @@ inline UBool operator!=(const StringPiece& x, const StringPiece& y) { } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // __STRINGPIECE_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/stringtriebuilder.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/stringtriebuilder.h index 04447e5437..fc02dba629 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/stringtriebuilder.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/stringtriebuilder.h @@ -1,10 +1,12 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2010-2012,2014, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* * file name: stringtriebuilder.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -24,8 +26,10 @@ */ // Forward declaration. +/// \cond struct UHashtable; typedef struct UHashtable UHashtable; +/// \endcond /** * Build options for BytesTrieBuilder and CharsTrieBuilder. @@ -50,6 +54,7 @@ enum UStringTrieBuildOption { USTRINGTRIE_BUILD_SMALL }; +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -62,7 +67,7 @@ class U_COMMON_API StringTrieBuilder : public UObject { public: #ifndef U_HIDE_INTERNAL_API /** @internal */ - static UBool hashNode(const void *node); + static int32_t hashNode(const void *node); /** @internal */ static UBool equalNodes(const void *left, const void *right); #endif /* U_HIDE_INTERNAL_API */ @@ -103,7 +108,7 @@ class U_COMMON_API StringTrieBuilder : public UObject { /** @internal */ virtual int32_t getElementStringLength(int32_t i) const = 0; /** @internal */ - virtual UChar getElementUnit(int32_t i, int32_t unitIndex) const = 0; + virtual char16_t getElementUnit(int32_t i, int32_t unitIndex) const = 0; /** @internal */ virtual int32_t getElementValue(int32_t i) const = 0; @@ -118,7 +123,7 @@ class U_COMMON_API StringTrieBuilder : public UObject { /** @internal */ virtual int32_t skipElementsBySomeUnits(int32_t i, int32_t unitIndex, int32_t count) const = 0; /** @internal */ - virtual int32_t indexOfElementWithNextUnit(int32_t i, int32_t unitIndex, UChar unit) const = 0; + virtual int32_t indexOfElementWithNextUnit(int32_t i, int32_t unitIndex, char16_t unit) const = 0; /** @internal */ virtual UBool matchNodesCanHaveValues() const = 0; @@ -135,7 +140,7 @@ class U_COMMON_API StringTrieBuilder : public UObject { /** @internal */ static const int32_t kMaxBranchLinearSubNodeLength=5; - // Maximum number of nested split-branch levels for a branch on all 2^16 possible UChar units. + // Maximum number of nested split-branch levels for a branch on all 2^16 possible char16_t units. // log2(2^16/kMaxBranchLinearSubNodeLength) rounded up. /** @internal */ static const int32_t kMaxSplitBranchLevels=14; @@ -184,8 +189,12 @@ class U_COMMON_API StringTrieBuilder : public UObject { /** @internal */ UHashtable *nodes; -#ifndef U_HIDE_INTERNAL_API - /** @internal */ + // Do not conditionalize the following with #ifndef U_HIDE_INTERNAL_API, + // it is needed for layout of other objects. + /** + * @internal + * \cond + */ class Node : public UObject { public: Node(int32_t initialHash) : hash(initialHash), offset(0) {} @@ -243,6 +252,7 @@ class U_COMMON_API StringTrieBuilder : public UObject { int32_t offset; }; +#ifndef U_HIDE_INTERNAL_API // This class should not be overridden because // registerFinalValue() compares a stack-allocated FinalValueNode // (stack-allocated so that we don't unnecessarily create lots of duplicate nodes) @@ -252,13 +262,16 @@ class U_COMMON_API StringTrieBuilder : public UObject { /** @internal */ class FinalValueNode : public Node { public: - FinalValueNode(int32_t v) : Node(0x111111*37+v), value(v) {} + FinalValueNode(int32_t v) : Node(0x111111u*37u+v), value(v) {} virtual UBool operator==(const Node &other) const; virtual void write(StringTrieBuilder &builder); protected: int32_t value; }; +#endif /* U_HIDE_INTERNAL_API */ + // Do not conditionalize the following with #ifndef U_HIDE_INTERNAL_API, + // it is needed for layout of other objects. /** * @internal */ @@ -269,34 +282,38 @@ class U_COMMON_API StringTrieBuilder : public UObject { void setValue(int32_t v) { hasValue=TRUE; value=v; - hash=hash*37+v; + hash=hash*37u+v; } protected: UBool hasValue; int32_t value; }; +#ifndef U_HIDE_INTERNAL_API /** * @internal */ class IntermediateValueNode : public ValueNode { public: IntermediateValueNode(int32_t v, Node *nextNode) - : ValueNode(0x222222*37+hashCode(nextNode)), next(nextNode) { setValue(v); } + : ValueNode(0x222222u*37u+hashCode(nextNode)), next(nextNode) { setValue(v); } virtual UBool operator==(const Node &other) const; virtual int32_t markRightEdgesFirst(int32_t edgeNumber); virtual void write(StringTrieBuilder &builder); protected: Node *next; }; +#endif /* U_HIDE_INTERNAL_API */ + // Do not conditionalize the following with #ifndef U_HIDE_INTERNAL_API, + // it is needed for layout of other objects. /** * @internal */ class LinearMatchNode : public ValueNode { public: LinearMatchNode(int32_t len, Node *nextNode) - : ValueNode((0x333333*37+len)*37+hashCode(nextNode)), + : ValueNode((0x333333u*37u+len)*37u+hashCode(nextNode)), length(len), next(nextNode) {} virtual UBool operator==(const Node &other) const; virtual int32_t markRightEdgesFirst(int32_t edgeNumber); @@ -305,6 +322,7 @@ class U_COMMON_API StringTrieBuilder : public UObject { Node *next; }; +#ifndef U_HIDE_INTERNAL_API /** * @internal */ @@ -326,25 +344,25 @@ class U_COMMON_API StringTrieBuilder : public UObject { virtual void write(StringTrieBuilder &builder); // Adds a unit with a final value. void add(int32_t c, int32_t value) { - units[length]=(UChar)c; + units[length]=(char16_t)c; equal[length]=NULL; values[length]=value; ++length; - hash=(hash*37+c)*37+value; + hash=(hash*37u+c)*37u+value; } // Adds a unit which leads to another match node. void add(int32_t c, Node *node) { - units[length]=(UChar)c; + units[length]=(char16_t)c; equal[length]=node; values[length]=0; ++length; - hash=(hash*37+c)*37+hashCode(node); + hash=(hash*37u+c)*37u+hashCode(node); } protected: Node *equal[kMaxBranchLinearSubNodeLength]; // NULL means "has final value". int32_t length; int32_t values[kMaxBranchLinearSubNodeLength]; - UChar units[kMaxBranchLinearSubNodeLength]; + char16_t units[kMaxBranchLinearSubNodeLength]; }; /** @@ -352,15 +370,15 @@ class U_COMMON_API StringTrieBuilder : public UObject { */ class SplitBranchNode : public BranchNode { public: - SplitBranchNode(UChar middleUnit, Node *lessThanNode, Node *greaterOrEqualNode) - : BranchNode(((0x555555*37+middleUnit)*37+ - hashCode(lessThanNode))*37+hashCode(greaterOrEqualNode)), + SplitBranchNode(char16_t middleUnit, Node *lessThanNode, Node *greaterOrEqualNode) + : BranchNode(((0x555555u*37u+middleUnit)*37u+ + hashCode(lessThanNode))*37u+hashCode(greaterOrEqualNode)), unit(middleUnit), lessThan(lessThanNode), greaterOrEqual(greaterOrEqualNode) {} virtual UBool operator==(const Node &other) const; virtual int32_t markRightEdgesFirst(int32_t edgeNumber); virtual void write(StringTrieBuilder &builder); protected: - UChar unit; + char16_t unit; Node *lessThan; Node *greaterOrEqual; }; @@ -370,7 +388,7 @@ class U_COMMON_API StringTrieBuilder : public UObject { class BranchHeadNode : public ValueNode { public: BranchHeadNode(int32_t len, Node *subNode) - : ValueNode((0x666666*37+len)*37+hashCode(subNode)), + : ValueNode((0x666666u*37u+len)*37u+hashCode(subNode)), length(len), next(subNode) {} virtual UBool operator==(const Node &other) const; virtual int32_t markRightEdgesFirst(int32_t edgeNumber); @@ -379,7 +397,9 @@ class U_COMMON_API StringTrieBuilder : public UObject { int32_t length; Node *next; // A branch sub-node. }; + #endif /* U_HIDE_INTERNAL_API */ + /// \endcond /** @internal */ virtual Node *createLinearMatchNode(int32_t i, int32_t unitIndex, int32_t length, @@ -398,5 +418,6 @@ class U_COMMON_API StringTrieBuilder : public UObject { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // __STRINGTRIEBUILDER_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/stsearch.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/stsearch.h index d38cb23f21..028fe24de0 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/stsearch.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/stsearch.h @@ -1,3 +1,5 @@ +// © 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. @@ -23,6 +25,7 @@ #include "unicode/coleitr.h" #include "unicode/search.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -497,6 +500,7 @@ private : }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_COLLATION */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/symtable.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/symtable.h index 428f8bff23..95c22a4165 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/symtable.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/symtable.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2000-2005, International Business Machines @@ -19,6 +21,7 @@ * symbolic names. */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class ParsePosition; @@ -108,5 +111,6 @@ class U_COMMON_API SymbolTable /* not : public UObject because this is an interf ParsePosition& pos, int32_t limit) const = 0; }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tblcoll.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tblcoll.h index e56f189ad2..d4cf184a45 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tblcoll.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tblcoll.h @@ -1,6 +1,8 @@ +// © 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 +* Copyright (C) 1996-2016, International Business Machines Corporation and * others. All Rights Reserved. ****************************************************************************** */ @@ -69,6 +71,7 @@ #include "unicode/uiter.h" #include "unicode/ucol.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN struct CollationCacheEntry; @@ -94,12 +97,12 @@ class UVector64; * Collator, using data-driven tables. The user can create a customized * table-based collation. *

        - * For more information about the collation service see + * For more information about the collation service see * the User Guide. *

        - * Collation service provides correct sorting orders for most locales supported in ICU. + * Collation service provides correct sorting orders for most locales supported in ICU. * If specific data for a locale is not available, the orders eventually falls back - * to the CLDR root sort order. + * to the CLDR root sort order. *

        * Sort ordering may be customized by providing your own set of rules. For more on * this subject see the @@ -161,7 +164,7 @@ class U_I18N_API RuleBasedCollator : public Collator { UColAttributeValue decompositionMode, UErrorCode& status); -#ifndef U_HIDE_INTERNAL_API +#ifndef U_HIDE_INTERNAL_API /** * TODO: document & propose as public API * @internal @@ -180,8 +183,8 @@ class U_I18N_API RuleBasedCollator : public Collator { /** Opens a collator from a collator binary image created using - * cloneBinary. Binary image used in instantiation of the - * collator remains owned by the user and should stay around for + * cloneBinary. Binary image used in instantiation of the + * collator remains owned by the user and should stay around for * the lifetime of the collator. The API also takes a base collator * which must be the root collator. * @param bin binary image owned by the user and required through the @@ -196,8 +199,8 @@ class U_I18N_API RuleBasedCollator : public Collator { * @see cloneBinary * @stable ICU 3.4 */ - RuleBasedCollator(const uint8_t *bin, int32_t length, - const RuleBasedCollator *base, + RuleBasedCollator(const uint8_t *bin, int32_t length, + const RuleBasedCollator *base, UErrorCode &status); /** @@ -258,7 +261,7 @@ class U_I18N_API RuleBasedCollator : public Collator { /** * The comparison function compares the character data stored in two - * different strings. Returns information about whether a string is less + * different strings. Returns information about whether a string is less * than, greater than or equal to another string. * @param source the source string to be compared with. * @param target the string that is to be compared with the source string. @@ -273,15 +276,15 @@ class U_I18N_API RuleBasedCollator : public Collator { UErrorCode &status) const; /** - * Does the same thing as compare but limits the comparison to a specified + * Does the same thing as compare but limits the comparison to a specified * length * @param source the source string to be compared with. * @param target the string that is to be compared with the source string. * @param length the length the comparison is limited to * @param status possible error code - * @return Returns an enum value. UCOL_GREATER if source (up to the specified - * length) is greater than target; UCOL_EQUAL if source (up to specified - * length) is equal to target; UCOL_LESS if source (up to the specified + * @return Returns an enum value. UCOL_GREATER if source (up to the specified + * length) is greater than target; UCOL_EQUAL if source (up to specified + * length) is equal to target; UCOL_LESS if source (up to the specified * length) is less than target. * @stable ICU 2.6 */ @@ -292,7 +295,7 @@ class U_I18N_API RuleBasedCollator : public Collator { /** * The comparison function compares the character data stored in two - * different string arrays. Returns information about whether a string array + * different string arrays. Returns information about whether a string array * is less than, greater than or equal to another string array. * @param source the source string array to be compared with. * @param sourceLength the length of the source string array. If this value @@ -306,8 +309,8 @@ class U_I18N_API RuleBasedCollator : public Collator { * than target * @stable ICU 2.6 */ - virtual UCollationResult compare(const UChar* source, int32_t sourceLength, - const UChar* target, int32_t targetLength, + virtual UCollationResult compare(const char16_t* source, int32_t sourceLength, + const char16_t* target, int32_t targetLength, UErrorCode &status) const; /** @@ -346,7 +349,7 @@ class U_I18N_API RuleBasedCollator : public Collator { * Transforms the string into a series of characters * that can be compared with CollationKey.compare(). * - * Note that sort keys are often less efficient than simply doing comparison. + * Note that sort keys are often less efficient than simply doing comparison. * For more details, see the ICU User Guide. * * @param source the source string. @@ -364,7 +367,7 @@ class U_I18N_API RuleBasedCollator : public Collator { * Transforms a specified region of the string into a series of characters * that can be compared with CollationKey.compare. * - * Note that sort keys are often less efficient than simply doing comparison. + * Note that sort keys are often less efficient than simply doing comparison. * For more details, see the ICU User Guide. * * @param source the source string. @@ -375,7 +378,7 @@ class U_I18N_API RuleBasedCollator : public Collator { * @see CollationKey * @stable ICU 2.0 */ - virtual CollationKey& getCollationKey(const UChar *source, + virtual CollationKey& getCollationKey(const char16_t *source, int32_t sourceLength, CollationKey& key, UErrorCode& status) const; @@ -413,7 +416,7 @@ class U_I18N_API RuleBasedCollator : public Collator { */ virtual void getVersion(UVersionInfo info) const; -#ifndef U_HIDE_DEPRECATED_API +#ifndef U_HIDE_DEPRECATED_API /** * Returns the maximum length of any expansion sequences that end with the * specified comparison order. @@ -458,7 +461,7 @@ class U_I18N_API RuleBasedCollator : public Collator { */ static UClassID U_EXPORT2 getStaticClassID(void); -#ifndef U_HIDE_DEPRECATED_API +#ifndef U_HIDE_DEPRECATED_API /** * Do not use this method: The caller and the ICU library might use different heaps. * Use cloneBinary() instead which writes to caller-provided memory. @@ -472,7 +475,7 @@ class U_I18N_API RuleBasedCollator : public Collator { uint8_t *cloneRuleData(int32_t &length, UErrorCode &status) const; #endif /* U_HIDE_DEPRECATED_API */ - /** Creates a binary image of a collator. This binary image can be stored and + /** Creates a binary image of a collator. This binary image can be stored and * later used to instantiate a collator using ucol_openBinary. * This API supports preflighting. * @param buffer a fill-in buffer to receive the binary image @@ -550,7 +553,7 @@ class U_I18N_API RuleBasedCollator : public Collator { * the top of one of the supported reordering groups, * and it must not be beyond the last of those groups. * See setMaxVariable(). - * @param varTop one or more (if contraction) UChars to which the variable top should be set + * @param varTop one or more (if contraction) char16_ts to which the variable top should be set * @param len length of variable top string. If -1 it is considered to be zero terminated. * @param status error code. If error code is set, the return value is undefined. Errors set by this function are:
        * U_CE_NOT_FOUND_ERROR if more than one character was passed and there is no such contraction
        @@ -559,7 +562,7 @@ class U_I18N_API RuleBasedCollator : public Collator { * @return variable top primary weight * @deprecated ICU 53 Call setMaxVariable() instead. */ - virtual uint32_t setVariableTop(const UChar *varTop, int32_t len, UErrorCode &status); + virtual uint32_t setVariableTop(const char16_t *varTop, int32_t len, UErrorCode &status); /** * Sets the variable top to the primary weight of the specified string. @@ -568,7 +571,7 @@ class U_I18N_API RuleBasedCollator : public Collator { * the top of one of the supported reordering groups, * and it must not be beyond the last of those groups. * See setMaxVariable(). - * @param varTop a UnicodeString size 1 or more (if contraction) of UChars to which the variable top should be set + * @param varTop a UnicodeString size 1 or more (if contraction) of char16_ts to which the variable top should be set * @param status error code. If error code is set, the return value is undefined. Errors set by this function are:
        * U_CE_NOT_FOUND_ERROR if more than one character was passed and there is no such contraction
        * U_ILLEGAL_ARGUMENT_ERROR if the variable top is beyond @@ -601,10 +604,10 @@ class U_I18N_API RuleBasedCollator : public Collator { virtual uint32_t getVariableTop(UErrorCode &status) const; /** - * Get a UnicodeSet that contains all the characters and sequences tailored in + * Get a UnicodeSet that contains all the characters and sequences tailored in * this collator. * @param status error code of the operation - * @return a pointer to a UnicodeSet object containing all the + * @return a pointer to a UnicodeSet object containing all the * code points and sequences that may sort differently than * in the root collator. The object must be disposed of by using delete * @stable ICU 2.4 @@ -614,7 +617,7 @@ class U_I18N_API RuleBasedCollator : public Collator { /** * Get the sort key as an array of bytes from a UnicodeString. * - * Note that sort keys are often less efficient than simply doing comparison. + * Note that sort keys are often less efficient than simply doing comparison. * For more details, see the ICU User Guide. * * @param source string to be processed. @@ -629,9 +632,9 @@ class U_I18N_API RuleBasedCollator : public Collator { int32_t resultLength) const; /** - * Get the sort key as an array of bytes from a UChar buffer. + * Get the sort key as an array of bytes from a char16_t buffer. * - * Note that sort keys are often less efficient than simply doing comparison. + * Note that sort keys are often less efficient than simply doing comparison. * For more details, see the ICU User Guide. * * @param source string to be processed. @@ -644,7 +647,7 @@ class U_I18N_API RuleBasedCollator : public Collator { * @return Number of bytes needed for storing the sort key * @stable ICU 2.2 */ - virtual int32_t getSortKey(const UChar *source, int32_t sourceLength, + virtual int32_t getSortKey(const char16_t *source, int32_t sourceLength, uint8_t *result, int32_t resultLength) const; /** @@ -658,7 +661,7 @@ class U_I18N_API RuleBasedCollator : public Collator { * @see ucol_setReorderCodes * @see Collator#getEquivalentReorderCodes * @see Collator#setReorderCodes - * @stable ICU 4.8 + * @stable ICU 4.8 */ virtual int32_t getReorderCodes(int32_t *dest, int32_t destCapacity, @@ -666,14 +669,14 @@ class U_I18N_API RuleBasedCollator : public Collator { /** * Sets the ordering of scripts for this collator. - * @param reorderCodes An array of script codes in the new order. This can be NULL if the + * @param reorderCodes An array of script codes in the new order. This can be NULL if the * length is also set to 0. An empty array will clear any reordering codes on the collator. * @param reorderCodesLength The length of reorderCodes. * @param status error code * @see ucol_setReorderCodes * @see Collator#getReorderCodes * @see Collator#getEquivalentReorderCodes - * @stable ICU 4.8 + * @stable ICU 4.8 */ virtual void setReorderCodes(const int32_t* reorderCodes, int32_t reorderCodesLength, @@ -689,18 +692,18 @@ class U_I18N_API RuleBasedCollator : public Collator { UErrorCode &errorCode) const; /** Get the short definition string for a collator. This internal API harvests the collator's - * locale and the attribute set and produces a string that can be used for opening + * locale and the attribute set and produces a string that can be used for opening * a collator with the same attributes using the ucol_openFromShortString API. * This string will be normalized. * The structure and the syntax of the string is defined in the "Naming collators" - * section of the users guide: + * section of the users guide: * http://userguide.icu-project.org/collation/concepts#TOC-Collator-naming-scheme * This function supports preflighting. - * + * * This is internal, and intended to be used with delegate converters. * * @param locale a locale that will appear as a collators locale in the resulting - * short string definition. If NULL, the locale will be harvested + * short string definition. If NULL, the locale will be harvested * from the collator. * @param buffer space to hold the resulting string * @param capacity capacity of the buffer @@ -724,6 +727,7 @@ class U_I18N_API RuleBasedCollator : public Collator { UCharIterator *iter, uint32_t state[2], uint8_t *dest, int32_t count, UErrorCode &errorCode) const; + // Do not enclose the default constructor with #ifndef U_HIDE_INTERNAL_API /** * Only for use in ucol_openRules(). * @internal @@ -818,17 +822,17 @@ class U_I18N_API RuleBasedCollator : public Collator { void adoptTailoring(CollationTailoring *t, UErrorCode &errorCode); // Both lengths must be <0 or else both must be >=0. - UCollationResult doCompare(const UChar *left, int32_t leftLength, - const UChar *right, int32_t rightLength, + UCollationResult doCompare(const char16_t *left, int32_t leftLength, + const char16_t *right, int32_t rightLength, UErrorCode &errorCode) const; UCollationResult doCompare(const uint8_t *left, int32_t leftLength, const uint8_t *right, int32_t rightLength, UErrorCode &errorCode) const; - void writeSortKey(const UChar *s, int32_t length, + void writeSortKey(const char16_t *s, int32_t length, SortKeyByteSink &sink, UErrorCode &errorCode) const; - void writeIdenticalLevel(const UChar *s, const UChar *limit, + void writeIdenticalLevel(const char16_t *s, const char16_t *limit, SortKeyByteSink &sink, UErrorCode &errorCode) const; const CollationSettings &getDefaultSettings() const; @@ -853,7 +857,7 @@ class U_I18N_API RuleBasedCollator : public Collator { */ 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; @@ -869,6 +873,7 @@ class U_I18N_API RuleBasedCollator : public Collator { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // !UCONFIG_NO_COLLATION #endif // TBLCOLL_H diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/timezone.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/timezone.h index c3356c9738..552da8cd68 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/timezone.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/timezone.h @@ -1,5 +1,7 @@ +// © 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 +* Copyright (c) 1997-2016, International Business Machines Corporation * and others. All Rights Reserved. ************************************************************************** * @@ -41,6 +43,7 @@ #include "unicode/ures.h" #include "unicode/ucal.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class StringEnumeration; @@ -66,8 +69,8 @@ class StringEnumeration; * TimeZone *tz = TimeZone::createTimeZone("America/Los_Angeles"); * * \htmlonly\endhtmlonly - * You can use getAvailableIDs method to iterate through - * all the supported time zone IDs, or getCanonicalID method to check + * You can use the createEnumeration method to iterate through + * all the supported time zone IDs, or the getCanonicalID method to check * if a time zone ID is supported or not. You can then choose a * supported ID to get a TimeZone. * If the time zone you want is not represented by one of the @@ -273,33 +276,42 @@ class U_I18N_API TimeZone : public UObject { static const UnicodeString U_EXPORT2 getEquivalentID(const UnicodeString& id, int32_t index); -#ifndef U_HIDE_DRAFT_API /** * Creates an instance of TimeZone detected from the current host - * system configuration. Note that ICU4C does not change the default - * time zone unless TimeZone::adoptDefault(TimeZone*) or - * TimeZone::setDefault(const TimeZone&) is explicitly called by a + * system configuration. If the host system detection routines fail, + * or if they specify a TimeZone or TimeZone offset which is not + * recognized, then the special TimeZone "Etc/Unknown" is returned. + * + * Note that ICU4C does not change the default time zone unless + * `TimeZone::adoptDefault(TimeZone*)` or + * `TimeZone::setDefault(const TimeZone&)` is explicitly called by a * user. This method does not update the current ICU's default, * and may return a different TimeZone from the one returned by - * TimeZone::createDefault(). + * `TimeZone::createDefault()`. + * + *

        This function is not thread safe.

        * * @return A new instance of TimeZone detected from the current host system * configuration. - * @draft ICU 55 + * @see adoptDefault + * @see setDefault + * @see createDefault + * @see getUnknown + * @stable ICU 55 */ static TimeZone* U_EXPORT2 detectHostTimeZone(); -#endif /** * Creates a new copy of the default TimeZone for this host. Unless the default time * zone has already been set using adoptDefault() or setDefault(), the default is - * determined by querying the system using methods in TPlatformUtilities. If the - * system routines fail, or if they specify a TimeZone or TimeZone offset which is not - * recognized, the TimeZone indicated by the ID kLastResortID is instantiated - * and made the default. + * determined by querying the host system configuration. If the host system detection + * routines fail, or if they specify a TimeZone or TimeZone offset which is not + * recognized, then the special TimeZone "Etc/Unknown" is instantiated and made the + * default. * * @return A default TimeZone. Clients are responsible for deleting the time zone * object returned. + * @see getUnknown * @stable ICU 2.0 */ static TimeZone* U_EXPORT2 createDefault(void); @@ -655,13 +667,13 @@ class U_I18N_API TimeZone : public UObject { * If the display name is not available for the locale, * then this method returns a string in the localized GMT offset format * such as GMT[+-]HH:mm. - * @param daylight if true, return the daylight savings name. + * @param inDaylight if true, return the daylight savings name. * @param style * @param result the human-readable name of this time zone in the default locale. * @return A reference to 'result'. * @stable ICU 2.0 */ - UnicodeString& getDisplayName(UBool daylight, EDisplayType style, UnicodeString& result) const; + UnicodeString& getDisplayName(UBool inDaylight, EDisplayType style, UnicodeString& result) const; /** * Returns a name of this time zone suitable for presentation to the user @@ -669,15 +681,15 @@ class U_I18N_API TimeZone : public UObject { * If the display name is not available for the locale, * then this method returns a string in the localized GMT offset format * such as GMT[+-]HH:mm. - * @param daylight if true, return the daylight savings name. + * @param inDaylight if true, return the daylight savings name. * @param style * @param locale the locale in which to supply the display name. * @param result the human-readable name of this time zone in the given locale * or in the default locale if the given locale is not recognized. - * @return A refence to 'result'. + * @return A reference to 'result'. * @stable ICU 2.0 */ - UnicodeString& getDisplayName(UBool daylight, EDisplayType style, const Locale& locale, UnicodeString& result) const; + UnicodeString& getDisplayName(UBool inDaylight, EDisplayType style, const Locale& locale, UnicodeString& result) const; /** * Queries if this time zone uses daylight savings time. @@ -863,7 +875,7 @@ class U_I18N_API TimeZone : public UObject { * @param id zone id string * @return the pointer of the ID resource, or NULL. */ - static const UChar* findID(const UnicodeString& id); + static const char16_t* findID(const UnicodeString& id); /** * Resolve a link in Olson tzdata. When the given id is known and it's not a link, @@ -873,7 +885,7 @@ class U_I18N_API TimeZone : public UObject { * @param id zone id string * @return the dereferenced zone or NULL */ - static const UChar* dereferOlsonLink(const UnicodeString& id); + static const char16_t* dereferOlsonLink(const UnicodeString& id); /** * Returns the region code associated with the given zone, @@ -881,7 +893,7 @@ class U_I18N_API TimeZone : public UObject { * @param id zone id string * @return the region associated with the given zone */ - static const UChar* getRegion(const UnicodeString& id); + static const char16_t* getRegion(const UnicodeString& id); public: #ifndef U_HIDE_INTERNAL_API @@ -893,7 +905,7 @@ class U_I18N_API TimeZone : public UObject { * @return the region associated with the given zone * @internal */ - static const UChar* getRegion(const UnicodeString& id, UErrorCode& status); + static const char16_t* getRegion(const UnicodeString& id, UErrorCode& status); #endif /* U_HIDE_INTERNAL_API */ private: @@ -924,7 +936,7 @@ class U_I18N_API TimeZone : public UObject { UErrorCode& status); /** - * Returns the normalized custome time zone ID for the given offset fields. + * Returns the normalized custom time zone ID for the given offset fields. * @param hour offset hours * @param min offset minutes * @param sec offset seconds @@ -958,6 +970,7 @@ TimeZone::setID(const UnicodeString& ID) fID = ID; } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tmunit.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tmunit.h index e417f3522b..ce9fc65261 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tmunit.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tmunit.h @@ -1,7 +1,9 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* - * Copyright (C) 2009-2014, Google, International Business Machines Corporation and * - * others. All Rights Reserved. * + * Copyright (C) 2009-2016, International Business Machines Corporation, * + * Google, and others. All Rights Reserved. * ******************************************************************************* */ @@ -19,6 +21,7 @@ #if !UCONFIG_NO_FORMATTING +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -41,18 +44,24 @@ class U_I18N_API TimeUnit: public MeasureUnit { 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 }; /** * Create Instance. - * @param timeUnitField time unit field based on which the instance + * @param timeUnitField time unit field based on which the instance * is created. - * @param status input-output error code. + * @param status input-output error code. * If the timeUnitField is invalid, * then this will be set to U_ILLEGAL_ARGUMENT_ERROR. * @return a TimeUnit instance - * @stable ICU 4.2 + * @stable ICU 4.2 */ static TimeUnit* U_EXPORT2 createInstance(UTimeUnitFields timeUnitField, UErrorCode& status); @@ -60,19 +69,19 @@ class U_I18N_API TimeUnit: public MeasureUnit { /** * Override clone. - * @stable ICU 4.2 + * @stable ICU 4.2 */ virtual UObject* clone() const; /** * Copy operator. - * @stable ICU 4.2 + * @stable ICU 4.2 */ TimeUnit(const TimeUnit& other); /** * Assignment operator. - * @stable ICU 4.2 + * @stable ICU 4.2 */ TimeUnit& operator=(const TimeUnit& other); @@ -82,7 +91,7 @@ class U_I18N_API TimeUnit: public MeasureUnit { * @return The class ID for this object. All objects of a given * class have the same class ID. Objects of other classes have * different class IDs. - * @stable ICU 4.2 + * @stable ICU 4.2 */ virtual UClassID getDynamicClassID() const; @@ -90,7 +99,7 @@ class U_I18N_API TimeUnit: public MeasureUnit { * Returns the class ID for this class. This is used to compare to * the return value of getDynamicClassID(). * @return The class ID for all objects of this class. - * @stable ICU 4.2 + * @stable ICU 4.2 */ static UClassID U_EXPORT2 getStaticClassID(); @@ -98,13 +107,13 @@ class U_I18N_API TimeUnit: public MeasureUnit { /** * Get time unit field. * @return time unit field. - * @stable ICU 4.2 + * @stable ICU 4.2 */ UTimeUnitFields getTimeUnitField() const; /** * Destructor. - * @stable ICU 4.2 + * @stable ICU 4.2 */ virtual ~TimeUnit(); @@ -113,7 +122,7 @@ class U_I18N_API TimeUnit: public MeasureUnit { /** * Constructor - * @internal ICU 4.2 + * @internal (private) */ TimeUnit(UTimeUnitFields timeUnitField); @@ -121,6 +130,7 @@ class U_I18N_API TimeUnit: public MeasureUnit { U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tmutamt.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tmutamt.h index bd2b8a4a9e..726ee09cb5 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tmutamt.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tmutamt.h @@ -1,3 +1,5 @@ +// © 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 * @@ -19,6 +21,7 @@ #if !UCONFIG_NO_FORMATTING +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN @@ -160,6 +163,7 @@ TimeUnitAmount::operator!=(const UObject& other) const { } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tmutfmt.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tmutfmt.h index 728ff13219..686d1f6700 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tmutfmt.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tmutfmt.h @@ -1,3 +1,5 @@ +// © 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 @@ -45,11 +47,14 @@ enum UTimeUnitFormatStyle { typedef enum UTimeUnitFormatStyle UTimeUnitFormatStyle; /**< @deprecated ICU 53 */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class Hashtable; class UVector; +struct TimeUnitFormatReadSink; + /** * Format or parse a TimeUnitAmount, using plural rules for the units where available. * @@ -227,6 +232,7 @@ class U_I18N_API TimeUnitFormat: public MeasureFormat { // UTIMEUNIT_YEAR. static const char* getTimeUnitName(TimeUnit::UTimeUnitFields field, UErrorCode& status); + friend struct TimeUnitFormatReadSink; }; inline UBool @@ -235,6 +241,7 @@ TimeUnitFormat::operator!=(const Format& other) const { } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* U_HIDE_DEPRECATED_API */ #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/translit.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/translit.h index 22e1e24e50..c1b23a3e1d 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/translit.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/translit.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2014, International Business Machines @@ -13,10 +15,10 @@ #include "unicode/utypes.h" /** - * \file + * \file * \brief C++ API: Tranforms text from one format to another. */ - + #if !UCONFIG_NO_TRANSLITERATION #include "unicode/uobject.h" @@ -25,11 +27,11 @@ #include "unicode/utrans.h" // UTransPosition, UTransDirection #include "unicode/strenum.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class UnicodeFilter; class UnicodeSet; -class CompoundTransliterator; class TransliteratorParser; class NormalizationTransliterator; class TransliteratorIDParser; @@ -75,8 +77,7 @@ class TransliteratorIDParser; * transliteration. For example, given a string input * and a transliterator t, the call * - * \htmlonly
        \endhtmlonlyString result = t.transliterate(input); - * \htmlonly
        \endhtmlonly + * String result = t.transliterate(input); * * will transliterate it and return the result. Other methods allow * the client to specify a substring to be transliterated and to use @@ -96,22 +97,20 @@ class TransliteratorIDParser; * contents of the buffer may show text being modified as each new * character arrives. * - *

        Consider the simple RuleBasedTransliterator: - * - * \htmlonly

        \endhtmlonly - * th>{theta}
        - * t>{tau} - *
        \htmlonly
        \endhtmlonly + *

        Consider the simple rule-based Transliterator: + *

        + *     th>{theta}
        + *     t>{tau}
        + * 
        * * When the user types 't', nothing will happen, since the * transliterator is waiting to see if the next character is 'h'. To * remedy this, we introduce the notion of a cursor, marked by a '|' * in the output string: - * - * \htmlonly
        \endhtmlonly - * t>|{tau}
        - * {tau}h>{theta} - *
        \htmlonly
        \endhtmlonly + *
        + *     t>|{tau}
        + *     {tau}h>{theta}
        + * 
        * * Now when the user types 't', tau appears, and if the next character * is 'h', the tau changes to a theta. This is accomplished by @@ -133,7 +132,7 @@ class TransliteratorIDParser; * which the transliterator last stopped, either because it reached * the end, or because it required more characters to disambiguate * between possible inputs. The CURSOR can also be - * explicitly set by rules in a RuleBasedTransliterator. + * explicitly set by rules in a rule-based Transliterator. * Any characters before the CURSOR index are frozen; * future keyboard transliteration calls within this input sequence * will not change them. New text is inserted at the @@ -235,6 +234,255 @@ class TransliteratorIDParser; * if the performance of these methods can be improved over the * performance obtained by the default implementations in this class. * + *

        Rule syntax + * + *

        A set of rules determines how to perform translations. + * Rules within a rule set are separated by semicolons (';'). + * To include a literal semicolon, prefix it with a backslash ('\'). + * Unicode Pattern_White_Space is ignored. + * If the first non-blank character on a line is '#', + * the entire line is ignored as a comment. + * + *

        Each set of rules consists of two groups, one forward, and one + * reverse. This is a convention that is not enforced; rules for one + * direction may be omitted, with the result that translations in + * that direction will not modify the source text. In addition, + * bidirectional forward-reverse rules may be specified for + * symmetrical transformations. + * + *

        Note: Another description of the Transliterator rule syntax is available in + * section + * Transform Rules Syntax of UTS #35: Unicode LDML. + * The rules are shown there using arrow symbols ← and → and ↔. + * ICU supports both those and the equivalent ASCII symbols < and > and <>. + * + *

        Rule statements take one of the following forms: + * + *

        + *
        $alefmadda=\\u0622;
        + *
        Variable definition. The name on the + * left is assigned the text on the right. In this example, + * after this statement, instances of the left hand name, + * "$alefmadda", will be replaced by + * the Unicode character U+0622. Variable names must begin + * with a letter and consist only of letters, digits, and + * underscores. Case is significant. Duplicate names cause + * an exception to be thrown, that is, variables cannot be + * redefined. The right hand side may contain well-formed + * text of any length, including no text at all ("$empty=;"). + * The right hand side may contain embedded UnicodeSet + * patterns, for example, "$softvowel=[eiyEIY]".
        + *
        ai>$alefmadda;
        + *
        Forward translation rule. This rule + * states that the string on the left will be changed to the + * string on the right when performing forward + * transliteration.
        + *
        ai<$alefmadda;
        + *
        Reverse translation rule. This rule + * states that the string on the right will be changed to + * the string on the left when performing reverse + * transliteration.
        + *
        + * + *
        + *
        ai<>$alefmadda;
        + *
        Bidirectional translation rule. This + * rule states that the string on the right will be changed + * to the string on the left when performing forward + * transliteration, and vice versa when performing reverse + * transliteration.
        + *
        + * + *

        Translation rules consist of a match pattern and an output + * string. The match pattern consists of literal characters, + * optionally preceded by context, and optionally followed by + * context. Context characters, like literal pattern characters, + * must be matched in the text being transliterated. However, unlike + * literal pattern characters, they are not replaced by the output + * text. For example, the pattern "abc{def}" + * indicates the characters "def" must be + * preceded by "abc" for a successful match. + * If there is a successful match, "def" will + * be replaced, but not "abc". The final '}' + * is optional, so "abc{def" is equivalent to + * "abc{def}". Another example is "{123}456" + * (or "123}456") in which the literal + * pattern "123" must be followed by "456". + * + *

        The output string of a forward or reverse rule consists of + * characters to replace the literal pattern characters. If the + * output string contains the character '|', this is + * taken to indicate the location of the cursor after + * replacement. The cursor is the point in the text at which the + * next replacement, if any, will be applied. The cursor is usually + * placed within the replacement text; however, it can actually be + * placed into the precending or following context by using the + * special character '@'. Examples: + * + *

        + *     a {foo} z > | @ bar; # foo -> bar, move cursor before a
        + *     {foo} xyz > bar @@|; # foo -> bar, cursor between y and z
        + * 
        + * + *

        UnicodeSet + * + *

        UnicodeSet patterns may appear anywhere that + * makes sense. They may appear in variable definitions. + * Contrariwise, UnicodeSet patterns may themselves + * contain variable references, such as "$a=[a-z];$not_a=[^$a]", + * or "$range=a-z;$ll=[$range]". + * + *

        UnicodeSet patterns may also be embedded directly + * into rule strings. Thus, the following two rules are equivalent: + * + *

        + *     $vowel=[aeiou]; $vowel>'*'; # One way to do this
        + *     [aeiou]>'*'; # Another way
        + * 
        + * + *

        See {@link UnicodeSet} for more documentation and examples. + * + *

        Segments + * + *

        Segments of the input string can be matched and copied to the + * output string. This makes certain sets of rules simpler and more + * general, and makes reordering possible. For example: + * + *

        + *     ([a-z]) > $1 $1; # double lowercase letters
        + *     ([:Lu:]) ([:Ll:]) > $2 $1; # reverse order of Lu-Ll pairs
        + * 
        + * + *

        The segment of the input string to be copied is delimited by + * "(" and ")". Up to + * nine segments may be defined. Segments may not overlap. In the + * output string, "$1" through "$9" + * represent the input string segments, in left-to-right order of + * definition. + * + *

        Anchors + * + *

        Patterns can be anchored to the beginning or the end of the text. This is done with the + * special characters '^' and '$'. For example: + * + *

        + *   ^ a   > 'BEG_A';   # match 'a' at start of text
        + *     a   > 'A'; # match other instances of 'a'
        + *     z $ > 'END_Z';   # match 'z' at end of text
        + *     z   > 'Z';       # match other instances of 'z'
        + * 
        + * + *

        It is also possible to match the beginning or the end of the text using a UnicodeSet. + * This is done by including a virtual anchor character '$' at the end of the + * set pattern. Although this is usually the match chafacter for the end anchor, the set will + * match either the beginning or the end of the text, depending on its placement. For + * example: + * + *

        + *   $x = [a-z$];   # match 'a' through 'z' OR anchor
        + *   $x 1    > 2;   # match '1' after a-z or at the start
        + *      3 $x > 4;   # match '3' before a-z or at the end
        + * 
        + * + *

        Example + * + *

        The following example rules illustrate many of the features of + * the rule language. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
        Rule 1.abc{def}>x|y
        Rule 2.xyz>r
        Rule 3.yz>q
        + * + *

        Applying these rules to the string "adefabcdefz" + * yields the following results: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
        |adefabcdefzInitial state, no rules match. Advance + * cursor.
        a|defabcdefzStill no match. Rule 1 does not match + * because the preceding context is not present.
        ad|efabcdefzStill no match. Keep advancing until + * there is a match...
        ade|fabcdefz...
        adef|abcdefz...
        adefa|bcdefz...
        adefab|cdefz...
        adefabc|defzRule 1 matches; replace "def" + * with "xy" and back up the cursor + * to before the 'y'.
        adefabcx|yzAlthough "xyz" is + * present, rule 2 does not match because the cursor is + * before the 'y', not before the 'x'. + * Rule 3 does match. Replace "yz" + * with "q".
        adefabcxq|The cursor is at the end; + * transliteration is complete.
        + * + *

        The order of rules is significant. If multiple rules may match + * at some point, the first matching rule is applied. + * + *

        Forward and reverse rules may have an empty output string. + * Otherwise, an empty left or right hand side of any statement is a + * syntax error. + * + *

        Single quotes are used to quote any character other than a + * digit or letter. To specify a single quote itself, inside or + * outside of quotes, use two single quotes in a row. For example, + * the rule "'>'>o''clock" changes the + * string ">" to the string "o'clock". + * + *

        Notes + * + *

        While a Transliterator is being built from rules, it checks that + * the rules are added in proper order. For example, if the rule + * "a>x" is followed by the rule "ab>y", + * then the second rule will throw an exception. The reason is that + * the second rule can never be triggered, since the first rule + * always matches anything it matches. In other words, the first + * rule masks the second rule. + * * @author Alan Liu * @stable ICU 2.0 */ @@ -497,9 +745,9 @@ class U_I18N_API Transliterator : public UObject { * for details. * @param text the buffer holding transliterated and * untransliterated text - * @param index an array of three integers. See {@link #transliterate(Replaceable&, UTransPosition&, const UnicodeString*, UErrorCode&) const }. + * @param index an array of three integers. * @param status Output param to filled in with a success or an error. - * @see #transliterate(Replaceable, int[], String) + * @see #transliterate(Replaceable&, UTransPosition&, const UnicodeString&, UErrorCode &) const * @stable ICU 2.0 */ virtual void transliterate(Replaceable& text, UTransPosition& index, @@ -630,7 +878,7 @@ class U_I18N_API Transliterator : public UObject { /** * Transliterate a substring of text, as specified by index, taking filters * into account. This method is for subclasses that need to delegate to - * another transliterator, such as CompoundTransliterator. + * another transliterator. * @param text the text to be transliterated * @param index the position indices * @param incremental if TRUE, then assume more characters may be inserted @@ -844,17 +1092,19 @@ class U_I18N_API Transliterator : public UObject { /** * Returns a Transliterator object constructed from - * the given rule string. This will be a RuleBasedTransliterator, + * the given rule string. This will be a rule-based Transliterator, * if the rule string contains only rules, or a - * CompoundTransliterator, if it contains ID blocks, or a - * NullTransliterator, if it contains ID blocks which parse as + * compound Transliterator, if it contains ID blocks, or a + * null Transliterator, if it contains ID blocks which parse as * empty for the given direction. + * * @param ID the id for the transliterator. * @param rules rules, separated by ';' * @param dir either FORWARD or REVERSE. - * @param parseError Struct to recieve information on position + * @param parseError Struct to receive information on position * of error if an error is encountered * @param status Output param set to success/failure code. + * @return a newly created Transliterator * @stable ICU 2.0 */ static Transliterator* U_EXPORT2 createFromRules(const UnicodeString& ID, @@ -1317,7 +1567,7 @@ inline int32_t Transliterator::getMaximumContextLength(void) const { inline void Transliterator::setID(const UnicodeString& id) { ID = id; // NUL-terminate the ID string, which is a non-aliased copy. - ID.append((UChar)0); + ID.append((char16_t)0); ID.truncate(ID.length()-1); } @@ -1336,6 +1586,7 @@ inline Transliterator::Token Transliterator::pointerToken(void* p) { #endif /* U_HIDE_INTERNAL_API */ U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_TRANSLITERATION */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tzfmt.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tzfmt.h index 24f0e49eb7..f0acd9be8f 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tzfmt.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tzfmt.h @@ -1,6 +1,8 @@ +// © 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 +* Copyright (C) 2011-2015, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************************* */ @@ -233,22 +235,20 @@ typedef enum UTimeZoneFormatParseOption { * by other styles. * @stable ICU 50 */ - UTZFMT_PARSE_OPTION_ALL_STYLES = 0x01 -#ifndef U_HIDE_DRAFT_API - , + UTZFMT_PARSE_OPTION_ALL_STYLES = 0x01, /** - * When parsing a time zone display name in UTZFMT_STYLE_SPECIFIC_SHORT, + * When parsing a time zone display name in \link UTZFMT_STYLE_SPECIFIC_SHORT \endlink, * look for the IANA tz database compatible zone abbreviations in addition - * to the localized names coming from the {@link TimeZoneNames} currently - * used by the {@link TimeZoneFormat}. - * @draft ICU 54 + * to the localized names coming from the icu::TimeZoneNames currently + * used by the icu::TimeZoneFormat. + * @stable ICU 54 */ UTZFMT_PARSE_OPTION_TZ_DATABASE_ABBREVIATIONS = 0x02 -#endif /* U_HIDE_DRAFT_API */ } UTimeZoneFormatParseOption; U_CDECL_END +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class TimeZoneGenericNames; @@ -943,7 +943,7 @@ class U_I18N_API TimeZoneFormat : public Format { * @param parsedLen the parsed length, or 0 on failure. * @return the parsed offset in milliseconds. */ - int32_t parseDefaultOffsetFields(const UnicodeString& text, int32_t start, UChar separator, + int32_t parseDefaultOffsetFields(const UnicodeString& text, int32_t start, char16_t separator, int32_t& parsedLen) const; /** @@ -983,7 +983,7 @@ class U_I18N_API TimeZoneFormat : public Format { * @param maxFields The maximum fields * @return The offset string */ - static UnicodeString& formatOffsetWithAsciiDigits(int32_t offset, UChar sep, + static UnicodeString& formatOffsetWithAsciiDigits(int32_t offset, char16_t sep, OffsetFields minFields, OffsetFields maxFields, UnicodeString& result); /** @@ -1013,7 +1013,7 @@ class U_I18N_API TimeZoneFormat : public Format { * @param maxFields The maximum Fields to be parsed * @return Parsed offset, 0 or positive number. */ - static int32_t parseAsciiOffsetFields(const UnicodeString& text, ParsePosition& pos, UChar sep, + static int32_t parseAsciiOffsetFields(const UnicodeString& text, ParsePosition& pos, char16_t sep, OffsetFields minFields, OffsetFields maxFields); /** @@ -1093,6 +1093,7 @@ class U_I18N_API TimeZoneFormat : public Format { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* !UCONFIG_NO_FORMATTING */ #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tznames.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tznames.h index 9583ded022..6078262957 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tznames.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tznames.h @@ -1,6 +1,8 @@ +// © 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 +* Copyright (C) 2011-2016, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************************* */ @@ -69,6 +71,7 @@ typedef enum UTimeZoneNameType { U_CDECL_END +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class UVector; @@ -133,7 +136,7 @@ class U_I18N_API TimeZoneNames : public UObject { 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 @@ -167,7 +170,6 @@ class U_I18N_API TimeZoneNames : public UObject { */ static TimeZoneNames* U_EXPORT2 createInstance(const Locale& locale, UErrorCode& status); -#ifndef U_HIDE_DRAFT_API /** * Returns an instance of TimeZoneNames containing only short specific * zone names (SHORT_STANDARD and SHORT_DAYLIGHT), @@ -176,10 +178,9 @@ class U_I18N_API TimeZoneNames : public UObject { * Note: The input locale is used for resolving ambiguous names (e.g. "IST" is parsed * as Israel Standard Time for Israel, while it is parsed as India Standard Time for * all other regions). The zone names returned by this instance are not localized. - * @draft ICU 54 + * @stable ICU 54 */ static TimeZoneNames* U_EXPORT2 createTZDBInstance(const Locale& locale, UErrorCode& status); -#endif /* U_HIDE_DRAFT_API */ /** * Returns an enumeration of all available meta zone IDs. @@ -290,6 +291,16 @@ class U_I18N_API TimeZoneNames : public UObject { */ virtual UnicodeString& getDisplayName(const UnicodeString& tzID, UTimeZoneNameType type, UDate date, UnicodeString& name) const; + /** + * @internal ICU internal only, for specific users only until proposed publicly. + */ + virtual void loadAllDisplayNames(UErrorCode& status); + + /** + * @internal ICU internal only, for specific users only until proposed publicly. + */ + virtual void getDisplayNames(const UnicodeString& tzID, const UTimeZoneNameType types[], int32_t numTypes, UDate date, UnicodeString dest[], UErrorCode& status) const; + /** * MatchInfoCollection represents a collection of time zone name matches used by * {@link TimeZoneNames#find}. @@ -399,6 +410,7 @@ class U_I18N_API TimeZoneNames : public UObject { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tzrule.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tzrule.h index afa40148d4..88d27e6935 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tzrule.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tzrule.h @@ -1,3 +1,5 @@ +// © 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 * @@ -20,6 +22,7 @@ #include "unicode/unistr.h" #include "unicode/dtrule.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -820,6 +823,7 @@ class U_I18N_API TimeArrayTimeZoneRule : public TimeZoneRule { U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tztrans.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tztrans.h index 94b8e91267..b295741671 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tztrans.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/tztrans.h @@ -1,3 +1,5 @@ +// © 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 * @@ -18,6 +20,7 @@ #include "unicode/uobject.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN // Forward declaration @@ -187,6 +190,7 @@ class U_I18N_API TimeZoneTransition : public UObject { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ualoc.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ualoc.h index ee57e54649..8260c17602 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ualoc.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ualoc.h @@ -263,8 +263,9 @@ ualoc_getAppleParent(const char* localeID, * Unordered array of pointers to identifiers for available * localizations (lprojs); handles old Apple-style * identifiers such as "English", as well as currently- - * superseded identifiers such as "no", "tl". Must not - * be NULL. + * superseded identifiers such as "no", "tl". Must not be + * NULL. Entries with the following values will be ignored: + * NULL, "", "root", any entry beginning with '-' or '_'. * @param availableLocalizationsCount * Count of entries in availableLocalizations. * @param localizationsToUse diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uameasureformat.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uameasureformat.h index 4584f8aa07..7622cd6aa2 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uameasureformat.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uameasureformat.h @@ -1,6 +1,6 @@ /* ***************************************************************************************** -* Copyright (C) 2014-2015 Apple Inc. All Rights Reserved. +* Copyright (C) 2014-2017 Apple Inc. All Rights Reserved. ***************************************************************************************** */ @@ -15,6 +15,7 @@ #include "unicode/localpointer.h" #include "unicode/unum.h" #include "unicode/umisc.h" +#include "unicode/ufieldpositer.h" /** * \file @@ -43,13 +44,13 @@ typedef enum UAMeasureFormatWidth { UAMEASFMT_WIDTH_WIDE, /** - * Abbreviated unit names, e.g. "5 hrs, 37 mins" + * Abbreviated unit names, e.g. "5 hr, 37 min" * @draft ICU 53 */ UAMEASFMT_WIDTH_SHORT, /** - * Use unit symbols if possible, e.g. "5 h, 37 m" + * Use unit symbols if possible, e.g. "5h 37m" * @draft ICU 53 */ UAMEASFMT_WIDTH_NARROW, @@ -60,6 +61,12 @@ typedef enum UAMeasureFormatWidth { */ UAMEASFMT_WIDTH_NUMERIC, + /** + * Shorter, between SHORT and NARROW, e.g. "5hr 37min" + * @draft ICU 57 + */ + UAMEASFMT_WIDTH_SHORTER, + /** * Count of values in this enum. * @draft ICU 53 @@ -79,6 +86,7 @@ typedef enum UAMeasureUnit { UAMEASUNIT_ANGLE_ARC_MINUTE = (1 << 8) + 1, UAMEASUNIT_ANGLE_ARC_SECOND = (1 << 8) + 2, UAMEASUNIT_ANGLE_RADIAN = (1 << 8) + 3, // (CLDR 26, ICU-541) + UAMEASUNIT_ANGLE_REVOLUTION = (1 << 8) + 4, // (CLDR 28, ICU-561.3) // UAMEASUNIT_AREA_SQUARE_METER = (2 << 8) + 0, UAMEASUNIT_AREA_SQUARE_KILOMETER = (2 << 8) + 1, @@ -89,6 +97,7 @@ typedef enum UAMeasureUnit { UAMEASUNIT_AREA_SQUARE_CENTIMETER = (2 << 8) + 6, // (CLDR 26, ICU-541) UAMEASUNIT_AREA_SQUARE_INCH = (2 << 8) + 7, // (CLDR 26, ICU-541) UAMEASUNIT_AREA_SQUARE_YARD = (2 << 8) + 8, // (CLDR 26, ICU-541) + UAMEASUNIT_AREA_DUNAM = (2 << 8) + 9, // (CLDR 35, ICU-641) // // (3 reserved for currency, handled separately) // @@ -102,6 +111,11 @@ typedef enum UAMeasureUnit { UAMEASUNIT_DURATION_MILLISECOND = (4 << 8) + 7, UAMEASUNIT_DURATION_MICROSECOND = (4 << 8) + 8, // (CLDR 26, ICU-541) UAMEASUNIT_DURATION_NANOSECOND = (4 << 8) + 9, // (CLDR 26, ICU-541) + UAMEASUNIT_DURATION_CENTURY = (4 << 8) + 10, // (CLDR 28, ICU-561.3) + UAMEASUNIT_DURATION_YEAR_PERSON = (4 << 8) + 11, // (CLDR 35, ICU-641) + UAMEASUNIT_DURATION_MONTH_PERSON = (4 << 8) + 12, // (CLDR 35, ICU-641) + UAMEASUNIT_DURATION_WEEK_PERSON = (4 << 8) + 13, // (CLDR 35, ICU-641) + UAMEASUNIT_DURATION_DAY_PERSON = (4 << 8) + 14, // (CLDR 35, ICU-641) // UAMEASUNIT_LENGTH_METER = (5 << 8) + 0, UAMEASUNIT_LENGTH_CENTIMETER = (5 << 8) + 1, @@ -121,6 +135,9 @@ typedef enum UAMeasureUnit { UAMEASUNIT_LENGTH_FURLONG = (5 << 8) + 15, // (CLDR 26, ICU-541) UAMEASUNIT_LENGTH_ASTRONOMICAL_UNIT = (5 << 8) + 16, // (CLDR 26, ICU-541) UAMEASUNIT_LENGTH_PARSEC = (5 << 8) + 17, // (CLDR 26, ICU-541) + UAMEASUNIT_LENGTH_MILE_SCANDINAVIAN = (5 << 8) + 18, // (CLDR 28, ICU-561.3) + UAMEASUNIT_LENGTH_POINT = (5 << 8) + 19, // (CLDR 31, ICU-590) + UAMEASUNIT_LENGTH_SOLAR_RADIUS = (5 << 8) + 20, // (CLDR 35, ICU-641) // UAMEASUNIT_MASS_GRAM = (6 << 8) + 0, UAMEASUNIT_MASS_KILOGRAM = (6 << 8) + 1, @@ -133,6 +150,9 @@ typedef enum UAMeasureUnit { UAMEASUNIT_MASS_TON = (6 << 8) + 8, // = "short ton", U.S. ton (CLDR 26, ICU-541) UAMEASUNIT_MASS_CARAT = (6 << 8) + 9, // (CLDR 26, ICU-541) UAMEASUNIT_MASS_OUNCE_TROY = (6 << 8) + 10, // (CLDR 26, ICU-541) + UAMEASUNIT_MASS_DALTON = (6 << 8) + 11, // (CLDR 35, ICU-641) + UAMEASUNIT_MASS_EARTH_MASS = (6 << 8) + 12, // (CLDR 35, ICU-641) + UAMEASUNIT_MASS_SOLAR_MASS = (6 << 8) + 13, // (CLDR 35, ICU-641) // UAMEASUNIT_POWER_WATT = (7 << 8) + 0, UAMEASUNIT_POWER_KILOWATT = (7 << 8) + 1, @@ -146,10 +166,14 @@ typedef enum UAMeasureUnit { UAMEASUNIT_PRESSURE_MILLIBAR = (8 << 8) + 2, UAMEASUNIT_PRESSURE_MILLIMETER_OF_MERCURY = (8 << 8) + 3, // (CLDR 26, ICU-541) UAMEASUNIT_PRESSURE_POUND_PER_SQUARE_INCH = (8 << 8) + 4, // (CLDR 26, ICU-541) + UAMEASUNIT_PRESSURE_ATMOSPHERE = (8 << 8) + 5, // (CLDR 34, ICU-631) + UAMEASUNIT_PRESSURE_KILOPASCAL = (8 << 8) + 6, // (CLDR 35, ICU-641) + UAMEASUNIT_PRESSURE_MEGAPASCAL = (8 << 8) + 7, // (CLDR 35, ICU-641) // UAMEASUNIT_SPEED_METER_PER_SECOND = (9 << 8) + 0, UAMEASUNIT_SPEED_KILOMETER_PER_HOUR = (9 << 8) + 1, UAMEASUNIT_SPEED_MILE_PER_HOUR = (9 << 8) + 2, + UAMEASUNIT_SPEED_KNOT = (9 << 8) + 3, // (CLDR 28, ICU-561.3) // UAMEASUNIT_TEMPERATURE_CELSIUS = (10 << 8) + 0, UAMEASUNIT_TEMPERATURE_FAHRENHEIT = (10 << 8) + 1, @@ -178,6 +202,11 @@ typedef enum UAMeasureUnit { UAMEASUNIT_VOLUME_PINT = (11 << 8) + 19, // (CLDR 26, ICU-541) UAMEASUNIT_VOLUME_QUART = (11 << 8) + 20, // (CLDR 26, ICU-541) UAMEASUNIT_VOLUME_GALLON = (11 << 8) + 21, // (CLDR 26, ICU-541) + UAMEASUNIT_VOLUME_CUP_METRIC = (11 << 8) + 22, // (CLDR 28, ICU-561.3) + UAMEASUNIT_VOLUME_PINT_METRIC = (11 << 8) + 23, // (CLDR 28, ICU-561.3) + UAMEASUNIT_VOLUME_GALLON_IMPERIAL = (11 << 8) + 24, // (CLDR 29, ICU-561.8+) + UAMEASUNIT_VOLUME_FLUID_OUNCE_IMPERIAL = (11 << 8) + 25, // (CLDR 35, ICU-641) + UAMEASUNIT_VOLUME_BARREL = (11 << 8) + 26, // (CLDR 35, ICU-641) // // new categories/values in CLDR 26 // @@ -187,11 +216,15 @@ typedef enum UAMeasureUnit { UAMEASUNIT_ENERGY_KILOCALORIE = (12 << 8) + 3, // kilocalories in general (chemistry, food), abbr "kcal" UAMEASUNIT_ENERGY_FOODCALORIE = (12 << 8) + 1, // kilocalories specifically for food; in US/UK/? "Calories" abbr "C", elsewhere same as "kcal" UAMEASUNIT_ENERGY_KILOWATT_HOUR = (12 << 8) + 5, // (ICU-541) + UAMEASUNIT_ENERGY_ELECTRONVOLT = (12 << 8) + 6, // (CLDR 35, ICU-641) + UAMEASUNIT_ENERGY_BRITISH_THERMAL_UNIT = (12 << 8) + 7, // (CLDR 35, ICU-641) // // new categories/values in CLDR 26 & ICU-541 // UAMEASUNIT_CONSUMPTION_LITER_PER_KILOMETER = (13 << 8) + 0, UAMEASUNIT_CONSUMPTION_MILE_PER_GALLON = (13 << 8) + 1, + UAMEASUNIT_CONSUMPTION_LITER_PER_100_KILOMETERs = (13 << 8) + 2, // (CLDR 28, ICU-561.3) + UAMEASUNIT_CONSUMPTION_MILE_PER_GALLON_IMPERIAL = (13 << 8) + 3, // (CLDR 29, ICU-561.8+) // UAMEASUNIT_DIGITAL_BIT = (14 << 8) + 0, UAMEASUNIT_DIGITAL_BYTE = (14 << 8) + 1, @@ -203,6 +236,7 @@ typedef enum UAMeasureUnit { UAMEASUNIT_DIGITAL_MEGABYTE = (14 << 8) + 7, UAMEASUNIT_DIGITAL_TERABIT = (14 << 8) + 8, UAMEASUNIT_DIGITAL_TERABYTE = (14 << 8) + 9, + UAMEASUNIT_DIGITAL_PETABYTE = (14 << 8) + 10, // (CLDR 34, ICU-631) // UAMEASUNIT_ELECTRIC_AMPERE = (15 << 8) + 0, UAMEASUNIT_ELECTRIC_MILLIAMPERE = (15 << 8) + 1, @@ -215,10 +249,35 @@ typedef enum UAMeasureUnit { UAMEASUNIT_FREQUENCY_GIGAHERTZ = (16 << 8) + 3, // UAMEASUNIT_LIGHT_LUX = (17 << 8) + 0, + UAMEASUNIT_LIGHT_SOLAR_LUMINOSITY = (17 << 8) + 1, // (CLDR 35, ICU-641) + // + // new categories/values in CLDR 29, ICU-561.8+ + // + UAMEASUNIT_CONCENTRATION_KARAT = (18 << 8) + 0, // (CLDR 29, ICU-561.8+) + UAMEASUNIT_CONCENTRATION_MILLIGRAM_PER_DECILITER = (18 << 8) + 1, // (CLDR 29, ICU-561.8+) + UAMEASUNIT_CONCENTRATION_MILLIMOLE_PER_LITER = (18 << 8) + 2, // (CLDR 29, ICU-561.8+) + UAMEASUNIT_CONCENTRATION_PART_PER_MILLION = (18 << 8) + 3, // (CLDR 29, ICU-561.8+) + UAMEASUNIT_CONCENTRATION_PERCENT = (18 << 8) + 4, // (CLDR 34, ICU-631nn) + UAMEASUNIT_CONCENTRATION_PERMILLE = (18 << 8) + 5, // (CLDR 34, ICU-631nn) + UAMEASUNIT_CONCENTRATION_PERMYRIAD = (18 << 8) + 6, // (CLDR 35, ICU-641) + UAMEASUNIT_CONCENTRATION_MOLE = (18 << 8) + 7, // (CLDR 35, ICU-641) + // + // new categories/values in CLDR 35, ICU-641+ + // + UAMEASUNIT_FORCE_NEWTON = (19 << 8) + 0, // (CLDR 35, ICU-641) + UAMEASUNIT_FORCE_POUND_FORCE = (19 << 8) + 1, // (CLDR 35, ICU-641) + // + UAMEASUNIT_TORQUE_NEWTON_METER = (20 << 8) + 0, // (CLDR 35, ICU-641) + UAMEASUNIT_TORQUE_POUND_FOOT = (20 << 8) + 1, // (CLDR 35, ICU-641) // - //UAMEASUNIT_PROPORTION_KARAT = (18 << 8) + 0, // wait on this one } UAMeasureUnit; +enum { + // Mask bit set in UFieldPosition, in addition to a UAMeasureUnit value, + // to indicate the numeric portion of the field corresponding to the UAMeasureUnit. + UAMEASFMT_NUMERIC_FIELD_FLAG = (1 << 30) +}; + /** * Structure that combines value and UAMeasureUnit, * for use with uameasfmt_formatMultiple to specify a @@ -236,9 +295,11 @@ typedef struct UAMeasure { * along with a number formatter (if desired) to override the default formatter * that would be used for the numeric part of the unit in uameasfmt_format, or the * numeric part of the *last unit* (only) in uameasfmt_formatMultiple. The default - * formatter uses zero decimal places and rounds toward 0; an alternate number formatter - * can be used to produce (e.g.) "37.2 mins" instead of "37 mins", or - * "5 hours, 37.2 minutes" instead of "5 hours, 37 minutes". + * formatter typically rounds toward 0 and has a minimum of 0 fraction digits and a + * maximum of 3 fraction digits (i.e. it will show as many decimal places as + * necessary up to 3, without showing trailing 0s). An alternate number formatter + * can be used to produce (e.g.) "37.0 mins" instead of "37 mins", or + * "5 hours, 37.2 minutes" instead of "5 hours, 37.217 minutes". * * @param locale * The locale @@ -292,7 +353,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUAMeasureFormatPointer, UAMeasureFormat, uameas U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** @@ -398,6 +459,224 @@ uameasfmt_formatMultiple( const UAMeasureFormat* measfmt, int32_t resultCapacity, UErrorCode* status ); +/** + * Format a list of value and unit combinations, using locale-appropriate + * conventions for the list. This has the same format behavior as + * uameasfmt_formatMultiple but adds the fpositer parameter. + * + * @param measfmt + * The UAMeasureFormat object specifying the format conventions. + * @param measures + * A list of UAMeasure structs each specifying a numeric value + * and a UAMeasureUnit. + * @param measureCount + * The count of UAMeasureUnits in measures. Currently this has a limit of 8. + * @param result + * A pointer to a buffer to receive the formatted result. + * @param resultCapacity + * The maximum size of result. + * @param fpositer + * A pointer to a UFieldPositionIterator created by ufieldpositer_open + * (may be NULL if field position information is not needed). Any + * iteration information already present in the UFieldPositionIterator + * will be deleted, and the iterator will be reset to apply to the + * fields in the formatted string created by this function call. In the + * the formatted result, each unit field (unit name or symbol plus any + * associated numeric value) will correspond to one or two results from + * ufieldpositer_next. The first result returns a UAMeasureUnit value and + * indicates the begin and end index for the complete field. If there is + * a numeric value contained in the field, then a subsequent call to + * ufieldpositer_next returns a value with UAMEASFMT_NUMERIC_FIELD_FLAG + * set and the same UAMeasureUnit value in the low-order bits, and + * indicates the begin and end index for the numeric portion of the field. + * For example with the string "3 hours, dualminute" the sequence of + * calls to ufieldpositer_next would result in: + * (1) return UAMEASUNIT_DURATION_HOUR, begin index 0, end index 7 + * (2) return UAMEASUNIT_DURATION_HOUR | UAMEASFMT_NUMERIC_FIELD_FLAG, begin index 0, end index 1 + * (3) return UAMEASUNIT_DURATION_MINUTE, begin index 9, end index 19 + * (4) return -1 to indicate end of interation + * @param status + * A pointer to a UErrorCode to receive any errors. In case of error status, + * the contents of result are undefined. + * @return + * The length of the formatted result; may be greater than resultCapacity, + * in which case an error is returned. + * @draft ICU 58 + */ +U_DRAFT int32_t U_EXPORT2 +uameasfmt_formatMultipleForFields( const UAMeasureFormat* measfmt, + const UAMeasure* measures, + int32_t measureCount, + UChar* result, + int32_t resultCapacity, + UFieldPositionIterator* fpositer, + UErrorCode* status ); + +/** + * Get the display name for a unit, such as "minutes" or "kilometers". + * + * @param measfmt + * The UAMeasureFormat object specifying the format conventions. + * @param unit + * The unit whose localized name to get + * @param result + * A pointer to a buffer to receive the name. + * @param resultCapacity + * The maximum size of result. + * @param status + * A pointer to a UErrorCode to receive any errors. In case of error status, + * the contents of result are undefined. + * @return + * The length of the name; may be greater than resultCapacity, + * in which case an error is returned. + * @draft ICU 57 + */ +U_DRAFT int32_t U_EXPORT2 +uameasfmt_getUnitName( const UAMeasureFormat* measfmt, + UAMeasureUnit unit, + UChar* result, + int32_t resultCapacity, + UErrorCode* status ); + +/** + * Constants for unit display name list styles + * @draft ICU 57 + */ +typedef enum UAMeasureNameListStyle { + /** + * Use standard (linguistic) list style, the same for all unit widths; e.g. + * wide: "hours, minutes, and seconds" + * short: "hours, min, and secs" + * narrow: "hour, min, and sec" + * @draft ICU 57 + */ + UAMEASNAME_LIST_STANDARD, + + /** + * Use the same list style as used by the formatted units, depends on width; e.g. + * wide: "hours, minutes, seconds" + * short: "hours, min, secs" + * narrow: "hour min sec" + * @draft ICU 57 + */ + UAMEASNAME_LIST_MATCHUNITS, +} UAMeasureNameListStyle; + +/** + * Get a list of display names for multiple units + * + * @param measfmt + * The UAMeasureFormat object specifying the format conventions. + * @param units + * The array of unit types whose names to get. + * @param unitCount + * The number of unit types in the units array. + * @param listStyle + * The list style used for combining the unit names. + * @param result + * A pointer to a buffer to receive the list of names. + * @param resultCapacity + * The maximum size of result. + * @param status + * A pointer to a UErrorCode to receive any errors. In case of error status, + * the contents of result are undefined. + * @return + * The length of the list of names; may be greater than resultCapacity, + * in which case an error is returned. + * @draft ICU 57 + */ +U_DRAFT int32_t U_EXPORT2 +uameasfmt_getMultipleUnitNames( const UAMeasureFormat* measfmt, + const UAMeasureUnit* units, + int32_t unitCount, + UAMeasureNameListStyle listStyle, + UChar* result, + int32_t resultCapacity, + UErrorCode* status ); + +/** + * Get the units used for a particular usage. This low-level function depends + * one some knowledge of the relevant CLDR keys. After more experience with + * usage, enums for relevant usage values may be created. + * + * This is sensitive to two locale keywords. + * If the "ms" keyword is present, then the measurement system specified by its + * value is used (except for certain categories like duration and concentr). + * Else if the "rg" keyword is present, then the region specified by its value + * determines the unit usage. + * Else if the locale has a region subtag, it determines the unit usage. + * Otherwise the likely region for the language determines the usage. + * + * @param locale + * The locale, which determines the usage as specified above. + * @param category + * A string representing the CLDR category key for the desired usage, + * such as "length" or "mass". Must not be NULL. + * @param usage + * A string representing the CLDR usage subkey for the desired usage, + * such as "person", "person-small" (for infants), "person-informal" + * (for conversational/informal usage), etc. To get the general unit + * for the category (not for a specific usage), this may be NULL, or + * may be just "large" or "small" to indicate a variant of the general + * unit for larger or smaller ranges than normal. + * @param units + * Array to be filled in with UAMeasureUnit values; the size is + * specified by unitsCapacity (which in general should be at least 3). + * The number of array elements actually filled in is indicated by + * the return value; if no error status is set then this will be + * non-zero. + * + * If the return value is positive then units represents an ordered + * list of one or more units that should be used in combination for + * the desired usage (e.g. the values UAMEASUNIT_LENGTH_FOOT, + * UAMEASUNIT_LENGTH_INCH to indicate a height expressed as a + * combination of feet and inches, or just UAMEASUNIT_LENGTH_CENTIMETER + * to indicate height expressed in centimeters alone). + * + * Negative return values may be used for future uses (such as + * indicating an X-per-Y relationship among the returned units). + * + * The units parameter may be NULL if unitsCapacity is 0, for + * pre-flighting (i.e. to determine the size of the units array that + * woud be required for the given category and usage). + * @param unitsCapacity + * The maximum capacity of the passed-in units array. + * @param status + * A pointer to a UErrorCode to receive any errors. In case of error status, + * the contents of result are undefined. + * @return + * Positive values indicate the number of units require for the usage; + * may be greater than resultCapacity, in which case an error is returned. + * If no error, than this number of units are actually provided in the + * units array. Negative return values are reserved for future uses. + * @draft ICU 57 + */ +U_DRAFT int32_t U_EXPORT2 +uameasfmt_getUnitsForUsage( const char* locale, + const char* category, + const char* usage, + UAMeasureUnit* units, + int32_t unitsCapacity, + UErrorCode* status ); + +/** + * Get the (non-localized) category name for a unit. For example, for + * UAMEASUNIT_VOLUME_LITER, returns "volume". + * + * @param unit + * The unit whose category name to get + * @param status + * A pointer to a UErrorCode to receive any errors. In case of error status, + * the return value is undefined. + * @return + * Pointer to a zero-terminated string giving the + * (non-localized) category name. + * @draft ICU 58 + */ +U_DRAFT const char * U_EXPORT2 +uameasfmt_getUnitCategory(UAMeasureUnit unit, + UErrorCode* status ); + #endif /* U_HIDE_DRAFT_API */ #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uatimeunitformat.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uatimeunitformat.h index a42e84cb8d..cdecd3630f 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uatimeunitformat.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uatimeunitformat.h @@ -46,6 +46,10 @@ typedef enum UATimeUnitStyle { * narrow style, e.g. "1.0 m" * @draft ICU 53 */ UATIMEUNITSTYLE_NARROW, + /** + * shorter style,between abbreviated and narrow" + * @draft ICU 57 */ + UATIMEUNITSTYLE_SHORTER, /** @draft ICU 53 */ UATIMEUNITSTYLE_COUNT } UATimeUnitStyle; @@ -69,8 +73,16 @@ typedef enum UATimeUnitField { UATIMEUNITFIELD_MINUTE, /** @draft ICU 53 */ UATIMEUNITFIELD_SECOND, - /** @draft ICU 53 */ + /** @draft ICU 63 */ + UATIMEUNITFIELD_MILLISECOND, + /** @draft ICU 63 */ + UATIMEUNITFIELD_MICROSECOND, + /** @draft ICU 63 */ + UATIMEUNITFIELD_NANOSECOND, +#ifndef U_HIDE_DEPRECATED_API + /** @deprecated The numeric value may change over time */ UATIMEUNITFIELD_COUNT +#endif /* U_HIDE_DEPRECATED_API */ } UATimeUnitField; /** @@ -149,7 +161,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUATimeUnitFormatPointer, UATimeUnitFormat, uatm U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ubidi.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ubidi.h index 27042ed7f4..53bd843444 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ubidi.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ubidi.h @@ -1,12 +1,14 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * -* Copyright (C) 1999-2013, International Business Machines +* Copyright (C) 1999-2015, International Business Machines * Corporation and others. All Rights Reserved. * ****************************************************************************** * file name: ubidi.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -321,6 +323,10 @@ * these special values are designed that way. Also, the implementation * assumes that UBIDI_MAX_EXPLICIT_LEVEL is odd. * + * Note: The numeric values of the related constants will not change: + * They are tied to the use of 7-bit byte values (plus the override bit) + * and of the UBiDiLevel=uint8_t data type in this API. + * * @see UBIDI_DEFAULT_LTR * @see UBIDI_DEFAULT_RTL * @see UBIDI_LEVEL_OVERRIDE @@ -384,6 +390,8 @@ typedef uint8_t UBiDiLevel; /** * Maximum explicit embedding level. + * Same as the max_depth value in the + * Unicode Bidirectional Algorithm. * (The maximum resolved level can be up to UBIDI_MAX_EXPLICIT_LEVEL+1). * @stable ICU 2.0 */ @@ -568,7 +576,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUBiDiPointer, UBiDi, ubidi_close); U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Modify the operation of the Bidi algorithm such that it @@ -690,7 +698,7 @@ typedef enum UBiDiReorderingMode { * @stable ICU 3.6 */ UBIDI_REORDER_DEFAULT = 0, /** Logical to Visual algorithm which handles numbers in a way which - * mimicks the behavior of Windows XP. + * mimics the behavior of Windows XP. * @stable ICU 3.6 */ UBIDI_REORDER_NUMBERS_SPECIAL, /** Logical to Visual algorithm grouping numbers with adjacent R characters @@ -718,9 +726,13 @@ typedef enum UBiDiReorderingMode { * UBIDI_REORDER_NUMBERS_SPECIAL Bidi algorithm. * @stable ICU 3.6 */ UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL, - /** Number of values for reordering mode. - * @stable ICU 3.6 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * Number of values for reordering mode. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UBIDI_REORDER_COUNT +#endif // U_HIDE_DEPRECATED_API } UBiDiReorderingMode; /** @@ -1136,9 +1148,9 @@ ubidi_setContext(UBiDi *pBiDi, /** * Perform the Unicode Bidi algorithm. It is defined in the - * Unicode Standard Anned #9, - * version 13, - * also described in The Unicode Standard, Version 4.0 .

        + * Unicode Standard Annex #9, + * Unicode 8.0.0 / revision 33, + * also described in The Unicode Standard, Version 8.0 .

        * * This function takes a piece of plain text containing one or more paragraphs, * with or without externally specified embedding levels from styled @@ -1190,11 +1202,14 @@ ubidi_setContext(UBiDi *pBiDi, * A level overrides the directional property of its corresponding * (same index) character if the level has the * #UBIDI_LEVEL_OVERRIDE bit set.

        - * Except for that bit, it must be + * Aside from that bit, it must be * paraLevel<=embeddingLevels[]<=UBIDI_MAX_EXPLICIT_LEVEL, - * with one exception: a level of zero may be specified for a paragraph - * separator even if paraLevel>0 when multiple paragraphs - * are submitted in the same call to ubidi_setPara().

        + * except that level 0 is always allowed. + * Level 0 for a paragraph separator prevents reordering of paragraphs; + * this only works reliably if #UBIDI_LEVEL_OVERRIDE + * is also set for paragraph separators. + * Level 0 for other characters is treated as a wildcard + * and is lifted up to the resolved level of the surrounding paragraph.

        * Caution: A copy of this pointer, not of the levels, * will be stored in the UBiDi object; * the embeddingLevels array must not be @@ -1218,6 +1233,159 @@ ubidi_setPara(UBiDi *pBiDi, const UChar *text, int32_t length, UBiDiLevel paraLevel, UBiDiLevel *embeddingLevels, UErrorCode *pErrorCode); +#ifndef U_HIDE_INTERNAL_API +/** + * Perform the Unicode Bidi algorithm. It is defined in the + * Unicode Standard Annex #9, + * Unicode 8.0.0 / revision 33, + * also described in The Unicode Standard, Version 8.0 .

        + * + * This function takes a piece of plain text containing one or more paragraphs, + * with or without externally specified direction overrides (in the form of + * sequences of one or more bidi control characters for + * embeddings/overrides/isolates to be effectively inserted at specified points + * in the text), and computes the left-right-directionality of each character. + * Note that ubidi_setContext may be used to set the context before or after the + * text passed to ubidi_setPara, so ubidi_setParaWithControls is only needed if + * externally specified direction overrides need to be effectively inserted at + * other locations in the text.

        + * + * Note: Currently the external specified direction overrides are only supported + * for the Logical to Visual values of UBiDiReorderingMode: UBIDI_REORDER_DEFAULT, + * UBIDI_REORDER_NUMBERS_SPECIAL, UBIDI_REORDER_GROUP_NUMBERS_WITH_R. With other + * UBiDiReorderingMode settings, this function behaves as if offsetCount is 0.

        + * + * If the entire text is all of the same directionality, then the function may + * not perform all the steps described by the algorithm, i.e., some levels may + * not be the same as if all steps were performed. This is not relevant for + * unidirectional text.
        + * For example, in pure LTR text with numbers the numbers would get a resolved + * level of 2 higher than the surrounding text according to the algorithm. This + * implementation may set all resolved levels to the same value in such a case.

        + * + * The text can be composed of multiple paragraphs. Occurrence of a block + * separator in the text terminates a paragraph, and whatever comes next starts + * a new paragraph. The exception to this rule is when a Carriage Return (CR) + * is followed by a Line Feed (LF). Both CR and LF are block separators, but + * in that case, the pair of characters is considered as terminating the + * preceding paragraph, and a new paragraph will be started by a character + * coming after the LF.

        + * + * @param pBiDi A UBiDi object allocated with ubidi_open() + * which will be set to contain the reordering information, + * especially the resolved levels for all the characters in text. + * + * @param text is a pointer to the text that the Bidi algorithm will be performed on. + * This pointer is stored in the UBiDi object and can be retrieved + * with ubidi_getText().
        + * Note: the text must be (at least) length long. + * + * @param length is the length of the text; if length==-1 then + * the text must be zero-terminated. + * + * @param paraLevel specifies the default level for the text; + * it is typically 0 (LTR) or 1 (RTL). + * If the function shall determine the paragraph level from the text, + * then paraLevel can be set to + * either #UBIDI_DEFAULT_LTR + * or #UBIDI_DEFAULT_RTL; if the text contains multiple + * paragraphs, the paragraph level shall be determined separately for + * each paragraph; if a paragraph does not include any strongly typed + * character, then the desired default is used (0 for LTR or 1 for RTL). + * Any other value between 0 and #UBIDI_MAX_EXPLICIT_LEVEL + * is also valid, with odd levels indicating RTL. + * + * @param offsets Array of text offsets at which sequences of one or more + * bidi controls are to be effectively inserted. The offset values must + * be >= 0 and < length (use ubidi_setContext + * to provide the effect of inserting controls after the last character + * of the text). This must be non-NULL if offsetCount > 0. + * + * @param offsetCount The number of entries in the offsets array, and in the + * controlStringIndices array if the latter is present (non NULL). If + * offsetCount is 0, then no controls will be inserted and + * the parameters offsets, controlStringIndices + * and controlStrings will be ignored. + * + * @param controlStringIndices If not NULL, this array must have the same + * number of entries as the offsets array; each entry in this array + * maps from the corresponding offset to the index in controlStrings + * of the control sequence that is to be effectively inserted at that + * offset. This indirection is useful when certain control sequences + * are to be effectively inserted in many different places in the text. + * If this array is NULL, then the entries in controlStrings correspond + * directly to the entries in the offsets array. + * + * @param controlStrings Array of const pointers to zero-terminated + * const UChar strings each consisting of zero or more characters that + * are bidi controls for embeddings, overrides, or isolates (see list + * below). Other characters that might be supported in the future + * (depending on need) include bidi marks an characters with + * bidi class B (block separator) or class S (segment separator). + * The characters in these strings only affect the bidi levels assigned + * to the characters in he text array, they are not used for any other + * purpose.
        + * If controlStringIndices is NULL, then controlStrings must have the + * same number of entries as the offsets array, and each entry provides + * the UChar string that is effectively inserted at the corresponding + * offset. If controlStringIndices is not NULL, then controlStrings must + * have at least enough entries to accommodate to all of the index values + * in the controlStringIndices array. This must be non-NULL if + * offsetCount > 0.
        + * Current limitations:
        + * Each zero-terminated const UChar string is limited a maximum length + * of 4, not including the zero terminator.
        + * Each zero-terminated const UChar string may contain at most one + * instance of FSI, LRI, or RLI.
        + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @discussion + *

        + * Supported bidi controls for embeddings / overrides / isolates as of Unicode 8.0:
        + *   LRE   U+202A   LEFT-TO-RIGHT EMBEDDING
        + *   RLE   U+202B   RIGHT-TO-LEFT EMBEDDING
        + *   PDF   U+202C   POP DIRECTIONAL FORMATTING
        + *   LRO   U+202D   LEFT-TO-RIGHT OVERRIDE
        + *   RLO   U+202E   RIGHT-TO-LEFT OVERRIDE
        + *   #
        + *   LRI   U+2066   LEFT‑TO‑RIGHT ISOLATE
        + *   RLI   U+2067   RIGHT‑TO‑LEFT ISOLATE
        + *   FSI   U+2068   FIRST STRONG ISOLATE
        + *   PDI   U+2069   POP DIRECTIONAL ISOLATE
        + *
        + * Bidi marks as of Unicode 8.0:
        + *   ALM   U+061C   ARABIC LETTER MARK (bidi class AL)
        + *   LRM   U+200E   LEFT-TO-RIGHT MARK (bidi class L)
        + *   RLM   U+200F   RIGHT-TO-LEFT MARK (bidi class R)
        + * Characters with bidi class B (block separator) as of Unicode 8.0:
        + *   B     U+000A   LINE FEED (LF)
        + *   B     U+000D   CARRIAGE RETURN (CR)
        + *   B     U+001C   INFORMATION SEPARATOR FOUR
        + *   B     U+001D   INFORMATION SEPARATOR THREE
        + *   B     U+001E   INFORMATION SEPARATOR TWO
        + *   B     U+0085   NEXT LINE (NEL)
        + *   B     U+2029   PARAGRAPH SEPARATOR
        + * Characters with bidi class S (segment separator) as of Unicode 8.0:
        + *   S     U+0009   CHARACTER TABULATION
        + *   S     U+000B   LINE TABULATION
        + *   S     U+001F   INFORMATION SEPARATOR ONE
        + * 
        + * + * @see ubidi_setContext + * @internal technology preview as of ICU 57 + */ +U_INTERNAL void U_EXPORT2 +ubidi_setParaWithControls(UBiDi *pBiDi, + const UChar *text, int32_t length, + UBiDiLevel paraLevel, + const int32_t *offsets, int32_t offsetCount, + const int32_t *controlStringIndices, + const UChar * const * controlStrings, + UErrorCode *pErrorCode); + +#endif /* U_HIDE_INTERNAL_API */ + /** * ubidi_setLine() sets a UBiDi to * contain the reordering information, especially the resolved levels, @@ -1959,13 +2127,19 @@ U_STABLE int32_t U_EXPORT2 ubidi_getResultLength(const UBiDi *pBiDi); U_CDECL_BEGIN + +#ifndef U_HIDE_DEPRECATED_API /** - * value returned by UBiDiClassCallback callbacks when + * Value returned by UBiDiClassCallback callbacks when * there is no need to override the standard Bidi class for a given code point. + * + * This constant is deprecated; use u_getIntPropertyMaxValue(UCHAR_BIDI_CLASS)+1 instead. + * * @see UBiDiClassCallback - * @stable ICU 3.6 + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ #define U_BIDI_CLASS_DEFAULT U_CHAR_DIRECTION_COUNT +#endif // U_HIDE_DEPRECATED_API /** * Callback type declaration for overriding default Bidi class values with @@ -1981,8 +2155,8 @@ U_CDECL_BEGIN * * @return The directional property / Bidi class for the given code point * c if the default class has been overridden, or - * #U_BIDI_CLASS_DEFAULT if the standard Bidi class value - * for c is to be used. + * u_getIntPropertyMaxValue(UCHAR_BIDI_CLASS)+1 + * if the standard Bidi class value for c is to be used. * @see ubidi_setClassCallback * @see ubidi_getClassCallback * @stable ICU 3.6 @@ -1995,8 +2169,8 @@ U_CDECL_END /** * Retrieve the Bidi class for a given code point. *

        If a #UBiDiClassCallback callback is defined and returns a - * value other than #U_BIDI_CLASS_DEFAULT, that value is used; - * otherwise the default class determination mechanism is invoked.

        + * value other than u_getIntPropertyMaxValue(UCHAR_BIDI_CLASS)+1, + * that value is used; otherwise the default class determination mechanism is invoked.

        * * @param pBiDi is the paragraph UBiDi object. * diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ubiditransform.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ubiditransform.h new file mode 100644 index 0000000000..7c58f768f3 --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ubiditransform.h @@ -0,0 +1,323 @@ +/* +****************************************************************************** +* +* © 2016 and later: Unicode, Inc. and others. +* License & terms of use: http://www.unicode.org/copyright.html +* +****************************************************************************** +* file name: ubiditransform.h +* encoding: UTF-8 +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2016jul24 +* created by: Lina Kemmel +* +*/ + +#ifndef UBIDITRANSFORM_H +#define UBIDITRANSFORM_H + +#include "unicode/utypes.h" +#include "unicode/ubidi.h" +#include "unicode/uchar.h" +#include "unicode/localpointer.h" + +/** + * \file + * \brief Bidi Transformations + */ + +/** + * `UBiDiOrder` indicates the order of text. + * + * This bidi transformation engine supports all possible combinations (4 in + * total) of input and output text order: + * + * - : unless the output direction is RTL, this + * corresponds to a normal operation of the Bidi algorithm as described in the + * Unicode Technical Report and implemented by `UBiDi` when the + * reordering mode is set to `UBIDI_REORDER_DEFAULT`. Visual RTL + * mode is not supported by `UBiDi` and is accomplished through + * reversing a visual LTR string, + * + * - : unless the input direction is RTL, this + * corresponds to an "inverse bidi algorithm" in `UBiDi` with the + * reordering mode set to `UBIDI_REORDER_INVERSE_LIKE_DIRECT`. + * Visual RTL mode is not not supported by `UBiDi` and is + * accomplished through reversing a visual LTR string, + * + * - : if the input and output base directions + * mismatch, this corresponds to the `UBiDi` implementation with the + * reordering mode set to `UBIDI_REORDER_RUNS_ONLY`; and if the + * input and output base directions are identical, the transformation engine + * will only handle character mirroring and Arabic shaping operations without + * reordering, + * + * - : this reordering mode is not supported by + * the `UBiDi` engine; it implies character mirroring, Arabic + * shaping, and - if the input/output base directions mismatch - string + * reverse operations. + * @see ubidi_setInverse + * @see ubidi_setReorderingMode + * @see UBIDI_REORDER_DEFAULT + * @see UBIDI_REORDER_INVERSE_LIKE_DIRECT + * @see UBIDI_REORDER_RUNS_ONLY + * @stable ICU 58 + */ +typedef enum { + /** 0: Constant indicating a logical order. + * This is the default for input text. + * @stable ICU 58 + */ + UBIDI_LOGICAL = 0, + /** 1: Constant indicating a visual order. + * This is a default for output text. + * @stable ICU 58 + */ + UBIDI_VISUAL +} UBiDiOrder; + +/** + * UBiDiMirroring indicates whether or not characters with the + * "mirrored" property in RTL runs should be replaced with their mirror-image + * counterparts. + * @see UBIDI_DO_MIRRORING + * @see ubidi_setReorderingOptions + * @see ubidi_writeReordered + * @see ubidi_writeReverse + * @stable ICU 58 + */ +typedef enum { + /** 0: Constant indicating that character mirroring should not be + * performed. + * This is the default. + * @stable ICU 58 + */ + UBIDI_MIRRORING_OFF = 0, + /** 1: Constant indicating that character mirroring should be performed. + * This corresponds to calling ubidi_writeReordered or + * ubidi_writeReverse with the + * UBIDI_DO_MIRRORING option bit set. + * @stable ICU 58 + */ + UBIDI_MIRRORING_ON +} UBiDiMirroring; + +/** + * Forward declaration of the UBiDiTransform structure that stores + * information used by the layout transformation engine. + * @stable ICU 58 + */ +typedef struct UBiDiTransform UBiDiTransform; + +/** + * Performs transformation of text from the bidi layout defined by the input + * ordering scheme to the bidi layout defined by the output ordering scheme, + * and applies character mirroring and Arabic shaping operations.

        + * In terms of UBiDi, such a transformation implies: + *

          + *
        • calling ubidi_setReorderingMode as needed (when the + * reordering mode is other than normal),
        • + *
        • calling ubidi_setInverse as needed (when text should be + * transformed from a visual to a logical form),
        • + *
        • resolving embedding levels of each character in the input text by + * calling ubidi_setPara,
        • + *
        • reordering the characters based on the computed embedding levels, also + * performing character mirroring as needed, and streaming the result to the + * output, by calling ubidi_writeReordered,
        • + *
        • performing Arabic digit and letter shaping on the output text by calling + * u_shapeArabic.
        • + *
        + * An "ordering scheme" encompasses the base direction and the order of text, + * and these characteristics must be defined by the caller for both input and + * output explicitly .

        + * There are 36 possible combinations of ordering schemes, + * which are partially supported by UBiDi already. Examples of the + * currently supported combinations: + *

          + *
        • : this is equivalent to calling + * ubidi_setPara with paraLevel == UBIDI_LTR,
        • + *
        • : this is equivalent to calling + * ubidi_setPara with paraLevel == UBIDI_RTL,
        • + *
        • : this is equivalent to + * calling ubidi_setPara with + * paraLevel == UBIDI_DEFAULT_LTR,
        • + *
        • : this is equivalent to + * calling ubidi_setPara with + * paraLevel == UBIDI_DEFAULT_RTL,
        • + *
        • : this is equivalent to + * calling ubidi_setInverse(UBiDi*, TRUE) and then + * ubidi_setPara with paraLevel == UBIDI_LTR,
        • + *
        • : this is equivalent to + * calling ubidi_setInverse(UBiDi*, TRUE) and then + * ubidi_setPara with paraLevel == UBIDI_RTL.
        • + *
        + * All combinations that involve the Visual RTL scheme are unsupported by + * UBiDi, for instance: + *
          + *
        • ,
        • + *
        • .
        • + *
        + *

        Example of usage of the transformation engine:
        + *

        + * \code
        + * UChar text1[] = {'a', 'b', 'c', 0x0625, '1', 0};
        + * UChar text2[] = {'a', 'b', 'c', 0x0625, '1', 0};
        + * UErrorCode errorCode = U_ZERO_ERROR;
        + * // Run a transformation.
        + * ubiditransform_transform(pBidiTransform,
        + *          text1, -1, text2, -1,
        + *          UBIDI_LTR, UBIDI_VISUAL,
        + *          UBIDI_RTL, UBIDI_LOGICAL,
        + *          UBIDI_MIRRORING_OFF,
        + *          U_SHAPE_DIGITS_AN2EN | U_SHAPE_DIGIT_TYPE_AN_EXTENDED,
        + *          &errorCode);
        + * // Do something with text2.
        + *  text2[4] = '2';
        + * // Run a reverse transformation.
        + * ubiditransform_transform(pBidiTransform,
        + *          text2, -1, text1, -1,
        + *          UBIDI_RTL, UBIDI_LOGICAL,
        + *          UBIDI_LTR, UBIDI_VISUAL,
        + *          UBIDI_MIRRORING_OFF,
        + *          U_SHAPE_DIGITS_EN2AN | U_SHAPE_DIGIT_TYPE_AN_EXTENDED,
        + *          &errorCode);
        + *\endcode
        + * 
        + *

        + * + * @param pBiDiTransform A pointer to a UBiDiTransform object + * allocated with ubiditransform_open() or + * NULL.

        + * This object serves for one-time setup to amortize initialization + * overheads. Use of this object is not thread-safe. All other threads + * should allocate a new UBiDiTransform object by calling + * ubiditransform_open() before using it. Alternatively, + * a caller can set this parameter to NULL, in which case + * the object will be allocated by the engine on the fly.

        + * @param src A pointer to the text that the Bidi layout transformations will + * be performed on. + *

        Note: the text must be (at least) + * srcLength long.

        + * @param srcLength The length of the text, in number of UChars. If + * length == -1 then the text must be zero-terminated. + * @param dest A pointer to where the processed text is to be copied. + * @param destSize The size of the dest buffer, in number of + * UChars. If the U_SHAPE_LETTERS_UNSHAPE option is set, + * then the destination length could be as large as + * srcLength * 2. Otherwise, the destination length will + * not exceed srcLength. If the caller reserves the last + * position for zero-termination, it should be excluded from + * destSize. + *

        destSize == -1 is allowed and makes sense when + * dest was holds some meaningful value, e.g. that of + * src. In this case dest must be + * zero-terminated.

        + * @param inParaLevel A base embedding level of the input as defined in + * ubidi_setPara documentation for the + * paraLevel parameter. + * @param inOrder An order of the input, which can be one of the + * UBiDiOrder values. + * @param outParaLevel A base embedding level of the output as defined in + * ubidi_setPara documentation for the + * paraLevel parameter. + * @param outOrder An order of the output, which can be one of the + * UBiDiOrder values. + * @param doMirroring Indicates whether or not to perform character mirroring, + * and can accept one of the UBiDiMirroring values. + * @param shapingOptions Arabic digit and letter shaping options defined in the + * ushape.h documentation. + *

        Note: Direction indicator options are computed by + * the transformation engine based on the effective ordering schemes, so + * user-defined direction indicators will be ignored.

        + * @param pErrorCode A pointer to an error code value. + * + * @return The destination length, i.e. the number of UChars written to + * dest. If the transformation fails, the return value + * will be 0 (and the error code will be written to + * pErrorCode). + * + * @see UBiDiLevel + * @see UBiDiOrder + * @see UBiDiMirroring + * @see ubidi_setPara + * @see u_shapeArabic + * @stable ICU 58 + */ +U_STABLE uint32_t U_EXPORT2 +ubiditransform_transform(UBiDiTransform *pBiDiTransform, + const UChar *src, int32_t srcLength, + UChar *dest, int32_t destSize, + UBiDiLevel inParaLevel, UBiDiOrder inOrder, + UBiDiLevel outParaLevel, UBiDiOrder outOrder, + UBiDiMirroring doMirroring, uint32_t shapingOptions, + UErrorCode *pErrorCode); + +/** + * Allocates a UBiDiTransform object. This object can be reused, + * e.g. with different ordering schemes, mirroring or shaping options.

        + * Note:The object can only be reused in the same thread. + * All other threads should allocate a new UBiDiTransform object + * before using it.

        + * Example of usage:

        + *

        + * \code
        + * UErrorCode errorCode = U_ZERO_ERROR;
        + * // Open a new UBiDiTransform.
        + * UBiDiTransform* transform = ubiditransform_open(&errorCode);
        + * // Run a transformation.
        + * ubiditransform_transform(transform,
        + *          text1, -1, text2, -1,
        + *          UBIDI_RTL, UBIDI_LOGICAL,
        + *          UBIDI_LTR, UBIDI_VISUAL,
        + *          UBIDI_MIRRORING_ON,
        + *          U_SHAPE_DIGITS_EN2AN,
        + *          &errorCode);
        + * // Do something with the output text and invoke another transformation using
        + * //   that text as input.
        + * ubiditransform_transform(transform,
        + *          text2, -1, text3, -1,
        + *          UBIDI_LTR, UBIDI_VISUAL,
        + *          UBIDI_RTL, UBIDI_VISUAL,
        + *          UBIDI_MIRRORING_ON,
        + *          0, &errorCode);
        + *\endcode
        + * 
        + *

        + * The UBiDiTransform object must be deallocated by calling + * ubiditransform_close(). + * + * @return An empty UBiDiTransform object. + * @stable ICU 58 + */ +U_STABLE UBiDiTransform* U_EXPORT2 +ubiditransform_open(UErrorCode *pErrorCode); + +/** + * Deallocates the given UBiDiTransform object. + * @stable ICU 58 + */ +U_STABLE void U_EXPORT2 +ubiditransform_close(UBiDiTransform *pBidiTransform); + +#if U_SHOW_CPLUSPLUS_API + +U_NAMESPACE_BEGIN + +/** + * \class LocalUBiDiTransformPointer + * "Smart pointer" class, closes a UBiDiTransform via ubiditransform_close(). + * For most methods see the LocalPointerBase base class. + * + * @see LocalPointerBase + * @see LocalPointer + * @stable ICU 58 + */ +U_DEFINE_LOCAL_OPEN_POINTER(LocalUBiDiTransformPointer, UBiDiTransform, ubiditransform_close); + +U_NAMESPACE_END + +#endif // U_SHOW_CPLUSPLUS_API + +#endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ubrk.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ubrk.h index dfa2fe7127..532083fc71 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ubrk.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ubrk.h @@ -1,3 +1,5 @@ +// © 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. @@ -57,9 +59,7 @@ * Note: The locale keyword "ss" can be used to enable use of * segmentation suppression data (preventing breaks in English after * abbreviations such as "Mr." or "Est.", for example), as follows: - * "en@ss=standard". However, use of the suppression data is - * currently supported only for ubrk_next; ubrk_previous, ubrk_following, - * and ubrk_preceding will ignore the suppression data. + * "en@ss=standard". *

        * Word boundary analysis is used by search and replace functions, as * well as within text editing applications that allow the user to @@ -72,7 +72,7 @@ * "Extended Grapheme Clusters", which are groupings of codepoints * that should be treated as character-like units for many text operations. * Please see Unicode Standard Annex #29, Unicode Text Segmentation, - * http://www.unicode.org/reports/tr29/ for additional information + * http://www.unicode.org/reports/tr29/ for additional information * on grapheme clusters and guidelines on their use. *

        * Title boundary analysis locates all positions, @@ -116,8 +116,12 @@ typedef enum UBreakIteratorType { * @deprecated ICU 2.8 Use the word break iterator for titlecasing for Unicode 4 and later. */ UBRK_TITLE = 4, -#endif /* U_HIDE_DEPRECATED_API */ - UBRK_COUNT = 5 + /** + * One more than the highest normal UBreakIteratorType value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + UBRK_COUNT = 5 +#endif // U_HIDE_DEPRECATED_API } UBreakIteratorType; /** Value indicating all text boundaries have been returned. @@ -132,7 +136,10 @@ typedef enum UBreakIteratorType { * word, to allow for further subdivisions of a category in future releases. * Applications should check for tag values falling within the range, rather * than for single individual values. - * @stable ICU 2.2 + * + * The numeric values of all of these constants are stable (will not change). + * + * @stable ICU 2.2 */ typedef enum UWordBreak { /** Tag value for "words" that do not fit into any of other categories. @@ -165,7 +172,10 @@ typedef enum UWordBreak { * word, to allow for further subdivisions of a category in future releases. * Applications should check for tag values falling within the range, rather * than for single individual values. - * @stable ICU 2.8 + * + * The numeric values of all of these constants are stable (will not change). + * + * @stable ICU 2.8 */ typedef enum ULineBreakTag { /** Tag value for soft line breaks, positions at which a line break @@ -187,7 +197,10 @@ typedef enum ULineBreakTag { * sentence, to allow for further subdivisions of a category in future releases. * Applications should check for tag values falling within the range, rather * than for single individual values. - * @stable ICU 2.8 + * + * The numeric values of all of these constants are stable (will not change). + * + * @stable ICU 2.8 */ typedef enum USentenceBreakTag { /** Tag value for for sentences ending with a sentence terminator @@ -208,6 +221,25 @@ typedef enum USentenceBreakTag { } USentenceBreakTag; +/** + * Masks to control line break word options (per the CSS word-break property). + * NORMAL allows breaks between CJK characters in the middle of words. Other masks + * prohibit breaks between characters of specific scripts (or all scripts) except as + * determined by a dictionary, or by spaces or other mechanisms (Western-style breaking). + * + * @internal Apple only +*/ +typedef enum ULineWordOptions { + /** Allow breaks between characters of all CJK scripts */ + UBRK_LINEWORD_NORMAL = 0, + /** Prevent breaks between Hangul characters, except as determined by a dictionary. */ + UBRK_LINEWORD_KEEP_HANGUL = 1, + /** Prevent breaks between characters of any script, except as determined by a dictionary. */ + UBRK_LINEWORD_KEEP_ALL = 0x7F +} ULineWordOptions; + + + /** * Open a new UBreakIterator for locating text boundaries for a specified locale. * A UBreakIterator may be used for detecting character, line, word, @@ -217,7 +249,8 @@ typedef enum USentenceBreakTag { * @param locale The locale specifying the text-breaking conventions. Note that * locale keys such as "lb" and "ss" may be used to modify text break behavior, * see general discussion of BreakIterator C API. - * @param text The text to be iterated over. + * @param text The text to be iterated over. May be null, in which case ubrk_setText() is + * used to specify the text to be iterated. * @param textLength The number of characters in text, or -1 if null-terminated. * @param status A UErrorCode to receive any errors. * @return A UBreakIterator for the specified locale. @@ -254,6 +287,31 @@ ubrk_openRules(const UChar *rules, UParseError *parseErr, UErrorCode *status); +/** + * Open a new UBreakIterator for locating text boundaries using precompiled binary rules. + * Opening a UBreakIterator this way is substantially faster than using ubrk_openRules. + * Binary rules may be obtained using ubrk_getBinaryRules. The compiled rules are not + * compatible across different major versions of ICU, nor across platforms of different + * endianness or different base character set family (ASCII vs EBCDIC). + * @param binaryRules A set of compiled binary rules specifying the text breaking + * conventions. Ownership of the storage containing the compiled + * rules remains with the caller of this function. The compiled + * rules must not be modified or deleted during the life of the + * break iterator. + * @param rulesLength The length of binaryRules in bytes; must be >= 0. + * @param text The text to be iterated over. May be null, in which case + * ubrk_setText() is used to specify the text to be iterated. + * @param textLength The number of characters in text, or -1 if null-terminated. + * @param status Pointer to UErrorCode to receive any errors. + * @return UBreakIterator for the specified rules. + * @see ubrk_getBinaryRules + * @stable ICU 59 + */ +U_STABLE UBreakIterator* U_EXPORT2 +ubrk_openBinaryRules(const uint8_t *binaryRules, int32_t rulesLength, + const UChar * text, int32_t textLength, + UErrorCode * status); + /** * Thread safe cloning operation * @param bi iterator to be cloned @@ -315,10 +373,28 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUBreakIteratorPointer, UBreakIterator, ubrk_clo U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API + +#ifndef U_HIDE_INTERNAL_API +/** + * Set the ULineWordOptions for the specified break iterator. + * + * @param bi The iterator to use + * @param lineWordOpts The ULineWordOptions to set. + * @internal Apple only + */ +U_INTERNAL void U_EXPORT2 +ubrk_setLineWordOpts(UBreakIterator* bi, + ULineWordOptions lineWordOpts); + +#endif /* U_HIDE_INTERNAL_API */ /** - * Sets an existing iterator to point to a new piece of text + * Sets an existing iterator to point to a new piece of text. + * The break iterator retains a pointer to the supplied text. + * The caller must not modify or delete the text while the BreakIterator + * retains the reference. + * * @param bi The iterator to use * @param text The text to be set * @param textLength The length of the text @@ -464,7 +540,7 @@ ubrk_countAvailable(void); /** -* Returns true if the specfied position is a boundary position. As a side +* Returns true if the specified position is a boundary position. As a side * effect, leaves the iterator pointing to the first boundary position at * or after "offset". * @param bi The break iterator to use. @@ -498,7 +574,7 @@ ubrk_getRuleStatus(UBreakIterator *bi); * @param fillInVec an array to be filled in with the status values. * @param capacity the length of the supplied vector. A length of zero causes * the function to return the number of status values, in the - * normal way, without attemtping to store any values. + * normal way, without attempting to store any values. * @param status receives error codes. * @return The number of rule status values from rules that determined * the most recent boundary returned by the break iterator. @@ -549,6 +625,37 @@ ubrk_refreshUText(UBreakIterator *bi, UText *text, UErrorCode *status); + +/** + * Get a compiled binary version of the rules specifying the behavior of a UBreakIterator. + * The binary rules may be used with ubrk_openBinaryRules to open a new UBreakIterator + * more quickly than using ubrk_openRules. The compiled rules are not compatible across + * different major versions of ICU, nor across platforms of different endianness or + * different base character set family (ASCII vs EBCDIC). Supports preflighting (with + * binaryRules=NULL and rulesCapacity=0) to get the rules length without copying them to + * the binaryRules buffer. However, whether preflighting or not, if the actual length + * is greater than INT32_MAX, then the function returns 0 and sets *status to + * U_INDEX_OUTOFBOUNDS_ERROR. + + * @param bi The break iterator to use. + * @param binaryRules Buffer to receive the compiled binary rules; set to NULL for + * preflighting. + * @param rulesCapacity Capacity (in bytes) of the binaryRules buffer; set to 0 for + * preflighting. Must be >= 0. + * @param status Pointer to UErrorCode to receive any errors, such as + * U_BUFFER_OVERFLOW_ERROR, U_INDEX_OUTOFBOUNDS_ERROR, or + * U_ILLEGAL_ARGUMENT_ERROR. + * @return The actual byte length of the binary rules, if <= INT32_MAX; + * otherwise 0. If not preflighting and this is larger than + * rulesCapacity, *status will be set to an error. + * @see ubrk_openBinaryRules + * @stable ICU 59 + */ +U_STABLE int32_t U_EXPORT2 +ubrk_getBinaryRules(UBreakIterator *bi, + uint8_t * binaryRules, int32_t rulesCapacity, + UErrorCode * status); + #endif /* #if !UCONFIG_NO_BREAK_ITERATION */ #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucal.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucal.h index 46c56affa3..5e3c53fe91 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucal.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucal.h @@ -1,3 +1,5 @@ +// © 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 @@ -103,7 +105,7 @@ *

        * Note: for some non-Gregorian calendars, different * fields may be necessary for complete disambiguation. For example, a full - * specification of the historial Arabic astronomical calendar requires year, + * specification of the historical Arabic astronomical calendar requires year, * month, day-of-month and day-of-week in some cases. * *

        @@ -137,11 +139,25 @@ * For example, subtracting 5 days from the date September 12, 1996 * results in September 7, 1996. * + *

        + * The Japanese calendar uses a combination of era name and year number. + * When an emperor of Japan abdicates and a new emperor ascends the throne, + * a new era is declared and year number is reset to 1. Even if the date of + * abdication is scheduled ahead of time, the new era name might not be + * announced until just before the date. In such case, ICU4C may include + * a start date of future era without actual era name, but not enabled + * by default. ICU4C users who want to test the behavior of the future era + * can enable the tentative era by: + *

          + *
        • Environment variable ICU_ENABLE_TENTATIVE_ERA=true.
        • + *
        + * * @stable ICU 2.0 */ /** * The time zone ID reserved for unknown time zone. + * It behaves like the GMT/UTC time zone but has the special ID "Etc/Unknown". * @stable ICU 4.8 */ #define UCAL_UNKNOWN_ZONE_ID "Etc/Unknown" @@ -423,10 +439,12 @@ enum UCalendarDateFields { */ UCAL_IS_LEAP_MONTH, - /** - * Field count - * @stable ICU 2.6 - */ + /* Do not conditionalize the following 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, /** @@ -603,8 +621,13 @@ ucal_openCountryTimeZones(const char* country, UErrorCode* ec); /** * Return the default time zone. The default is determined initially - * by querying the host operating system. It may be changed with - * ucal_setDefaultTimeZone() or with the C++ TimeZone API. + * by querying the host operating system. If the host system detection + * routines fail, or if they specify a TimeZone or TimeZone offset + * which is not recognized, then the special TimeZone "Etc/Unknown" + * is returned. + * + * The default may be changed with `ucal_setDefaultTimeZone()` or with + * the C++ TimeZone API, `TimeZone::adoptDefault(TimeZone*)`. * * @param result A buffer to receive the result, or NULL * @@ -614,7 +637,9 @@ ucal_openCountryTimeZones(const char* country, UErrorCode* ec); * * @return The result string length, not including the terminating * null - * + * + * @see #UCAL_UNKNOWN_ZONE_ID + * * @stable ICU 2.6 */ U_STABLE int32_t U_EXPORT2 @@ -716,7 +741,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUCalendarPointer, UCalendar, ucal_close); U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Open a copy of a UCalendar. diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucasemap.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucasemap.h index b37e165886..e00d7eaec1 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucasemap.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucasemap.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -6,7 +8,7 @@ * ******************************************************************************* * file name: ucasemap.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -20,8 +22,9 @@ #define __UCASEMAP_H__ #include "unicode/utypes.h" -#include "unicode/ustring.h" #include "unicode/localpointer.h" +#include "unicode/stringoptions.h" +#include "unicode/ustring.h" /** * \file @@ -94,7 +97,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUCaseMapPointer, UCaseMap, ucasemap_close); U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Get the locale ID that is used for language-dependent case mappings. @@ -142,47 +145,6 @@ ucasemap_setLocale(UCaseMap *csm, const char *locale, UErrorCode *pErrorCode); U_STABLE void U_EXPORT2 ucasemap_setOptions(UCaseMap *csm, uint32_t options, UErrorCode *pErrorCode); -/** - * Do not lowercase non-initial parts of words when titlecasing. - * Option bit for titlecasing APIs that take an options bit set. - * - * By default, titlecasing will titlecase the first cased character - * of a word and lowercase all other characters. - * With this option, the other characters will not be modified. - * - * @see ucasemap_setOptions - * @see ucasemap_toTitle - * @see ucasemap_utf8ToTitle - * @see UnicodeString::toTitle - * @stable ICU 3.8 - */ -#define U_TITLECASE_NO_LOWERCASE 0x100 - -/** - * Do not adjust the titlecasing indexes from BreakIterator::next() indexes; - * titlecase exactly the characters at breaks from the iterator. - * Option bit for titlecasing APIs that take an options bit set. - * - * By default, titlecasing will take each break iterator index, - * adjust it by looking for the next cased character, and titlecase that one. - * Other characters are lowercased. - * - * This follows Unicode 4 & 5 section 3.13 Default Case Operations: - * - * R3 toTitlecase(X): Find the word boundaries based on Unicode Standard Annex - * #29, "Text Boundaries." Between each pair of word boundaries, find the first - * cased character F. If F exists, map F to default_title(F); then map each - * subsequent character C to default_lower(C). - * - * @see ucasemap_setOptions - * @see ucasemap_toTitle - * @see ucasemap_utf8ToTitle - * @see UnicodeString::toTitle - * @see U_TITLECASE_NO_LOWERCASE - * @stable ICU 3.8 - */ -#define U_TITLECASE_NO_BREAK_ADJUSTMENT 0x200 - #if !UCONFIG_NO_BREAK_ITERATION /** @@ -240,7 +202,7 @@ ucasemap_setBreakIterator(UCaseMap *csm, UBreakIterator *iterToAdopt, UErrorCode * The standard titlecase iterator for the root locale implements the * algorithm of Unicode TR 21. * - * This function uses only the setUText(), first(), next() and close() methods of the + * This function uses only the setText(), first() and next() methods of the * provided break iterator. * * The result may be longer or shorter than the original. @@ -251,7 +213,7 @@ ucasemap_setBreakIterator(UCaseMap *csm, UBreakIterator *iterToAdopt, UErrorCode * @param dest A buffer for the result string. The result will be NUL-terminated if * the buffer is large enough. * The contents is undefined in case of failure. - * @param destCapacity The size of the buffer (number of bytes). If it is 0, then + * @param destCapacity The size of the buffer (number of UChars). If it is 0, then * dest may be NULL and the function will only return the length of the result * without writing any of the result string. * @param src The original string. @@ -270,7 +232,7 @@ ucasemap_toTitle(UCaseMap *csm, const UChar *src, int32_t srcLength, UErrorCode *pErrorCode); -#endif +#endif // UCONFIG_NO_BREAK_ITERATION /** * Lowercase the characters in a UTF-8 string. diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucat.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucat.h index ad9f0373a3..4d1ff3f6b2 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucat.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucat.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2003-2004, International Business Machines diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uchar.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uchar.h index 1d3ae0dd43..2d2c5c33d7 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uchar.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uchar.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** -* Copyright (C) 1997-2014, International Business Machines +* Copyright (C) 1997-2016, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * @@ -24,6 +26,25 @@ #define UCHAR_H #include "unicode/utypes.h" +#include "unicode/stringoptions.h" +#include "unicode/ucpmap.h" + +#if !defined(USET_DEFINED) && !defined(U_IN_DOXYGEN) + +#define USET_DEFINED + +/** + * USet is the C API type corresponding to C++ class UnicodeSet. + * It is forward-declared here to avoid including unicode/uset.h file if related + * APIs are not used. + * + * @see ucnv_getUnicodeSet + * @stable ICU 2.4 + */ +typedef struct USet USet; + +#endif + U_CDECL_BEGIN @@ -39,7 +60,7 @@ U_CDECL_BEGIN * @see u_getUnicodeVersion * @stable ICU 2.0 */ -#define U_UNICODE_VERSION "7.0" +#define U_UNICODE_VERSION "12.1" /** * \file @@ -58,6 +79,18 @@ U_CDECL_BEGIN * "About the Unicode Character Database" (http://www.unicode.org/ucd/) * and the ICU User Guide chapter on Properties (http://icu-project.org/userguide/properties.html). * + * Many properties are accessible via generic functions that take a UProperty selector. + * - u_hasBinaryProperty() returns a binary value (TRUE/FALSE) per property and code point. + * - u_getIntPropertyValue() returns an integer value per property and code point. + * For each supported enumerated or catalog property, there is + * an enum type for all of the property's values, and + * u_getIntPropertyValue() returns the numeric values of those constants. + * - u_getBinaryPropertySet() returns a set for each ICU-supported binary property with + * all code points for which the property is true. + * - u_getIntPropertyMap() returns a map for each + * ICU-supported enumerated/catalog/int-valued property which + * maps all Unicode code points to their values for that property. + * * Many functions are designed to match java.lang.Character functions. * See the individual function documentation, * and see the JDK 1.4 java.lang.Character documentation @@ -109,11 +142,11 @@ U_CDECL_BEGIN * Comparison: * - u_isUWhiteSpace=UCHAR_WHITE_SPACE: Unicode White_Space property; * most of general categories "Z" (separators) + most whitespace ISO controls - * (including no-break spaces, but excluding IS1..IS4 and ZWSP) + * (including no-break spaces, but excluding IS1..IS4) * - u_isWhitespace: Java isWhitespace; Z + whitespace ISO controls but excluding no-break spaces * - u_isJavaSpaceChar: Java isSpaceChar; just Z (including no-break spaces) * - u_isspace: Z + whitespace ISO controls (including no-break spaces) - * - u_isblank: "horizontal spaces" = TAB + Zs - ZWSP + * - u_isblank: "horizontal spaces" = TAB + Zs */ /** @@ -146,8 +179,9 @@ U_CDECL_BEGIN * * The properties APIs are intended to reflect Unicode properties as defined * in the Unicode Character Database (UCD) and Unicode Technical Reports (UTR). - * For details about the properties see http://www.unicode.org/ucd/ . - * For names of Unicode properties see the UCD file PropertyAliases.txt. + * + * For details about the properties see + * UAX #44: Unicode Character Database (http://www.unicode.org/reports/tr44/). * * Important: If ICU is built with UCD files from Unicode versions below, e.g., 3.2, * then properties marked with "new in Unicode 3.2" are not or not fully available. @@ -397,8 +431,65 @@ typedef enum UProperty { UCHAR_CHANGES_WHEN_CASEMAPPED=55, /** Binary property Changes_When_NFKC_Casefolded. @stable ICU 4.4 */ UCHAR_CHANGES_WHEN_NFKC_CASEFOLDED=56, - /** One more than the last constant for binary Unicode properties. @stable ICU 2.1 */ - UCHAR_BINARY_LIMIT=57, + /** + * Binary property Emoji. + * See http://www.unicode.org/reports/tr51/#Emoji_Properties + * + * @stable ICU 57 + */ + UCHAR_EMOJI=57, + /** + * Binary property Emoji_Presentation. + * See http://www.unicode.org/reports/tr51/#Emoji_Properties + * + * @stable ICU 57 + */ + UCHAR_EMOJI_PRESENTATION=58, + /** + * Binary property Emoji_Modifier. + * See http://www.unicode.org/reports/tr51/#Emoji_Properties + * + * @stable ICU 57 + */ + UCHAR_EMOJI_MODIFIER=59, + /** + * Binary property Emoji_Modifier_Base. + * See http://www.unicode.org/reports/tr51/#Emoji_Properties + * + * @stable ICU 57 + */ + UCHAR_EMOJI_MODIFIER_BASE=60, + /** + * Binary property Emoji_Component. + * See http://www.unicode.org/reports/tr51/#Emoji_Properties + * + * @stable ICU 60 + */ + UCHAR_EMOJI_COMPONENT=61, + /** + * Binary property Regional_Indicator. + * @stable ICU 60 + */ + UCHAR_REGIONAL_INDICATOR=62, + /** + * Binary property Prepended_Concatenation_Mark. + * @stable ICU 60 + */ + UCHAR_PREPENDED_CONCATENATION_MARK=63, + /** + * Binary property Extended_Pictographic. + * See http://www.unicode.org/reports/tr51/#Emoji_Properties + * + * @stable ICU 62 + */ + UCHAR_EXTENDED_PICTOGRAPHIC=64, +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the last constant for binary Unicode properties. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + UCHAR_BINARY_LIMIT, +#endif // U_HIDE_DEPRECATED_API /** Enumerated property Bidi_Class. Same as u_charDirection, returns UCharDirection values. @stable ICU 2.2 */ @@ -485,8 +576,35 @@ typedef enum UProperty { (http://www.unicode.org/reports/tr9/) Returns UBidiPairedBracketType values. @stable ICU 52 */ UCHAR_BIDI_PAIRED_BRACKET_TYPE=0x1015, - /** One more than the last constant for enumerated/integer Unicode properties. @stable ICU 2.2 */ - UCHAR_INT_LIMIT=0x1016, + /** + * Enumerated property Indic_Positional_Category. + * New in Unicode 6.0 as provisional property Indic_Matra_Category; + * renamed and changed to informative in Unicode 8.0. + * See http://www.unicode.org/reports/tr44/#IndicPositionalCategory.txt + * @stable ICU 63 + */ + UCHAR_INDIC_POSITIONAL_CATEGORY=0x1016, + /** + * Enumerated property Indic_Syllabic_Category. + * New in Unicode 6.0 as provisional; informative since Unicode 8.0. + * See http://www.unicode.org/reports/tr44/#IndicSyllabicCategory.txt + * @stable ICU 63 + */ + UCHAR_INDIC_SYLLABIC_CATEGORY=0x1017, + /** + * Enumerated property Vertical_Orientation. + * Used for UAX #50 Unicode Vertical Text Layout (https://www.unicode.org/reports/tr50/). + * New as a UCD property in Unicode 10.0. + * @stable ICU 63 + */ + UCHAR_VERTICAL_ORIENTATION=0x1018, +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the last constant for enumerated/integer Unicode properties. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + UCHAR_INT_LIMIT=0x1019, +#endif // U_HIDE_DEPRECATED_API /** Bitmask property General_Category_Mask. This is the General_Category property returned as a bit mask. @@ -499,16 +617,26 @@ typedef enum UProperty { UCHAR_GENERAL_CATEGORY_MASK=0x2000, /** First constant for bit-mask Unicode properties. @stable ICU 2.4 */ UCHAR_MASK_START=UCHAR_GENERAL_CATEGORY_MASK, - /** One more than the last constant for bit-mask Unicode properties. @stable ICU 2.4 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the last constant for bit-mask Unicode properties. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UCHAR_MASK_LIMIT=0x2001, +#endif // U_HIDE_DEPRECATED_API /** Double property Numeric_Value. Corresponds to u_getNumericValue. @stable ICU 2.4 */ UCHAR_NUMERIC_VALUE=0x3000, /** First constant for double Unicode properties. @stable ICU 2.4 */ UCHAR_DOUBLE_START=UCHAR_NUMERIC_VALUE, - /** One more than the last constant for double Unicode properties. @stable ICU 2.4 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the last constant for double Unicode properties. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UCHAR_DOUBLE_LIMIT=0x3001, +#endif // U_HIDE_DEPRECATED_API /** String property Age. Corresponds to u_charAge. @stable ICU 2.4 */ @@ -560,8 +688,13 @@ typedef enum UProperty { /** String property Bidi_Paired_Bracket (new in Unicode 6.3). Corresponds to u_getBidiPairedBracket. @stable ICU 52 */ UCHAR_BIDI_PAIRED_BRACKET=0x400D, - /** One more than the last constant for string Unicode properties. @stable ICU 2.4 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the last constant for string Unicode properties. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UCHAR_STRING_LIMIT=0x400E, +#endif // U_HIDE_DEPRECATED_API /** Miscellaneous property Script_Extensions (new in Unicode 6.0). Some characters are commonly used in multiple scripts. @@ -571,9 +704,14 @@ typedef enum UProperty { UCHAR_SCRIPT_EXTENSIONS=0x7000, /** First constant for Unicode properties with unusual value types. @stable ICU 4.6 */ UCHAR_OTHER_PROPERTY_START=UCHAR_SCRIPT_EXTENSIONS, - /** One more than the last constant for Unicode properties with unusual value types. - * @stable ICU 4.6 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the last constant for Unicode properties with unusual value types. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UCHAR_OTHER_PROPERTY_LIMIT=0x7001, +#endif // U_HIDE_DEPRECATED_API + /** Represents a nonexistent or invalid property or property value. @stable ICU 2.4 */ UCHAR_INVALID_CODE = -1 } UProperty; @@ -654,7 +792,13 @@ typedef enum UCharCategory U_INITIAL_PUNCTUATION = 28, /** Pf @stable ICU 2.0 */ U_FINAL_PUNCTUATION = 29, - /** One higher than the last enum UCharCategory constant. @stable ICU 2.0 */ + /** + * One higher than the last enum UCharCategory constant. + * This numeric value is stable (will not change), see + * http://www.unicode.org/policies/stability_policy.html#Property_Value + * + * @stable ICU 2.0 + */ U_CHAR_CATEGORY_COUNT } UCharCategory; @@ -828,8 +972,15 @@ typedef enum UCharDirection { U_RIGHT_TO_LEFT_ISOLATE = 21, /** PDI @stable ICU 52 */ U_POP_DIRECTIONAL_ISOLATE = 22, - /** @stable ICU 2.0 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest UCharDirection value. + * The highest value is available via u_getIntPropertyMaxValue(UCHAR_BIDI_CLASS). + * + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ U_CHAR_DIRECTION_COUNT +#endif // U_HIDE_DEPRECATED_API } UCharDirection; /** @@ -851,8 +1002,15 @@ typedef enum UBidiPairedBracketType { U_BPT_OPEN, /** Close paired bracket. @stable ICU 52 */ U_BPT_CLOSE, - /** @stable ICU 52 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UBidiPairedBracketType value. + * The highest value is available via u_getIntPropertyMaxValue(UCHAR_BIDI_PAIRED_BRACKET_TYPE). + * + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ U_BPT_COUNT /* 3 */ +#endif // U_HIDE_DEPRECATED_API } UBidiPairedBracketType; /** @@ -1183,7 +1341,7 @@ enum UBlockCode { * Unicode 4.0.1 renames the "Cyrillic Supplementary" block to "Cyrillic Supplement". * @stable ICU 2.2 */ - UBLOCK_CYRILLIC_SUPPLEMENTARY = UBLOCK_CYRILLIC_SUPPLEMENT, + UBLOCK_CYRILLIC_SUPPLEMENTARY = UBLOCK_CYRILLIC_SUPPLEMENT, /** @stable ICU 2.2 */ UBLOCK_TAGALOG = 98, /*[1700]*/ /** @stable ICU 2.2 */ @@ -1519,8 +1677,126 @@ enum UBlockCode { /** @stable ICU 54 */ UBLOCK_WARANG_CITI = 252, /*[118A0]*/ - /** @stable ICU 2.0 */ - UBLOCK_COUNT = 253, + /* New blocks in Unicode 8.0 */ + + /** @stable ICU 56 */ + UBLOCK_AHOM = 253, /*[11700]*/ + /** @stable ICU 56 */ + UBLOCK_ANATOLIAN_HIEROGLYPHS = 254, /*[14400]*/ + /** @stable ICU 56 */ + UBLOCK_CHEROKEE_SUPPLEMENT = 255, /*[AB70]*/ + /** @stable ICU 56 */ + UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_E = 256, /*[2B820]*/ + /** @stable ICU 56 */ + UBLOCK_EARLY_DYNASTIC_CUNEIFORM = 257, /*[12480]*/ + /** @stable ICU 56 */ + UBLOCK_HATRAN = 258, /*[108E0]*/ + /** @stable ICU 56 */ + UBLOCK_MULTANI = 259, /*[11280]*/ + /** @stable ICU 56 */ + UBLOCK_OLD_HUNGARIAN = 260, /*[10C80]*/ + /** @stable ICU 56 */ + UBLOCK_SUPPLEMENTAL_SYMBOLS_AND_PICTOGRAPHS = 261, /*[1F900]*/ + /** @stable ICU 56 */ + UBLOCK_SUTTON_SIGNWRITING = 262, /*[1D800]*/ + + /* New blocks in Unicode 9.0 */ + + /** @stable ICU 58 */ + UBLOCK_ADLAM = 263, /*[1E900]*/ + /** @stable ICU 58 */ + UBLOCK_BHAIKSUKI = 264, /*[11C00]*/ + /** @stable ICU 58 */ + UBLOCK_CYRILLIC_EXTENDED_C = 265, /*[1C80]*/ + /** @stable ICU 58 */ + UBLOCK_GLAGOLITIC_SUPPLEMENT = 266, /*[1E000]*/ + /** @stable ICU 58 */ + UBLOCK_IDEOGRAPHIC_SYMBOLS_AND_PUNCTUATION = 267, /*[16FE0]*/ + /** @stable ICU 58 */ + UBLOCK_MARCHEN = 268, /*[11C70]*/ + /** @stable ICU 58 */ + UBLOCK_MONGOLIAN_SUPPLEMENT = 269, /*[11660]*/ + /** @stable ICU 58 */ + UBLOCK_NEWA = 270, /*[11400]*/ + /** @stable ICU 58 */ + UBLOCK_OSAGE = 271, /*[104B0]*/ + /** @stable ICU 58 */ + UBLOCK_TANGUT = 272, /*[17000]*/ + /** @stable ICU 58 */ + UBLOCK_TANGUT_COMPONENTS = 273, /*[18800]*/ + + // New blocks in Unicode 10.0 + + /** @stable ICU 60 */ + UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_F = 274, /*[2CEB0]*/ + /** @stable ICU 60 */ + UBLOCK_KANA_EXTENDED_A = 275, /*[1B100]*/ + /** @stable ICU 60 */ + UBLOCK_MASARAM_GONDI = 276, /*[11D00]*/ + /** @stable ICU 60 */ + UBLOCK_NUSHU = 277, /*[1B170]*/ + /** @stable ICU 60 */ + UBLOCK_SOYOMBO = 278, /*[11A50]*/ + /** @stable ICU 60 */ + UBLOCK_SYRIAC_SUPPLEMENT = 279, /*[0860]*/ + /** @stable ICU 60 */ + UBLOCK_ZANABAZAR_SQUARE = 280, /*[11A00]*/ + + // New blocks in Unicode 11.0 + + /** @stable ICU 62 */ + UBLOCK_CHESS_SYMBOLS = 281, /*[1FA00]*/ + /** @stable ICU 62 */ + UBLOCK_DOGRA = 282, /*[11800]*/ + /** @stable ICU 62 */ + UBLOCK_GEORGIAN_EXTENDED = 283, /*[1C90]*/ + /** @stable ICU 62 */ + UBLOCK_GUNJALA_GONDI = 284, /*[11D60]*/ + /** @stable ICU 62 */ + UBLOCK_HANIFI_ROHINGYA = 285, /*[10D00]*/ + /** @stable ICU 62 */ + UBLOCK_INDIC_SIYAQ_NUMBERS = 286, /*[1EC70]*/ + /** @stable ICU 62 */ + UBLOCK_MAKASAR = 287, /*[11EE0]*/ + /** @stable ICU 62 */ + UBLOCK_MAYAN_NUMERALS = 288, /*[1D2E0]*/ + /** @stable ICU 62 */ + UBLOCK_MEDEFAIDRIN = 289, /*[16E40]*/ + /** @stable ICU 62 */ + UBLOCK_OLD_SOGDIAN = 290, /*[10F00]*/ + /** @stable ICU 62 */ + UBLOCK_SOGDIAN = 291, /*[10F30]*/ + + // New blocks in Unicode 12.0 + + /** @stable ICU 64 */ + UBLOCK_EGYPTIAN_HIEROGLYPH_FORMAT_CONTROLS = 292, /*[13430]*/ + /** @stable ICU 64 */ + UBLOCK_ELYMAIC = 293, /*[10FE0]*/ + /** @stable ICU 64 */ + UBLOCK_NANDINAGARI = 294, /*[119A0]*/ + /** @stable ICU 64 */ + UBLOCK_NYIAKENG_PUACHUE_HMONG = 295, /*[1E100]*/ + /** @stable ICU 64 */ + UBLOCK_OTTOMAN_SIYAQ_NUMBERS = 296, /*[1ED00]*/ + /** @stable ICU 64 */ + UBLOCK_SMALL_KANA_EXTENSION = 297, /*[1B130]*/ + /** @stable ICU 64 */ + UBLOCK_SYMBOLS_AND_PICTOGRAPHS_EXTENDED_A = 298, /*[1FA70]*/ + /** @stable ICU 64 */ + UBLOCK_TAMIL_SUPPLEMENT = 299, /*[11FC0]*/ + /** @stable ICU 64 */ + UBLOCK_WANCHO = 300, /*[1E2C0]*/ + +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UBlockCode value. + * The highest value is available via u_getIntPropertyMaxValue(UCHAR_BLOCK). + * + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + UBLOCK_COUNT = 301, +#endif // U_HIDE_DEPRECATED_API /** @stable ICU 2.0 */ UBLOCK_INVALID_CODE=-1 @@ -1549,7 +1825,15 @@ typedef enum UEastAsianWidth { U_EA_FULLWIDTH, /*[F]*/ U_EA_NARROW, /*[Na]*/ U_EA_WIDE, /*[W]*/ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UEastAsianWidth value. + * The highest value is available via u_getIntPropertyMaxValue(UCHAR_EAST_ASIAN_WIDTH). + * + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ U_EA_COUNT +#endif // U_HIDE_DEPRECATED_API } UEastAsianWidth; /** @@ -1566,7 +1850,7 @@ typedef enum UEastAsianWidth { typedef enum UCharNameChoice { /** Unicode character name (Name property). @stable ICU 2.0 */ U_UNICODE_CHAR_NAME, -#ifndef U_HIDE_DEPRECATED_API +#ifndef U_HIDE_DEPRECATED_API /** * The Unicode_1_Name property value which is of little practical value. * Beginning with ICU 49, ICU APIs return an empty string for this name choice. @@ -1578,8 +1862,13 @@ typedef enum UCharNameChoice { U_EXTENDED_CHAR_NAME = U_UNICODE_CHAR_NAME+2, /** Corrected name from NameAliases.txt. @stable ICU 4.4 */ U_CHAR_NAME_ALIAS, - /** @stable ICU 2.0 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UCharNameChoice value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ U_CHAR_NAME_CHOICE_COUNT +#endif // U_HIDE_DEPRECATED_API } UCharNameChoice; /** @@ -1598,7 +1887,13 @@ typedef enum UCharNameChoice { typedef enum UPropertyNameChoice { U_SHORT_PROPERTY_NAME, U_LONG_PROPERTY_NAME, +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UPropertyNameChoice value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ U_PROPERTY_NAME_CHOICE_COUNT +#endif // U_HIDE_DEPRECATED_API } UPropertyNameChoice; /** @@ -1632,7 +1927,15 @@ typedef enum UDecompositionType { U_DT_SUPER, /*[sup]*/ U_DT_VERTICAL, /*[vert]*/ U_DT_WIDE, /*[wide]*/ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UDecompositionType value. + * The highest value is available via u_getIntPropertyMaxValue(UCHAR_DECOMPOSITION_TYPE). + * + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ U_DT_COUNT /* 18 */ +#endif // U_HIDE_DEPRECATED_API } UDecompositionType; /** @@ -1654,7 +1957,15 @@ typedef enum UJoiningType { U_JT_LEFT_JOINING, /*[L]*/ U_JT_RIGHT_JOINING, /*[R]*/ U_JT_TRANSPARENT, /*[T]*/ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UJoiningType value. + * The highest value is available via u_getIntPropertyMaxValue(UCHAR_JOINING_TYPE). + * + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ U_JT_COUNT /* 6 */ +#endif // U_HIDE_DEPRECATED_API } UJoiningType; /** @@ -1757,7 +2068,34 @@ typedef enum UJoiningGroup { U_JG_MANICHAEAN_YODH, /**< @stable ICU 54 */ U_JG_MANICHAEAN_ZAYIN, /**< @stable ICU 54 */ U_JG_STRAIGHT_WAW, /**< @stable ICU 54 */ + U_JG_AFRICAN_FEH, /**< @stable ICU 58 */ + U_JG_AFRICAN_NOON, /**< @stable ICU 58 */ + U_JG_AFRICAN_QAF, /**< @stable ICU 58 */ + + U_JG_MALAYALAM_BHA, /**< @stable ICU 60 */ + U_JG_MALAYALAM_JA, /**< @stable ICU 60 */ + U_JG_MALAYALAM_LLA, /**< @stable ICU 60 */ + U_JG_MALAYALAM_LLLA, /**< @stable ICU 60 */ + U_JG_MALAYALAM_NGA, /**< @stable ICU 60 */ + U_JG_MALAYALAM_NNA, /**< @stable ICU 60 */ + U_JG_MALAYALAM_NNNA, /**< @stable ICU 60 */ + U_JG_MALAYALAM_NYA, /**< @stable ICU 60 */ + U_JG_MALAYALAM_RA, /**< @stable ICU 60 */ + U_JG_MALAYALAM_SSA, /**< @stable ICU 60 */ + U_JG_MALAYALAM_TTA, /**< @stable ICU 60 */ + + U_JG_HANIFI_ROHINGYA_KINNA_YA, /**< @stable ICU 62 */ + U_JG_HANIFI_ROHINGYA_PA, /**< @stable ICU 62 */ + +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UJoiningGroup value. + * The highest value is available via u_getIntPropertyMaxValue(UCHAR_JOINING_GROUP). + * + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ U_JG_COUNT +#endif // U_HIDE_DEPRECATED_API } UJoiningGroup; /** @@ -1783,10 +2121,32 @@ typedef enum UGraphemeClusterBreak { U_GCB_LVT = 7, /*[LVT]*/ U_GCB_T = 8, /*[T]*/ U_GCB_V = 9, /*[V]*/ + /** @stable ICU 4.0 */ U_GCB_SPACING_MARK = 10, /*[SM]*/ /* from here on: new in Unicode 5.1/ICU 4.0 */ + /** @stable ICU 4.0 */ U_GCB_PREPEND = 11, /*[PP]*/ + /** @stable ICU 50 */ U_GCB_REGIONAL_INDICATOR = 12, /*[RI]*/ /* new in Unicode 6.2/ICU 50 */ - U_GCB_COUNT = 13 + /** @stable ICU 58 */ + U_GCB_E_BASE = 13, /*[EB]*/ /* from here on: new in Unicode 9.0/ICU 58 */ + /** @stable ICU 58 */ + U_GCB_E_BASE_GAZ = 14, /*[EBG]*/ + /** @stable ICU 58 */ + U_GCB_E_MODIFIER = 15, /*[EM]*/ + /** @stable ICU 58 */ + U_GCB_GLUE_AFTER_ZWJ = 16, /*[GAZ]*/ + /** @stable ICU 58 */ + U_GCB_ZWJ = 17, /*[ZWJ]*/ + +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UGraphemeClusterBreak value. + * The highest value is available via u_getIntPropertyMaxValue(UCHAR_GRAPHEME_CLUSTER_BREAK). + * + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + U_GCB_COUNT = 18 +#endif // U_HIDE_DEPRECATED_API } UGraphemeClusterBreak; /** @@ -1811,16 +2171,46 @@ typedef enum UWordBreakValues { U_WB_MIDNUM = 5, /*[MN]*/ U_WB_NUMERIC = 6, /*[NU]*/ U_WB_EXTENDNUMLET = 7, /*[EX]*/ + /** @stable ICU 4.0 */ U_WB_CR = 8, /*[CR]*/ /* from here on: new in Unicode 5.1/ICU 4.0 */ + /** @stable ICU 4.0 */ U_WB_EXTEND = 9, /*[Extend]*/ + /** @stable ICU 4.0 */ U_WB_LF = 10, /*[LF]*/ + /** @stable ICU 4.0 */ U_WB_MIDNUMLET =11, /*[MB]*/ + /** @stable ICU 4.0 */ U_WB_NEWLINE =12, /*[NL]*/ + /** @stable ICU 50 */ U_WB_REGIONAL_INDICATOR = 13, /*[RI]*/ /* new in Unicode 6.2/ICU 50 */ + /** @stable ICU 52 */ U_WB_HEBREW_LETTER = 14, /*[HL]*/ /* from here on: new in Unicode 6.3/ICU 52 */ + /** @stable ICU 52 */ U_WB_SINGLE_QUOTE = 15, /*[SQ]*/ + /** @stable ICU 52 */ U_WB_DOUBLE_QUOTE = 16, /*[DQ]*/ - U_WB_COUNT = 17 + /** @stable ICU 58 */ + U_WB_E_BASE = 17, /*[EB]*/ /* from here on: new in Unicode 9.0/ICU 58 */ + /** @stable ICU 58 */ + U_WB_E_BASE_GAZ = 18, /*[EBG]*/ + /** @stable ICU 58 */ + U_WB_E_MODIFIER = 19, /*[EM]*/ + /** @stable ICU 58 */ + U_WB_GLUE_AFTER_ZWJ = 20, /*[GAZ]*/ + /** @stable ICU 58 */ + U_WB_ZWJ = 21, /*[ZWJ]*/ + /** @stable ICU 62 */ + U_WB_WSEGSPACE = 22, /*[WSEGSPACE]*/ + +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UWordBreakValues value. + * The highest value is available via u_getIntPropertyMaxValue(UCHAR_WORD_BREAK). + * + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + U_WB_COUNT = 23 +#endif // U_HIDE_DEPRECATED_API } UWordBreakValues; /** @@ -1851,7 +2241,15 @@ typedef enum USentenceBreak { U_SB_EXTEND = 12, /*[EX]*/ U_SB_LF = 13, /*[LF]*/ U_SB_SCONTINUE = 14, /*[SC]*/ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal USentenceBreak value. + * The highest value is available via u_getIntPropertyMaxValue(UCHAR_SENTENCE_BREAK). + * + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ U_SB_COUNT = 15 +#endif // U_HIDE_DEPRECATED_API } USentenceBreak; /** @@ -1898,18 +2296,43 @@ typedef enum ULineBreak { U_LB_SPACE = 26, /*[SP]*/ U_LB_BREAK_SYMBOLS = 27, /*[SY]*/ U_LB_ZWSPACE = 28, /*[ZW]*/ + /** @stable ICU 2.6 */ U_LB_NEXT_LINE = 29, /*[NL]*/ /* from here on: new in Unicode 4/ICU 2.6 */ + /** @stable ICU 2.6 */ U_LB_WORD_JOINER = 30, /*[WJ]*/ + /** @stable ICU 3.4 */ U_LB_H2 = 31, /*[H2]*/ /* from here on: new in Unicode 4.1/ICU 3.4 */ + /** @stable ICU 3.4 */ U_LB_H3 = 32, /*[H3]*/ + /** @stable ICU 3.4 */ U_LB_JL = 33, /*[JL]*/ + /** @stable ICU 3.4 */ U_LB_JT = 34, /*[JT]*/ + /** @stable ICU 3.4 */ U_LB_JV = 35, /*[JV]*/ + /** @stable ICU 4.4 */ U_LB_CLOSE_PARENTHESIS = 36, /*[CP]*/ /* new in Unicode 5.2/ICU 4.4 */ + /** @stable ICU 49 */ U_LB_CONDITIONAL_JAPANESE_STARTER = 37,/*[CJ]*/ /* new in Unicode 6.1/ICU 49 */ + /** @stable ICU 49 */ U_LB_HEBREW_LETTER = 38, /*[HL]*/ /* new in Unicode 6.1/ICU 49 */ + /** @stable ICU 50 */ U_LB_REGIONAL_INDICATOR = 39,/*[RI]*/ /* new in Unicode 6.2/ICU 50 */ - U_LB_COUNT = 40 + /** @stable ICU 58 */ + U_LB_E_BASE = 40, /*[EB]*/ /* from here on: new in Unicode 9.0/ICU 58 */ + /** @stable ICU 58 */ + U_LB_E_MODIFIER = 41, /*[EM]*/ + /** @stable ICU 58 */ + U_LB_ZWJ = 42, /*[ZWJ]*/ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal ULineBreak value. + * The highest value is available via u_getIntPropertyMaxValue(UCHAR_LINE_BREAK). + * + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + U_LB_COUNT = 43 +#endif // U_HIDE_DEPRECATED_API } ULineBreak; /** @@ -1929,7 +2352,15 @@ typedef enum UNumericType { U_NT_DECIMAL, /*[de]*/ U_NT_DIGIT, /*[di]*/ U_NT_NUMERIC, /*[nu]*/ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UNumericType value. + * The highest value is available via u_getIntPropertyMaxValue(UCHAR_NUMERIC_TYPE). + * + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ U_NT_COUNT +#endif // U_HIDE_DEPRECATED_API } UNumericType; /** @@ -1951,9 +2382,172 @@ typedef enum UHangulSyllableType { U_HST_TRAILING_JAMO, /*[T]*/ U_HST_LV_SYLLABLE, /*[LV]*/ U_HST_LVT_SYLLABLE, /*[LVT]*/ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UHangulSyllableType value. + * The highest value is available via u_getIntPropertyMaxValue(UCHAR_HANGUL_SYLLABLE_TYPE). + * + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ U_HST_COUNT +#endif // U_HIDE_DEPRECATED_API } UHangulSyllableType; +/** + * Indic Positional Category constants. + * + * @see UCHAR_INDIC_POSITIONAL_CATEGORY + * @stable ICU 63 + */ +typedef enum UIndicPositionalCategory { + /* + * Note: UIndicPositionalCategory constants are parsed by preparseucd.py. + * It matches lines like + * U_INPC_ + */ + + /** @stable ICU 63 */ + U_INPC_NA, + /** @stable ICU 63 */ + U_INPC_BOTTOM, + /** @stable ICU 63 */ + U_INPC_BOTTOM_AND_LEFT, + /** @stable ICU 63 */ + U_INPC_BOTTOM_AND_RIGHT, + /** @stable ICU 63 */ + U_INPC_LEFT, + /** @stable ICU 63 */ + U_INPC_LEFT_AND_RIGHT, + /** @stable ICU 63 */ + U_INPC_OVERSTRUCK, + /** @stable ICU 63 */ + U_INPC_RIGHT, + /** @stable ICU 63 */ + U_INPC_TOP, + /** @stable ICU 63 */ + U_INPC_TOP_AND_BOTTOM, + /** @stable ICU 63 */ + U_INPC_TOP_AND_BOTTOM_AND_RIGHT, + /** @stable ICU 63 */ + U_INPC_TOP_AND_LEFT, + /** @stable ICU 63 */ + U_INPC_TOP_AND_LEFT_AND_RIGHT, + /** @stable ICU 63 */ + U_INPC_TOP_AND_RIGHT, + /** @stable ICU 63 */ + U_INPC_VISUAL_ORDER_LEFT, +} UIndicPositionalCategory; + +/** + * Indic Syllabic Category constants. + * + * @see UCHAR_INDIC_SYLLABIC_CATEGORY + * @stable ICU 63 + */ +typedef enum UIndicSyllabicCategory { + /* + * Note: UIndicSyllabicCategory constants are parsed by preparseucd.py. + * It matches lines like + * U_INSC_ + */ + + /** @stable ICU 63 */ + U_INSC_OTHER, + /** @stable ICU 63 */ + U_INSC_AVAGRAHA, + /** @stable ICU 63 */ + U_INSC_BINDU, + /** @stable ICU 63 */ + U_INSC_BRAHMI_JOINING_NUMBER, + /** @stable ICU 63 */ + U_INSC_CANTILLATION_MARK, + /** @stable ICU 63 */ + U_INSC_CONSONANT, + /** @stable ICU 63 */ + U_INSC_CONSONANT_DEAD, + /** @stable ICU 63 */ + U_INSC_CONSONANT_FINAL, + /** @stable ICU 63 */ + U_INSC_CONSONANT_HEAD_LETTER, + /** @stable ICU 63 */ + U_INSC_CONSONANT_INITIAL_POSTFIXED, + /** @stable ICU 63 */ + U_INSC_CONSONANT_KILLER, + /** @stable ICU 63 */ + U_INSC_CONSONANT_MEDIAL, + /** @stable ICU 63 */ + U_INSC_CONSONANT_PLACEHOLDER, + /** @stable ICU 63 */ + U_INSC_CONSONANT_PRECEDING_REPHA, + /** @stable ICU 63 */ + U_INSC_CONSONANT_PREFIXED, + /** @stable ICU 63 */ + U_INSC_CONSONANT_SUBJOINED, + /** @stable ICU 63 */ + U_INSC_CONSONANT_SUCCEEDING_REPHA, + /** @stable ICU 63 */ + U_INSC_CONSONANT_WITH_STACKER, + /** @stable ICU 63 */ + U_INSC_GEMINATION_MARK, + /** @stable ICU 63 */ + U_INSC_INVISIBLE_STACKER, + /** @stable ICU 63 */ + U_INSC_JOINER, + /** @stable ICU 63 */ + U_INSC_MODIFYING_LETTER, + /** @stable ICU 63 */ + U_INSC_NON_JOINER, + /** @stable ICU 63 */ + U_INSC_NUKTA, + /** @stable ICU 63 */ + U_INSC_NUMBER, + /** @stable ICU 63 */ + U_INSC_NUMBER_JOINER, + /** @stable ICU 63 */ + U_INSC_PURE_KILLER, + /** @stable ICU 63 */ + U_INSC_REGISTER_SHIFTER, + /** @stable ICU 63 */ + U_INSC_SYLLABLE_MODIFIER, + /** @stable ICU 63 */ + U_INSC_TONE_LETTER, + /** @stable ICU 63 */ + U_INSC_TONE_MARK, + /** @stable ICU 63 */ + U_INSC_VIRAMA, + /** @stable ICU 63 */ + U_INSC_VISARGA, + /** @stable ICU 63 */ + U_INSC_VOWEL, + /** @stable ICU 63 */ + U_INSC_VOWEL_DEPENDENT, + /** @stable ICU 63 */ + U_INSC_VOWEL_INDEPENDENT, +} UIndicSyllabicCategory; + +/** + * Vertical Orientation constants. + * + * @see UCHAR_VERTICAL_ORIENTATION + * @stable ICU 63 + */ +typedef enum UVerticalOrientation { + /* + * Note: UVerticalOrientation constants are parsed by preparseucd.py. + * It matches lines like + * U_VO_ + */ + + /** @stable ICU 63 */ + U_VO_ROTATED, + /** @stable ICU 63 */ + U_VO_TRANSFORMED_ROTATED, + /** @stable ICU 63 */ + U_VO_TRANSFORMED_UPRIGHT, + /** @stable ICU 63 */ + U_VO_UPRIGHT, +} UVerticalOrientation; + /** * Check a binary Unicode property for a code point. * @@ -1976,6 +2570,7 @@ typedef enum UHangulSyllableType { * does not have data for the property at all, or not for this code point. * * @see UProperty + * @see u_getBinaryPropertySet * @see u_getIntPropertyValue * @see u_getUnicodeVersion * @stable ICU 2.1 @@ -1983,6 +2578,28 @@ typedef enum UHangulSyllableType { U_STABLE UBool U_EXPORT2 u_hasBinaryProperty(UChar32 c, UProperty which); +#ifndef U_HIDE_DRAFT_API + +/** + * Returns a frozen USet for a binary property. + * The library retains ownership over the returned object. + * Sets an error code if the property number is not one for a binary property. + * + * The returned set contains all code points for which the property is true. + * + * @param property UCHAR_BINARY_START..UCHAR_BINARY_LIMIT-1 + * @param pErrorCode an in/out ICU UErrorCode + * @return the property as a set + * @see UProperty + * @see u_hasBinaryProperty + * @see Unicode::fromUSet + * @draft ICU 63 + */ +U_CAPI const USet * U_EXPORT2 +u_getBinaryPropertySet(UProperty property, UErrorCode *pErrorCode); + +#endif // U_HIDE_DRAFT_API + /** * Check if a code point has the Alphabetic Unicode property. * Same as u_hasBinaryProperty(c, UCHAR_ALPHABETIC). @@ -2083,6 +2700,7 @@ u_isUWhiteSpace(UChar32 c); * @see u_hasBinaryProperty * @see u_getIntPropertyMinValue * @see u_getIntPropertyMaxValue + * @see u_getIntPropertyMap * @see u_getUnicodeVersion * @stable ICU 2.2 */ @@ -2139,6 +2757,28 @@ u_getIntPropertyMinValue(UProperty which); U_STABLE int32_t U_EXPORT2 u_getIntPropertyMaxValue(UProperty which); +#ifndef U_HIDE_DRAFT_API + +/** + * Returns an immutable UCPMap for an enumerated/catalog/int-valued property. + * The library retains ownership over the returned object. + * Sets an error code if the property number is not one for an "int property". + * + * The returned object maps all Unicode code points to their values for that property. + * For documentation of the integer values see u_getIntPropertyValue(). + * + * @param property UCHAR_INT_START..UCHAR_INT_LIMIT-1 + * @param pErrorCode an in/out ICU UErrorCode + * @return the property as a map + * @see UProperty + * @see u_getIntPropertyValue + * @draft ICU 63 + */ +U_CAPI const UCPMap * U_EXPORT2 +u_getIntPropertyMap(UProperty property, UErrorCode *pErrorCode); + +#endif // U_HIDE_DRAFT_API + /** * Get the numeric value for a Unicode code point as defined in the * Unicode Character Database. @@ -2375,8 +3015,7 @@ u_isgraph(UChar32 c); * * same as * - * TRUE for U+0009 (TAB) and characters with general category "Zs" (space separators) - * except Zero Width Space (ZWSP, U+200B). + * TRUE for U+0009 (TAB) and characters with general category "Zs" (space separators). * * Note: There are several ICU whitespace functions; please see the uchar.h * file documentation for a detailed comparison. @@ -2562,8 +3201,8 @@ u_isprint(UChar32 c); * True for general categories "L" (letters), "N" (numbers), * "Mc" (spacing combining marks), and "Me" (enclosing marks). * - * Note that this is different from the Unicode definition in - * chapter 3.5, conformance clause D13, + * Note that this is different from the definition in the Unicode + * Standard section 3.6, conformance clause D51, * which defines base characters to be all characters (not Cn) * that do not graphically combine with preceding characters (M) * and that are neither control (Cc) or format (Cf) characters. @@ -2816,7 +3455,7 @@ u_charName(UChar32 code, UCharNameChoice nameChoice, char *buffer, int32_t bufferLength, UErrorCode *pErrorCode); -#ifndef U_HIDE_DEPRECATED_API +#ifndef U_HIDE_DEPRECATED_API /** * Returns an empty string. * Used to return the ISO 10646 comment for a character. @@ -3243,27 +3882,6 @@ u_toupper(UChar32 c); U_STABLE UChar32 U_EXPORT2 u_totitle(UChar32 c); -/** Option value for case folding: use default mappings defined in CaseFolding.txt. @stable ICU 2.0 */ -#define U_FOLD_CASE_DEFAULT 0 - -/** - * Option value for case folding: - * - * Use the modified set of mappings provided in CaseFolding.txt to handle dotted I - * and dotless i appropriately for Turkic languages (tr, az). - * - * Before Unicode 3.2, CaseFolding.txt contains mappings marked with 'I' that - * are to be included for default mappings and - * excluded for the Turkic-specific mappings. - * - * Unicode 3.2 CaseFolding.txt instead contains mappings marked with 'T' that - * are to be excluded for default mappings and - * included for the Turkic-specific mappings. - * - * @stable ICU 2.0 - */ -#define U_FOLD_CASE_EXCLUDE_SPECIAL_I 1 - /** * The given character is mapped to its case folding equivalent according to * UnicodeData.txt and CaseFolding.txt; diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucharstrie.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucharstrie.h index 0575a974d0..533e8c554b 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucharstrie.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucharstrie.h @@ -1,10 +1,12 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2010-2012, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* * file name: ucharstrie.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -26,6 +28,7 @@ #include "unicode/uobject.h" #include "unicode/ustringtrie.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class Appendable; @@ -34,7 +37,7 @@ class UVector32; /** * Light-weight, non-const reader class for a UCharsTrie. - * Traverses a UChar-serialized data structure with minimal state, + * Traverses a char16_t-serialized data structure with minimal state, * for mapping strings (16-bit-unit sequences) to non-negative integer values. * * This class owns the serialized trie data only if it was constructed by @@ -50,18 +53,18 @@ class U_COMMON_API UCharsTrie : public UMemory { /** * Constructs a UCharsTrie reader instance. * - * The trieUChars must contain a copy of a UChar sequence from the UCharsTrieBuilder, - * starting with the first UChar of that sequence. - * The UCharsTrie object will not read more UChars than + * The trieUChars must contain a copy of a char16_t sequence from the UCharsTrieBuilder, + * starting with the first char16_t of that sequence. + * The UCharsTrie object will not read more char16_ts than * the UCharsTrieBuilder generated in the corresponding build() call. * * The array is not copied/cloned and must not be modified while * the UCharsTrie object is in use. * - * @param trieUChars The UChar array that contains the serialized trie. + * @param trieUChars The char16_t array that contains the serialized trie. * @stable ICU 4.8 */ - UCharsTrie(const UChar *trieUChars) + UCharsTrie(ConstChar16Ptr trieUChars) : ownedArray_(NULL), uchars_(trieUChars), pos_(uchars_), remainingMatchLength_(-1) {} @@ -73,7 +76,7 @@ class U_COMMON_API UCharsTrie : public UMemory { /** * Copy constructor, copies the other trie reader object and its state, - * but not the UChar array which will be shared. (Shallow copy.) + * but not the char16_t array which will be shared. (Shallow copy.) * @param other Another UCharsTrie object. * @stable ICU 4.8 */ @@ -107,8 +110,8 @@ class U_COMMON_API UCharsTrie : public UMemory { private: friend class UCharsTrie; - const UChar *uchars; - const UChar *pos; + const char16_t *uchars; + const char16_t *pos; int32_t remainingMatchLength; }; @@ -146,14 +149,14 @@ class U_COMMON_API UCharsTrie : public UMemory { /** * Determines whether the string so far matches, whether it has a value, - * and whether another input UChar can continue a matching string. + * and whether another input char16_t can continue a matching string. * @return The match/value Result. * @stable ICU 4.8 */ UStringTrieResult current() const; /** - * Traverses the trie from the initial state for this input UChar. + * Traverses the trie from the initial state for this input char16_t. * Equivalent to reset().next(uchar). * @param uchar Input char value. Values below 0 and above 0xffff will never match. * @return The match/value Result. @@ -175,7 +178,7 @@ class U_COMMON_API UCharsTrie : public UMemory { UStringTrieResult firstForCodePoint(UChar32 cp); /** - * Traverses the trie from the current state for this input UChar. + * Traverses the trie from the current state for this input char16_t. * @param uchar Input char value. Values below 0 and above 0xffff will never match. * @return The match/value Result. * @stable ICU 4.8 @@ -206,7 +209,7 @@ class U_COMMON_API UCharsTrie : public UMemory { * @return The match/value Result. * @stable ICU 4.8 */ - UStringTrieResult next(const UChar *s, int32_t length); + UStringTrieResult next(ConstChar16Ptr s, int32_t length); /** * Returns a matching string's value if called immediately after @@ -218,7 +221,7 @@ class U_COMMON_API UCharsTrie : public UMemory { * @stable ICU 4.8 */ inline int32_t getValue() const { - const UChar *pos=pos_; + const char16_t *pos=pos_; int32_t leadUnit=*pos++; // U_ASSERT(leadUnit>=kMinValueLead); return leadUnit&kValueIsFinal ? @@ -235,16 +238,16 @@ class U_COMMON_API UCharsTrie : public UMemory { * @stable ICU 4.8 */ inline UBool hasUniqueValue(int32_t &uniqueValue) const { - const UChar *pos=pos_; + const char16_t *pos=pos_; // Skip the rest of a pending linear-match node. return pos!=NULL && findUniqueValue(pos+remainingMatchLength_+1, FALSE, uniqueValue); } /** - * Finds each UChar which continues the string from the current state. - * That is, each UChar c for which it would be next(c)!=USTRINGTRIE_NO_MATCH now. - * @param out Each next UChar is appended to this object. - * @return the number of UChars which continue the string from here + * Finds each char16_t which continues the string from the current state. + * That is, each char16_t c for which it would be next(c)!=USTRINGTRIE_NO_MATCH now. + * @param out Each next char16_t is appended to this object. + * @return the number of char16_ts which continue the string from here * @stable ICU 4.8 */ int32_t getNextUChars(Appendable &out) const; @@ -256,8 +259,8 @@ class U_COMMON_API UCharsTrie : public UMemory { class U_COMMON_API Iterator : public UMemory { public: /** - * Iterates from the root of a UChar-serialized UCharsTrie. - * @param trieUChars The trie UChars. + * Iterates from the root of a char16_t-serialized UCharsTrie. + * @param trieUChars The trie char16_ts. * @param maxStringLength If 0, the iterator returns full strings. * Otherwise, the iterator returns strings with this maximum length. * @param errorCode Standard ICU error code. Its input value must @@ -266,7 +269,7 @@ class U_COMMON_API UCharsTrie : public UMemory { * function chaining. (See User Guide for details.) * @stable ICU 4.8 */ - Iterator(const UChar *trieUChars, int32_t maxStringLength, UErrorCode &errorCode); + Iterator(ConstChar16Ptr trieUChars, int32_t maxStringLength, UErrorCode &errorCode); /** * Iterates from the current state of the specified UCharsTrie. @@ -334,11 +337,11 @@ class U_COMMON_API UCharsTrie : public UMemory { return TRUE; } - const UChar *branchNext(const UChar *pos, int32_t length, UErrorCode &errorCode); + const char16_t *branchNext(const char16_t *pos, int32_t length, UErrorCode &errorCode); - const UChar *uchars_; - const UChar *pos_; - const UChar *initialPos_; + const char16_t *uchars_; + const char16_t *pos_; + const char16_t *initialPos_; int32_t remainingMatchLength_; int32_t initialRemainingMatchLength_; UBool skipValue_; // Skip intermediate value which was already delivered. @@ -366,7 +369,7 @@ class U_COMMON_API UCharsTrie : public UMemory { * this constructor adopts the builder's array. * This constructor is only called by the builder. */ - UCharsTrie(UChar *adoptUChars, const UChar *trieUChars) + UCharsTrie(char16_t *adoptUChars, const char16_t *trieUChars) : ownedArray_(adoptUChars), uchars_(trieUChars), pos_(uchars_), remainingMatchLength_(-1) {} @@ -379,7 +382,7 @@ class U_COMMON_API UCharsTrie : public UMemory { // Reads a compact 32-bit integer. // pos is already after the leadUnit, and the lead unit has bit 15 reset. - static inline int32_t readValue(const UChar *pos, int32_t leadUnit) { + static inline int32_t readValue(const char16_t *pos, int32_t leadUnit) { int32_t value; if(leadUnit=kMinTwoUnitValueLead) { if(leadUnit=kMinTwoUnitNodeValueLead) { if(leadUnit=kMinTwoUnitDeltaLead) { if(delta==kThreeUnitDeltaLead) { @@ -442,7 +445,7 @@ class U_COMMON_API UCharsTrie : public UMemory { return pos+delta; } - static const UChar *skipDelta(const UChar *pos) { + static const char16_t *skipDelta(const char16_t *pos) { int32_t delta=*pos++; if(delta>=kMinTwoUnitDeltaLead) { if(delta==kThreeUnitDeltaLead) { @@ -459,28 +462,28 @@ class U_COMMON_API UCharsTrie : public UMemory { } // Handles a branch node for both next(uchar) and next(string). - UStringTrieResult branchNext(const UChar *pos, int32_t length, int32_t uchar); + UStringTrieResult branchNext(const char16_t *pos, int32_t length, int32_t uchar); // Requires remainingLength_<0. - UStringTrieResult nextImpl(const UChar *pos, int32_t uchar); + UStringTrieResult nextImpl(const char16_t *pos, int32_t uchar); // Helper functions for hasUniqueValue(). // Recursively finds a unique value (or whether there is not a unique one) // from a branch. - static const UChar *findUniqueValueFromBranch(const UChar *pos, int32_t length, + static const char16_t *findUniqueValueFromBranch(const char16_t *pos, int32_t length, UBool haveUniqueValue, int32_t &uniqueValue); // Recursively finds a unique value (or whether there is not a unique one) // starting from a position on a node lead unit. - static UBool findUniqueValue(const UChar *pos, UBool haveUniqueValue, int32_t &uniqueValue); + static UBool findUniqueValue(const char16_t *pos, UBool haveUniqueValue, int32_t &uniqueValue); // Helper functions for getNextUChars(). // getNextUChars() when pos is on a branch node. - static void getNextBranchUChars(const UChar *pos, int32_t length, Appendable &out); + static void getNextBranchUChars(const char16_t *pos, int32_t length, Appendable &out); // UCharsTrie data structure // - // The trie consists of a series of UChar-serialized nodes for incremental - // Unicode string/UChar sequence matching. (UChar=16-bit unsigned integer) + // The trie consists of a series of char16_t-serialized nodes for incremental + // Unicode string/char16_t sequence matching. (char16_t=16-bit unsigned integer) // The root node is at the beginning of the trie data. // // Types of nodes are distinguished by their node lead unit ranges. @@ -489,9 +492,9 @@ class U_COMMON_API UCharsTrie : public UMemory { // // Node types: // - Final-value node: Stores a 32-bit integer in a compact, variable-length format. - // The value is for the string/UChar sequence so far. + // The value is for the string/char16_t sequence so far. // - Match node, optionally with an intermediate value in a different compact format. - // The value, if present, is for the string/UChar sequence so far. + // The value, if present, is for the string/char16_t sequence so far. // // Aside from the value, which uses the node lead unit's high bits: // @@ -558,19 +561,20 @@ class U_COMMON_API UCharsTrie : public UMemory { static const int32_t kMaxTwoUnitDelta=((kThreeUnitDeltaLead-kMinTwoUnitDeltaLead)<<16)-1; // 0x03feffff - UChar *ownedArray_; + char16_t *ownedArray_; // Fixed value referencing the UCharsTrie words. - const UChar *uchars_; + const char16_t *uchars_; // Iterator variables. // Pointer to next trie unit to read. NULL if no more matches. - const UChar *pos_; + const char16_t *pos_; // Remaining length of a linear-match node, minus 1. Negative if not in such a node. int32_t remainingMatchLength_; }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // __UCHARSTRIE_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucharstriebuilder.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucharstriebuilder.h index 35e353d41b..e8e7390bdc 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucharstriebuilder.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucharstriebuilder.h @@ -1,10 +1,12 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* -* Copyright (C) 2010-2014, International Business Machines +* Copyright (C) 2010-2016, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* * file name: ucharstriebuilder.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -25,6 +27,7 @@ * \brief C++ API: Builder for icu::UCharsTrie */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class UCharsTrieElement; @@ -87,21 +90,21 @@ class U_COMMON_API UCharsTrieBuilder : public StringTrieBuilder { UCharsTrie *build(UStringTrieBuildOption buildOption, UErrorCode &errorCode); /** - * Builds a UCharsTrie for the add()ed data and UChar-serializes it. + * Builds a UCharsTrie for the add()ed data and char16_t-serializes it. * Once built, no further data can be add()ed until clear() is called. * * A UCharsTrie cannot be empty. At least one (string, value) pair * must have been add()ed. * * Multiple calls to buildUnicodeString() set the UnicodeStrings to the - * builder's same UChar array, without rebuilding. + * builder's same char16_t array, without rebuilding. * If buildUnicodeString() is called after build(), the trie will be * re-serialized into a new array. * If build() is called after buildUnicodeString(), the trie object will become * the owner of the previously returned array. * After clear() has been called, a new array will be used as well. * @param buildOption Build option, see UStringTrieBuildOption. - * @param result A UnicodeString which will be set to the UChar-serialized + * @param result A UnicodeString which will be set to the char16_t-serialized * UCharsTrie for the add()ed data. * @param errorCode Standard ICU error code. Its input value must * pass the U_SUCCESS() test, or else the function returns @@ -133,14 +136,14 @@ class U_COMMON_API UCharsTrieBuilder : public StringTrieBuilder { void buildUChars(UStringTrieBuildOption buildOption, UErrorCode &errorCode); virtual int32_t getElementStringLength(int32_t i) const; - virtual UChar getElementUnit(int32_t i, int32_t unitIndex) const; + virtual char16_t getElementUnit(int32_t i, int32_t unitIndex) const; virtual int32_t getElementValue(int32_t i) const; virtual int32_t getLimitOfLinearMatch(int32_t first, int32_t last, int32_t unitIndex) const; virtual int32_t countElementUnits(int32_t start, int32_t limit, int32_t unitIndex) const; virtual int32_t skipElementsBySomeUnits(int32_t i, int32_t unitIndex, int32_t count) const; - virtual int32_t indexOfElementWithNextUnit(int32_t i, int32_t unitIndex, UChar unit) const; + virtual int32_t indexOfElementWithNextUnit(int32_t i, int32_t unitIndex, char16_t unit) const; virtual UBool matchNodesCanHaveValues() const { return TRUE; } @@ -150,11 +153,11 @@ class U_COMMON_API UCharsTrieBuilder : public StringTrieBuilder { class UCTLinearMatchNode : public LinearMatchNode { public: - UCTLinearMatchNode(const UChar *units, int32_t len, Node *nextNode); + UCTLinearMatchNode(const char16_t *units, int32_t len, Node *nextNode); virtual UBool operator==(const Node &other) const; virtual void write(StringTrieBuilder &builder); private: - const UChar *s; + const char16_t *s; }; virtual Node *createLinearMatchNode(int32_t i, int32_t unitIndex, int32_t length, @@ -162,7 +165,7 @@ class U_COMMON_API UCharsTrieBuilder : public StringTrieBuilder { UBool ensureCapacity(int32_t length); virtual int32_t write(int32_t unit); - int32_t write(const UChar *s, int32_t length); + int32_t write(const char16_t *s, int32_t length); virtual int32_t writeElementUnits(int32_t i, int32_t unitIndex, int32_t length); virtual int32_t writeValueAndFinal(int32_t i, UBool isFinal); virtual int32_t writeValueAndType(UBool hasValue, int32_t value, int32_t node); @@ -173,13 +176,14 @@ class U_COMMON_API UCharsTrieBuilder : public StringTrieBuilder { int32_t elementsCapacity; int32_t elementsLength; - // UChar serialization of the trie. + // char16_t serialization of the trie. // Grows from the back: ucharsLength measures from the end of the buffer! - UChar *uchars; + char16_t *uchars; int32_t ucharsCapacity; int32_t ucharsLength; }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif // __UCHARSTRIEBUILDER_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uchriter.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uchriter.h index 6d5a990f7b..686f87e1f5 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uchriter.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uchriter.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1998-2005, International Business Machines @@ -13,18 +15,19 @@ /** * \file - * \brief C++ API: UChar Character Iterator + * \brief C++ API: char16_t Character Iterator */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** * A concrete subclass of CharacterIterator that iterates over the - * characters (code units or code points) in a UChar array. + * characters (code units or code points) in a char16_t array. * It's possible not only to create an - * iterator that iterates over an entire UChar array, but also to - * create one that iterates over only a subrange of a UChar array - * (iterators over different subranges of the same UChar array don't + * iterator that iterates over an entire char16_t array, but also to + * create one that iterates over only a subrange of a char16_t array + * (iterators over different subranges of the same char16_t array don't * compare equal). * @see CharacterIterator * @see ForwardCharacterIterator @@ -33,34 +36,34 @@ U_NAMESPACE_BEGIN class U_COMMON_API UCharCharacterIterator : public CharacterIterator { public: /** - * Create an iterator over the UChar array referred to by "textPtr". + * Create an iterator over the char16_t array referred to by "textPtr". * The iteration range is 0 to length-1. * text is only aliased, not adopted (the * destructor will not delete it). - * @param textPtr The UChar array to be iterated over - * @param length The length of the UChar array + * @param textPtr The char16_t array to be iterated over + * @param length The length of the char16_t array * @stable ICU 2.0 */ - UCharCharacterIterator(const UChar* textPtr, int32_t length); + UCharCharacterIterator(ConstChar16Ptr textPtr, int32_t length); /** - * Create an iterator over the UChar array referred to by "textPtr". + * Create an iterator over the char16_t array referred to by "textPtr". * The iteration range is 0 to length-1. * text is only aliased, not adopted (the * destructor will not delete it). * The starting * position is specified by "position". If "position" is outside the valid * iteration range, the behavior of this object is undefined. - * @param textPtr The UChar array to be iteratd over - * @param length The length of the UChar array + * @param textPtr The char16_t array to be iteratd over + * @param length The length of the char16_t array * @param position The starting position of the iteration * @stable ICU 2.0 */ - UCharCharacterIterator(const UChar* textPtr, int32_t length, + UCharCharacterIterator(ConstChar16Ptr textPtr, int32_t length, int32_t position); /** - * Create an iterator over the UChar array referred to by "textPtr". + * Create an iterator over the char16_t array referred to by "textPtr". * The iteration range is 0 to end-1. * text is only aliased, not adopted (the * destructor will not delete it). @@ -68,14 +71,14 @@ class U_COMMON_API UCharCharacterIterator : public CharacterIterator { * position is specified by "position". If begin and end do not * form a valid iteration range or "position" is outside the valid * iteration range, the behavior of this object is undefined. - * @param textPtr The UChar array to be iterated over - * @param length The length of the UChar array + * @param textPtr The char16_t array to be iterated over + * @param length The length of the char16_t array * @param textBegin The begin position of the iteration range * @param textEnd The end position of the iteration range * @param position The starting position of the iteration * @stable ICU 2.0 */ - UCharCharacterIterator(const UChar* textPtr, int32_t length, + UCharCharacterIterator(ConstChar16Ptr textPtr, int32_t length, int32_t textBegin, int32_t textEnd, int32_t position); @@ -139,7 +142,7 @@ class U_COMMON_API UCharCharacterIterator : public CharacterIterator { * @return the first code unit in its iteration range. * @stable ICU 2.0 */ - virtual UChar first(void); + virtual char16_t first(void); /** * Sets the iterator to refer to the first code unit in its @@ -149,7 +152,7 @@ class U_COMMON_API UCharCharacterIterator : public CharacterIterator { * @return the first code unit in its iteration range * @stable ICU 2.0 */ - virtual UChar firstPostInc(void); + virtual char16_t firstPostInc(void); /** * Sets the iterator to refer to the first code point in its @@ -179,7 +182,7 @@ class U_COMMON_API UCharCharacterIterator : public CharacterIterator { * @return the last code unit in its iteration range. * @stable ICU 2.0 */ - virtual UChar last(void); + virtual char16_t last(void); /** * Sets the iterator to refer to the last code point in its @@ -198,7 +201,7 @@ class U_COMMON_API UCharCharacterIterator : public CharacterIterator { * @return the code unit * @stable ICU 2.0 */ - virtual UChar setIndex(int32_t position); + virtual char16_t setIndex(int32_t position); /** * Sets the iterator to refer to the beginning of the code point @@ -218,7 +221,7 @@ class U_COMMON_API UCharCharacterIterator : public CharacterIterator { * @return the code unit the iterator currently refers to. * @stable ICU 2.0 */ - virtual UChar current(void) const; + virtual char16_t current(void) const; /** * Returns the code point the iterator currently refers to. @@ -234,7 +237,7 @@ class U_COMMON_API UCharCharacterIterator : public CharacterIterator { * @return the next code unit in the iteration range. * @stable ICU 2.0 */ - virtual UChar next(void); + virtual char16_t next(void); /** * Gets the current code unit for returning and advances to the next code unit @@ -244,7 +247,7 @@ class U_COMMON_API UCharCharacterIterator : public CharacterIterator { * @return the current code unit. * @stable ICU 2.0 */ - virtual UChar nextPostInc(void); + virtual char16_t nextPostInc(void); /** * Advances to the next code point in the iteration range (toward @@ -286,7 +289,7 @@ class U_COMMON_API UCharCharacterIterator : public CharacterIterator { * @return the previous code unit in the iteration range. * @stable ICU 2.0 */ - virtual UChar previous(void); + virtual char16_t previous(void); /** * Advances to the previous code point in the iteration range (toward @@ -332,16 +335,20 @@ class U_COMMON_API UCharCharacterIterator : public CharacterIterator { * @return the new position * @stable ICU 2.0 */ +#ifdef move32 + // One of the system headers right now is sometimes defining a conflicting macro we don't use +#undef move32 +#endif virtual int32_t move32(int32_t delta, EOrigin origin); /** * Sets the iterator to iterate over a new range of text * @stable ICU 2.0 */ - void setText(const UChar* newText, int32_t newTextLength); + void setText(ConstChar16Ptr newText, int32_t newTextLength); /** - * Copies the UChar array under iteration into the UnicodeString + * Copies the char16_t array under iteration into the UnicodeString * referred to by "result". Even if this iterator iterates across * only a part of this string, the whole string is copied. * @param result Receives a copy of the text under iteration. @@ -373,9 +380,11 @@ class U_COMMON_API UCharCharacterIterator : public CharacterIterator { * Protected member text * @stable ICU 2.0 */ - const UChar* text; + const char16_t* text; }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API + #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uclean.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uclean.h index d9a1e53905..7cef6dba68 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uclean.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uclean.h @@ -1,10 +1,12 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2001-2014, International Business Machines * Corporation and others. All Rights Reserved. ****************************************************************************** * file name: uclean.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -68,7 +70,7 @@ u_init(UErrorCode *status); * This has the effect of restoring ICU to its initial condition, before * any of these override functions were installed. Refer to * u_setMemoryFunctions(), u_setMutexFunctions and - * utrace_setFunctions(). If ICU is to be reinitialized after after + * utrace_setFunctions(). If ICU is to be reinitialized after * calling u_cleanup(), these runtime override functions will need to * be set up again if they are still required. *

        @@ -99,10 +101,10 @@ u_init(UErrorCode *status); U_STABLE void U_EXPORT2 u_cleanup(void); - +U_CDECL_BEGIN /** * Pointer type for a user supplied memory allocation function. - * @param context user supplied value, obtained from from u_setMemoryFunctions(). + * @param context user supplied value, obtained from u_setMemoryFunctions(). * @param size The number of bytes to be allocated * @return Pointer to the newly allocated memory, or NULL if the allocation failed. * @stable ICU 2.8 @@ -111,7 +113,7 @@ u_cleanup(void); typedef void *U_CALLCONV UMemAllocFn(const void *context, size_t size); /** * Pointer type for a user supplied memory re-allocation function. - * @param context user supplied value, obtained from from u_setMemoryFunctions(). + * @param context user supplied value, obtained from u_setMemoryFunctions(). * @param size The number of bytes to be allocated * @return Pointer to the newly allocated memory, or NULL if the allocation failed. * @stable ICU 2.8 @@ -121,7 +123,7 @@ typedef void *U_CALLCONV UMemReallocFn(const void *context, void *mem, size_t si /** * Pointer type for a user supplied memory free function. Behavior should be * similar the standard C library free(). - * @param context user supplied value, obtained from from u_setMemoryFunctions(). + * @param context user supplied value, obtained from u_setMemoryFunctions(). * @param mem Pointer to the memory block to be resized * @param size The new size for the block * @return Pointer to the resized memory block, or NULL if the resizing failed. @@ -147,9 +149,10 @@ typedef void U_CALLCONV UMemFreeFn (const void *context, void *mem); * @system */ U_STABLE void U_EXPORT2 -u_setMemoryFunctions(const void *context, UMemAllocFn *a, UMemReallocFn *r, UMemFreeFn *f, +u_setMemoryFunctions(const void *context, UMemAllocFn * U_CALLCONV_FPTR a, UMemReallocFn * U_CALLCONV_FPTR r, UMemFreeFn * U_CALLCONV_FPTR f, UErrorCode *status); +U_CDECL_END #ifndef U_HIDE_DEPRECATED_API /********************************************************************************* @@ -170,13 +173,14 @@ u_setMemoryFunctions(const void *context, UMemAllocFn *a, UMemReallocFn *r, UMem */ typedef void *UMTX; +U_CDECL_BEGIN /** * Function Pointer type for a user supplied mutex initialization function. * The user-supplied function will be called by ICU whenever ICU needs to create a * new mutex. The function implementation should create a mutex, and store a pointer * to something that uniquely identifies the mutex into the UMTX that is supplied - * as a paramter. - * @param context user supplied value, obtained from from u_setMutexFunctions(). + * as a parameter. + * @param context user supplied value, obtained from u_setMutexFunctions(). * @param mutex Receives a pointer that identifies the new mutex. * The mutex init function must set the UMTX to a non-null value. * Subsequent calls by ICU to lock, unlock, or destroy a mutex will @@ -193,13 +197,13 @@ typedef void U_CALLCONV UMtxInitFn (const void *context, UMTX *mutex, UErrorCod * Function Pointer type for a user supplied mutex functions. * One of the user-supplied functions with this signature will be called by ICU * whenever ICU needs to lock, unlock, or destroy a mutex. - * @param context user supplied value, obtained from from u_setMutexFunctions(). + * @param context user supplied value, obtained from u_setMutexFunctions(). * @param mutex specify the mutex on which to operate. * @deprecated ICU 52. This function is no longer supported. * @system */ typedef void U_CALLCONV UMtxFn (const void *context, UMTX *mutex); - +U_CDECL_END /** * Set the functions that ICU will use for mutex operations @@ -225,7 +229,7 @@ u_setMutexFunctions(const void *context, UMtxInitFn *init, UMtxFn *destroy, UMtx /** * Pointer type for a user supplied atomic increment or decrement function. - * @param context user supplied value, obtained from from u_setAtomicIncDecFunctions(). + * @param context user supplied value, obtained from u_setAtomicIncDecFunctions(). * @param p Pointer to a 32 bit int to be incremented or decremented * @return The value of the variable after the inc or dec operation. * @deprecated ICU 52. This function is no longer supported. diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucnv.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucnv.h index 564656c284..902bc1595e 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucnv.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucnv.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2014, International Business Machines @@ -27,7 +29,7 @@ * converter, you can get its properties, set options, convert your data and * close the converter.

        * - *

        Since many software programs recogize different converter names for + *

        Since many software programs recognize different converter names for * different types of converters, there are other functions in this API to * iterate over the converter aliases. The functions {@link ucnv_getAvailableName() }, * {@link ucnv_getAlias() } and {@link ucnv_getStandardName() } are some of the @@ -51,19 +53,18 @@ #include "unicode/uenum.h" #include "unicode/localpointer.h" -#ifndef __USET_H__ +#if !defined(USET_DEFINED) && !defined(U_IN_DOXYGEN) + +#define USET_DEFINED /** - * USet is the C API type for Unicode sets. - * It is forward-declared here to avoid including the header file if related + * USet is the C API type corresponding to C++ class UnicodeSet. + * It is forward-declared here to avoid including unicode/uset.h file if related * conversion APIs are not used. - * See unicode/uset.h * * @see ucnv_getUnicodeSet - * @stable ICU 2.6 + * @stable ICU 2.4 */ -struct USet; -/** @stable ICU 2.6 */ typedef struct USet USet; #endif @@ -182,7 +183,7 @@ typedef enum { /** * Function pointer for error callback in the codepage to unicode direction. - * Called when an error has occured in conversion to unicode, or on open/close of the callback (see reason). + * Called when an error has occurred in conversion to unicode, or on open/close of the callback (see reason). * @param context Pointer to the callback's private data * @param args Information about the conversion in progress * @param codeUnits Points to 'length' bytes of the concerned codepage sequence @@ -205,7 +206,7 @@ typedef void (U_EXPORT2 *UConverterToUCallback) ( /** * Function pointer for error callback in the unicode to codepage direction. - * Called when an error has occured in conversion from unicode, or on open/close of the callback (see reason). + * Called when an error has occurred in conversion from unicode, or on open/close of the callback (see reason). * @param context Pointer to the callback's private data * @param args Information about the conversion in progress * @param codeUnits Points to 'length' UChars of the concerned Unicode sequence @@ -351,7 +352,7 @@ ucnv_compareNames(const char *name1, const char *name2); * ucnv_getAlias for a complete list that is available. * If this parameter is NULL, the default converter will be used. * @param err outgoing error status U_MEMORY_ALLOCATION_ERROR, U_FILE_ACCESS_ERROR - * @return the created Unicode converter object, or NULL if an error occured + * @return the created Unicode converter object, or NULL if an error occurred * @see ucnv_openU * @see ucnv_openCCSID * @see ucnv_getAvailableName @@ -384,7 +385,7 @@ ucnv_open(const char *converterName, UErrorCode *err); * @param err outgoing error status U_MEMORY_ALLOCATION_ERROR, * U_FILE_ACCESS_ERROR * @return the created Unicode converter object, or NULL if an - * error occured + * error occurred * @see ucnv_open * @see ucnv_openCCSID * @see ucnv_close @@ -450,7 +451,7 @@ ucnv_openU(const UChar *name, * @param platform the platform in which the codepage number exists * @param err error status U_MEMORY_ALLOCATION_ERROR, U_FILE_ACCESS_ERROR * @return the created Unicode converter object, or NULL if an error - * occured. + * occurred. * @see ucnv_open * @see ucnv_openU * @see ucnv_close @@ -487,7 +488,7 @@ ucnv_openCCSID(int32_t codepage, * @param packageName name of the package (equivalent to 'path' in udata_open() call) * @param converterName name of the data item to be used, without suffix. * @param err outgoing error status U_MEMORY_ALLOCATION_ERROR, U_FILE_ACCESS_ERROR - * @return the created Unicode converter object, or NULL if an error occured + * @return the created Unicode converter object, or NULL if an error occurred * @see udata_open * @see ucnv_open * @see ucnv_safeClone @@ -585,7 +586,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUConverterPointer, UConverter, ucnv_close); U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Fills in the output parameter, subChars, with the substitution characters @@ -594,7 +595,7 @@ U_NAMESPACE_END * stateful, then subChars will be an empty string. * * @param converter the Unicode converter - * @param subChars the subsitution characters + * @param subChars the substitution characters * @param len on input the capacity of subChars, on output the number * of bytes copied to it * @param err the outgoing error status code. @@ -830,7 +831,7 @@ ucnv_getMinCharSize(const UConverter *converter); * name will be filled in. * * @param converter the Unicode converter. - * @param displayLocale is the specific Locale we want to localised for + * @param displayLocale is the specific Locale we want to localized for * @param displayName user provided buffer to be filled in * @param displayNameCapacity size of displayName Buffer * @param err error status code @@ -875,7 +876,7 @@ ucnv_getName(const UConverter *converter, UErrorCode *err); * * @param converter the Unicode converter * @param err the error status code. - * @return If any error occurrs, -1 will be returned otherwise, the codepage number + * @return If any error occurs, -1 will be returned otherwise, the codepage number * will be returned * @see ucnv_openCCSID * @see ucnv_getPlatform @@ -941,8 +942,13 @@ typedef enum UConverterUnicodeSet { UCNV_ROUNDTRIP_SET, /** Select the set of Unicode code points with roundtrip or fallback mappings. @stable ICU 4.0 */ UCNV_ROUNDTRIP_AND_FALLBACK_SET, - /** Number of UConverterUnicodeSet selectors. @stable ICU 2.6 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * Number of UConverterUnicodeSet selectors. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UCNV_SET_COUNT +#endif // U_HIDE_DEPRECATED_API } UConverterUnicodeSet; diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucnv_cb.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucnv_cb.h index f0e67ba11e..14169ed61c 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucnv_cb.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucnv_cb.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2000-2004, International Business Machines diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucnv_err.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucnv_err.h index e092e95f80..d234710a8b 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucnv_err.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucnv_err.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2009, International Business Machines @@ -117,19 +119,19 @@ typedef struct UConverter UConverter; #define UCNV_ESCAPE_JAVA "J" /** * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to C (\\uXXXX \\UXXXXXXXX) - * TO_U_CALLBACK_ESCAPE option to escape the character value accoding to C (\\xXXXX) + * TO_U_CALLBACK_ESCAPE option to escape the character value according to C (\\xXXXX) * @stable ICU 2.0 */ #define UCNV_ESCAPE_C "C" /** * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to XML Decimal escape \htmlonly(&#DDDD;)\endhtmlonly - * TO_U_CALLBACK_ESCAPE context option to escape the character value accoding to XML Decimal escape \htmlonly(&#DDDD;)\endhtmlonly + * TO_U_CALLBACK_ESCAPE context option to escape the character value according to XML Decimal escape \htmlonly(&#DDDD;)\endhtmlonly * @stable ICU 2.0 */ #define UCNV_ESCAPE_XML_DEC "D" /** * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to XML Hex escape \htmlonly(&#xXXXX;)\endhtmlonly - * TO_U_CALLBACK_ESCAPE context option to escape the character value accoding to XML Hex escape \htmlonly(&#xXXXX;)\endhtmlonly + * TO_U_CALLBACK_ESCAPE context option to escape the character value according to XML Hex escape \htmlonly(&#xXXXX;)\endhtmlonly * @stable ICU 2.0 */ #define UCNV_ESCAPE_XML_HEX "X" @@ -169,7 +171,7 @@ typedef enum { code points. The error code U_INVALID_CHAR_FOUND will be set. */ UCNV_RESET = 3, /**< The callback is called with this reason when a - 'reset' has occured. Callback should reset all + 'reset' has occurred. Callback should reset all state. */ UCNV_CLOSE = 4, /**< Called when the converter is closed. The callback should release any allocated memory.*/ @@ -197,7 +199,7 @@ typedef struct { const UChar *sourceLimit; /**< Pointer to the limit (end + 1) of source buffer. @stable ICU 2.0 */ char *target; /**< Pointer to the target buffer. @stable ICU 2.0 */ const char *targetLimit; /**< Pointer to the limit (end + 1) of target buffer. @stable ICU 2.0 */ - int32_t *offsets; /**< Pointer to the buffer that recieves the offsets. *offset = blah ; offset++;. @stable ICU 2.0 */ + int32_t *offsets; /**< Pointer to the buffer that receives the offsets. *offset = blah ; offset++;. @stable ICU 2.0 */ } UConverterFromUnicodeArgs; @@ -213,7 +215,7 @@ typedef struct { const char *sourceLimit; /**< Pointer to the limit (end + 1) of source buffer. @stable ICU 2.0 */ UChar *target; /**< Pointer to the target buffer. @stable ICU 2.0 */ const UChar *targetLimit; /**< Pointer to the limit (end + 1) of target buffer. @stable ICU 2.0 */ - int32_t *offsets; /**< Pointer to the buffer that recieves the offsets. *offset = blah ; offset++;. @stable ICU 2.0 */ + int32_t *offsets; /**< Pointer to the buffer that receives the offsets. *offset = blah ; offset++;. @stable ICU 2.0 */ } UConverterToUnicodeArgs; diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucnvsel.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucnvsel.h index eb9588eb2d..6fc2285c6a 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucnvsel.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucnvsel.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -108,7 +110,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUConverterSelectorPointer, UConverterSelector, U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Open a selector from its serialized form. diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucol.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucol.h index 510ddc8c6b..f9c767b657 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucol.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucol.h @@ -1,3 +1,5 @@ +// © 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; @@ -528,7 +539,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUCollatorPointer, UCollator, ucol_close); U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Compare two strings. @@ -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; /** @@ -1132,7 +1149,7 @@ ucol_getUCAVersion(const UCollator* coll, UVersionInfo info); * The recommended way to achieve "merged" sorting is by * concatenating strings with U+FFFE between them. * The concatenation has the same sort order as the merged sort keys, - * but merge(getSortKey(str1), getSortKey(str2)) may differ from getSortKey(str1 + '\uFFFE' + str2). + * but merge(getSortKey(str1), getSortKey(str2)) may differ from getSortKey(str1 + '\\uFFFE' + str2). * Using strings with U+FFFE may yield shorter sort keys. * * For details about Sort Key Features see @@ -1269,6 +1286,7 @@ ucol_setVariableTop(UCollator *coll, */ U_STABLE uint32_t U_EXPORT2 ucol_getVariableTop(const UCollator *coll, UErrorCode *status); +#ifndef U_HIDE_DEPRECATED_API /** * Sets the variable top to the specified primary weight. * @@ -1276,6 +1294,7 @@ U_STABLE uint32_t U_EXPORT2 ucol_getVariableTop(const UCollator *coll, UErrorCod * the top of one of the supported reordering groups, * and it must not be beyond the last of those groups. * See ucol_setMaxVariable(). + * @param coll collator to be set * @param varTop primary weight, as returned by ucol_setVariableTop or ucol_getVariableTop * @param status error code * @see ucol_getVariableTop @@ -1284,6 +1303,7 @@ U_STABLE uint32_t U_EXPORT2 ucol_getVariableTop(const UCollator *coll, UErrorCod */ U_DEPRECATED void U_EXPORT2 ucol_restoreVariableTop(UCollator *coll, const uint32_t varTop, UErrorCode *status); +#endif /* U_HIDE_DEPRECATED_API */ /** * Thread safe cloning operation. The result is a clone of a given collator. diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucoleitr.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucoleitr.h index 58e677a1c7..b6986fcf0c 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucoleitr.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucoleitr.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2001-2014, International Business Machines @@ -162,7 +164,7 @@ ucol_reset(UCollationElements *elems); * A single character may contain more than one collation element. * @param elems The UCollationElements containing the text. * @param status A pointer to a UErrorCode to receive any errors. - * @return The next collation elements ordering, otherwise returns NULLORDER + * @return The next collation elements ordering, otherwise returns UCOL_NULLORDER * if an error has occured or if the end of string has been reached * @stable ICU 2.0 */ @@ -178,7 +180,7 @@ ucol_next(UCollationElements *elems, UErrorCode *status); * a U_BUFFER_OVERFLOW_ERROR is returned if the internal stack * buffer has been exhausted. * @return The previous collation elements ordering, otherwise returns - * NULLORDER if an error has occured or if the start of string has + * UCOL_NULLORDER if an error has occured or if the start of string has * been reached. * @stable ICU 2.0 */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uconfig.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uconfig.h index dce67d50e4..284dee7eeb 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uconfig.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uconfig.h @@ -1,10 +1,12 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** -* Copyright (C) 2002-2015, International Business Machines +* Copyright (C) 2002-2016, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * file name: uconfig.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -74,7 +76,7 @@ #endif /** - * Determines wheter to enable auto cleanup of libraries. + * Determines whether to enable auto cleanup of libraries. * @internal */ #ifndef UCLN_NO_AUTO_CLEANUP @@ -134,6 +136,15 @@ #define U_ENABLE_TRACING 0 #endif +/** + * \def UCONFIG_ENABLE_PLUGINS + * Determines whether to enable ICU plugins. + * @internal + */ +#ifndef UCONFIG_ENABLE_PLUGINS +#define UCONFIG_ENABLE_PLUGINS 0 +#endif + /** * \def U_ENABLE_DYLOAD * Whether to enable Dynamic loading in ICU. @@ -152,7 +163,6 @@ #define U_CHECK_DYLOAD 1 #endif - /** * \def U_DEFAULT_SHOW_DRAFT * Do we allow ICU users to use the draft APIs by default? @@ -173,7 +183,7 @@ */ #ifdef U_HAVE_LIB_SUFFIX /* Use the predefined value. */ -#elif defined(U_LIB_SUFFIX_C_NAME) +#elif defined(U_LIB_SUFFIX_C_NAME) || defined(U_IN_DOXYGEN) # define U_HAVE_LIB_SUFFIX 1 #endif @@ -252,7 +262,8 @@ /** * \def UCONFIG_NO_CONVERSION - * ICU will not completely build with this switch turned on. + * ICU will not completely build (compiling the tools fails) with this + * switch turned on. * This switch turns off all converters. * * You may want to use this together with U_CHARSET_IS_UTF8 defined to 1 @@ -278,7 +289,7 @@ * This is not possible on EBCDIC platforms * because they need ibm-37 or ibm-1047 default converters. * - * @draft ICU 55 + * @stable ICU 55 */ #ifndef UCONFIG_ONLY_HTML_CONVERSION # define UCONFIG_ONLY_HTML_CONVERSION 0 @@ -310,7 +321,9 @@ */ #ifndef UCONFIG_NO_NORMALIZATION # define UCONFIG_NO_NORMALIZATION 0 -#elif UCONFIG_NO_NORMALIZATION +#endif + +#if UCONFIG_NO_NORMALIZATION /* common library */ /* ICU 50 CJK dictionary BreakIterator uses normalization */ # define UCONFIG_NO_BREAK_ITERATION 1 @@ -356,6 +369,18 @@ # define UCONFIG_MSGPAT_DEFAULT_APOSTROPHE_MODE UMSGPAT_APOS_DOUBLE_OPTIONAL #endif +/** + * \def UCONFIG_USE_WINDOWS_LCID_MAPPING_API + * On platforms where U_PLATFORM_HAS_WIN32_API is true, this switch determines + * if the Windows platform APIs are used for LCID<->Locale Name conversions. + * Otherwise, only the built-in ICU tables are used. + * + * @internal ICU 64 + */ +#ifndef UCONFIG_USE_WINDOWS_LCID_MAPPING_API +# define UCONFIG_USE_WINDOWS_LCID_MAPPING_API 1 +#endif + /* i18n library switches ---------------------------------------------------- */ /** @@ -418,17 +443,6 @@ # define UCONFIG_HAVE_PARSEALLINPUT 1 #endif - -/** - * \def UCONFIG_FORMAT_FASTPATHS_49 - * This switch turns on other formatting fastpaths. Binary incompatible in object DecimalFormat and DecimalFormatSymbols - * - * @internal - */ -#ifndef UCONFIG_FORMAT_FASTPATHS_49 -# define UCONFIG_FORMAT_FASTPATHS_49 1 -#endif - /** * \def UCONFIG_NO_FILTERED_BREAK_ITERATION * This switch turns off filtered break iteration code. @@ -437,9 +451,6 @@ */ #ifndef UCONFIG_NO_FILTERED_BREAK_ITERATION # define UCONFIG_NO_FILTERED_BREAK_ITERATION 0 - - - #endif #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucpmap.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucpmap.h new file mode 100644 index 0000000000..f2c42b6b7f --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucpmap.h @@ -0,0 +1,162 @@ +// © 2018 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +// ucpmap.h +// created: 2018sep03 Markus W. Scherer + +#ifndef __UCPMAP_H__ +#define __UCPMAP_H__ + +#include "unicode/utypes.h" + +#ifndef U_HIDE_DRAFT_API + +U_CDECL_BEGIN + +/** + * \file + * + * This file defines an abstract map from Unicode code points to integer values. + * + * @see UCPMap + * @see UCPTrie + * @see UMutableCPTrie + */ + +/** + * Abstract map from Unicode code points (U+0000..U+10FFFF) to integer values. + * + * @see UCPTrie + * @see UMutableCPTrie + * @draft ICU 63 + */ +typedef struct UCPMap UCPMap; + +/** + * Selectors for how ucpmap_getRange() etc. should report value ranges overlapping with surrogates. + * Most users should use UCPMAP_RANGE_NORMAL. + * + * @see ucpmap_getRange + * @see ucptrie_getRange + * @see umutablecptrie_getRange + * @draft ICU 63 + */ +enum UCPMapRangeOption { + /** + * ucpmap_getRange() enumerates all same-value ranges as stored in the map. + * Most users should use this option. + * @draft ICU 63 + */ + UCPMAP_RANGE_NORMAL, + /** + * ucpmap_getRange() enumerates all same-value ranges as stored in the map, + * except that lead surrogates (U+D800..U+DBFF) are treated as having the + * surrogateValue, which is passed to getRange() as a separate parameter. + * The surrogateValue is not transformed via filter(). + * See U_IS_LEAD(c). + * + * Most users should use UCPMAP_RANGE_NORMAL instead. + * + * This option is useful for maps that map surrogate code *units* to + * special values optimized for UTF-16 string processing + * or for special error behavior for unpaired surrogates, + * but those values are not to be associated with the lead surrogate code *points*. + * @draft ICU 63 + */ + UCPMAP_RANGE_FIXED_LEAD_SURROGATES, + /** + * ucpmap_getRange() enumerates all same-value ranges as stored in the map, + * except that all surrogates (U+D800..U+DFFF) are treated as having the + * surrogateValue, which is passed to getRange() as a separate parameter. + * The surrogateValue is not transformed via filter(). + * See U_IS_SURROGATE(c). + * + * Most users should use UCPMAP_RANGE_NORMAL instead. + * + * This option is useful for maps that map surrogate code *units* to + * special values optimized for UTF-16 string processing + * or for special error behavior for unpaired surrogates, + * but those values are not to be associated with the lead surrogate code *points*. + * @draft ICU 63 + */ + UCPMAP_RANGE_FIXED_ALL_SURROGATES +}; +#ifndef U_IN_DOXYGEN +typedef enum UCPMapRangeOption UCPMapRangeOption; +#endif + +/** + * Returns the value for a code point as stored in the map, with range checking. + * Returns an implementation-defined error value if c is not in the range 0..U+10FFFF. + * + * @param map the map + * @param c the code point + * @return the map value, + * or an implementation-defined error value if the code point is not in the range 0..U+10FFFF + * @draft ICU 63 + */ +U_CAPI uint32_t U_EXPORT2 +ucpmap_get(const UCPMap *map, UChar32 c); + +/** + * Callback function type: Modifies a map value. + * Optionally called by ucpmap_getRange()/ucptrie_getRange()/umutablecptrie_getRange(). + * The modified value will be returned by the getRange function. + * + * Can be used to ignore some of the value bits, + * make a filter for one of several values, + * return a value index computed from the map value, etc. + * + * @param context an opaque pointer, as passed into the getRange function + * @param value a value from the map + * @return the modified value + * @draft ICU 63 + */ +typedef uint32_t U_CALLCONV +UCPMapValueFilter(const void *context, uint32_t value); + +/** + * Returns the last code point such that all those from start to there have the same value. + * Can be used to efficiently iterate over all same-value ranges in a map. + * (This is normally faster than iterating over code points and get()ting each value, + * but much slower than a data structure that stores ranges directly.) + * + * If the UCPMapValueFilter function pointer is not NULL, then + * the value to be delivered is passed through that function, and the return value is the end + * of the range where all values are modified to the same actual value. + * The value is unchanged if that function pointer is NULL. + * + * Example: + * \code + * UChar32 start = 0, end; + * uint32_t value; + * while ((end = ucpmap_getRange(map, start, UCPMAP_RANGE_NORMAL, 0, + * NULL, NULL, &value)) >= 0) { + * // Work with the range start..end and its value. + * start = end + 1; + * } + * \endcode + * + * @param map the map + * @param start range start + * @param option defines whether surrogates are treated normally, + * or as having the surrogateValue; usually UCPMAP_RANGE_NORMAL + * @param surrogateValue value for surrogates; ignored if option==UCPMAP_RANGE_NORMAL + * @param filter a pointer to a function that may modify the map data value, + * or NULL if the values from the map are to be used unmodified + * @param context an opaque pointer that is passed on to the filter function + * @param pValue if not NULL, receives the value that every code point start..end has; + * may have been modified by filter(context, map value) + * if that function pointer is not NULL + * @return the range end code point, or -1 if start is not a valid code point + * @draft ICU 63 + */ +U_CAPI UChar32 U_EXPORT2 +ucpmap_getRange(const UCPMap *map, UChar32 start, + UCPMapRangeOption option, uint32_t surrogateValue, + UCPMapValueFilter *filter, const void *context, uint32_t *pValue); + +U_CDECL_END + +#endif // U_HIDE_DRAFT_API +#endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucptrie.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucptrie.h new file mode 100644 index 0000000000..2718c984e4 --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucptrie.h @@ -0,0 +1,646 @@ +// © 2017 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +// ucptrie.h (modified from utrie2.h) +// created: 2017dec29 Markus W. Scherer + +#ifndef __UCPTRIE_H__ +#define __UCPTRIE_H__ + +#include "unicode/utypes.h" + +#ifndef U_HIDE_DRAFT_API + +#include "unicode/localpointer.h" +#include "unicode/ucpmap.h" +#include "unicode/utf8.h" + +U_CDECL_BEGIN + +/** + * \file + * + * This file defines an immutable Unicode code point trie. + * + * @see UCPTrie + * @see UMutableCPTrie + */ + +#ifndef U_IN_DOXYGEN +/** @internal */ +typedef union UCPTrieData { + /** @internal */ + const void *ptr0; + /** @internal */ + const uint16_t *ptr16; + /** @internal */ + const uint32_t *ptr32; + /** @internal */ + const uint8_t *ptr8; +} UCPTrieData; +#endif + +/** + * Immutable Unicode code point trie structure. + * Fast, reasonably compact, map from Unicode code points (U+0000..U+10FFFF) to integer values. + * For details see http://site.icu-project.org/design/struct/utrie + * + * Do not access UCPTrie fields directly; use public functions and macros. + * Functions are easy to use: They support all trie types and value widths. + * + * When performance is really important, macros provide faster access. + * Most macros are specific to either "fast" or "small" tries, see UCPTrieType. + * There are "fast" macros for special optimized use cases. + * + * The macros will return bogus values, or may crash, if used on the wrong type or value width. + * + * @see UMutableCPTrie + * @draft ICU 63 + */ +struct UCPTrie { +#ifndef U_IN_DOXYGEN + /** @internal */ + const uint16_t *index; + /** @internal */ + UCPTrieData data; + + /** @internal */ + int32_t indexLength; + /** @internal */ + int32_t dataLength; + /** Start of the last range which ends at U+10FFFF. @internal */ + UChar32 highStart; + /** highStart>>12 @internal */ + uint16_t shifted12HighStart; + + /** @internal */ + int8_t type; // UCPTrieType + /** @internal */ + int8_t valueWidth; // UCPTrieValueWidth + + /** padding/reserved @internal */ + uint32_t reserved32; + /** padding/reserved @internal */ + uint16_t reserved16; + + /** + * Internal index-3 null block offset. + * Set to an impossibly high value (e.g., 0xffff) if there is no dedicated index-3 null block. + * @internal + */ + uint16_t index3NullOffset; + /** + * Internal data null block offset, not shifted. + * Set to an impossibly high value (e.g., 0xfffff) if there is no dedicated data null block. + * @internal + */ + int32_t dataNullOffset; + /** @internal */ + uint32_t nullValue; + +#ifdef UCPTRIE_DEBUG + /** @internal */ + const char *name; +#endif +#endif +}; +#ifndef U_IN_DOXYGEN +typedef struct UCPTrie UCPTrie; +#endif + +/** + * Selectors for the type of a UCPTrie. + * Different trade-offs for size vs. speed. + * + * @see umutablecptrie_buildImmutable + * @see ucptrie_openFromBinary + * @see ucptrie_getType + * @draft ICU 63 + */ +enum UCPTrieType { + /** + * For ucptrie_openFromBinary() to accept any type. + * ucptrie_getType() will return the actual type. + * @draft ICU 63 + */ + UCPTRIE_TYPE_ANY = -1, + /** + * Fast/simple/larger BMP data structure. Use functions and "fast" macros. + * @draft ICU 63 + */ + UCPTRIE_TYPE_FAST, + /** + * Small/slower BMP data structure. Use functions and "small" macros. + * @draft ICU 63 + */ + UCPTRIE_TYPE_SMALL +}; +#ifndef U_IN_DOXYGEN +typedef enum UCPTrieType UCPTrieType; +#endif + +/** + * Selectors for the number of bits in a UCPTrie data value. + * + * @see umutablecptrie_buildImmutable + * @see ucptrie_openFromBinary + * @see ucptrie_getValueWidth + * @draft ICU 63 + */ +enum UCPTrieValueWidth { + /** + * For ucptrie_openFromBinary() to accept any data value width. + * ucptrie_getValueWidth() will return the actual data value width. + * @draft ICU 63 + */ + UCPTRIE_VALUE_BITS_ANY = -1, + /** + * The trie stores 16 bits per data value. + * It returns them as unsigned values 0..0xffff=65535. + * @draft ICU 63 + */ + UCPTRIE_VALUE_BITS_16, + /** + * The trie stores 32 bits per data value. + * @draft ICU 63 + */ + UCPTRIE_VALUE_BITS_32, + /** + * The trie stores 8 bits per data value. + * It returns them as unsigned values 0..0xff=255. + * @draft ICU 63 + */ + UCPTRIE_VALUE_BITS_8 +}; +#ifndef U_IN_DOXYGEN +typedef enum UCPTrieValueWidth UCPTrieValueWidth; +#endif + +/** + * Opens a trie from its binary form, stored in 32-bit-aligned memory. + * Inverse of ucptrie_toBinary(). + * + * The memory must remain valid and unchanged as long as the trie is used. + * You must ucptrie_close() the trie once you are done using it. + * + * @param type selects the trie type; results in an + * U_INVALID_FORMAT_ERROR if it does not match the binary data; + * use UCPTRIE_TYPE_ANY to accept any type + * @param valueWidth selects the number of bits in a data value; results in an + * U_INVALID_FORMAT_ERROR if it does not match the binary data; + * use UCPTRIE_VALUE_BITS_ANY to accept any data value width + * @param data a pointer to 32-bit-aligned memory containing the binary data of a UCPTrie + * @param length the number of bytes available at data; + * can be more than necessary + * @param pActualLength receives the actual number of bytes at data taken up by the trie data; + * can be NULL + * @param pErrorCode an in/out ICU UErrorCode + * @return the trie + * + * @see umutablecptrie_open + * @see umutablecptrie_buildImmutable + * @see ucptrie_toBinary + * @draft ICU 63 + */ +U_CAPI UCPTrie * U_EXPORT2 +ucptrie_openFromBinary(UCPTrieType type, UCPTrieValueWidth valueWidth, + const void *data, int32_t length, int32_t *pActualLength, + UErrorCode *pErrorCode); + +/** + * Closes a trie and releases associated memory. + * + * @param trie the trie + * @draft ICU 63 + */ +U_CAPI void U_EXPORT2 +ucptrie_close(UCPTrie *trie); + +#if U_SHOW_CPLUSPLUS_API + +U_NAMESPACE_BEGIN + +/** + * \class LocalUCPTriePointer + * "Smart pointer" class, closes a UCPTrie via ucptrie_close(). + * For most methods see the LocalPointerBase base class. + * + * @see LocalPointerBase + * @see LocalPointer + * @draft ICU 63 + */ +U_DEFINE_LOCAL_OPEN_POINTER(LocalUCPTriePointer, UCPTrie, ucptrie_close); + +U_NAMESPACE_END + +#endif + +/** + * Returns the trie type. + * + * @param trie the trie + * @return the trie type + * @see ucptrie_openFromBinary + * @see UCPTRIE_TYPE_ANY + * @draft ICU 63 + */ +U_CAPI UCPTrieType U_EXPORT2 +ucptrie_getType(const UCPTrie *trie); + +/** + * Returns the number of bits in a trie data value. + * + * @param trie the trie + * @return the number of bits in a trie data value + * @see ucptrie_openFromBinary + * @see UCPTRIE_VALUE_BITS_ANY + * @draft ICU 63 + */ +U_CAPI UCPTrieValueWidth U_EXPORT2 +ucptrie_getValueWidth(const UCPTrie *trie); + +/** + * Returns the value for a code point as stored in the trie, with range checking. + * Returns the trie error value if c is not in the range 0..U+10FFFF. + * + * Easier to use than UCPTRIE_FAST_GET() and similar macros but slower. + * Easier to use because, unlike the macros, this function works on all UCPTrie + * objects, for all types and value widths. + * + * @param trie the trie + * @param c the code point + * @return the trie value, + * or the trie error value if the code point is not in the range 0..U+10FFFF + * @draft ICU 63 + */ +U_CAPI uint32_t U_EXPORT2 +ucptrie_get(const UCPTrie *trie, UChar32 c); + +/** + * Returns the last code point such that all those from start to there have the same value. + * Can be used to efficiently iterate over all same-value ranges in a trie. + * (This is normally faster than iterating over code points and get()ting each value, + * but much slower than a data structure that stores ranges directly.) + * + * If the UCPMapValueFilter function pointer is not NULL, then + * the value to be delivered is passed through that function, and the return value is the end + * of the range where all values are modified to the same actual value. + * The value is unchanged if that function pointer is NULL. + * + * Example: + * \code + * UChar32 start = 0, end; + * uint32_t value; + * while ((end = ucptrie_getRange(trie, start, UCPMAP_RANGE_NORMAL, 0, + * NULL, NULL, &value)) >= 0) { + * // Work with the range start..end and its value. + * start = end + 1; + * } + * \endcode + * + * @param trie the trie + * @param start range start + * @param option defines whether surrogates are treated normally, + * or as having the surrogateValue; usually UCPMAP_RANGE_NORMAL + * @param surrogateValue value for surrogates; ignored if option==UCPMAP_RANGE_NORMAL + * @param filter a pointer to a function that may modify the trie data value, + * or NULL if the values from the trie are to be used unmodified + * @param context an opaque pointer that is passed on to the filter function + * @param pValue if not NULL, receives the value that every code point start..end has; + * may have been modified by filter(context, trie value) + * if that function pointer is not NULL + * @return the range end code point, or -1 if start is not a valid code point + * @draft ICU 63 + */ +U_CAPI UChar32 U_EXPORT2 +ucptrie_getRange(const UCPTrie *trie, UChar32 start, + UCPMapRangeOption option, uint32_t surrogateValue, + UCPMapValueFilter *filter, const void *context, uint32_t *pValue); + +/** + * Writes a memory-mappable form of the trie into 32-bit aligned memory. + * Inverse of ucptrie_openFromBinary(). + * + * @param trie the trie + * @param data a pointer to 32-bit-aligned memory to be filled with the trie data; + * can be NULL if capacity==0 + * @param capacity the number of bytes available at data, or 0 for pure preflighting + * @param pErrorCode an in/out ICU UErrorCode; + * U_BUFFER_OVERFLOW_ERROR if the capacity is too small + * @return the number of bytes written or (if buffer overflow) needed for the trie + * + * @see ucptrie_openFromBinary() + * @draft ICU 63 + */ +U_CAPI int32_t U_EXPORT2 +ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *pErrorCode); + +/** + * Macro parameter value for a trie with 16-bit data values. + * Use the name of this macro as a "dataAccess" parameter in other macros. + * Do not use this macro in any other way. + * + * @see UCPTRIE_VALUE_BITS_16 + * @draft ICU 63 + */ +#define UCPTRIE_16(trie, i) ((trie)->data.ptr16[i]) + +/** + * Macro parameter value for a trie with 32-bit data values. + * Use the name of this macro as a "dataAccess" parameter in other macros. + * Do not use this macro in any other way. + * + * @see UCPTRIE_VALUE_BITS_32 + * @draft ICU 63 + */ +#define UCPTRIE_32(trie, i) ((trie)->data.ptr32[i]) + +/** + * Macro parameter value for a trie with 8-bit data values. + * Use the name of this macro as a "dataAccess" parameter in other macros. + * Do not use this macro in any other way. + * + * @see UCPTRIE_VALUE_BITS_8 + * @draft ICU 63 + */ +#define UCPTRIE_8(trie, i) ((trie)->data.ptr8[i]) + +/** + * Returns a trie value for a code point, with range checking. + * Returns the trie error value if c is not in the range 0..U+10FFFF. + * + * @param trie (const UCPTrie *, in) the trie; must have type UCPTRIE_TYPE_FAST + * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width + * @param c (UChar32, in) the input code point + * @return The code point's trie value. + * @draft ICU 63 + */ +#define UCPTRIE_FAST_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_CP_INDEX(trie, 0xffff, c)) + +/** + * Returns a 16-bit trie value for a code point, with range checking. + * Returns the trie error value if c is not in the range U+0000..U+10FFFF. + * + * @param trie (const UCPTrie *, in) the trie; must have type UCPTRIE_TYPE_SMALL + * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width + * @param c (UChar32, in) the input code point + * @return The code point's trie value. + * @draft ICU 63 + */ +#define UCPTRIE_SMALL_GET(trie, dataAccess, c) \ + dataAccess(trie, _UCPTRIE_CP_INDEX(trie, UCPTRIE_SMALL_MAX, c)) + +/** + * UTF-16: Reads the next code point (UChar32 c, out), post-increments src, + * and gets a value from the trie. + * Sets the trie error value if c is an unpaired surrogate. + * + * @param trie (const UCPTrie *, in) the trie; must have type UCPTRIE_TYPE_FAST + * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width + * @param src (const UChar *, in/out) the source text pointer + * @param limit (const UChar *, in) the limit pointer for the text, or NULL if NUL-terminated + * @param c (UChar32, out) variable for the code point + * @param result (out) variable for the trie lookup result + * @draft ICU 63 + */ +#define UCPTRIE_FAST_U16_NEXT(trie, dataAccess, src, limit, c, result) { \ + (c) = *(src)++; \ + int32_t __index; \ + if (!U16_IS_SURROGATE(c)) { \ + __index = _UCPTRIE_FAST_INDEX(trie, c); \ + } else { \ + uint16_t __c2; \ + if (U16_IS_SURROGATE_LEAD(c) && (src) != (limit) && U16_IS_TRAIL(__c2 = *(src))) { \ + ++(src); \ + (c) = U16_GET_SUPPLEMENTARY((c), __c2); \ + __index = _UCPTRIE_SMALL_INDEX(trie, c); \ + } else { \ + __index = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET; \ + } \ + } \ + (result) = dataAccess(trie, __index); \ +} + +/** + * UTF-16: Reads the previous code point (UChar32 c, out), pre-decrements src, + * and gets a value from the trie. + * Sets the trie error value if c is an unpaired surrogate. + * + * @param trie (const UCPTrie *, in) the trie; must have type UCPTRIE_TYPE_FAST + * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width + * @param start (const UChar *, in) the start pointer for the text + * @param src (const UChar *, in/out) the source text pointer + * @param c (UChar32, out) variable for the code point + * @param result (out) variable for the trie lookup result + * @draft ICU 63 + */ +#define UCPTRIE_FAST_U16_PREV(trie, dataAccess, start, src, c, result) { \ + (c) = *--(src); \ + int32_t __index; \ + if (!U16_IS_SURROGATE(c)) { \ + __index = _UCPTRIE_FAST_INDEX(trie, c); \ + } else { \ + uint16_t __c2; \ + if (U16_IS_SURROGATE_TRAIL(c) && (src) != (start) && U16_IS_LEAD(__c2 = *((src) - 1))) { \ + --(src); \ + (c) = U16_GET_SUPPLEMENTARY(__c2, (c)); \ + __index = _UCPTRIE_SMALL_INDEX(trie, c); \ + } else { \ + __index = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET; \ + } \ + } \ + (result) = dataAccess(trie, __index); \ +} + +/** + * UTF-8: Post-increments src and gets a value from the trie. + * Sets the trie error value for an ill-formed byte sequence. + * + * Unlike UCPTRIE_FAST_U16_NEXT() this UTF-8 macro does not provide the code point + * because it would be more work to do so and is often not needed. + * If the trie value differs from the error value, then the byte sequence is well-formed, + * and the code point can be assembled without revalidation. + * + * @param trie (const UCPTrie *, in) the trie; must have type UCPTRIE_TYPE_FAST + * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width + * @param src (const char *, in/out) the source text pointer + * @param limit (const char *, in) the limit pointer for the text (must not be NULL) + * @param result (out) variable for the trie lookup result + * @draft ICU 63 + */ +#define UCPTRIE_FAST_U8_NEXT(trie, dataAccess, src, limit, result) { \ + int32_t __lead = (uint8_t)*(src)++; \ + if (!U8_IS_SINGLE(__lead)) { \ + uint8_t __t1, __t2, __t3; \ + if ((src) != (limit) && \ + (__lead >= 0xe0 ? \ + __lead < 0xf0 ? /* U+0800..U+FFFF except surrogates */ \ + U8_LEAD3_T1_BITS[__lead &= 0xf] & (1 << ((__t1 = *(src)) >> 5)) && \ + ++(src) != (limit) && (__t2 = *(src) - 0x80) <= 0x3f && \ + (__lead = ((int32_t)(trie)->index[(__lead << 6) + (__t1 & 0x3f)]) + __t2, 1) \ + : /* U+10000..U+10FFFF */ \ + (__lead -= 0xf0) <= 4 && \ + U8_LEAD4_T1_BITS[(__t1 = *(src)) >> 4] & (1 << __lead) && \ + (__lead = (__lead << 6) | (__t1 & 0x3f), ++(src) != (limit)) && \ + (__t2 = *(src) - 0x80) <= 0x3f && \ + ++(src) != (limit) && (__t3 = *(src) - 0x80) <= 0x3f && \ + (__lead = __lead >= (trie)->shifted12HighStart ? \ + (trie)->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET : \ + ucptrie_internalSmallU8Index((trie), __lead, __t2, __t3), 1) \ + : /* U+0080..U+07FF */ \ + __lead >= 0xc2 && (__t1 = *(src) - 0x80) <= 0x3f && \ + (__lead = (int32_t)(trie)->index[__lead & 0x1f] + __t1, 1))) { \ + ++(src); \ + } else { \ + __lead = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET; /* ill-formed*/ \ + } \ + } \ + (result) = dataAccess(trie, __lead); \ +} + +/** + * UTF-8: Pre-decrements src and gets a value from the trie. + * Sets the trie error value for an ill-formed byte sequence. + * + * Unlike UCPTRIE_FAST_U16_PREV() this UTF-8 macro does not provide the code point + * because it would be more work to do so and is often not needed. + * If the trie value differs from the error value, then the byte sequence is well-formed, + * and the code point can be assembled without revalidation. + * + * @param trie (const UCPTrie *, in) the trie; must have type UCPTRIE_TYPE_FAST + * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width + * @param start (const char *, in) the start pointer for the text + * @param src (const char *, in/out) the source text pointer + * @param result (out) variable for the trie lookup result + * @draft ICU 63 + */ +#define UCPTRIE_FAST_U8_PREV(trie, dataAccess, start, src, result) { \ + int32_t __index = (uint8_t)*--(src); \ + if (!U8_IS_SINGLE(__index)) { \ + __index = ucptrie_internalU8PrevIndex((trie), __index, (const uint8_t *)(start), \ + (const uint8_t *)(src)); \ + (src) -= __index & 7; \ + __index >>= 3; \ + } \ + (result) = dataAccess(trie, __index); \ +} + +/** + * Returns a trie value for an ASCII code point, without range checking. + * + * @param trie (const UCPTrie *, in) the trie (of either fast or small type) + * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width + * @param c (UChar32, in) the input code point; must be U+0000..U+007F + * @return The ASCII code point's trie value. + * @draft ICU 63 + */ +#define UCPTRIE_ASCII_GET(trie, dataAccess, c) dataAccess(trie, c) + +/** + * Returns a trie value for a BMP code point (U+0000..U+FFFF), without range checking. + * Can be used to look up a value for a UTF-16 code unit if other parts of + * the string processing check for surrogates. + * + * @param trie (const UCPTrie *, in) the trie; must have type UCPTRIE_TYPE_FAST + * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width + * @param c (UChar32, in) the input code point, must be U+0000..U+FFFF + * @return The BMP code point's trie value. + * @draft ICU 63 + */ +#define UCPTRIE_FAST_BMP_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_FAST_INDEX(trie, c)) + +/** + * Returns a trie value for a supplementary code point (U+10000..U+10FFFF), + * without range checking. + * + * @param trie (const UCPTrie *, in) the trie; must have type UCPTRIE_TYPE_FAST + * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width + * @param c (UChar32, in) the input code point, must be U+10000..U+10FFFF + * @return The supplementary code point's trie value. + * @draft ICU 63 + */ +#define UCPTRIE_FAST_SUPP_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_SMALL_INDEX(trie, c)) + +/* Internal definitions ----------------------------------------------------- */ + +#ifndef U_IN_DOXYGEN + +/** + * Internal implementation constants. + * These are needed for the API macros, but users should not use these directly. + * @internal + */ +enum { + /** @internal */ + UCPTRIE_FAST_SHIFT = 6, + + /** Number of entries in a data block for code points below the fast limit. 64=0x40 @internal */ + UCPTRIE_FAST_DATA_BLOCK_LENGTH = 1 << UCPTRIE_FAST_SHIFT, + + /** Mask for getting the lower bits for the in-fast-data-block offset. @internal */ + UCPTRIE_FAST_DATA_MASK = UCPTRIE_FAST_DATA_BLOCK_LENGTH - 1, + + /** @internal */ + UCPTRIE_SMALL_MAX = 0xfff, + + /** + * Offset from dataLength (to be subtracted) for fetching the + * value returned for out-of-range code points and ill-formed UTF-8/16. + * @internal + */ + UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET = 1, + /** + * Offset from dataLength (to be subtracted) for fetching the + * value returned for code points highStart..U+10FFFF. + * @internal + */ + UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET = 2 +}; + +/* Internal functions and macros -------------------------------------------- */ +// Do not conditionalize with #ifndef U_HIDE_INTERNAL_API, needed for public API + +/** @internal */ +U_INTERNAL int32_t U_EXPORT2 +ucptrie_internalSmallIndex(const UCPTrie *trie, UChar32 c); + +/** @internal */ +U_INTERNAL int32_t U_EXPORT2 +ucptrie_internalSmallU8Index(const UCPTrie *trie, int32_t lt1, uint8_t t2, uint8_t t3); + +/** + * Internal function for part of the UCPTRIE_FAST_U8_PREVxx() macro implementations. + * Do not call directly. + * @internal + */ +U_INTERNAL int32_t U_EXPORT2 +ucptrie_internalU8PrevIndex(const UCPTrie *trie, UChar32 c, + const uint8_t *start, const uint8_t *src); + +/** Internal trie getter for a code point below the fast limit. Returns the data index. @internal */ +#define _UCPTRIE_FAST_INDEX(trie, c) \ + ((int32_t)(trie)->index[(c) >> UCPTRIE_FAST_SHIFT] + ((c) & UCPTRIE_FAST_DATA_MASK)) + +/** Internal trie getter for a code point at or above the fast limit. Returns the data index. @internal */ +#define _UCPTRIE_SMALL_INDEX(trie, c) \ + ((c) >= (trie)->highStart ? \ + (trie)->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET : \ + ucptrie_internalSmallIndex(trie, c)) + +/** + * Internal trie getter for a code point, with checking that c is in U+0000..10FFFF. + * Returns the data index. + * @internal + */ +#define _UCPTRIE_CP_INDEX(trie, fastMax, c) \ + ((uint32_t)(c) <= (uint32_t)(fastMax) ? \ + _UCPTRIE_FAST_INDEX(trie, c) : \ + (uint32_t)(c) <= 0x10ffff ? \ + _UCPTRIE_SMALL_INDEX(trie, c) : \ + (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET) + +U_CDECL_END + +#endif // U_IN_DOXYGEN +#endif // U_HIDE_DRAFT_API +#endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucsdet.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucsdet.h index d3a297be1e..892f3ee412 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucsdet.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucsdet.h @@ -1,10 +1,12 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2013, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * file name: ucsdet.h - * encoding: US-ASCII + * encoding: UTF-8 * indentation:4 * * created on: 2005Aug04 @@ -43,6 +45,10 @@ * in a single language, and a minimum of a few hundred bytes worth of plain text * in the language are needed. The detection process will attempt to * ignore html or xml style markup that could otherwise obscure the content. + *

        + * An alternative to the ICU Charset Detector is the + * Compact Encoding Detector, https://github.com/google/compact_enc_det. + * It often gives more accurate results, especially with short input samples. */ @@ -101,7 +107,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUCharsetDetectorPointer, UCharsetDetector, ucsd U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Set the input byte data whose charset is to detected. @@ -348,7 +354,8 @@ ucsdet_getAllDetectableCharsets(const UCharsetDetector *ucsd, UErrorCode *statu * Test whether input filtering is enabled for this charset detector. * Input filtering removes text that appears to be HTML or xml * markup from the input before applying the code page detection - * heuristics. + * heuristics. Apple addition per : Will also + * remove text that appears to be CSS declaration blocks. * * @param ucsd The charset detector to check. * @return TRUE if filtering is enabled. @@ -363,6 +370,8 @@ ucsdet_isInputFilterEnabled(const UCharsetDetector *ucsd); * Enable filtering of input text. If filtering is enabled, * text within angle brackets ("<" and ">") will be removed * before detection, which will remove most HTML or xml markup. + * Apple addition per : Will also + * remove text between '{' and '}', e.g. CSS declaration blocks. * * @param ucsd the charset detector to be modified. * @param filter true to enable input text filtering. @@ -393,7 +402,7 @@ ucsdet_getDetectableCharsets(const UCharsetDetector *ucsd, UErrorCode *status); /** * Enable or disable individual charset encoding. * A name of charset encoding must be included in the names returned by - * {@link #getAllDetectableCharsets()}. + * {@link #ucsdet_getAllDetectableCharsets()}. * * @param ucsd a Charset detector. * @param encoding encoding the name of charset encoding. diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucurr.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucurr.h index 5b19690169..c915327d38 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucurr.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ucurr.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** -* Copyright (c) 2002-2014, International Business Machines +* Copyright (c) 2002-2016, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -13,55 +15,54 @@ /** * \file * \brief C API: Encapsulates information about a currency. + * + * The ucurr API encapsulates information about a currency, as defined by + * ISO 4217. A currency is represented by a 3-character string + * containing its ISO 4217 code. This API can return various data + * necessary the proper display of a currency: + * + *

        • A display symbol, for a specific locale + *
        • The number of fraction digits to display + *
        • A rounding increment + *
        + * + * The DecimalFormat class uses these data to display + * currencies. + * @author Alan Liu + * @since ICU 2.2 */ #if !UCONFIG_NO_FORMATTING /** * Currency Usage used for Decimal Format - * @draft ICU 54 + * @stable ICU 54 */ enum UCurrencyUsage { -#ifndef U_HIDE_DRAFT_API /** * a setting to specify currency usage which determines currency digit * and rounding for standard usage, for example: "50.00 NT$" * used as DEFAULT value - * @draft ICU 54 + * @stable ICU 54 */ UCURR_USAGE_STANDARD=0, /** * a setting to specify currency usage which determines currency digit * and rounding for cash usage, for example: "50 NT$" - * @draft ICU 54 + * @stable ICU 54 */ UCURR_USAGE_CASH=1, -#endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DEPRECATED_API /** * One higher than the last enum UCurrencyUsage constant. - * @draft ICU 54 + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ UCURR_USAGE_COUNT=2 +#endif // U_HIDE_DEPRECATED_API }; +/** Currency Usage used for Decimal Format */ typedef enum UCurrencyUsage UCurrencyUsage; -/** - * The ucurr API encapsulates information about a currency, as defined by - * ISO 4217. A currency is represented by a 3-character string - * containing its ISO 4217 code. This API can return various data - * necessary the proper display of a currency: - * - *
        • A display symbol, for a specific locale - *
        • The number of fraction digits to display - *
        • A rounding increment - *
        - * - * The DecimalFormat class uses these data to display - * currencies. - * @author Alan Liu - * @since ICU 2.2 - */ - /** * Finds a currency code for the given locale. * @param locale the locale for which to retrieve a currency code. @@ -102,7 +103,17 @@ typedef enum UCurrNameStyle { * currency, such as "US Dollar" for USD. * @stable ICU 2.6 */ - UCURR_LONG_NAME + UCURR_LONG_NAME, + + /** + * Selector for getName() indicating the narrow currency symbol. + * The narrow currency symbol is similar to the regular currency + * symbol, but it always takes the shortest form: for example, + * "$" instead of "US$" for USD in en-CA. + * + * @stable ICU 61 + */ + UCURR_NARROW_SYMBOL_NAME } UCurrNameStyle; #if !UCONFIG_NO_SERVICE @@ -194,6 +205,13 @@ ucurr_getPluralName(const UChar* currency, * Returns the number of the number of fraction digits that should * be displayed for the given currency. * This is equivalent to ucurr_getDefaultFractionDigitsForUsage(currency,UCURR_USAGE_STANDARD,ec); + * + * Important: The number of fraction digits for a given currency is NOT + * guaranteed to be constant across versions of ICU or CLDR. For example, + * do NOT use this value as a mechanism for deciding the magnitude used + * to store currency values in a database. You should use this value for + * display purposes only. + * * @param currency null-terminated 3-letter ISO 4217 code * @param ec input-output error code * @return a non-negative number of fraction digits to be @@ -204,22 +222,27 @@ U_STABLE int32_t U_EXPORT2 ucurr_getDefaultFractionDigits(const UChar* currency, UErrorCode* ec); -#ifndef U_HIDE_DRAFT_API /** * Returns the number of the number of fraction digits that should * be displayed for the given currency with usage. + * + * Important: The number of fraction digits for a given currency is NOT + * guaranteed to be constant across versions of ICU or CLDR. For example, + * do NOT use this value as a mechanism for deciding the magnitude used + * to store currency values in a database. You should use this value for + * display purposes only. + * * @param currency null-terminated 3-letter ISO 4217 code * @param usage enum usage for the currency * @param ec input-output error code * @return a non-negative number of fraction digits to be * displayed, or 0 if there is an error - * @draft ICU 54 + * @stable ICU 54 */ -U_DRAFT int32_t U_EXPORT2 +U_STABLE int32_t U_EXPORT2 ucurr_getDefaultFractionDigitsForUsage(const UChar* currency, const UCurrencyUsage usage, UErrorCode* ec); -#endif /* U_HIDE_DRAFT_API */ /** * Returns the rounding increment for the given currency, or 0.0 if no @@ -235,7 +258,6 @@ U_STABLE double U_EXPORT2 ucurr_getRoundingIncrement(const UChar* currency, UErrorCode* ec); -#ifndef U_HIDE_DRAFT_API /** * Returns the rounding increment for the given currency, or 0.0 if no * rounding is done by the currency given usage. @@ -244,13 +266,12 @@ ucurr_getRoundingIncrement(const UChar* currency, * @param ec input-output error code * @return the non-negative rounding increment, or 0.0 if none, * or 0.0 if there is an error - * @draft ICU 54 + * @stable ICU 54 */ -U_DRAFT double U_EXPORT2 +U_STABLE double U_EXPORT2 ucurr_getRoundingIncrementForUsage(const UChar* currency, const UCurrencyUsage usage, UErrorCode* ec); -#endif /* U_HIDE_DRAFT_API */ /** * Selector constants for ucurr_openCurrencies(). diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udat.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udat.h index 4eaba39b74..9368ee78eb 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udat.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udat.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* - * Copyright (C) 1996-2015, International Business Machines + * Copyright (C) 1996-2016, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* */ @@ -150,7 +152,7 @@ */ typedef void* UDateFormat; -/** The possible date/time format styles +/** The possible date/time format styles * @stable ICU 2.6 */ typedef enum UDateFormatStyle { @@ -167,16 +169,16 @@ typedef enum UDateFormatStyle { /** Bitfield for relative date */ UDAT_RELATIVE = (1 << 7), - + UDAT_FULL_RELATIVE = UDAT_FULL | UDAT_RELATIVE, - + UDAT_LONG_RELATIVE = UDAT_LONG | UDAT_RELATIVE, - + UDAT_MEDIUM_RELATIVE = UDAT_MEDIUM | UDAT_RELATIVE, - + UDAT_SHORT_RELATIVE = UDAT_SHORT | UDAT_RELATIVE, - - + + /** No style */ UDAT_NONE = -1, @@ -294,7 +296,7 @@ typedef enum UDateFormatStyle { * Used in combinations date + time, date + time + zone, or time + zone. * @stable ICU 4.0 */ -#define UDAT_YEAR_ABBR_MONTH_WEEKDAY_DAY "yMMMEd" +#define UDAT_YEAR_ABBR_MONTH_WEEKDAY_DAY "yMMMEd" /** * Constant for date skeleton with year, numeric month, weekday, and day. * Used in combinations date + time, date + time + zone, or time + zone. @@ -446,7 +448,7 @@ typedef enum UDateFormatStyle { /* deprecated skeleton constants */ -#ifndef U_HIDE_DEPRECATED_API +#ifndef U_HIDE_DEPRECATED_API /** * Constant for date skeleton with standalone month. * @deprecated ICU 50 Use UDAT_MONTH instead. @@ -480,6 +482,27 @@ typedef enum UDateFormatStyle { #define UDAT_HOUR_TZ "jz" #endif /* U_HIDE_DEPRECATED_API */ +#ifndef U_HIDE_INTERNAL_API +/** + * Constant for Unicode string name of new (in 2019) Japanese calendar era, + * root/English abbreviated version (ASCII-range characters). + * @internal + */ +#define JP_ERA_2019_ROOT "Reiwa" +/** + * Constant for Unicode string name of new (in 2019) Japanese calendar era, + * Japanese abbreviated version (Han, or fullwidth Latin for testing). + * @internal + */ +#define JP_ERA_2019_JA "\\u4EE4\\u548C" +/** + * Constant for Unicode string name of new (in 2019) Japanese calendar era, + * root and Japanese narrow version (ASCII-range characters). + * @internal + */ +#define JP_ERA_2019_NARROW "R" +#endif // U_HIDE_INTERNAL_API + /** * FieldPosition and UFieldPosition selectors for format fields * defined by DateFormat and UDateFormat. @@ -759,30 +782,54 @@ typedef enum UDateFormatField { * @internal ICU 53 */ UDAT_RELATED_YEAR_FIELD = 34, -#endif /* U_HIDE_INTERNAL_API */ +#endif /* U_HIDE_INTERNAL_API */ -#ifndef U_HIDE_DRAFT_API /** - * FieldPosition and UFieldPosition selector for ':' time separator, - * no corresponding UCAL_ field. - * @draft ICU 55 + * FieldPosition selector for 'b' field alignment. + * Displays midnight and noon for 12am and 12pm, respectively, if available; + * otherwise fall back to AM / PM. + * @stable ICU 57 */ - UDAT_TIME_SEPARATOR_FIELD = 35, -#endif /* U_HIDE_DRAFT_API */ + UDAT_AM_PM_MIDNIGHT_NOON_FIELD = 35, - /** + /* FieldPosition selector for 'B' field alignment. + * Displays flexible day periods, such as "in the morning", if available. + * @stable ICU 57 + */ + UDAT_FLEXIBLE_DAY_PERIOD_FIELD = 36, + +#ifndef U_HIDE_INTERNAL_API + /** + * FieldPosition and UFieldPosition selector for time separator, + * no corresponding UCAL_ field. No pattern character is currently + * defined for this. + * @internal + */ + 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 = 36 - + UDAT_FIELD_COUNT = 38 +#endif /* U_HIDE_DEPRECATED_API */ } UDateFormatField; +#ifndef U_HIDE_INTERNAL_API +/** + * Is a pattern character defined for UDAT_TIME_SEPARATOR_FIELD? + * In ICU 55 it was COLON, but that was withdrawn in ICU 56. + * @internal ICU 56 + */ +#define UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR 0 +#endif /* U_HIDE_INTERNAL_API */ + + /** * Maps from a UDateFormatField to the corresponding UCalendarDateFields. * Note: since the mapping is many-to-one, there is no inverse mapping. @@ -791,7 +838,7 @@ typedef enum UDateFormatField { * of error (e.g., the input field is UDAT_FIELD_COUNT). * @stable ICU 4.4 */ -U_STABLE UCalendarDateFields U_EXPORT2 +U_CAPI UCalendarDateFields U_EXPORT2 udat_toCalendarDateField(UDateFormatField field); @@ -823,7 +870,7 @@ udat_toCalendarDateField(UDateFormatField field); * an error occurred. * @stable ICU 2.0 */ -U_STABLE UDateFormat* U_EXPORT2 +U_CAPI UDateFormat* U_EXPORT2 udat_open(UDateFormatStyle timeStyle, UDateFormatStyle dateStyle, const char *locale, @@ -840,13 +887,13 @@ udat_open(UDateFormatStyle timeStyle, * @param format The formatter to close. * @stable ICU 2.0 */ -U_STABLE void U_EXPORT2 +U_CAPI void U_EXPORT2 udat_close(UDateFormat* format); /** * DateFormat boolean attributes - * + * * @stable ICU 53 */ typedef enum UDateFormatBooleanAttribute { @@ -861,22 +908,24 @@ typedef enum UDateFormatBooleanAttribute { * @stable ICU 53 */ UDAT_PARSE_ALLOW_NUMERIC = 1, -#ifndef U_HIDE_DRAFT_API /** * indicates tolerance of a partial literal match - * @draft ICU 53 + * e.g. accepting "--mon-02-march-2011" for a pattern of "'--: 'EEE-WW-MMMM-yyyy" + * @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") + * @stable ICU 56 */ - UDAT_PARSE_PARTIAL_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 53 - */ 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; @@ -891,7 +940,7 @@ typedef enum UDateFormatBooleanAttribute { * @return The value of attr. * @stable ICU 53 */ -U_STABLE UBool U_EXPORT2 +U_CAPI UBool U_EXPORT2 udat_getBooleanAttribute(const UDateFormat* fmt, UDateFormatBooleanAttribute attr, UErrorCode* status); /** @@ -904,7 +953,7 @@ udat_getBooleanAttribute(const UDateFormat* fmt, UDateFormatBooleanAttribute att * @param status A pointer to an UErrorCode to receive any errors * @stable ICU 53 */ -U_STABLE void U_EXPORT2 +U_CAPI void U_EXPORT2 udat_setBooleanAttribute(UDateFormat *fmt, UDateFormatBooleanAttribute attr, UBool newValue, UErrorCode* status); @@ -926,7 +975,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUDateFormatPointer, UDateFormat, udat_close); U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Open a copy of a UDateFormat. @@ -936,7 +985,7 @@ U_NAMESPACE_END * @return A pointer to a UDateFormat identical to fmt. * @stable ICU 2.0 */ -U_STABLE UDateFormat* U_EXPORT2 +U_CAPI UDateFormat* U_EXPORT2 udat_clone(const UDateFormat *fmt, UErrorCode *status); @@ -958,7 +1007,7 @@ udat_clone(const UDateFormat *fmt, * @see UFieldPosition * @stable ICU 2.0 */ -U_STABLE int32_t U_EXPORT2 +U_CAPI int32_t U_EXPORT2 udat_format( const UDateFormat* format, UDate dateToFormat, UChar* result, @@ -966,7 +1015,6 @@ udat_format( const UDateFormat* format, UFieldPosition* position, UErrorCode* status); -#ifndef U_HIDE_DRAFT_API /** * Format a date using an UDateFormat. * The date will be formatted using the conventions specified in {@link #udat_open } @@ -987,9 +1035,9 @@ udat_format( const UDateFormat* format, * @see udat_format * @see udat_parseCalendar * @see UFieldPosition -* @draft ICU 55 +* @stable ICU 55 */ -U_DRAFT int32_t U_EXPORT2 +U_CAPI int32_t U_EXPORT2 udat_formatCalendar( const UDateFormat* format, UCalendar* calendar, UChar* result, @@ -1022,9 +1070,9 @@ udat_formatCalendar( const UDateFormat* format, * The total buffer size needed; if greater than resultLength, the output was truncated. * @see udat_parse * @see UFieldPositionIterator -* @draft ICU 55 +* @stable ICU 55 */ -U_DRAFT int32_t U_EXPORT2 +U_CAPI int32_t U_EXPORT2 udat_formatForFields( const UDateFormat* format, UDate dateToFormat, UChar* result, @@ -1060,9 +1108,9 @@ udat_formatForFields( const UDateFormat* format, * @see udat_format * @see udat_parseCalendar * @see UFieldPositionIterator -* @draft ICU 55 +* @stable ICU 55 */ -U_DRAFT int32_t U_EXPORT2 +U_CAPI int32_t U_EXPORT2 udat_formatCalendarForFields( const UDateFormat* format, UCalendar* calendar, UChar* result, @@ -1070,7 +1118,6 @@ udat_formatCalendarForFields( const UDateFormat* format, UFieldPositionIterator* fpositer, UErrorCode* status); -#endif /* U_HIDE_DRAFT_API */ /** * Parse a string into an date/time using a UDateFormat. @@ -1097,7 +1144,7 @@ udat_formatCalendarForFields( const UDateFormat* format, * @see udat_format * @stable ICU 2.0 */ -U_STABLE UDate U_EXPORT2 +U_CAPI UDate U_EXPORT2 udat_parse(const UDateFormat* format, const UChar* text, int32_t textLength, @@ -1125,7 +1172,7 @@ udat_parse(const UDateFormat* format, * @see udat_format * @stable ICU 2.0 */ -U_STABLE void U_EXPORT2 +U_CAPI void U_EXPORT2 udat_parseCalendar(const UDateFormat* format, UCalendar* calendar, const UChar* text, @@ -1142,7 +1189,7 @@ udat_parseCalendar(const UDateFormat* format, * @see udat_setLenient * @stable ICU 2.0 */ -U_STABLE UBool U_EXPORT2 +U_CAPI UBool U_EXPORT2 udat_isLenient(const UDateFormat* fmt); /** @@ -1154,7 +1201,7 @@ udat_isLenient(const UDateFormat* fmt); * @see dat_isLenient * @stable ICU 2.0 */ -U_STABLE void U_EXPORT2 +U_CAPI void U_EXPORT2 udat_setLenient( UDateFormat* fmt, UBool isLenient); @@ -1167,7 +1214,7 @@ udat_setLenient( UDateFormat* fmt, * @see udat_setCalendar * @stable ICU 2.0 */ -U_STABLE const UCalendar* U_EXPORT2 +U_CAPI const UCalendar* U_EXPORT2 udat_getCalendar(const UDateFormat* fmt); /** @@ -1179,7 +1226,7 @@ udat_getCalendar(const UDateFormat* fmt); * @see udat_setCalendar * @stable ICU 2.0 */ -U_STABLE void U_EXPORT2 +U_CAPI void U_EXPORT2 udat_setCalendar( UDateFormat* fmt, const UCalendar* calendarToSet); @@ -1192,10 +1239,9 @@ udat_setCalendar( UDateFormat* fmt, * @see udat_setNumberFormat * @stable ICU 2.0 */ -U_STABLE const UNumberFormat* U_EXPORT2 +U_CAPI const UNumberFormat* U_EXPORT2 udat_getNumberFormat(const UDateFormat* fmt); -#ifndef U_HIDE_DRAFT_API /** * Get the UNumberFormat for specific field associated with an UDateFormat. * For example: 'y' for year and 'M' for month @@ -1203,16 +1249,16 @@ udat_getNumberFormat(const UDateFormat* fmt); * @param field the field to query * @return A pointer to the UNumberFormat used by fmt to format field numbers. * @see udat_setNumberFormatForField -* @draft ICU 54 +* @stable ICU 54 */ -U_DRAFT const UNumberFormat* U_EXPORT2 +U_CAPI const UNumberFormat* U_EXPORT2 udat_getNumberFormatForField(const UDateFormat* fmt, UChar field); /** * Set the UNumberFormat for specific field associated with an UDateFormat. * It can be a single field like: "y"(year) or "M"(month) * It can be several field combined together: "yM"(year and month) -* Note: +* Note: * 1 symbol field is enough for multiple symbol field (so "y" will override "yy", "yyy") * If the field is not numeric, then override has no effect (like "MMM" will use abbreviation, not numerical field) * @@ -1221,32 +1267,28 @@ udat_getNumberFormatForField(const UDateFormat* fmt, UChar field); * @param numberFormatToSet A pointer to the UNumberFormat to be used by fmt to format numbers. * @param status error code passed around (memory allocation or invalid fields) * @see udat_getNumberFormatForField -* @draft ICU 54 +* @stable ICU 54 */ -U_DRAFT void U_EXPORT2 +U_CAPI void U_EXPORT2 udat_adoptNumberFormatForFields( UDateFormat* fmt, const UChar* fields, UNumberFormat* numberFormatToSet, UErrorCode* status); -#endif /* U_HIDE_DRAFT_API */ - /** * Set the UNumberFormat associated with an UDateFormat. * A UDateFormat uses a UNumberFormat to format numbers within a date, * for example the day number. -* This method also clears per field NumberFormat instances previously -* set by {@see udat_setNumberFormatForField} +* This method also clears per field NumberFormat instances previously +* set by {@see udat_setNumberFormatForField} * @param fmt The formatter to set. * @param numberFormatToSet A pointer to the UNumberFormat to be used by fmt to format numbers. * @see udat_getNumberFormat * @see udat_setNumberFormatForField * @stable ICU 2.0 */ -U_STABLE void U_EXPORT2 +U_CAPI void U_EXPORT2 udat_setNumberFormat( UDateFormat* fmt, const UNumberFormat* numberFormatToSet); - -#ifndef U_HIDE_DRAFT_API /** * Adopt the UNumberFormat associated with an UDateFormat. * A UDateFormat uses a UNumberFormat to format numbers within a date, @@ -1254,13 +1296,11 @@ udat_setNumberFormat( UDateFormat* fmt, * @param fmt The formatter to set. * @param numberFormatToAdopt A pointer to the UNumberFormat to be used by fmt to format numbers. * @see udat_getNumberFormat -* @draft ICU 54 +* @stable ICU 54 */ -U_DRAFT void U_EXPORT2 +U_CAPI void U_EXPORT2 udat_adoptNumberFormat( UDateFormat* fmt, UNumberFormat* numberFormatToAdopt); -#endif /* U_HIDE_DRAFT_API */ - /** * Get a locale for which date/time formatting patterns are available. * A UDateFormat in a locale returned by this function will perform the correct @@ -1270,7 +1310,7 @@ udat_adoptNumberFormat( UDateFormat* fmt, * @see udat_countAvailable * @stable ICU 2.0 */ -U_STABLE const char* U_EXPORT2 +U_CAPI const char* U_EXPORT2 udat_getAvailable(int32_t localeIndex); /** @@ -1281,7 +1321,7 @@ udat_getAvailable(int32_t localeIndex); * @see udat_getAvailable * @stable ICU 2.0 */ -U_STABLE int32_t U_EXPORT2 +U_CAPI int32_t U_EXPORT2 udat_countAvailable(void); /** @@ -1294,7 +1334,7 @@ udat_countAvailable(void); * @see udat_Set2DigitYearStart * @stable ICU 2.0 */ -U_STABLE UDate U_EXPORT2 +U_CAPI UDate U_EXPORT2 udat_get2DigitYearStart( const UDateFormat *fmt, UErrorCode *status); @@ -1308,7 +1348,7 @@ udat_get2DigitYearStart( const UDateFormat *fmt, * @see udat_Set2DigitYearStart * @stable ICU 2.0 */ -U_STABLE void U_EXPORT2 +U_CAPI void U_EXPORT2 udat_set2DigitYearStart( UDateFormat *fmt, UDate d, UErrorCode *status); @@ -1325,7 +1365,7 @@ udat_set2DigitYearStart( UDateFormat *fmt, * @see udat_applyPattern * @stable ICU 2.0 */ -U_STABLE int32_t U_EXPORT2 +U_CAPI int32_t U_EXPORT2 udat_toPattern( const UDateFormat *fmt, UBool localized, UChar *result, @@ -1342,14 +1382,14 @@ udat_toPattern( const UDateFormat *fmt, * @see udat_toPattern * @stable ICU 2.0 */ -U_STABLE void U_EXPORT2 +U_CAPI void U_EXPORT2 udat_applyPattern( UDateFormat *format, UBool localized, const UChar *pattern, int32_t patternLength); -/** - * The possible types of date format symbols +/** + * The possible types of date format symbols * @stable ICU 2.6 */ typedef enum UDateFormatSymbolType { @@ -1408,44 +1448,41 @@ typedef enum UDateFormatSymbolType { * Standalone version of UDAT_SHORTER_WEEKDAYS. * @stable ICU 51 */ - UDAT_STANDALONE_SHORTER_WEEKDAYS -#ifndef U_HIDE_DRAFT_API - , + UDAT_STANDALONE_SHORTER_WEEKDAYS, /** * Cyclic year names (only supported for some calendars, and only for FORMAT usage; * udat_setSymbols not supported for UDAT_CYCLIC_YEARS_WIDE) - * @draft ICU 54 + * @stable ICU 54 */ UDAT_CYCLIC_YEARS_WIDE, /** * Cyclic year names (only supported for some calendars, and only for FORMAT usage) - * @draft ICU 54 + * @stable ICU 54 */ UDAT_CYCLIC_YEARS_ABBREVIATED, /** * Cyclic year names (only supported for some calendars, and only for FORMAT usage; * udat_setSymbols not supported for UDAT_CYCLIC_YEARS_NARROW) - * @draft ICU 54 + * @stable ICU 54 */ UDAT_CYCLIC_YEARS_NARROW, /** * Calendar zodiac names (only supported for some calendars, and only for FORMAT usage; * udat_setSymbols not supported for UDAT_ZODIAC_NAMES_WIDE) - * @draft ICU 54 + * @stable ICU 54 */ UDAT_ZODIAC_NAMES_WIDE, /** * Calendar zodiac names (only supported for some calendars, and only for FORMAT usage) - * @draft ICU 54 + * @stable ICU 54 */ UDAT_ZODIAC_NAMES_ABBREVIATED, /** * Calendar zodiac names (only supported for some calendars, and only for FORMAT usage; * udat_setSymbols not supported for UDAT_ZODIAC_NAMES_NARROW) - * @draft ICU 54 + * @stable ICU 54 */ UDAT_ZODIAC_NAMES_NARROW -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_INTERNAL_API , /** @@ -1481,7 +1518,7 @@ typedef struct UDateFormatSymbols UDateFormatSymbols; * @see udat_setSymbols * @stable ICU 2.0 */ -U_STABLE int32_t U_EXPORT2 +U_CAPI int32_t U_EXPORT2 udat_getSymbols(const UDateFormat *fmt, UDateFormatSymbolType type, int32_t symbolIndex, @@ -1501,7 +1538,7 @@ udat_getSymbols(const UDateFormat *fmt, * @see udat_setSymbols * @stable ICU 2.0 */ -U_STABLE int32_t U_EXPORT2 +U_CAPI int32_t U_EXPORT2 udat_countSymbols( const UDateFormat *fmt, UDateFormatSymbolType type); @@ -1520,7 +1557,7 @@ udat_countSymbols( const UDateFormat *fmt, * @see udat_countSymbols * @stable ICU 2.0 */ -U_STABLE void U_EXPORT2 +U_CAPI void U_EXPORT2 udat_setSymbols( UDateFormat *format, UDateFormatSymbolType type, int32_t symbolIndex, @@ -1532,15 +1569,15 @@ udat_setSymbols( UDateFormat *format, * Get the locale for this date format object. * You can choose between valid and actual locale. * @param fmt The formatter to get the locale from - * @param type type of the locale we're looking for (valid or actual) + * @param type type of the locale we're looking for (valid or actual) * @param status error code for the operation * @return the locale name * @stable ICU 2.8 */ -U_STABLE const char* U_EXPORT2 +U_CAPI const char* U_EXPORT2 udat_getLocaleByType(const UDateFormat *fmt, ULocDataLocaleType type, - UErrorCode* status); + UErrorCode* status); /** * Set a particular UDisplayContext value in the formatter, such as @@ -1550,7 +1587,7 @@ udat_getLocaleByType(const UDateFormat *fmt, * @param status A pointer to an UErrorCode to receive any errors * @stable ICU 51 */ -U_DRAFT void U_EXPORT2 +U_CAPI void U_EXPORT2 udat_setContext(UDateFormat* fmt, UDisplayContext value, UErrorCode* status); /** @@ -1562,7 +1599,7 @@ udat_setContext(UDateFormat* fmt, UDisplayContext value, UErrorCode* status); * @return The UDisplayContextValue for the specified type. * @stable ICU 53 */ -U_STABLE UDisplayContext U_EXPORT2 +U_CAPI UDisplayContext U_EXPORT2 udat_getContext(const UDateFormat* fmt, UDisplayContextType type, UErrorCode* status); #ifndef U_HIDE_INTERNAL_API @@ -1577,7 +1614,7 @@ udat_getContext(const UDateFormat* fmt, UDisplayContextType type, UErrorCode* st * @see udat_applyPatternRelative * @internal ICU 4.2 technology preview */ -U_INTERNAL int32_t U_EXPORT2 +U_INTERNAL int32_t U_EXPORT2 udat_toPatternRelativeDate(const UDateFormat *fmt, UChar *result, int32_t resultLength, @@ -1594,7 +1631,7 @@ udat_toPatternRelativeDate(const UDateFormat *fmt, * @see udat_applyPatternRelative * @internal ICU 4.2 technology preview */ -U_INTERNAL int32_t U_EXPORT2 +U_INTERNAL int32_t U_EXPORT2 udat_toPatternRelativeTime(const UDateFormat *fmt, UChar *result, int32_t resultLength, @@ -1612,7 +1649,7 @@ udat_toPatternRelativeTime(const UDateFormat *fmt, * @see udat_toPatternRelativeDate, udat_toPatternRelativeTime * @internal ICU 4.2 technology preview */ -U_INTERNAL void U_EXPORT2 +U_INTERNAL void U_EXPORT2 udat_applyPatternRelative(UDateFormat *format, const UChar *datePattern, int32_t datePatternLength, diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udata.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udata.h index 29e46630d5..600272a3d0 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udata.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udata.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * @@ -6,7 +8,7 @@ * ****************************************************************************** * file name: udata.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -279,7 +281,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUDataMemoryPointer, UDataMemory, udata_close); U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Get the pointer to the actual data inside the data memory. @@ -408,8 +410,13 @@ typedef enum UDataFileAccess { UDATA_PACKAGES_FIRST, /** ICU does not access the file system for data loading. @stable ICU 3.4 */ UDATA_NO_FILES, - /** Number of real UDataFileAccess values. @stable ICU 3.4 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * Number of real UDataFileAccess values. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UDATA_FILE_ACCESS_COUNT +#endif // U_HIDE_DEPRECATED_API } UDataFileAccess; /** diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udateintervalformat.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udateintervalformat.h index 2a251b5bfe..ed9fa1e2b2 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udateintervalformat.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udateintervalformat.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************************** -* Copyright (C) 2010-2012, International Business Machines +* Copyright (C) 2010-2012,2015-2016 International Business Machines * Corporation and others. All Rights Reserved. ***************************************************************************************** */ @@ -14,6 +16,8 @@ #include "unicode/umisc.h" #include "unicode/localpointer.h" +#include "unicode/uformattedvalue.h" +#include "unicode/udisplaycontext.h" /** * \file @@ -79,6 +83,15 @@ struct UDateIntervalFormat; typedef struct UDateIntervalFormat UDateIntervalFormat; /**< C typedef for struct UDateIntervalFormat. @stable ICU 4.8 */ +#ifndef U_HIDE_DRAFT_API +struct UFormattedDateInterval; +/** + * Opaque struct to contain the results of a UDateIntervalFormat operation. + * @draft ICU 64 + */ +typedef struct UFormattedDateInterval UFormattedDateInterval; +#endif /* U_HIDE_DRAFT_API */ + /** * Open a new UDateIntervalFormat object using the predefined rules for a * given locale plus a specified skeleton. @@ -121,6 +134,55 @@ U_STABLE void U_EXPORT2 udtitvfmt_close(UDateIntervalFormat *formatter); +#ifndef U_HIDE_DRAFT_API +/** + * Creates an object to hold the result of a UDateIntervalFormat + * operation. The object can be used repeatedly; it is cleared whenever + * passed to a format function. + * + * @param ec Set if an error occurs. + * @return A pointer needing ownership. + * @draft ICU 64 + */ +U_CAPI UFormattedDateInterval* U_EXPORT2 +udtitvfmt_openResult(UErrorCode* ec); + +/** + * Returns a representation of a UFormattedDateInterval as a UFormattedValue, + * which can be subsequently passed to any API requiring that type. + * + * The returned object is owned by the UFormattedDateInterval and is valid + * only as long as the UFormattedDateInterval is present and unchanged in memory. + * + * You can think of this method as a cast between types. + * + * When calling ufmtval_nextPosition(): + * The fields are returned from left to right. The special field category + * UFIELD_CATEGORY_DATE_INTERVAL_SPAN is used to indicate which datetime + * primitives came from which arguments: 0 means fromCalendar, and 1 means + * toCalendar. The span category will always occur before the + * corresponding fields in UFIELD_CATEGORY_DATE + * in the ufmtval_nextPosition() iterator. + * + * @param uresult The object containing the formatted string. + * @param ec Set if an error occurs. + * @return A UFormattedValue owned by the input object. + * @draft ICU 64 + */ +U_CAPI const UFormattedValue* U_EXPORT2 +udtitvfmt_resultAsValue(const UFormattedDateInterval* uresult, UErrorCode* ec); + +/** + * Releases the UFormattedDateInterval created by udtitvfmt_openResult(). + * + * @param uresult The object to release. + * @draft ICU 64 + */ +U_CAPI void U_EXPORT2 +udtitvfmt_closeResult(UFormattedDateInterval* uresult); +#endif /* U_HIDE_DRAFT_API */ + + #if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN @@ -136,9 +198,22 @@ U_NAMESPACE_BEGIN */ U_DEFINE_LOCAL_OPEN_POINTER(LocalUDateIntervalFormatPointer, UDateIntervalFormat, udtitvfmt_close); +#ifndef U_HIDE_DRAFT_API +/** + * \class LocalUFormattedDateIntervalPointer + * "Smart pointer" class, closes a UFormattedDateInterval via udtitvfmt_close(). + * For most methods see the LocalPointerBase base class. + * + * @see LocalPointerBase + * @see LocalPointer + * @draft ICU 64 + */ +U_DEFINE_LOCAL_OPEN_POINTER(LocalUFormattedDateIntervalPointer, UFormattedDateInterval, udtitvfmt_closeResult); +#endif /* U_HIDE_DRAFT_API */ + U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** @@ -160,6 +235,9 @@ U_NAMESPACE_END * the beginning and ending indices of field number position->field, * if such a field exists. This parameter may be NULL, in which case * no field position data is returned. + * There may be multiple instances of a given field type in an + * interval format; in this case the position indices refer to the + * first instance. * @param status * A pointer to a UErrorCode to receive any errors. * @return @@ -199,7 +277,13 @@ typedef enum UDateIntervalFormatAttributeValue { * only show one month (use format for greatestDifference=d). * @internal */ - UDTITVFMT_MINIMIZE_ADJACENT_MONTHS + UDTITVFMT_MINIMIZE_ADJACENT_MONTHS, + /** + * For intervals of less than 12 hours that cross day boundaries, + * only show one day (use format for greatestDifference=h). + * @internal + */ + UDTITVFMT_MINIMIZE_ADJACENT_DAYS } UDateIntervalFormatAttributeValue; /** @@ -221,6 +305,62 @@ udtitvfmt_setAttribute(UDateIntervalFormat* formatter, UErrorCode* status); #endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API +/** + * Formats a date/time range using the conventions established for the + * UDateIntervalFormat object. + * @param formatter + * The UDateIntervalFormat object specifying the format conventions. + * @param result + * The UFormattedDateInterval to contain the result of the + * formatting operation. + * @param fromDate + * The starting point of the range. + * @param toDate + * The ending point of the range. + * @param status + * A pointer to a UErrorCode to receive any errors. + * @draft ICU 64 + */ +U_DRAFT void U_EXPORT2 +udtitvfmt_formatToResult( + const UDateIntervalFormat* formatter, + UFormattedDateInterval* result, + UDate fromDate, + UDate toDate, + UErrorCode* status); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API +/** + * Set a particular UDisplayContext value in the formatter, such as + * UDISPCTX_CAPITALIZATION_FOR_STANDALONE. This causes the formatted + * result to be capitalized appropriately for the context in which + * it is intended to be used, considering both the locale and the + * type of field at the beginning of the formatted result. + * @param formatter The formatter for which to set a UDisplayContext value. + * @param value The UDisplayContext value to set. + * @param status A pointer to an UErrorCode to receive any errors + * @draft ICU 65 + */ +U_DRAFT void U_EXPORT2 +udtitvfmt_setContext(UDateIntervalFormat* formatter, UDisplayContext value, UErrorCode* status); + +/** + * Get the formatter's UDisplayContext value for the specified UDisplayContextType, + * such as UDISPCTX_TYPE_CAPITALIZATION. + * @param formatter The formatter to query. + * @param type The UDisplayContextType whose value to return + * @param status A pointer to an UErrorCode to receive any errors + * @return The UDisplayContextValue for the specified type. + * @draft ICU 65 + */ +U_DRAFT UDisplayContext U_EXPORT2 +udtitvfmt_getContext(const UDateIntervalFormat* formatter, UDisplayContextType type, UErrorCode* status); + +#endif /* U_HIDE_DRAFT_API */ + #endif /* #if !UCONFIG_NO_FORMATTING */ #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udatpg.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udatpg.h index 715de3f087..07339bbc4b 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udatpg.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udatpg.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -6,7 +8,7 @@ * ******************************************************************************* * file name: udatpg.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -83,10 +85,29 @@ 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; +/** + * Field display name width constants for udatpg_getFieldDisplayName(). + * @stable ICU 61 + */ +typedef enum UDateTimePGDisplayWidth { + /** @stable ICU 61 */ + UDATPG_WIDE, + /** @stable ICU 61 */ + UDATPG_ABBREVIATED, + /** @stable ICU 61 */ + UDATPG_NARROW +} UDateTimePGDisplayWidth; + /** * Masks to control forcing the length of specified fields in the returned * pattern to match those in the skeleton (when this would not happen @@ -126,8 +147,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; /** @@ -176,7 +202,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUDateTimePatternGeneratorPointer, UDateTimePatt U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Create a copy pf a generator. @@ -265,7 +291,8 @@ udatpg_getBestPatternWithOptions(UDateTimePatternGenerator *dtpg, * Consecutive calls to this function do not affect each other, * but this function cannot be used concurrently on a single generator object. * - * @param dtpg a pointer to UDateTimePatternGenerator. + * @param unusedDtpg a pointer to UDateTimePatternGenerator. + * This parameter is no longer used. Callers may pass NULL. * @param pattern input pattern, such as "dd/MMM". * @param length the length of pattern. * @param skeleton such as "MMMdd" @@ -276,7 +303,7 @@ udatpg_getBestPatternWithOptions(UDateTimePatternGenerator *dtpg, * @stable ICU 3.8 */ U_STABLE int32_t U_EXPORT2 -udatpg_getSkeleton(UDateTimePatternGenerator *dtpg, +udatpg_getSkeleton(UDateTimePatternGenerator *unusedDtpg, const UChar *pattern, int32_t length, UChar *skeleton, int32_t capacity, UErrorCode *pErrorCode); @@ -294,7 +321,8 @@ udatpg_getSkeleton(UDateTimePatternGenerator *dtpg, * Consecutive calls to this function do not affect each other, * but this function cannot be used concurrently on a single generator object. * - * @param dtpg a pointer to UDateTimePatternGenerator. + * @param unusedDtpg a pointer to UDateTimePatternGenerator. + * This parameter is no longer used. Callers may pass NULL. * @param pattern input pattern, such as "dd/MMM". * @param length the length of pattern. * @param baseSkeleton such as "Md" @@ -305,7 +333,7 @@ udatpg_getSkeleton(UDateTimePatternGenerator *dtpg, * @stable ICU 3.8 */ U_STABLE int32_t U_EXPORT2 -udatpg_getBaseSkeleton(UDateTimePatternGenerator *dtpg, +udatpg_getBaseSkeleton(UDateTimePatternGenerator *unusedDtpg, const UChar *pattern, int32_t length, UChar *baseSkeleton, int32_t capacity, UErrorCode *pErrorCode); @@ -401,12 +429,14 @@ udatpg_setAppendItemName(UDateTimePatternGenerator *dtpg, /** * Getter corresponding to setAppendItemNames. Values below 0 or at or above - * UDATPG_FIELD_COUNT are illegal arguments. + * UDATPG_FIELD_COUNT are illegal arguments. Note: The more general function + * for getting date/time field display names is udatpg_getFieldDisplayName. * * @param dtpg a pointer to UDateTimePatternGenerator. * @param field UDateTimePatternField, such as UDATPG_ERA_FIELD * @param pLength A pointer that will receive the length of the name for field. * @return name for field + * @see udatpg_getFieldDisplayName * @stable ICU 3.8 */ U_STABLE const UChar * U_EXPORT2 @@ -414,6 +444,38 @@ udatpg_getAppendItemName(const UDateTimePatternGenerator *dtpg, UDateTimePatternField field, int32_t *pLength); +/** + * The general interface to get a display name for a particular date/time field, + * in one of several possible display widths. + * + * @param dtpg + * A pointer to the UDateTimePatternGenerator object with the localized + * display names. + * @param field + * The desired UDateTimePatternField, such as UDATPG_ERA_FIELD. + * @param width + * The desired UDateTimePGDisplayWidth, such as UDATPG_ABBREVIATED. + * @param fieldName + * A pointer to a buffer to receive the NULL-terminated display name. If the name + * fits into fieldName but cannot be NULL-terminated (length == capacity) then + * the error code is set to U_STRING_NOT_TERMINATED_WARNING. If the name doesn't + * fit into fieldName then the error code is set to U_BUFFER_OVERFLOW_ERROR. + * @param capacity + * The size of fieldName (in UChars). + * @param pErrorCode + * A pointer to a UErrorCode to receive any errors + * @return + * The full length of the name; if greater than capacity, fieldName contains a + * truncated result. + * @stable ICU 61 + */ +U_STABLE int32_t U_EXPORT2 +udatpg_getFieldDisplayName(const UDateTimePatternGenerator *dtpg, + UDateTimePatternField field, + UDateTimePGDisplayWidth width, + UChar *fieldName, int32_t capacity, + UErrorCode *pErrorCode); + /** * The DateTimeFormat is a message format pattern used to compose date and * time patterns. The default pattern in the root locale is "{1} {0}", where diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udisplaycontext.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udisplaycontext.h index 53f365bb73..f9fb1fdf18 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udisplaycontext.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/udisplaycontext.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************************** -* Copyright (C) 2014, International Business Machines +* Copyright (C) 2014-2016, International Business Machines * Corporation and others. All Rights Reserved. ***************************************************************************************** */ @@ -35,16 +37,19 @@ enum UDisplayContextType { * UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, etc. * @stable ICU 51 */ - UDISPCTX_TYPE_CAPITALIZATION = 1 -#ifndef U_HIDE_DRAFT_API - , + UDISPCTX_TYPE_CAPITALIZATION = 1, /** * Type to retrieve the display length setting, e.g. * UDISPCTX_LENGTH_FULL, UDISPCTX_LENGTH_SHORT. - * @draft ICU 54 + * @stable ICU 54 + */ + UDISPCTX_TYPE_DISPLAY_LENGTH = 2, + /** + * Type to retrieve the substitute handling setting, e.g. + * UDISPCTX_SUBSTITUTE, UDISPCTX_NO_SUBSTITUTE. + * @stable ICU 58 */ - UDISPCTX_TYPE_DISPLAY_LENGTH = 2 -#endif /* U_HIDE_DRAFT_API */ + UDISPCTX_TYPE_SUBSTITUTE_HANDLING = 3 #ifndef U_HIDE_INTERNAL_API , /** @@ -124,9 +129,7 @@ enum UDisplayContext { * isolated name on a calendar page. * @stable ICU 51 */ - UDISPCTX_CAPITALIZATION_FOR_STANDALONE = (UDISPCTX_TYPE_CAPITALIZATION<<8) + 4 -#ifndef U_HIDE_DRAFT_API - , + UDISPCTX_CAPITALIZATION_FOR_STANDALONE = (UDISPCTX_TYPE_CAPITALIZATION<<8) + 4, /** * ================================ * DISPLAY_LENGTH can be set to one of UDISPCTX_LENGTH_FULL or @@ -137,17 +140,35 @@ enum UDisplayContext { * A possible setting for DISPLAY_LENGTH: * use full names when generating a locale name, * e.g. "United States" for US. - * @draft ICU 54 + * @stable ICU 54 */ UDISPCTX_LENGTH_FULL = (UDISPCTX_TYPE_DISPLAY_LENGTH<<8) + 0, /** * A possible setting for DISPLAY_LENGTH: * use short names when generating a locale name, * e.g. "U.S." for US. - * @draft ICU 54 + * @stable ICU 54 */ - UDISPCTX_LENGTH_SHORT = (UDISPCTX_TYPE_DISPLAY_LENGTH<<8) + 1 -#endif /* U_HIDE_DRAFT_API */ + UDISPCTX_LENGTH_SHORT = (UDISPCTX_TYPE_DISPLAY_LENGTH<<8) + 1, + /** + * ================================ + * SUBSTITUTE_HANDLING can be set to one of UDISPCTX_SUBSTITUTE or + * UDISPCTX_NO_SUBSTITUTE. Use UDisplayContextType UDISPCTX_TYPE_SUBSTITUTE_HANDLING + * to get the value. + */ + /** + * A possible setting for SUBSTITUTE_HANDLING: + * Returns a fallback value (e.g., the input code) when no data is available. + * This is the default value. + * @stable ICU 58 + */ + UDISPCTX_SUBSTITUTE = (UDISPCTX_TYPE_SUBSTITUTE_HANDLING<<8) + 0, + /** + * A possible setting for SUBSTITUTE_HANDLING: + * Returns a null value when no data is available. + * @stable ICU 58 + */ + UDISPCTX_NO_SUBSTITUTE = (UDISPCTX_TYPE_SUBSTITUTE_HANDLING<<8) + 1 #ifndef U_HIDE_INTERNAL_API , /** @@ -171,6 +192,7 @@ enum UDisplayContext { */ UADISPCTX_LENGTH_SHORT = (UADISPCTX_TYPE_LENGTH<<8) + 1, #endif /* U_HIDE_INTERNAL_API */ + }; /** * @stable ICU 51 diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uenum.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uenum.h index 5408ec5a66..0f14444a3e 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uenum.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uenum.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -6,7 +8,7 @@ * ******************************************************************************* * file name: uenum.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:2 * @@ -21,8 +23,10 @@ #include "unicode/localpointer.h" #if U_SHOW_CPLUSPLUS_API -#include "unicode/strenum.h" -#endif +U_NAMESPACE_BEGIN +class StringEnumeration; +U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API /** * \file @@ -65,7 +69,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUEnumerationPointer, UEnumeration, uenum_close) U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Returns the number of elements that the iterator traverses. If @@ -169,7 +173,7 @@ uenum_reset(UEnumeration* en, UErrorCode* status); U_STABLE UEnumeration* U_EXPORT2 uenum_openFromStringEnumeration(icu::StringEnumeration* adopted, UErrorCode* ec); -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Given an array of const UChar* strings, return a UEnumeration. String pointers from 0..count-1 must not be null. @@ -186,8 +190,6 @@ U_STABLE UEnumeration* U_EXPORT2 uenum_openUCharStringsEnumeration(const UChar* const strings[], int32_t count, UErrorCode* ec); -/* Note: next function is not hidden as draft, as it is used internally (it was formerly an internal function). */ - /** * Given an array of const char* strings (invariant chars only), return a UEnumeration. String pointers from 0..count-1 must not be null. * Do not free or modify either the string array or the characters it points to until this object has been destroyed with uenum_close. diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ufieldpositer.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ufieldpositer.h index 6cc9ffada4..8cc25260ee 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ufieldpositer.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ufieldpositer.h @@ -1,6 +1,8 @@ +// © 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) 2015-2016, International Business Machines * Corporation and others. All Rights Reserved. ***************************************************************************************** */ @@ -11,7 +13,6 @@ #include "unicode/utypes.h" #if !UCONFIG_NO_FORMATTING -#ifndef U_HIDE_DRAFT_API #include "unicode/localpointer.h" @@ -37,10 +38,10 @@ /** * Opaque UFieldPositionIterator object for use in C. - * @draft ICU 55 + * @stable ICU 55 */ struct UFieldPositionIterator; -typedef struct UFieldPositionIterator UFieldPositionIterator; /**< C typedef for struct UFieldPositionIterator. @draft ICU 55 */ +typedef struct UFieldPositionIterator UFieldPositionIterator; /**< C typedef for struct UFieldPositionIterator. @stable ICU 55 */ /** * Open a new, unset UFieldPositionIterator object. @@ -49,18 +50,18 @@ typedef struct UFieldPositionIterator UFieldPositionIterator; /**< C typedef fo * @return * A pointer to an empty (unset) UFieldPositionIterator object, * or NULL if an error occurred. - * @draft ICU 55 + * @stable ICU 55 */ -U_DRAFT UFieldPositionIterator* U_EXPORT2 +U_STABLE UFieldPositionIterator* U_EXPORT2 ufieldpositer_open(UErrorCode* status); /** * Close a UFieldPositionIterator object. Once closed it may no longer be used. * @param fpositer * A pointer to the UFieldPositionIterator object to close. - * @draft ICU 55 + * @stable ICU 55 */ -U_DRAFT void U_EXPORT2 +U_STABLE void U_EXPORT2 ufieldpositer_close(UFieldPositionIterator *fpositer); @@ -75,18 +76,18 @@ U_NAMESPACE_BEGIN * * @see LocalPointerBase * @see LocalPointer - * @draft ICU 55 + * @stable ICU 55 */ U_DEFINE_LOCAL_OPEN_POINTER(LocalUFieldPositionIteratorPointer, UFieldPositionIterator, ufieldpositer_close); U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * 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. @@ -109,13 +110,12 @@ U_NAMESPACE_END * descriptions of format functions that take a UFieldPositionIterator* * parameter, such as {@link #udat_formatForFields}. * - * @draft ICU 55 + * @stable ICU 55 */ -U_DRAFT int32_t U_EXPORT2 +U_STABLE int32_t U_EXPORT2 ufieldpositer_next(UFieldPositionIterator *fpositer, int32_t *beginIndex, int32_t *endIndex); -#endif /* U_HIDE_DRAFT_API */ #endif /* #if !UCONFIG_NO_FORMATTING */ #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uformattable.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uformattable.h index a64ae14653..15830a14fb 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uformattable.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uformattable.h @@ -1,3 +1,5 @@ +// © 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; @@ -100,7 +108,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUFormattablePointer, UFormattable, ufmt_close); U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Return the type of this object diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uformattedvalue.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uformattedvalue.h new file mode 100644 index 0000000000..eaa4f28893 --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uformattedvalue.h @@ -0,0 +1,440 @@ +// © 2018 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#ifndef __UFORMATTEDVALUE_H__ +#define __UFORMATTEDVALUE_H__ + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING +#ifndef U_HIDE_DRAFT_API + +#include "unicode/ufieldpositer.h" + +/** + * \file + * \brief C API: Abstract operations for localized strings. + * + * This file contains declarations for classes that deal with formatted strings. A number + * of APIs throughout ICU use these classes for expressing their localized output. + */ + + +/** + * All possible field categories in ICU. Every entry in this enum corresponds + * to another enum that exists in ICU. + * + * In the APIs that take a UFieldCategory, an int32_t type is used. Field + * categories having any of the top four bits turned on are reserved as + * private-use for external APIs implementing FormattedValue. This means that + * categories 2^28 and higher or below zero (with the highest bit turned on) + * are private-use and will not be used by ICU in the future. + * + * @draft ICU 64 + */ +typedef enum UFieldCategory { + /** + * For an undefined field category. + * + * @draft ICU 64 + */ + UFIELD_CATEGORY_UNDEFINED = 0, + + /** + * For fields in UDateFormatField (udat.h), from ICU 3.0. + * + * @draft ICU 64 + */ + UFIELD_CATEGORY_DATE, + + /** + * For fields in UNumberFormatFields (unum.h), from ICU 49. + * + * @draft ICU 64 + */ + UFIELD_CATEGORY_NUMBER, + + /** + * For fields in UListFormatterField (ulistformatter.h), from ICU 63. + * + * @draft ICU 64 + */ + UFIELD_CATEGORY_LIST, + + /** + * For fields in URelativeDateTimeFormatterField (ureldatefmt.h), from ICU 64. + * + * @draft ICU 64 + */ + UFIELD_CATEGORY_RELATIVE_DATETIME, + + /** + * Reserved for possible future fields in UDateIntervalFormatField. + * + * @internal + */ + UFIELD_CATEGORY_DATE_INTERVAL, + +#ifndef U_HIDE_INTERNAL_API + /** @internal */ + UFIELD_CATEGORY_COUNT, +#endif /* U_HIDE_INTERNAL_API */ + + /** + * Category for spans in a list. + * + * @draft ICU 64 + */ + UFIELD_CATEGORY_LIST_SPAN = 0x1000 + UFIELD_CATEGORY_LIST, + + /** + * Category for spans in a date interval. + * + * @draft ICU 64 + */ + UFIELD_CATEGORY_DATE_INTERVAL_SPAN = 0x1000 + UFIELD_CATEGORY_DATE_INTERVAL, + +} UFieldCategory; + + +struct UConstrainedFieldPosition; +/** + * Represents a span of a string containing a given field. + * + * This struct differs from UFieldPosition in the following ways: + * + * 1. It has information on the field category. + * 2. It allows you to set constraints to use when iterating over field positions. + * 3. It is used for the newer FormattedValue APIs. + * + * @draft ICU 64 + */ +typedef struct UConstrainedFieldPosition UConstrainedFieldPosition; + + +/** + * Creates a new UConstrainedFieldPosition. + * + * By default, the UConstrainedFieldPosition has no iteration constraints. + * + * @param ec Set if an error occurs. + * @return The new object, or NULL if an error occurs. + * @draft ICU 64 + */ +U_DRAFT UConstrainedFieldPosition* U_EXPORT2 +ucfpos_open(UErrorCode* ec); + + +/** + * Resets a UConstrainedFieldPosition to its initial state, as if it were newly created. + * + * Removes any constraints that may have been set on the instance. + * + * @param ucfpos The instance of UConstrainedFieldPosition. + * @param ec Set if an error occurs. + * @draft ICU 64 + */ +U_DRAFT void U_EXPORT2 +ucfpos_reset( + UConstrainedFieldPosition* ucfpos, + UErrorCode* ec); + + +/** + * Destroys a UConstrainedFieldPosition and releases its memory. + * + * @param ucfpos The instance of UConstrainedFieldPosition. + * @draft ICU 64 + */ +U_DRAFT void U_EXPORT2 +ucfpos_close(UConstrainedFieldPosition* ucfpos); + + +/** + * Sets a constraint on the field category. + * + * When this instance of UConstrainedFieldPosition is passed to ufmtval_nextPosition, + * positions are skipped unless they have the given category. + * + * Any previously set constraints are cleared. + * + * For example, to loop over only the number-related fields: + * + * UConstrainedFieldPosition* ucfpos = ucfpos_open(ec); + * ucfpos_constrainCategory(ucfpos, UFIELDCATEGORY_NUMBER_FORMAT, ec); + * while (ufmtval_nextPosition(ufmtval, ucfpos, ec)) { + * // handle the number-related field position + * } + * ucfpos_close(ucfpos); + * + * Changing the constraint while in the middle of iterating over a FormattedValue + * does not generally have well-defined behavior. + * + * @param ucfpos The instance of UConstrainedFieldPosition. + * @param category The field category to fix when iterating. + * @param ec Set if an error occurs. + * @draft ICU 64 + */ +U_DRAFT void U_EXPORT2 +ucfpos_constrainCategory( + UConstrainedFieldPosition* ucfpos, + int32_t category, + UErrorCode* ec); + + +/** + * Sets a constraint on the category and field. + * + * When this instance of UConstrainedFieldPosition is passed to ufmtval_nextPosition, + * positions are skipped unless they have the given category and field. + * + * Any previously set constraints are cleared. + * + * For example, to loop over all grouping separators: + * + * UConstrainedFieldPosition* ucfpos = ucfpos_open(ec); + * ucfpos_constrainField(ucfpos, UFIELDCATEGORY_NUMBER_FORMAT, UNUM_GROUPING_SEPARATOR_FIELD, ec); + * while (ufmtval_nextPosition(ufmtval, ucfpos, ec)) { + * // handle the grouping separator position + * } + * ucfpos_close(ucfpos); + * + * Changing the constraint while in the middle of iterating over a FormattedValue + * does not generally have well-defined behavior. + * + * @param ucfpos The instance of UConstrainedFieldPosition. + * @param category The field category to fix when iterating. + * @param field The field to fix when iterating. + * @param ec Set if an error occurs. + * @draft ICU 64 + */ +U_DRAFT void U_EXPORT2 +ucfpos_constrainField( + UConstrainedFieldPosition* ucfpos, + int32_t category, + int32_t field, + UErrorCode* ec); + + +/** + * Gets the field category for the current position. + * + * If a category or field constraint was set, this function returns the constrained + * category. Otherwise, the return value is well-defined only after + * ufmtval_nextPosition returns TRUE. + * + * @param ucfpos The instance of UConstrainedFieldPosition. + * @param ec Set if an error occurs. + * @return The field category saved in the instance. + * @draft ICU 64 + */ +U_DRAFT int32_t U_EXPORT2 +ucfpos_getCategory( + const UConstrainedFieldPosition* ucfpos, + UErrorCode* ec); + + +/** + * Gets the field for the current position. + * + * If a field constraint was set, this function returns the constrained + * field. Otherwise, the return value is well-defined only after + * ufmtval_nextPosition returns TRUE. + * + * @param ucfpos The instance of UConstrainedFieldPosition. + * @param ec Set if an error occurs. + * @return The field saved in the instance. + * @draft ICU 64 + */ +U_DRAFT int32_t U_EXPORT2 +ucfpos_getField( + const UConstrainedFieldPosition* ucfpos, + UErrorCode* ec); + + +/** + * Gets the INCLUSIVE start and EXCLUSIVE end index stored for the current position. + * + * The output values are well-defined only after ufmtval_nextPosition returns TRUE. + * + * @param ucfpos The instance of UConstrainedFieldPosition. + * @param pStart Set to the start index saved in the instance. Ignored if nullptr. + * @param pLimit Set to the end index saved in the instance. Ignored if nullptr. + * @param ec Set if an error occurs. + * @draft ICU 64 + */ +U_DRAFT void U_EXPORT2 +ucfpos_getIndexes( + const UConstrainedFieldPosition* ucfpos, + int32_t* pStart, + int32_t* pLimit, + UErrorCode* ec); + + +/** + * Gets an int64 that FormattedValue implementations may use for storage. + * + * The initial value is zero. + * + * Users of FormattedValue should not need to call this method. + * + * @param ucfpos The instance of UConstrainedFieldPosition. + * @param ec Set if an error occurs. + * @return The current iteration context from ucfpos_setInt64IterationContext. + * @draft ICU 64 + */ +U_DRAFT int64_t U_EXPORT2 +ucfpos_getInt64IterationContext( + const UConstrainedFieldPosition* ucfpos, + UErrorCode* ec); + + +/** + * Sets an int64 that FormattedValue implementations may use for storage. + * + * Intended to be used by FormattedValue implementations. + * + * @param ucfpos The instance of UConstrainedFieldPosition. + * @param context The new iteration context. + * @param ec Set if an error occurs. + * @draft ICU 64 + */ +U_DRAFT void U_EXPORT2 +ucfpos_setInt64IterationContext( + UConstrainedFieldPosition* ucfpos, + int64_t context, + UErrorCode* ec); + + +/** + * Determines whether a given field should be included given the + * constraints. + * + * Intended to be used by FormattedValue implementations. + * + * @param ucfpos The instance of UConstrainedFieldPosition. + * @param category The category to test. + * @param field The field to test. + * @param ec Set if an error occurs. + * @draft ICU 64 + */ +U_DRAFT UBool U_EXPORT2 +ucfpos_matchesField( + const UConstrainedFieldPosition* ucfpos, + int32_t category, + int32_t field, + UErrorCode* ec); + + +/** + * Sets new values for the primary public getters. + * + * Intended to be used by FormattedValue implementations. + * + * It is up to the implementation to ensure that the user-requested + * constraints are satisfied. This method does not check! + * + * @param ucfpos The instance of UConstrainedFieldPosition. + * @param category The new field category. + * @param field The new field. + * @param start The new inclusive start index. + * @param limit The new exclusive end index. + * @param ec Set if an error occurs. + * @draft ICU 64 + */ +U_DRAFT void U_EXPORT2 +ucfpos_setState( + UConstrainedFieldPosition* ucfpos, + int32_t category, + int32_t field, + int32_t start, + int32_t limit, + UErrorCode* ec); + + +struct UFormattedValue; +/** + * An abstract formatted value: a string with associated field attributes. + * Many formatters format to types compatible with UFormattedValue. + * + * @draft ICU 64 + */ +typedef struct UFormattedValue UFormattedValue; + + +/** + * Returns a pointer to the formatted string. The pointer is owned by the UFormattedValue. The + * return value is valid only as long as the UFormattedValue is present and unchanged in memory. + * + * The return value is NUL-terminated but could contain internal NULs. + * + * @param ufmtval + * The object containing the formatted string and attributes. + * @param pLength Output variable for the length of the string. Ignored if NULL. + * @param ec Set if an error occurs. + * @return A NUL-terminated char16 string owned by the UFormattedValue. + * @draft ICU 64 + */ +U_DRAFT const UChar* U_EXPORT2 +ufmtval_getString( + const UFormattedValue* ufmtval, + int32_t* pLength, + UErrorCode* ec); + + +/** + * Iterates over field positions in the UFormattedValue. This lets you determine the position + * of specific types of substrings, like a month or a decimal separator. + * + * To loop over all field positions: + * + * UConstrainedFieldPosition* ucfpos = ucfpos_open(ec); + * while (ufmtval_nextPosition(ufmtval, ucfpos, ec)) { + * // handle the field position; get information from ucfpos + * } + * ucfpos_close(ucfpos); + * + * @param ufmtval + * The object containing the formatted string and attributes. + * @param ucfpos + * The object used for iteration state; can provide constraints to iterate over only + * one specific category or field; + * see ucfpos_constrainCategory + * and ucfpos_constrainField. + * @param ec Set if an error occurs. + * @return TRUE if another position was found; FALSE otherwise. + * @draft ICU 64 + */ +U_DRAFT UBool U_EXPORT2 +ufmtval_nextPosition( + const UFormattedValue* ufmtval, + UConstrainedFieldPosition* ucfpos, + UErrorCode* ec); + + +#if U_SHOW_CPLUSPLUS_API +U_NAMESPACE_BEGIN + +/** + * \class LocalUConstrainedFieldPositionPointer + * "Smart pointer" class; closes a UConstrainedFieldPosition via ucfpos_close(). + * For most methods see the LocalPointerBase base class. + * + * Usage: + * + * LocalUConstrainedFieldPositionPointer ucfpos(ucfpos_open(ec)); + * // no need to explicitly call ucfpos_close() + * + * @draft ICU 64 + */ +U_DEFINE_LOCAL_OPEN_POINTER(LocalUConstrainedFieldPositionPointer, + UConstrainedFieldPosition, + ucfpos_close); + +U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API + + +#endif /* U_HIDE_DRAFT_API */ +#endif /* #if !UCONFIG_NO_FORMATTING */ +#endif // __UFORMATTEDVALUE_H__ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ugender.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ugender.h index 86e229df61..903f3dd5de 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ugender.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ugender.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************************** * Copyright (C) 2010-2013, International Business Machines @@ -47,11 +49,11 @@ enum UGender { */ typedef enum UGender UGender; +struct UGenderInfo; /** * Opaque UGenderInfo object for use in C programs. * @stable ICU 50 */ -struct UGenderInfo; typedef struct UGenderInfo UGenderInfo; /** @@ -75,7 +77,7 @@ ugender_getInstance(const char *locale, UErrorCode *status); * @stable ICU 50 */ U_STABLE UGender U_EXPORT2 -ugender_getListGender(const UGenderInfo* genderinfo, const UGender *genders, int32_t size, UErrorCode *status); +ugender_getListGender(const UGenderInfo* genderInfo, const UGender *genders, int32_t size, UErrorCode *status); #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uidna.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uidna.h index decece1fb0..13e147234c 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uidna.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uidna.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -6,7 +8,7 @@ * ******************************************************************************* * file name: uidna.h - * encoding: US-ASCII + * encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -164,7 +166,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUIDNAPointer, UIDNA, uidna_close); U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Output container for IDNA processing errors. diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uiter.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uiter.h index 0cdb8ffbe5..9792095e00 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uiter.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uiter.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -6,7 +8,7 @@ * ******************************************************************************* * file name: uiter.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -33,7 +35,7 @@ class Replaceable; U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API U_CDECL_BEGIN @@ -700,7 +702,7 @@ uiter_setCharacterIterator(UCharIterator *iter, icu::CharacterIterator *charIter U_STABLE void U_EXPORT2 uiter_setReplaceable(UCharIterator *iter, const icu::Replaceable *rep); -#endif +#endif // U_SHOW_CPLUSPLUS_API U_CDECL_END diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uldnames.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uldnames.h index b0a2bb0fc8..aff4712ab0 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uldnames.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uldnames.h @@ -1,7 +1,9 @@ +// © 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 * -* others. All Rights Reserved. * +* Copyright (C) 2010-2016, International Business Machines Corporation and +* others. All Rights Reserved. ******************************************************************************* */ @@ -55,7 +57,7 @@ typedef struct ULocaleDisplayNames ULocaleDisplayNames; * Returns an instance of LocaleDisplayNames that returns names * formatted for the provided locale, using the provided * dialectHandling. The usual value for dialectHandling is - * ULOC_STANDARD_NAMES. + * ULDN_STANDARD_NAMES. * * @param locale the display locale * @param dialectHandling how to select names for locales @@ -93,7 +95,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalULocaleDisplayNamesPointer, ULocaleDisplayNames U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /* getters for state */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ulistformatter.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ulistformatter.h index 1c6cb2d7b1..9d91ad17bb 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ulistformatter.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ulistformatter.h @@ -1,6 +1,8 @@ +// © 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) 2015-2016, International Business Machines * Corporation and others. All Rights Reserved. ***************************************************************************************** */ @@ -11,9 +13,9 @@ #include "unicode/utypes.h" #if !UCONFIG_NO_FORMATTING -#ifndef U_HIDE_DRAFT_API #include "unicode/localpointer.h" +#include "unicode/uformattedvalue.h" /** * \file @@ -27,10 +29,39 @@ /** * Opaque UListFormatter object for use in C - * @draft ICU 55 + * @stable ICU 55 */ struct UListFormatter; -typedef struct UListFormatter UListFormatter; /**< C typedef for struct UListFormatter. @draft ICU 55 */ +typedef struct UListFormatter UListFormatter; /**< C typedef for struct UListFormatter. @stable ICU 55 */ + +#ifndef U_HIDE_DRAFT_API +struct UFormattedList; +/** + * Opaque struct to contain the results of a UListFormatter operation. + * @draft ICU 64 + */ +typedef struct UFormattedList UFormattedList; +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API +/** + * FieldPosition and UFieldPosition selectors for format fields + * defined by ListFormatter. + * @draft ICU 63 + */ +typedef enum UListFormatterField { + /** + * The literal text in the result which came from the resources. + * @draft ICU 63 + */ + ULISTFMT_LITERAL_FIELD, + /** + * The element text in the result which came from the input strings. + * @draft ICU 63 + */ + ULISTFMT_ELEMENT_FIELD +} UListFormatterField; +#endif // U_HIDE_DRAFT_API /** * Open a new UListFormatter object using the rules for a given locale. @@ -46,9 +77,9 @@ typedef struct UListFormatter UListFormatter; /**< C typedef for struct UListFo * @return * A pointer to a UListFormatter object for the specified locale, * or NULL if an error occurred. - * @draft ICU 55 + * @stable ICU 55 */ -U_DRAFT UListFormatter* U_EXPORT2 +U_CAPI UListFormatter* U_EXPORT2 ulistfmt_open(const char* locale, UErrorCode* status); @@ -56,11 +87,58 @@ ulistfmt_open(const char* locale, * Close a UListFormatter object. Once closed it may no longer be used. * @param listfmt * The UListFormatter object to close. - * @draft ICU 55 + * @stable ICU 55 */ -U_DRAFT void U_EXPORT2 +U_CAPI void U_EXPORT2 ulistfmt_close(UListFormatter *listfmt); +#ifndef U_HIDE_DRAFT_API +/** + * Creates an object to hold the result of a UListFormatter + * operation. The object can be used repeatedly; it is cleared whenever + * passed to a format function. + * + * @param ec Set if an error occurs. + * @return A pointer needing ownership. + * @draft ICU 64 + */ +U_CAPI UFormattedList* U_EXPORT2 +ulistfmt_openResult(UErrorCode* ec); + +/** + * Returns a representation of a UFormattedList as a UFormattedValue, + * which can be subsequently passed to any API requiring that type. + * + * The returned object is owned by the UFormattedList and is valid + * only as long as the UFormattedList is present and unchanged in memory. + * + * You can think of this method as a cast between types. + * + * When calling ufmtval_nextPosition(): + * The fields are returned from start to end. The special field category + * UFIELD_CATEGORY_LIST_SPAN is used to indicate which argument + * was inserted at the given position. The span category will + * always occur before the corresponding instance of UFIELD_CATEGORY_LIST + * in the ufmtval_nextPosition() iterator. + * + * @param uresult The object containing the formatted string. + * @param ec Set if an error occurs. + * @return A UFormattedValue owned by the input object. + * @draft ICU 64 + */ +U_CAPI const UFormattedValue* U_EXPORT2 +ulistfmt_resultAsValue(const UFormattedList* uresult, UErrorCode* ec); + +/** + * Releases the UFormattedList created by ulistfmt_openResult(). + * + * @param uresult The object to release. + * @draft ICU 64 + */ +U_CAPI void U_EXPORT2 +ulistfmt_closeResult(UFormattedList* uresult); +#endif /* U_HIDE_DRAFT_API */ + #if U_SHOW_CPLUSPLUS_API @@ -73,13 +151,26 @@ U_NAMESPACE_BEGIN * * @see LocalPointerBase * @see LocalPointer - * @draft ICU 55 + * @stable ICU 55 */ U_DEFINE_LOCAL_OPEN_POINTER(LocalUListFormatterPointer, UListFormatter, ulistfmt_close); +#ifndef U_HIDE_DRAFT_API +/** + * \class LocalUFormattedListPointer + * "Smart pointer" class, closes a UFormattedList via ulistfmt_closeResult(). + * For most methods see the LocalPointerBase base class. + * + * @see LocalPointerBase + * @see LocalPointer + * @draft ICU 64 + */ +U_DEFINE_LOCAL_OPEN_POINTER(LocalUFormattedListPointer, UFormattedList, ulistfmt_closeResult); +#endif /* U_HIDE_DRAFT_API */ + U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Formats a list of strings using the conventions established for the @@ -113,9 +204,9 @@ U_NAMESPACE_END * The total buffer size needed; if greater than resultLength, the * output was truncated. May be <=0 if unable to determine the * total buffer size needed (e.g. for illegal arguments). - * @draft ICU 55 + * @stable ICU 55 */ -U_DRAFT int32_t U_EXPORT2 +U_CAPI int32_t U_EXPORT2 ulistfmt_format(const UListFormatter* listfmt, const UChar* const strings[], const int32_t * stringLengths, @@ -124,7 +215,43 @@ ulistfmt_format(const UListFormatter* listfmt, int32_t resultCapacity, UErrorCode* status); +#ifndef U_HIDE_DRAFT_API +/** + * Formats a list of strings to a UFormattedList, which exposes more + * information than the string exported by ulistfmt_format(). + * + * @param listfmt + * The UListFormatter object specifying the list conventions. + * @param strings + * An array of pointers to UChar strings; the array length is + * specified by stringCount. Must be non-NULL if stringCount > 0. + * @param stringLengths + * An array of string lengths corresponding to the strings[] + * parameter; any individual length value may be negative to indicate + * that the corresponding strings[] entry is 0-terminated, or + * stringLengths itself may be NULL if all of the strings are + * 0-terminated. If non-NULL, the stringLengths array must have + * stringCount entries. + * @param stringCount + * the number of entries in strings[], and the number of entries + * in the stringLengths array if it is not NULL. Must be >= 0. + * @param uresult + * The object in which to store the result of the list formatting + * operation. See ulistfmt_openResult(). + * @param status + * Error code set if an error occurred during formatting. + * @draft ICU 64 + */ +U_CAPI void U_EXPORT2 +ulistfmt_formatStringsToResult( + const UListFormatter* listfmt, + const UChar* const strings[], + const int32_t * stringLengths, + int32_t stringCount, + UFormattedList* uresult, + UErrorCode* status); #endif /* U_HIDE_DRAFT_API */ + #endif /* #if !UCONFIG_NO_FORMATTING */ #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uloc.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uloc.h index c305c8b78c..bc1d74fc80 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uloc.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uloc.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** -* Copyright (C) 1997-2014, International Business Machines +* Copyright (C) 1997-2016, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * @@ -59,7 +61,7 @@ * http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt * *

        - * The second option includes an additonal ISO Country + * The second option includes an additional ISO Country * Code. These codes are the upper-case two-letter codes * as defined by ISO-3166. * You can find a full list of these codes at a number of sites, such as: @@ -67,7 +69,7 @@ * http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html * *

        - * The third option requires another additonal information--the + * The third option requires another additional information--the * Variant. * The Variant codes are vendor and browser-specific. * For example, use WIN for Windows, MAC for Macintosh, and POSIX for POSIX. @@ -155,7 +157,7 @@ * just a mechanism for identifying these services. * *

        - * Each international serivce that performs locale-sensitive operations + * Each international service that performs locale-sensitive operations * allows you * to get all the available objects of that type. You can sift * through these objects by language, country, or variant, @@ -348,10 +350,14 @@ typedef enum { * @deprecated ICU 2.8 */ ULOC_REQUESTED_LOCALE = 2, -#endif /* U_HIDE_DEPRECATED_API */ - ULOC_DATA_LOCALE_TYPE_LIMIT = 3 -} ULocDataLocaleType ; + /** + * One more than the highest normal ULocDataLocaleType value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + ULOC_DATA_LOCALE_TYPE_LIMIT = 3 +#endif // U_HIDE_DEPRECATED_API +} ULocDataLocaleType; #ifndef U_HIDE_SYSTEM_API /** @@ -533,6 +539,9 @@ uloc_getISO3Country(const char* localeID); * Gets the Win32 LCID value for the specified locale. * If the ICU locale is not recognized by Windows, 0 will be returned. * + * LCIDs were deprecated with Windows Vista and Microsoft recommends + * that developers use BCP47 style tags instead (uloc_toLanguageTag). + * * @param localeID the locale to get the Win32 LCID value with * @return country the Win32 LCID for localeID * @stable ICU 2.0 @@ -571,7 +580,7 @@ uloc_getDisplayLanguage(const char* locale, * if the locale's language code is "en", passing Locale::getFrench() for * inLocale would result in "", while passing Locale::getGerman() * for inLocale would result in "". NULL may be used to specify the default. - * @param script the displayable country code for localeID + * @param script the displayable script for the localeID * @param scriptCapacity the size of the script buffer to store the * displayable script code with * @param status error information if retrieving the displayable script code failed @@ -588,6 +597,8 @@ uloc_getDisplayScript(const char* locale, /** * Gets the country name suitable for display for the specified locale. + * Warning: this is for the region part of a valid locale ID; it cannot just be the region code (like "FR"). + * To get the display name for a region alone, or for other options, use ULocaleDisplayNames instead. * * @param locale the locale to get the displayable country code with. NULL may be used to specify the default. * @param displayLocale Specifies the locale to be used to display the name. In other words, @@ -767,10 +778,11 @@ uloc_getISOLanguages(void); /** * - * Gets a list of all available 2-letter country codes defined in ISO 639. This is a - * pointer to an array of pointers to arrays of char. All of these pointers are - * owned by ICU-- do not delete them, and do not write through them. The array is - * terminated with a null pointer. + * Gets a list of all available 2-letter country codes which are valid regular + * region codes in CLDR; these are based on the non-deprecated alpha-2 region + * codes in ISO 3166-1. The return value is a pointer to an array of pointers + * C strings. All of these pointers are owned by ICU; do not delete them, and + * do not write through them. The array is terminated with a null pointer. * @return a list of all available country codes * @stable ICU 2.0 */ @@ -844,10 +856,12 @@ uloc_openKeywords(const char* localeID, * Get the value for a keyword. Locale name does not need to be normalized. * * @param localeID locale name containing the keyword ("de_DE@currency=EURO;collation=PHONEBOOK") - * @param keywordName name of the keyword for which we want the value. Case insensitive. + * @param keywordName name of the keyword for which we want the value; must not be + * NULL or empty, and must consist only of [A-Za-z0-9]. Case insensitive. * @param buffer receiving buffer * @param bufferCapacity capacity of receiving buffer - * @param status containing error code - buffer not big enough. + * @param status containing error code: e.g. buffer not big enough or ill-formed localeID + * or keywordName parameters. * @return the length of keyword value * @stable ICU 2.8 */ @@ -864,18 +878,26 @@ uloc_getKeywordValue(const char* localeID, * For removing all keywords, use uloc_getBaseName(). * * NOTE: Unlike almost every other ICU function which takes a - * buffer, this function will NOT truncate the output text. If a - * BUFFER_OVERFLOW_ERROR is received, it means that the original - * buffer is untouched. This is done to prevent incorrect or possibly - * even malformed locales from being generated and used. + * buffer, this function will NOT truncate the output text, and will + * not update the buffer with unterminated text setting a status of + * U_STRING_NOT_TERMINATED_WARNING. If a BUFFER_OVERFLOW_ERROR is received, + * it means a terminated version of the updated locale ID would not fit + * in the buffer, and the original buffer is untouched. This is done to + * prevent incorrect or possibly even malformed locales from being generated + * and used. * - * @param keywordName name of the keyword to be set. Case insensitive. + * @param keywordName name of the keyword to be set; must not be + * NULL or empty, and must consist only of [A-Za-z0-9]. Case insensitive. * @param keywordValue value of the keyword to be set. If 0-length or - * NULL, will result in the keyword being removed. No error is given if - * that keyword does not exist. - * @param buffer input buffer containing locale to be modified. + * NULL, will result in the keyword being removed; no error is given if + * that keyword does not exist. Otherwise, must consist only of + * [A-Za-z0-9] and [/_+-]. + * @param buffer input buffer containing well-formed locale ID to be + * modified. * @param bufferCapacity capacity of receiving buffer - * @param status containing error code - buffer not big enough. + * @param status containing error code: e.g. buffer not big enough + * or ill-formed keywordName or keywordValue parameters, or ill-formed + * locale ID in buffer on input. * @return the length needed for the buffer * @see uloc_getKeywordValue * @stable ICU 3.2 @@ -886,7 +908,6 @@ uloc_setKeywordValue(const char* keywordName, char* buffer, int32_t bufferCapacity, UErrorCode* status); -#ifndef U_HIDE_DRAFT_API /** * Returns whether the locale's script is written right-to-left. * If there is no script subtag, then the likely script is used, see uloc_addLikelySubtags(). @@ -899,11 +920,10 @@ uloc_setKeywordValue(const char* keywordName, * * @param locale input locale ID * @return TRUE if the locale's script is written right-to-left - * @draft ICU 54 + * @stable ICU 54 */ -U_DRAFT UBool U_EXPORT2 +U_STABLE UBool U_EXPORT2 uloc_isRightToLeft(const char *locale); -#endif /* U_HIDE_DRAFT_API */ /** * enums for the return value for the character and line orientation @@ -1151,7 +1171,6 @@ uloc_toLanguageTag(const char* localeID, UBool strict, UErrorCode* err); -#ifndef U_HIDE_DRAFT_API /** * Converts the specified keyword (legacy key, or BCP 47 Unicode locale * extension key) to the equivalent BCP 47 Unicode locale extension key. @@ -1171,9 +1190,9 @@ uloc_toLanguageTag(const char* localeID, * mapped to a well-formed BCP 47 Unicode locale extension * key. * @see uloc_toLegacyKey - * @draft ICU 54 + * @stable ICU 54 */ -U_DRAFT const char* U_EXPORT2 +U_STABLE const char* U_EXPORT2 uloc_toUnicodeLocaleKey(const char* keyword); /** @@ -1202,9 +1221,9 @@ uloc_toUnicodeLocaleKey(const char* keyword); * or NULL if the locale keyword value cannot be mapped to * a well-formed BCP 47 Unicode locale extension type. * @see uloc_toLegacyType - * @draft ICU 54 + * @stable ICU 54 */ -U_DRAFT const char* U_EXPORT2 +U_STABLE const char* U_EXPORT2 uloc_toUnicodeLocaleType(const char* keyword, const char* value); /** @@ -1217,9 +1236,9 @@ uloc_toUnicodeLocaleType(const char* keyword, const char* value); * @return the well-formed legacy key, or NULL if the specified * keyword cannot be mapped to a well-formed legacy key. * @see toUnicodeLocaleKey - * @draft ICU 54 + * @stable ICU 54 */ -U_DRAFT const char* U_EXPORT2 +U_STABLE const char* U_EXPORT2 uloc_toLegacyKey(const char* keyword); /** @@ -1246,11 +1265,9 @@ uloc_toLegacyKey(const char* keyword); * keyword value cannot be mapped to a well-formed legacy * type. * @see toUnicodeLocaleType - * @draft ICU 54 + * @stable ICU 54 */ -U_DRAFT const char* U_EXPORT2 +U_STABLE const char* U_EXPORT2 uloc_toLegacyType(const char* keyword, const char* value); -#endif /* U_HIDE_DRAFT_API */ - #endif /*_ULOC*/ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ulocdata.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ulocdata.h index 63495f681c..cbb8bfd866 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ulocdata.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ulocdata.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * * @@ -6,7 +8,7 @@ * * ****************************************************************************** * file name: ulocdata.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -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; /** @@ -104,7 +116,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalULocaleDataPointer, ULocaleData, ulocdata_close U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Sets the "no Substitute" attribute of the locale data @@ -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/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/umachine.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/umachine.h index 532159216a..b38bc2bf5a 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/umachine.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/umachine.h @@ -1,12 +1,14 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * -* Copyright (C) 1999-2014, International Business Machines +* Copyright (C) 1999-2015, International Business Machines * Corporation and others. All Rights Reserved. * ****************************************************************************** * file name: umachine.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -123,6 +125,9 @@ * May result in an error if it applied to something not an override. * @internal */ +#ifndef U_OVERRIDE +#define U_OVERRIDE override +#endif /** * \def U_FINAL @@ -131,24 +136,10 @@ * May result in an error if subclasses attempt to override. * @internal */ - -#if defined(__cplusplus) && __cplusplus>=201103L -/* C++11 */ -#ifndef U_OVERRIDE -#define U_OVERRIDE override -#endif -#ifndef U_FINAL +#if !defined(U_FINAL) || defined(U_IN_DOXYGEN) #define U_FINAL final #endif -#else -/* not C++11 - define to nothing */ -#ifndef U_OVERRIDE -#define U_OVERRIDE -#endif -#ifndef U_FINAL -#define U_FINAL -#endif -#endif + /*==========================================================================*/ /* limits for int32_t etc., like in POSIX inttypes.h */ @@ -288,30 +279,96 @@ typedef int8_t UBool; /** Number of bytes in a UChar. @stable ICU 2.0 */ #define U_SIZEOF_UCHAR 2 +/** + * \def U_CHAR16_IS_TYPEDEF + * If 1, then char16_t is a typedef and not a real type (yet) + * @internal + */ +#if (U_PLATFORM == U_PF_AIX) && defined(__cplusplus) &&(U_CPLUSPLUS_VERSION < 11) +// for AIX, uchar.h needs to be included +# include +# define U_CHAR16_IS_TYPEDEF 1 +#elif defined(_MSC_VER) && (_MSC_VER < 1900) +// Versions of Visual Studio/MSVC below 2015 do not support char16_t as a real type, +// and instead use a typedef. https://msdn.microsoft.com/library/bb531344.aspx +# define U_CHAR16_IS_TYPEDEF 1 +#else +# define U_CHAR16_IS_TYPEDEF 0 +#endif + + /** * \var UChar - * Define UChar to be UCHAR_TYPE, if that is #defined (for example, to char16_t), - * or wchar_t if that is 16 bits wide; always assumed to be unsigned. - * If neither is available, then define UChar to be uint16_t. * - * This makes the definition of UChar platform-dependent - * but allows direct string type compatibility with platforms with - * 16-bit wchar_t types. + * The base type for UTF-16 code units and pointers. + * Unsigned 16-bit integer. + * Starting with ICU 59, C++ API uses char16_t directly, while C API continues to use UChar. + * + * UChar is configurable by defining the macro UCHAR_TYPE + * on the preprocessor or compiler command line: + * -DUCHAR_TYPE=uint16_t or -DUCHAR_TYPE=wchar_t (if U_SIZEOF_WCHAR_T==2) etc. + * (The UCHAR_TYPE can also be \#defined earlier in this file, for outside the ICU library code.) + * This is for transitional use from application code that uses uint16_t or wchar_t for UTF-16. + * + * The default is UChar=char16_t. + * + * C++11 defines char16_t as bit-compatible with uint16_t, but as a distinct type. + * + * In C, char16_t is a simple typedef of uint_least16_t. + * ICU requires uint_least16_t=uint16_t for data memory mapping. + * On macOS, char16_t is not available because the uchar.h standard header is missing. * * @stable ICU 4.4 */ -#if defined(UCHAR_TYPE) + +#if 0 + // #if 1 is normal. UChar defaults to char16_t in C++. + // For configuration testing of UChar=uint16_t temporarily change this to #if 0. + // The intltest Makefile #defines UCHAR_TYPE=char16_t, + // so we only #define it to uint16_t if it is undefined so far. +#elif !defined(UCHAR_TYPE) +# define UCHAR_TYPE uint16_t +#endif + +#if defined(U_COMBINED_IMPLEMENTATION) || defined(U_COMMON_IMPLEMENTATION) || \ + defined(U_I18N_IMPLEMENTATION) || defined(U_IO_IMPLEMENTATION) + // Inside the ICU library code, never configurable. + typedef char16_t UChar; +#elif defined(UCHAR_TYPE) typedef UCHAR_TYPE UChar; -/* Not #elif U_HAVE_CHAR16_T -- because that is type-incompatible with pre-C++11 callers - typedef char16_t UChar; */ -#elif U_SIZEOF_WCHAR_T==2 - typedef wchar_t UChar; -#elif defined(__CHAR16_TYPE__) - typedef __CHAR16_TYPE__ UChar; +#elif defined(__cplusplus) + typedef char16_t UChar; #else typedef uint16_t UChar; #endif +/** + * \var OldUChar + * Default ICU 58 definition of UChar. + * A base type for UTF-16 code units and pointers. + * Unsigned 16-bit integer. + * + * Define OldUChar to be wchar_t if that is 16 bits wide. + * If wchar_t is not 16 bits wide, then define UChar to be uint16_t. + * + * This makes the definition of OldUChar platform-dependent + * but allows direct string type compatibility with platforms with + * 16-bit wchar_t types. + * + * This is how UChar was defined in ICU 58, for transition convenience. + * Exception: ICU 58 UChar was defined to UCHAR_TYPE if that macro was defined. + * The current UChar responds to UCHAR_TYPE but OldUChar does not. + * + * @stable ICU 59 + */ +#if U_SIZEOF_WCHAR_T==2 + typedef wchar_t OldUChar; +#elif defined(__CHAR16_TYPE__) + typedef __CHAR16_TYPE__ OldUChar; +#else + typedef uint16_t OldUChar; +#endif + /** * Define UChar32 as a type for single Unicode code points. * UChar32 is a signed 32-bit integer (same as int32_t). diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/umisc.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/umisc.h index d85451fc76..213290b9af 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/umisc.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/umisc.h @@ -1,10 +1,12 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2006, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * file name: umisc.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/umsg.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/umsg.h index 52fe90e2d6..aa4079034f 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/umsg.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/umsg.h @@ -1,3 +1,5 @@ +// © 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 @@ -6,7 +8,7 @@ ******************************************************************** * * file name: umsg.h - * encoding: US-ASCII + * encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -427,7 +429,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUMessageFormatPointer, UMessageFormat, umsg_clo U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Open a copy of a UMessageFormat. diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/umutablecptrie.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/umutablecptrie.h new file mode 100644 index 0000000000..e75191a449 --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/umutablecptrie.h @@ -0,0 +1,241 @@ +// © 2017 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +// umutablecptrie.h (split out of ucptrie.h) +// created: 2018jan24 Markus W. Scherer + +#ifndef __UMUTABLECPTRIE_H__ +#define __UMUTABLECPTRIE_H__ + +#include "unicode/utypes.h" + +#ifndef U_HIDE_DRAFT_API + +#include "unicode/localpointer.h" +#include "unicode/ucpmap.h" +#include "unicode/ucptrie.h" +#include "unicode/utf8.h" + +U_CDECL_BEGIN + +/** + * \file + * + * This file defines a mutable Unicode code point trie. + * + * @see UCPTrie + * @see UMutableCPTrie + */ + +/** + * Mutable Unicode code point trie. + * Fast map from Unicode code points (U+0000..U+10FFFF) to 32-bit integer values. + * For details see http://site.icu-project.org/design/struct/utrie + * + * Setting values (especially ranges) and lookup is fast. + * The mutable trie is only somewhat space-efficient. + * It builds a compacted, immutable UCPTrie. + * + * This trie can be modified while iterating over its contents. + * For example, it is possible to merge its values with those from another + * set of ranges (e.g., another mutable or immutable trie): + * Iterate over those source ranges; for each of them iterate over this trie; + * add the source value into the value of each trie range. + * + * @see UCPTrie + * @see umutablecptrie_buildImmutable + * @draft ICU 63 + */ +typedef struct UMutableCPTrie UMutableCPTrie; + +/** + * Creates a mutable trie that initially maps each Unicode code point to the same value. + * It uses 32-bit data values until umutablecptrie_buildImmutable() is called. + * umutablecptrie_buildImmutable() takes a valueWidth parameter which + * determines the number of bits in the data value in the resulting UCPTrie. + * You must umutablecptrie_close() the trie once you are done using it. + * + * @param initialValue the initial value that is set for all code points + * @param errorValue the value for out-of-range code points and ill-formed UTF-8/16 + * @param pErrorCode an in/out ICU UErrorCode + * @return the trie + * @draft ICU 63 + */ +U_CAPI UMutableCPTrie * U_EXPORT2 +umutablecptrie_open(uint32_t initialValue, uint32_t errorValue, UErrorCode *pErrorCode); + +/** + * Clones a mutable trie. + * You must umutablecptrie_close() the clone once you are done using it. + * + * @param other the trie to clone + * @param pErrorCode an in/out ICU UErrorCode + * @return the trie clone + * @draft ICU 63 + */ +U_CAPI UMutableCPTrie * U_EXPORT2 +umutablecptrie_clone(const UMutableCPTrie *other, UErrorCode *pErrorCode); + +/** + * Closes a mutable trie and releases associated memory. + * + * @param trie the trie + * @draft ICU 63 + */ +U_CAPI void U_EXPORT2 +umutablecptrie_close(UMutableCPTrie *trie); + +#if U_SHOW_CPLUSPLUS_API + +U_NAMESPACE_BEGIN + +/** + * \class LocalUMutableCPTriePointer + * "Smart pointer" class, closes a UMutableCPTrie via umutablecptrie_close(). + * For most methods see the LocalPointerBase base class. + * + * @see LocalPointerBase + * @see LocalPointer + * @draft ICU 63 + */ +U_DEFINE_LOCAL_OPEN_POINTER(LocalUMutableCPTriePointer, UMutableCPTrie, umutablecptrie_close); + +U_NAMESPACE_END + +#endif + +/** + * Creates a mutable trie with the same contents as the UCPMap. + * You must umutablecptrie_close() the mutable trie once you are done using it. + * + * @param map the source map + * @param pErrorCode an in/out ICU UErrorCode + * @return the mutable trie + * @draft ICU 63 + */ +U_CAPI UMutableCPTrie * U_EXPORT2 +umutablecptrie_fromUCPMap(const UCPMap *map, UErrorCode *pErrorCode); + +/** + * Creates a mutable trie with the same contents as the immutable one. + * You must umutablecptrie_close() the mutable trie once you are done using it. + * + * @param trie the immutable trie + * @param pErrorCode an in/out ICU UErrorCode + * @return the mutable trie + * @draft ICU 63 + */ +U_CAPI UMutableCPTrie * U_EXPORT2 +umutablecptrie_fromUCPTrie(const UCPTrie *trie, UErrorCode *pErrorCode); + +/** + * Returns the value for a code point as stored in the trie. + * + * @param trie the trie + * @param c the code point + * @return the value + * @draft ICU 63 + */ +U_CAPI uint32_t U_EXPORT2 +umutablecptrie_get(const UMutableCPTrie *trie, UChar32 c); + +/** + * Returns the last code point such that all those from start to there have the same value. + * Can be used to efficiently iterate over all same-value ranges in a trie. + * (This is normally faster than iterating over code points and get()ting each value, + * but much slower than a data structure that stores ranges directly.) + * + * The trie can be modified between calls to this function. + * + * If the UCPMapValueFilter function pointer is not NULL, then + * the value to be delivered is passed through that function, and the return value is the end + * of the range where all values are modified to the same actual value. + * The value is unchanged if that function pointer is NULL. + * + * See the same-signature ucptrie_getRange() for a code sample. + * + * @param trie the trie + * @param start range start + * @param option defines whether surrogates are treated normally, + * or as having the surrogateValue; usually UCPMAP_RANGE_NORMAL + * @param surrogateValue value for surrogates; ignored if option==UCPMAP_RANGE_NORMAL + * @param filter a pointer to a function that may modify the trie data value, + * or NULL if the values from the trie are to be used unmodified + * @param context an opaque pointer that is passed on to the filter function + * @param pValue if not NULL, receives the value that every code point start..end has; + * may have been modified by filter(context, trie value) + * if that function pointer is not NULL + * @return the range end code point, or -1 if start is not a valid code point + * @draft ICU 63 + */ +U_CAPI UChar32 U_EXPORT2 +umutablecptrie_getRange(const UMutableCPTrie *trie, UChar32 start, + UCPMapRangeOption option, uint32_t surrogateValue, + UCPMapValueFilter *filter, const void *context, uint32_t *pValue); + +/** + * Sets a value for a code point. + * + * @param trie the trie + * @param c the code point + * @param value the value + * @param pErrorCode an in/out ICU UErrorCode + * @draft ICU 63 + */ +U_CAPI void U_EXPORT2 +umutablecptrie_set(UMutableCPTrie *trie, UChar32 c, uint32_t value, UErrorCode *pErrorCode); + +/** + * Sets a value for each code point [start..end]. + * Faster and more space-efficient than setting the value for each code point separately. + * + * @param trie the trie + * @param start the first code point to get the value + * @param end the last code point to get the value (inclusive) + * @param value the value + * @param pErrorCode an in/out ICU UErrorCode + * @draft ICU 63 + */ +U_CAPI void U_EXPORT2 +umutablecptrie_setRange(UMutableCPTrie *trie, + UChar32 start, UChar32 end, + uint32_t value, UErrorCode *pErrorCode); + +/** + * Compacts the data and builds an immutable UCPTrie according to the parameters. + * After this, the mutable trie will be empty. + * + * The mutable trie stores 32-bit values until buildImmutable() is called. + * If values shorter than 32 bits are to be stored in the immutable trie, + * then the upper bits are discarded. + * For example, when the mutable trie contains values 0x81, -0x7f, and 0xa581, + * and the value width is 8 bits, then each of these is stored as 0x81 + * and the immutable trie will return that as an unsigned value. + * (Some implementations may want to make productive temporary use of the upper bits + * until buildImmutable() discards them.) + * + * Not every possible set of mappings can be built into a UCPTrie, + * because of limitations resulting from speed and space optimizations. + * Every Unicode assigned character can be mapped to a unique value. + * Typical data yields data structures far smaller than the limitations. + * + * It is possible to construct extremely unusual mappings that exceed the data structure limits. + * In such a case this function will fail with a U_INDEX_OUTOFBOUNDS_ERROR. + * + * @param trie the trie trie + * @param type selects the trie type + * @param valueWidth selects the number of bits in a trie data value; if smaller than 32 bits, + * then the values stored in the trie will be truncated first + * @param pErrorCode an in/out ICU UErrorCode + * + * @see umutablecptrie_fromUCPTrie + * @draft ICU 63 + */ +U_CAPI UCPTrie * U_EXPORT2 +umutablecptrie_buildImmutable(UMutableCPTrie *trie, UCPTrieType type, UCPTrieValueWidth valueWidth, + UErrorCode *pErrorCode); + +U_CDECL_END + +#endif // U_HIDE_DRAFT_API +#endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unifilt.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unifilt.h index ce952afaef..4e3f71fc9b 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unifilt.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unifilt.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2010, International Business Machines Corporation and others. @@ -18,6 +20,7 @@ * \brief C++ API: Unicode Filter */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -28,7 +31,7 @@ U_NAMESPACE_BEGIN * defined range. * @stable ICU 3.0 */ -#define U_ETHER ((UChar)0xFFFF) +#define U_ETHER ((char16_t)0xFFFF) /** * @@ -116,5 +119,6 @@ class U_COMMON_API UnicodeFilter : public UnicodeFunctor, public UnicodeMatcher /*inline UnicodeFilter::UnicodeFilter() {}*/ U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unifunct.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unifunct.h index 3aa7b0358c..3383733463 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unifunct.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unifunct.h @@ -1,3 +1,5 @@ +// © 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 @@ -18,6 +20,7 @@ * \brief C++ API: Unicode Functor */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class UnicodeMatcher; @@ -121,5 +124,6 @@ class U_COMMON_API UnicodeFunctor : public UObject { /*inline UnicodeFunctor::UnicodeFunctor() {}*/ U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unimatch.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unimatch.h index 0dbb14efc2..7d668b3f9a 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unimatch.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unimatch.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) 2001-2005, International Business Machines Corporation and others. All Rights Reserved. ********************************************************************** @@ -16,6 +18,7 @@ */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class Replaceable; @@ -159,5 +162,6 @@ class U_COMMON_API UnicodeMatcher /* not : public UObject because this is an int }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unirepl.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unirepl.h index 6b7746b221..822da8cd93 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unirepl.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unirepl.h @@ -1,3 +1,5 @@ +// © 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 @@ -17,6 +19,7 @@ * \brief C++ API: UnicodeReplacer */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class Replaceable; @@ -93,5 +96,6 @@ class U_I18N_API UnicodeReplacer /* not : public UObject because this is an inte }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uniset.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uniset.h index 237ebf766c..c3b8f5d7e3 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uniset.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uniset.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* *************************************************************************** -* Copyright (C) 1999-2014, International Business Machines Corporation +* Copyright (C) 1999-2016, International Business Machines Corporation * and others. All Rights Reserved. *************************************************************************** * Date Name Description @@ -11,6 +13,7 @@ #ifndef UNICODESET_H #define UNICODESET_H +#include "unicode/ucpmap.h" #include "unicode/unifilt.h" #include "unicode/unistr.h" #include "unicode/uset.h" @@ -20,11 +23,10 @@ * \brief C++ API: Unicode Set */ +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN // Forward Declarations. -void U_CALLCONV UnicodeSet_initInclusion(int32_t src, UErrorCode &status); /**< @internal */ - class BMPSet; class ParsePosition; class RBBIRuleScanner; @@ -274,14 +276,23 @@ class RuleCharacterIterator; * @stable ICU 2.0 */ class U_COMMON_API UnicodeSet U_FINAL : public UnicodeFilter { +private: + /** + * Enough for sets with few ranges. + * For example, White_Space has 10 ranges, list length 21. + */ + static constexpr int32_t INITIAL_CAPACITY = 25; + // fFlags constant + static constexpr uint8_t kIsBogus = 1; // This set is bogus (i.e. not valid) - int32_t len; // length of list used; 0 <= len <= capacity - int32_t capacity; // capacity of list - UChar32* list; // MUST be terminated with HIGH - BMPSet *bmpSet; // The set is frozen iff either bmpSet or stringSpan is not NULL. - UChar32* buffer; // internal buffer, may be NULL - int32_t bufferCapacity; // capacity of buffer - int32_t patLen; + UChar32* list = stackList; // MUST be terminated with HIGH + int32_t capacity = INITIAL_CAPACITY; // capacity of list + int32_t len = 1; // length of list used; 1 <= len <= capacity + uint8_t fFlags = 0; // Bit flag (see constants above) + + BMPSet *bmpSet = nullptr; // The set is frozen iff either bmpSet or stringSpan is not NULL. + UChar32* buffer = nullptr; // internal buffer, may be NULL + int32_t bufferCapacity = 0; // capacity of buffer /** * The pattern representation of this set. This may not be the @@ -292,27 +303,31 @@ class U_COMMON_API UnicodeSet U_FINAL : public UnicodeFilter { * indicating that toPattern() must generate a pattern * representation from the inversion list. */ - UChar *pat; - UVector* strings; // maintained in sorted order - UnicodeSetStringSpan *stringSpan; + char16_t *pat = nullptr; + int32_t patLen = 0; + + UVector* strings = nullptr; // maintained in sorted order + UnicodeSetStringSpan *stringSpan = nullptr; + + /** + * Initial list array. + * Avoids some heap allocations, and list is never nullptr. + * Increases the object size a bit. + */ + UChar32 stackList[INITIAL_CAPACITY]; -private: - enum { // constants - kIsBogus = 1 // This set is bogus (i.e. not valid) - }; - uint8_t fFlags; // Bit flag (see constants above) public: /** * Determine if this object contains a valid set. * A bogus set has no value. It is different from an empty set. * It can be used to indicate that no set value is available. * - * @return TRUE if the set is valid, FALSE otherwise + * @return TRUE if the set is bogus/invalid, FALSE otherwise * @see setToBogus() * @stable ICU 4.0 */ inline UBool isBogus(void) const; - + /** * Make this UnicodeSet object invalid. * The string will test TRUE with isBogus(). @@ -360,7 +375,7 @@ class U_COMMON_API UnicodeSet U_FINAL : public UnicodeFilter { UnicodeSet(); /** - * Constructs a set containing the given range. If end > + * Constructs a set containing the given range. If end < * start then an empty set is created. * * @param start first character, inclusive, of range @@ -369,6 +384,28 @@ class U_COMMON_API UnicodeSet U_FINAL : public UnicodeFilter { */ UnicodeSet(UChar32 start, UChar32 end); +#ifndef U_HIDE_INTERNAL_API + /** + * @internal + */ + enum ESerialization { + kSerialized /* result of serialize() */ + }; + + /** + * Constructs a set from the output of serialize(). + * + * @param buffer the 16 bit array + * @param bufferLen the original length returned from serialize() + * @param serialization the value 'kSerialized' + * @param status error code + * + * @internal + */ + UnicodeSet(const uint16_t buffer[], int32_t bufferLen, + ESerialization serialization, UErrorCode &status); +#endif /* U_HIDE_INTERNAL_API */ + /** * Constructs a set from the given pattern. See the class * description for the syntax of the pattern language. @@ -454,7 +491,7 @@ class U_COMMON_API UnicodeSet U_FINAL : public UnicodeFilter { * true if the specified set is not equal to this set. * @stable ICU 2.0 */ - UBool operator!=(const UnicodeSet& o) const; + inline UBool operator!=(const UnicodeSet& o) const; /** * Returns a copy of this object. All UnicodeFunctor objects have @@ -560,9 +597,8 @@ class U_COMMON_API UnicodeSet U_FINAL : public UnicodeFilter { //---------------------------------------------------------------- /** - * Make this object represent the range start - end. - * If end > start then this object is set to an - * an empty range. + * Make this object represent the range `start - end`. + * If `end > start` then this object is set to an empty range. * A frozen set will not be modified. * * @param start first character in the set, inclusive @@ -867,7 +903,7 @@ class U_COMMON_API UnicodeSet U_FINAL : public UnicodeFilter { * @stable ICU 3.8 * @see USetSpanCondition */ - int32_t span(const UChar *s, int32_t length, USetSpanCondition spanCondition) const; + int32_t span(const char16_t *s, int32_t length, USetSpanCondition spanCondition) const; /** * Returns the end of the substring of the input string according to the USetSpanCondition. @@ -900,7 +936,7 @@ class U_COMMON_API UnicodeSet U_FINAL : public UnicodeFilter { * @stable ICU 3.8 * @see USetSpanCondition */ - int32_t spanBack(const UChar *s, int32_t length, USetSpanCondition spanCondition) const; + int32_t spanBack(const char16_t *s, int32_t length, USetSpanCondition spanCondition) const; /** * Returns the start of the substring of the input string according to the USetSpanCondition. @@ -1457,8 +1493,6 @@ class U_COMMON_API UnicodeSet U_FINAL : public UnicodeFilter { friend class USetAccess; - int32_t getStringCount() const; - const UnicodeString* getString(int32_t index) const; //---------------------------------------------------------------- @@ -1476,12 +1510,14 @@ class U_COMMON_API UnicodeSet U_FINAL : public UnicodeFilter { private: friend class RBBIRuleScanner; + friend class RBBIRuleScanner57; //---------------------------------------------------------------- // Implementation: Clone as thawed (see ICU4J Freezable) //---------------------------------------------------------------- UnicodeSet(const UnicodeSet& o, UBool /* asThawed */); + UnicodeSet& copyFrom(const UnicodeSet& o, UBool asThawed); //---------------------------------------------------------------- // Implementation: Pattern parsing @@ -1497,19 +1533,25 @@ class U_COMMON_API UnicodeSet U_FINAL : public UnicodeFilter { UnicodeString& rebuiltPat, uint32_t options, UnicodeSet& (UnicodeSet::*caseClosure)(int32_t attribute), + int32_t depth, UErrorCode& ec); //---------------------------------------------------------------- // Implementation: Utility methods //---------------------------------------------------------------- - void ensureCapacity(int32_t newLen, UErrorCode& ec); + static int32_t nextCapacity(int32_t minCapacity); - void ensureBufferCapacity(int32_t newLen, UErrorCode& ec); + bool ensureCapacity(int32_t newLen); + + bool ensureBufferCapacity(int32_t newLen); void swapBuffers(void); UBool allocateStrings(UErrorCode &status); + UBool hasStrings() const; + int32_t stringsSize() const; + UBool stringsContains(const UnicodeString &s) const; UnicodeString& _toPattern(UnicodeString& result, UBool escapeUnprintable) const; @@ -1589,7 +1631,6 @@ class U_COMMON_API UnicodeSet U_FINAL : public UnicodeFilter { UnicodeString& rebuiltPat, UErrorCode& ec); - friend void U_CALLCONV UnicodeSet_initInclusion(int32_t src, UErrorCode &status); static const UnicodeSet* getInclusions(int32_t src, UErrorCode &status); /** @@ -1609,13 +1650,22 @@ class U_COMMON_API UnicodeSet U_FINAL : public UnicodeFilter { */ void applyFilter(Filter filter, void* context, - int32_t src, + const UnicodeSet* inclusions, UErrorCode &status); +#ifndef U_HIDE_DRAFT_API // Skipped: ucpmap.h is draft only. + void applyIntPropertyValue(const UCPMap *map, + UCPMapValueFilter *filter, const void *context, + UErrorCode &errorCode); +#endif /* U_HIDE_DRAFT_API */ + /** * Set the new pattern to cache. */ - void setPattern(const UnicodeString& newPat); + void setPattern(const UnicodeString& newPat) { + setPattern(newPat.getBuffer(), newPat.length()); + } + void setPattern(const char16_t *newPat, int32_t newPatLen); /** * Release existing cached pattern. */ @@ -1687,5 +1737,6 @@ inline int32_t UnicodeSet::spanBack(const UnicodeString &s, int32_t limit, USetS } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unistr.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unistr.h index 48fe2b3b1d..55739ac242 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unistr.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unistr.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** -* Copyright (C) 1998-2014, International Business Machines +* Copyright (C) 1998-2016, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * @@ -22,29 +24,19 @@ #define UNISTR_H /** - * \file - * \brief C++ API: Unicode String + * \file + * \brief C++ API: Unicode String */ +#include #include "unicode/utypes.h" +#include "unicode/char16ptr.h" #include "unicode/rep.h" #include "unicode/std_string.h" #include "unicode/stringpiece.h" #include "unicode/bytestream.h" -#include "unicode/ucasemap.h" struct UConverter; // unicode/ucnv.h -class StringThreadTest; - -#ifndef U_COMPARE_CODE_POINT_ORDER -/* see also ustring.h and unorm.h */ -/** - * Option bit for u_strCaseCompare, u_strcasecmp, unorm_compare, etc: - * Compare strings in code point order instead of code unit order. - * @stable ICU 2.2 - */ -#define U_COMPARE_CODE_POINT_ORDER 0x8000 -#endif #ifndef USTRING_H /** @@ -54,28 +46,39 @@ U_STABLE int32_t U_EXPORT2 u_strlen(const UChar *s); #endif -/** - * \def U_STRING_CASE_MAPPER_DEFINED - * @internal - */ -#ifndef U_STRING_CASE_MAPPER_DEFINED -#define U_STRING_CASE_MAPPER_DEFINED +#if U_SHOW_CPLUSPLUS_API +U_NAMESPACE_BEGIN +#if !UCONFIG_NO_BREAK_ITERATION +class BreakIterator; // unicode/brkiter.h +#endif +class Edits; + +U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API + +#if U_SHOW_CPLUSPLUS_API +// Not #ifndef U_HIDE_INTERNAL_API because UnicodeString needs the UStringCaseMapper. /** * Internal string case mapping function type. + * All error checking must be done. + * src and dest must not overlap. * @internal */ typedef int32_t U_CALLCONV -UStringCaseMapper(const UCaseMap *csm, - UChar *dest, int32_t destCapacity, - const UChar *src, int32_t srcLength, - UErrorCode *pErrorCode); - +UStringCaseMapper(int32_t caseLocale, uint32_t options, +#if !UCONFIG_NO_BREAK_ITERATION + icu::BreakIterator *iter, #endif + char16_t *dest, int32_t destCapacity, + const char16_t *src, int32_t srcLength, + icu::Edits *edits, + UErrorCode &errorCode); +#endif // U_SHOW_CPLUSPLUS_API +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN -class BreakIterator; // unicode/brkiter.h class Locale; // unicode/locid.h class StringCharacterIterator; class UnicodeStringAppendable; // unicode/appendable.h @@ -96,29 +99,25 @@ class UnicodeStringAppendable; // unicode/appendable.h /** * Unicode String literals in C++. - * Dependent on the platform properties, different UnicodeString - * constructors should be used to create a UnicodeString object from - * a string literal. - * The macros are defined for maximum performance. + * + * Note: these macros are not recommended for new code. + * Prior to the availability of C++11 and u"unicode string literals", + * these macros were provided for portability and efficiency when + * initializing UnicodeStrings from literals. + * * They work only for strings that contain "invariant characters", i.e., * only latin letters, digits, and some punctuation. * See utypes.h for details. * * The string parameter must be a C string literal. * The length of the string, not including the terminating - * NUL, must be specified as a constant. - * The U_STRING_DECL macro should be invoked exactly once for one - * such string variable before it is used. + * `NUL`, must be specified as a constant. * @stable ICU 2.0 */ -#if defined(U_DECLARE_UTF16) -# define UNICODE_STRING(cs, _length) icu::UnicodeString(TRUE, (const UChar *)U_DECLARE_UTF16(cs), _length) -#elif U_SIZEOF_WCHAR_T==U_SIZEOF_UCHAR && (U_CHARSET_FAMILY==U_ASCII_FAMILY || (U_SIZEOF_UCHAR == 2 && defined(U_WCHAR_IS_UTF16))) -# define UNICODE_STRING(cs, _length) icu::UnicodeString(TRUE, (const UChar *)L ## cs, _length) -#elif U_SIZEOF_UCHAR==1 && U_CHARSET_FAMILY==U_ASCII_FAMILY -# define UNICODE_STRING(cs, _length) icu::UnicodeString(TRUE, (const UChar *)cs, _length) +#if !U_CHAR16_IS_TYPEDEF +# define UNICODE_STRING(cs, _length) icu::UnicodeString(TRUE, u ## cs, _length) #else -# define UNICODE_STRING(cs, _length) icu::UnicodeString(cs, _length, US_INV) +# define UNICODE_STRING(cs, _length) icu::UnicodeString(TRUE, (const char16_t*)u ## cs, _length) #endif /** @@ -139,7 +138,7 @@ class UnicodeStringAppendable; // unicode/appendable.h /** * \def UNISTR_FROM_CHAR_EXPLICIT * This can be defined to be empty or "explicit". - * If explicit, then the UnicodeString(UChar) and UnicodeString(UChar32) + * If explicit, then the UnicodeString(char16_t) and UnicodeString(UChar32) * constructors are marked as explicit, preventing their inadvertent use. * @stable ICU 49 */ @@ -156,7 +155,7 @@ class UnicodeStringAppendable; // unicode/appendable.h /** * \def UNISTR_FROM_STRING_EXPLICIT * This can be defined to be empty or "explicit". - * If explicit, then the UnicodeString(const char *) and UnicodeString(const UChar *) + * If explicit, then the UnicodeString(const char *) and UnicodeString(const char16_t *) * constructors are marked as explicit, preventing their inadvertent use. * * In particular, this helps prevent accidentally depending on ICU conversion code @@ -173,39 +172,89 @@ class UnicodeStringAppendable; // unicode/appendable.h # endif #endif +/** + * \def UNISTR_OBJECT_SIZE + * Desired sizeof(UnicodeString) in bytes. + * It should be a multiple of sizeof(pointer) to avoid unusable space for padding. + * The object size may want to be a multiple of 16 bytes, + * which is a common granularity for heap allocation. + * + * Any space inside the object beyond sizeof(vtable pointer) + 2 + * is available for storing short strings inside the object. + * The bigger the object, the longer a string that can be stored inside the object, + * without additional heap allocation. + * + * Depending on a platform's pointer size, pointer alignment requirements, + * and struct padding, the compiler will usually round up sizeof(UnicodeString) + * to 4 * sizeof(pointer) (or 3 * sizeof(pointer) for P128 data models), + * to hold the fields for heap-allocated strings. + * Such a minimum size also ensures that the object is easily large enough + * to hold at least 2 char16_ts, for one supplementary code point (U16_MAX_LENGTH). + * + * sizeof(UnicodeString) >= 48 should work for all known platforms. + * + * For example, on a 64-bit machine where sizeof(vtable pointer) is 8, + * sizeof(UnicodeString) = 64 would leave space for + * (64 - sizeof(vtable pointer) - 2) / U_SIZEOF_UCHAR = (64 - 8 - 2) / 2 = 27 + * char16_ts stored inside the object. + * + * The minimum object size on a 64-bit machine would be + * 4 * sizeof(pointer) = 4 * 8 = 32 bytes, + * and the internal buffer would hold up to 11 char16_ts in that case. + * + * @see U16_MAX_LENGTH + * @stable ICU 56 + */ +#ifndef UNISTR_OBJECT_SIZE +# define UNISTR_OBJECT_SIZE 64 +#endif + /** * UnicodeString is a string class that stores Unicode characters directly and provides - * similar functionality as the Java String and StringBuffer classes. + * similar functionality as the Java String and StringBuffer/StringBuilder classes. * It is a concrete implementation of the abstract class Replaceable (for transliteration). * + * A UnicodeString may also "alias" an external array of characters + * (that is, point to it, rather than own the array) + * whose lifetime must then at least match the lifetime of the aliasing object. + * This aliasing may be preserved when returning a UnicodeString by value, + * depending on the compiler and the function implementation, + * via Return Value Optimization (RVO) or the move assignment operator. + * (However, the copy assignment operator does not preserve aliasing.) + * For details see the description of storage models at the end of the class API docs + * and in the User Guide chapter linked from there. + * * The UnicodeString class is not suitable for subclassing. * - *

        For an overview of Unicode strings in C and C++ see the - * User Guide Strings chapter.

        + * For an overview of Unicode strings in C and C++ see the + * [User Guide Strings chapter](http://userguide.icu-project.org/strings#TOC-Strings-in-C-C-). * - *

        In ICU, a Unicode string consists of 16-bit Unicode code units. + * In ICU, a Unicode string consists of 16-bit Unicode *code units*. * A Unicode character may be stored with either one code unit * (the most common case) or with a matched pair of special code units - * ("surrogates"). The data type for code units is UChar. - * For single-character handling, a Unicode character code point is a value - * in the range 0..0x10ffff. ICU uses the UChar32 type for code points.

        + * ("surrogates"). The data type for code units is char16_t. + * For single-character handling, a Unicode character code *point* is a value + * in the range 0..0x10ffff. ICU uses the UChar32 type for code points. * - *

        Indexes and offsets into and lengths of strings always count code units, not code points. + * Indexes and offsets into and lengths of strings always count code units, not code points. * This is the same as with multi-byte char* strings in traditional string handling. * Operations on partial strings typically do not test for code point boundaries. * If necessary, the user needs to take care of such boundaries by testing for the code unit * values or by using functions like * UnicodeString::getChar32Start() and UnicodeString::getChar32Limit() - * (or, in C, the equivalent macros U16_SET_CP_START() and U16_SET_CP_LIMIT(), see utf.h).

        + * (or, in C, the equivalent macros U16_SET_CP_START() and U16_SET_CP_LIMIT(), see utf.h). * * UnicodeString methods are more lenient with regard to input parameter values * than other ICU APIs. In particular: * - If indexes are out of bounds for a UnicodeString object - * (<0 or >length()) then they are "pinned" to the nearest boundary. - * - If primitive string pointer values (e.g., const UChar * or char *) + * (< 0 or > length()) then they are "pinned" to the nearest boundary. + * - If the buffer passed to an insert/append/replace operation is owned by the + * target object, e.g., calling str.append(str), an extra copy may take place + * to ensure safety. + * - If primitive string pointer values (e.g., const char16_t * or char *) * for input strings are NULL, then those input string parameters are treated * as if they pointed to an empty string. - * However, this is not the case for char * parameters for charset names + * However, this is *not* the case for char * parameters for charset names * or other IDs. * - Most UnicodeString methods do not take a UErrorCode parameter because * there are usually very few opportunities for failure other than a shortage @@ -229,14 +278,14 @@ class UnicodeStringAppendable; // unicode/appendable.h * This includes the const UnicodeString & parameters for * copy construction, assignment, and cloning. * - *

        UnicodeString uses several storage methods. + * UnicodeString uses several storage methods. * String contents can be stored inside the UnicodeString object itself, * in an allocated and shared buffer, or in an outside buffer that is "aliased". * Most of this is done transparently, but careful aliasing in particular provides * significant performance improvements. * Also, the internal buffer is accessible via special functions. * For details see the - * User Guide Strings chapter.

        + * [User Guide Strings chapter](http://userguide.icu-project.org/strings#TOC-Maximizing-Performance-with-the-UnicodeString-Storage-Model). * * @see utf.h * @see CharacterIterator @@ -271,7 +320,7 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Equality operator. Performs only bitwise comparison. * @param text The UnicodeString to compare to this one. - * @return TRUE if text contains the same characters as this one, + * @return TRUE if `text` contains the same characters as this one, * FALSE otherwise. * @stable ICU 2.0 */ @@ -280,7 +329,7 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Inequality operator. Performs only bitwise comparison. * @param text The UnicodeString to compare to this one. - * @return FALSE if text contains the same characters as this one, + * @return FALSE if `text` contains the same characters as this one, * TRUE otherwise. * @stable ICU 2.0 */ @@ -290,7 +339,7 @@ class U_COMMON_API UnicodeString : public Replaceable * Greater than operator. Performs only bitwise comparison. * @param text The UnicodeString to compare to this one. * @return TRUE if the characters in this are bitwise - * greater than the characters in text, FALSE otherwise + * greater than the characters in `text`, FALSE otherwise * @stable ICU 2.0 */ inline UBool operator> (const UnicodeString& text) const; @@ -299,7 +348,7 @@ class U_COMMON_API UnicodeString : public Replaceable * Less than operator. Performs only bitwise comparison. * @param text The UnicodeString to compare to this one. * @return TRUE if the characters in this are bitwise - * less than the characters in text, FALSE otherwise + * less than the characters in `text`, FALSE otherwise * @stable ICU 2.0 */ inline UBool operator< (const UnicodeString& text) const; @@ -308,7 +357,7 @@ class U_COMMON_API UnicodeString : public Replaceable * Greater than or equal operator. Performs only bitwise comparison. * @param text The UnicodeString to compare to this one. * @return TRUE if the characters in this are bitwise - * greater than or equal to the characters in text, FALSE otherwise + * greater than or equal to the characters in `text`, FALSE otherwise * @stable ICU 2.0 */ inline UBool operator>= (const UnicodeString& text) const; @@ -317,37 +366,37 @@ class U_COMMON_API UnicodeString : public Replaceable * Less than or equal operator. Performs only bitwise comparison. * @param text The UnicodeString to compare to this one. * @return TRUE if the characters in this are bitwise - * less than or equal to the characters in text, FALSE otherwise + * less than or equal to the characters in `text`, FALSE otherwise * @stable ICU 2.0 */ inline UBool operator<= (const UnicodeString& text) const; /** * Compare the characters bitwise in this UnicodeString to - * the characters in text. + * the characters in `text`. * @param text The UnicodeString to compare to this one. * @return The result of bitwise character comparison: 0 if this - * contains the same characters as text, -1 if the characters in - * this are bitwise less than the characters in text, +1 if the + * contains the same characters as `text`, -1 if the characters in + * this are bitwise less than the characters in `text`, +1 if the * characters in this are bitwise greater than the characters - * in text. + * in `text`. * @stable ICU 2.0 */ inline int8_t compare(const UnicodeString& text) const; /** * Compare the characters bitwise in the range - * [start, start + length) with the characters - * in the entire string text. + * [`start`, `start + length`) with the characters + * in the **entire string** `text`. * (The parameters "start" and "length" are not applied to the other text "text".) * @param start the offset at which the compare operation begins * @param length the number of characters of text to compare. * @param text the other text to be compared against this string. * @return The result of bitwise character comparison: 0 if this - * contains the same characters as text, -1 if the characters in - * this are bitwise less than the characters in text, +1 if the + * contains the same characters as `text`, -1 if the characters in + * this are bitwise less than the characters in `text`, +1 if the * characters in this are bitwise greater than the characters - * in text. + * in `text`. * @stable ICU 2.0 */ inline int8_t compare(int32_t start, @@ -356,19 +405,19 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Compare the characters bitwise in the range - * [start, start + length) with the characters - * in srcText in the range - * [srcStart, srcStart + srcLength). + * [`start`, `start + length`) with the characters + * in `srcText` in the range + * [`srcStart`, `srcStart + srcLength`). * @param start the offset at which the compare operation begins * @param length the number of characters in this to compare. * @param srcText the text to be compared - * @param srcStart the offset into srcText to start comparison - * @param srcLength the number of characters in src to compare + * @param srcStart the offset into `srcText` to start comparison + * @param srcLength the number of characters in `src` to compare * @return The result of bitwise character comparison: 0 if this - * contains the same characters as srcText, -1 if the characters in - * this are bitwise less than the characters in srcText, +1 if the + * contains the same characters as `srcText`, -1 if the characters in + * this are bitwise less than the characters in `srcText`, +1 if the * characters in this are bitwise greater than the characters - * in srcText. + * in `srcText`. * @stable ICU 2.0 */ inline int8_t compare(int32_t start, @@ -379,75 +428,75 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Compare the characters bitwise in this UnicodeString with the first - * srcLength characters in srcChars. + * `srcLength` characters in `srcChars`. * @param srcChars The characters to compare to this UnicodeString. - * @param srcLength the number of characters in srcChars to compare + * @param srcLength the number of characters in `srcChars` to compare * @return The result of bitwise character comparison: 0 if this - * contains the same characters as srcChars, -1 if the characters in - * this are bitwise less than the characters in srcChars, +1 if the + * contains the same characters as `srcChars`, -1 if the characters in + * this are bitwise less than the characters in `srcChars`, +1 if the * characters in this are bitwise greater than the characters - * in srcChars. + * in `srcChars`. * @stable ICU 2.0 */ - inline int8_t compare(const UChar *srcChars, + inline int8_t compare(ConstChar16Ptr srcChars, int32_t srcLength) const; /** * Compare the characters bitwise in the range - * [start, start + length) with the first - * length characters in srcChars + * [`start`, `start + length`) with the first + * `length` characters in `srcChars` * @param start the offset at which the compare operation begins * @param length the number of characters to compare. * @param srcChars the characters to be compared * @return The result of bitwise character comparison: 0 if this - * contains the same characters as srcChars, -1 if the characters in - * this are bitwise less than the characters in srcChars, +1 if the + * contains the same characters as `srcChars`, -1 if the characters in + * this are bitwise less than the characters in `srcChars`, +1 if the * characters in this are bitwise greater than the characters - * in srcChars. + * in `srcChars`. * @stable ICU 2.0 */ inline int8_t compare(int32_t start, int32_t length, - const UChar *srcChars) const; + const char16_t *srcChars) const; /** * Compare the characters bitwise in the range - * [start, start + length) with the characters - * in srcChars in the range - * [srcStart, srcStart + srcLength). + * [`start`, `start + length`) with the characters + * in `srcChars` in the range + * [`srcStart`, `srcStart + srcLength`). * @param start the offset at which the compare operation begins * @param length the number of characters in this to compare * @param srcChars the characters to be compared - * @param srcStart the offset into srcChars to start comparison - * @param srcLength the number of characters in srcChars to compare + * @param srcStart the offset into `srcChars` to start comparison + * @param srcLength the number of characters in `srcChars` to compare * @return The result of bitwise character comparison: 0 if this - * contains the same characters as srcChars, -1 if the characters in - * this are bitwise less than the characters in srcChars, +1 if the + * contains the same characters as `srcChars`, -1 if the characters in + * this are bitwise less than the characters in `srcChars`, +1 if the * characters in this are bitwise greater than the characters - * in srcChars. + * in `srcChars`. * @stable ICU 2.0 */ inline int8_t compare(int32_t start, int32_t length, - const UChar *srcChars, + const char16_t *srcChars, int32_t srcStart, int32_t srcLength) const; /** * Compare the characters bitwise in the range - * [start, limit) with the characters - * in srcText in the range - * [srcStart, srcLimit). + * [`start`, `limit`) with the characters + * in `srcText` in the range + * [`srcStart`, `srcLimit`). * @param start the offset at which the compare operation begins * @param limit the offset immediately following the compare operation * @param srcText the text to be compared - * @param srcStart the offset into srcText to start comparison - * @param srcLimit the offset into srcText to limit comparison + * @param srcStart the offset into `srcText` to start comparison + * @param srcLimit the offset into `srcText` to limit comparison * @return The result of bitwise character comparison: 0 if this - * contains the same characters as srcText, -1 if the characters in - * this are bitwise less than the characters in srcText, +1 if the + * contains the same characters as `srcText`, -1 if the characters in + * this are bitwise less than the characters in `srcText`, +1 if the * characters in this are bitwise greater than the characters - * in srcText. + * in `srcText`. * @stable ICU 2.0 */ inline int8_t compareBetween(int32_t start, @@ -543,7 +592,7 @@ class U_COMMON_API UnicodeString : public Replaceable * in code point order * @stable ICU 2.0 */ - inline int8_t compareCodePointOrder(const UChar *srcChars, + inline int8_t compareCodePointOrder(ConstChar16Ptr srcChars, int32_t srcLength) const; /** @@ -567,7 +616,7 @@ class U_COMMON_API UnicodeString : public Replaceable */ inline int8_t compareCodePointOrder(int32_t start, int32_t length, - const UChar *srcChars) const; + const char16_t *srcChars) const; /** * Compare two Unicode strings in code point order. @@ -592,7 +641,7 @@ class U_COMMON_API UnicodeString : public Replaceable */ inline int8_t compareCodePointOrder(int32_t start, int32_t length, - const UChar *srcChars, + const char16_t *srcChars, int32_t srcStart, int32_t srcLength) const; @@ -716,7 +765,7 @@ class U_COMMON_API UnicodeString : public Replaceable * @return A negative, zero, or positive integer indicating the comparison result. * @stable ICU 2.0 */ - inline int8_t caseCompare(const UChar *srcChars, + inline int8_t caseCompare(ConstChar16Ptr srcChars, int32_t srcLength, uint32_t options) const; @@ -742,7 +791,7 @@ class U_COMMON_API UnicodeString : public Replaceable */ inline int8_t caseCompare(int32_t start, int32_t length, - const UChar *srcChars, + const char16_t *srcChars, uint32_t options) const; /** @@ -769,7 +818,7 @@ class U_COMMON_API UnicodeString : public Replaceable */ inline int8_t caseCompare(int32_t start, int32_t length, - const UChar *srcChars, + const char16_t *srcChars, int32_t srcStart, int32_t srcLength, uint32_t options) const; @@ -804,21 +853,21 @@ class U_COMMON_API UnicodeString : public Replaceable uint32_t options) const; /** - * Determine if this starts with the characters in text + * Determine if this starts with the characters in `text` * @param text The text to match. - * @return TRUE if this starts with the characters in text, + * @return TRUE if this starts with the characters in `text`, * FALSE otherwise * @stable ICU 2.0 */ inline UBool startsWith(const UnicodeString& text) const; /** - * Determine if this starts with the characters in srcText - * in the range [srcStart, srcStart + srcLength). + * Determine if this starts with the characters in `srcText` + * in the range [`srcStart`, `srcStart + srcLength`). * @param srcText The text to match. - * @param srcStart the offset into srcText to start matching - * @param srcLength the number of characters in srcText to match - * @return TRUE if this starts with the characters in text, + * @param srcStart the offset into `srcText` to start matching + * @param srcLength the number of characters in `srcText` to match + * @return TRUE if this starts with the characters in `text`, * FALSE otherwise * @stable ICU 2.0 */ @@ -827,45 +876,45 @@ class U_COMMON_API UnicodeString : public Replaceable int32_t srcLength) const; /** - * Determine if this starts with the characters in srcChars + * Determine if this starts with the characters in `srcChars` * @param srcChars The characters to match. - * @param srcLength the number of characters in srcChars - * @return TRUE if this starts with the characters in srcChars, + * @param srcLength the number of characters in `srcChars` + * @return TRUE if this starts with the characters in `srcChars`, * FALSE otherwise * @stable ICU 2.0 */ - inline UBool startsWith(const UChar *srcChars, + inline UBool startsWith(ConstChar16Ptr srcChars, int32_t srcLength) const; /** - * Determine if this ends with the characters in srcChars - * in the range [srcStart, srcStart + srcLength). + * Determine if this ends with the characters in `srcChars` + * in the range [`srcStart`, `srcStart + srcLength`). * @param srcChars The characters to match. - * @param srcStart the offset into srcText to start matching - * @param srcLength the number of characters in srcChars to match - * @return TRUE if this ends with the characters in srcChars, FALSE otherwise + * @param srcStart the offset into `srcText` to start matching + * @param srcLength the number of characters in `srcChars` to match + * @return TRUE if this ends with the characters in `srcChars`, FALSE otherwise * @stable ICU 2.0 */ - inline UBool startsWith(const UChar *srcChars, + inline UBool startsWith(const char16_t *srcChars, int32_t srcStart, int32_t srcLength) const; /** - * Determine if this ends with the characters in text + * Determine if this ends with the characters in `text` * @param text The text to match. - * @return TRUE if this ends with the characters in text, + * @return TRUE if this ends with the characters in `text`, * FALSE otherwise * @stable ICU 2.0 */ inline UBool endsWith(const UnicodeString& text) const; /** - * Determine if this ends with the characters in srcText - * in the range [srcStart, srcStart + srcLength). + * Determine if this ends with the characters in `srcText` + * in the range [`srcStart`, `srcStart + srcLength`). * @param srcText The text to match. - * @param srcStart the offset into srcText to start matching - * @param srcLength the number of characters in srcText to match - * @return TRUE if this ends with the characters in text, + * @param srcStart the offset into `srcText` to start matching + * @param srcLength the number of characters in `srcText` to match + * @return TRUE if this ends with the characters in `text`, * FALSE otherwise * @stable ICU 2.0 */ @@ -874,27 +923,27 @@ class U_COMMON_API UnicodeString : public Replaceable int32_t srcLength) const; /** - * Determine if this ends with the characters in srcChars + * Determine if this ends with the characters in `srcChars` * @param srcChars The characters to match. - * @param srcLength the number of characters in srcChars - * @return TRUE if this ends with the characters in srcChars, + * @param srcLength the number of characters in `srcChars` + * @return TRUE if this ends with the characters in `srcChars`, * FALSE otherwise * @stable ICU 2.0 */ - inline UBool endsWith(const UChar *srcChars, + inline UBool endsWith(ConstChar16Ptr srcChars, int32_t srcLength) const; /** - * Determine if this ends with the characters in srcChars - * in the range [srcStart, srcStart + srcLength). + * Determine if this ends with the characters in `srcChars` + * in the range [`srcStart`, `srcStart + srcLength`). * @param srcChars The characters to match. - * @param srcStart the offset into srcText to start matching - * @param srcLength the number of characters in srcChars to match - * @return TRUE if this ends with the characters in srcChars, + * @param srcStart the offset into `srcText` to start matching + * @param srcLength the number of characters in `srcChars` to match + * @return TRUE if this ends with the characters in `srcChars`, * FALSE otherwise * @stable ICU 2.0 */ - inline UBool endsWith(const UChar *srcChars, + inline UBool endsWith(const char16_t *srcChars, int32_t srcStart, int32_t srcLength) const; @@ -902,21 +951,21 @@ class U_COMMON_API UnicodeString : public Replaceable /* Searching - bitwise only */ /** - * Locate in this the first occurrence of the characters in text, + * Locate in this the first occurrence of the characters in `text`, * using bitwise comparison. * @param text The text to search for. - * @return The offset into this of the start of text, + * @return The offset into this of the start of `text`, * or -1 if not found. * @stable ICU 2.0 */ inline int32_t indexOf(const UnicodeString& text) const; /** - * Locate in this the first occurrence of the characters in text - * starting at offset start, using bitwise comparison. + * Locate in this the first occurrence of the characters in `text` + * starting at offset `start`, using bitwise comparison. * @param text The text to search for. * @param start The offset at which searching will start. - * @return The offset into this of the start of text, + * @return The offset into this of the start of `text`, * or -1 if not found. * @stable ICU 2.0 */ @@ -925,12 +974,12 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Locate in this the first occurrence in the range - * [start, start + length) of the characters - * in text, using bitwise comparison. + * [`start`, `start + length`) of the characters + * in `text`, using bitwise comparison. * @param text The text to search for. * @param start The offset at which searching will start. * @param length The number of characters to search - * @return The offset into this of the start of text, + * @return The offset into this of the start of `text`, * or -1 if not found. * @stable ICU 2.0 */ @@ -940,17 +989,17 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Locate in this the first occurrence in the range - * [start, start + length) of the characters - * in srcText in the range - * [srcStart, srcStart + srcLength), + * [`start`, `start + length`) of the characters + * in `srcText` in the range + * [`srcStart`, `srcStart + srcLength`), * using bitwise comparison. * @param srcText The text to search for. - * @param srcStart the offset into srcText at which + * @param srcStart the offset into `srcText` at which * to start matching - * @param srcLength the number of characters in srcText to match + * @param srcLength the number of characters in `srcText` to match * @param start the offset into this at which to start matching * @param length the number of characters in this to search - * @return The offset into this of the start of text, + * @return The offset into this of the start of `text`, * or -1 if not found. * @stable ICU 2.0 */ @@ -962,123 +1011,123 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Locate in this the first occurrence of the characters in - * srcChars - * starting at offset start, using bitwise comparison. + * `srcChars` + * starting at offset `start`, using bitwise comparison. * @param srcChars The text to search for. - * @param srcLength the number of characters in srcChars to match + * @param srcLength the number of characters in `srcChars` to match * @param start the offset into this at which to start matching - * @return The offset into this of the start of text, + * @return The offset into this of the start of `text`, * or -1 if not found. * @stable ICU 2.0 */ - inline int32_t indexOf(const UChar *srcChars, + inline int32_t indexOf(const char16_t *srcChars, int32_t srcLength, int32_t start) const; /** * Locate in this the first occurrence in the range - * [start, start + length) of the characters - * in srcChars, using bitwise comparison. + * [`start`, `start + length`) of the characters + * in `srcChars`, using bitwise comparison. * @param srcChars The text to search for. - * @param srcLength the number of characters in srcChars + * @param srcLength the number of characters in `srcChars` * @param start The offset at which searching will start. * @param length The number of characters to search - * @return The offset into this of the start of srcChars, + * @return The offset into this of the start of `srcChars`, * or -1 if not found. * @stable ICU 2.0 */ - inline int32_t indexOf(const UChar *srcChars, + inline int32_t indexOf(ConstChar16Ptr srcChars, int32_t srcLength, int32_t start, int32_t length) const; /** * Locate in this the first occurrence in the range - * [start, start + length) of the characters - * in srcChars in the range - * [srcStart, srcStart + srcLength), + * [`start`, `start + length`) of the characters + * in `srcChars` in the range + * [`srcStart`, `srcStart + srcLength`), * using bitwise comparison. * @param srcChars The text to search for. - * @param srcStart the offset into srcChars at which + * @param srcStart the offset into `srcChars` at which * to start matching - * @param srcLength the number of characters in srcChars to match + * @param srcLength the number of characters in `srcChars` to match * @param start the offset into this at which to start matching * @param length the number of characters in this to search - * @return The offset into this of the start of text, + * @return The offset into this of the start of `text`, * or -1 if not found. * @stable ICU 2.0 */ - int32_t indexOf(const UChar *srcChars, + int32_t indexOf(const char16_t *srcChars, int32_t srcStart, int32_t srcLength, int32_t start, int32_t length) const; /** - * Locate in this the first occurrence of the BMP code point c, + * Locate in this the first occurrence of the BMP code point `c`, * using bitwise comparison. * @param c The code unit to search for. - * @return The offset into this of c, or -1 if not found. + * @return The offset into this of `c`, or -1 if not found. * @stable ICU 2.0 */ - inline int32_t indexOf(UChar c) const; + inline int32_t indexOf(char16_t c) const; /** - * Locate in this the first occurrence of the code point c, + * Locate in this the first occurrence of the code point `c`, * using bitwise comparison. * * @param c The code point to search for. - * @return The offset into this of c, or -1 if not found. + * @return The offset into this of `c`, or -1 if not found. * @stable ICU 2.0 */ inline int32_t indexOf(UChar32 c) const; /** - * Locate in this the first occurrence of the BMP code point c, - * starting at offset start, using bitwise comparison. + * Locate in this the first occurrence of the BMP code point `c`, + * starting at offset `start`, using bitwise comparison. * @param c The code unit to search for. * @param start The offset at which searching will start. - * @return The offset into this of c, or -1 if not found. + * @return The offset into this of `c`, or -1 if not found. * @stable ICU 2.0 */ - inline int32_t indexOf(UChar c, + inline int32_t indexOf(char16_t c, int32_t start) const; /** - * Locate in this the first occurrence of the code point c - * starting at offset start, using bitwise comparison. + * Locate in this the first occurrence of the code point `c` + * starting at offset `start`, using bitwise comparison. * * @param c The code point to search for. * @param start The offset at which searching will start. - * @return The offset into this of c, or -1 if not found. + * @return The offset into this of `c`, or -1 if not found. * @stable ICU 2.0 */ inline int32_t indexOf(UChar32 c, int32_t start) const; /** - * Locate in this the first occurrence of the BMP code point c - * in the range [start, start + length), + * Locate in this the first occurrence of the BMP code point `c` + * in the range [`start`, `start + length`), * using bitwise comparison. * @param c The code unit to search for. * @param start the offset into this at which to start matching * @param length the number of characters in this to search - * @return The offset into this of c, or -1 if not found. + * @return The offset into this of `c`, or -1 if not found. * @stable ICU 2.0 */ - inline int32_t indexOf(UChar c, + inline int32_t indexOf(char16_t c, int32_t start, int32_t length) const; /** - * Locate in this the first occurrence of the code point c - * in the range [start, start + length), + * Locate in this the first occurrence of the code point `c` + * in the range [`start`, `start + length`), * using bitwise comparison. * * @param c The code point to search for. * @param start the offset into this at which to start matching * @param length the number of characters in this to search - * @return The offset into this of c, or -1 if not found. + * @return The offset into this of `c`, or -1 if not found. * @stable ICU 2.0 */ inline int32_t indexOf(UChar32 c, @@ -1086,21 +1135,21 @@ class U_COMMON_API UnicodeString : public Replaceable int32_t length) const; /** - * Locate in this the last occurrence of the characters in text, + * Locate in this the last occurrence of the characters in `text`, * using bitwise comparison. * @param text The text to search for. - * @return The offset into this of the start of text, + * @return The offset into this of the start of `text`, * or -1 if not found. * @stable ICU 2.0 */ inline int32_t lastIndexOf(const UnicodeString& text) const; /** - * Locate in this the last occurrence of the characters in text - * starting at offset start, using bitwise comparison. + * Locate in this the last occurrence of the characters in `text` + * starting at offset `start`, using bitwise comparison. * @param text The text to search for. * @param start The offset at which searching will start. - * @return The offset into this of the start of text, + * @return The offset into this of the start of `text`, * or -1 if not found. * @stable ICU 2.0 */ @@ -1109,12 +1158,12 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Locate in this the last occurrence in the range - * [start, start + length) of the characters - * in text, using bitwise comparison. + * [`start`, `start + length`) of the characters + * in `text`, using bitwise comparison. * @param text The text to search for. * @param start The offset at which searching will start. * @param length The number of characters to search - * @return The offset into this of the start of text, + * @return The offset into this of the start of `text`, * or -1 if not found. * @stable ICU 2.0 */ @@ -1124,17 +1173,17 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Locate in this the last occurrence in the range - * [start, start + length) of the characters - * in srcText in the range - * [srcStart, srcStart + srcLength), + * [`start`, `start + length`) of the characters + * in `srcText` in the range + * [`srcStart`, `srcStart + srcLength`), * using bitwise comparison. * @param srcText The text to search for. - * @param srcStart the offset into srcText at which + * @param srcStart the offset into `srcText` at which * to start matching - * @param srcLength the number of characters in srcText to match + * @param srcLength the number of characters in `srcText` to match * @param start the offset into this at which to start matching * @param length the number of characters in this to search - * @return The offset into this of the start of text, + * @return The offset into this of the start of `text`, * or -1 if not found. * @stable ICU 2.0 */ @@ -1145,123 +1194,123 @@ class U_COMMON_API UnicodeString : public Replaceable int32_t length) const; /** - * Locate in this the last occurrence of the characters in srcChars - * starting at offset start, using bitwise comparison. + * Locate in this the last occurrence of the characters in `srcChars` + * starting at offset `start`, using bitwise comparison. * @param srcChars The text to search for. - * @param srcLength the number of characters in srcChars to match + * @param srcLength the number of characters in `srcChars` to match * @param start the offset into this at which to start matching - * @return The offset into this of the start of text, + * @return The offset into this of the start of `text`, * or -1 if not found. * @stable ICU 2.0 */ - inline int32_t lastIndexOf(const UChar *srcChars, + inline int32_t lastIndexOf(const char16_t *srcChars, int32_t srcLength, int32_t start) const; /** * Locate in this the last occurrence in the range - * [start, start + length) of the characters - * in srcChars, using bitwise comparison. + * [`start`, `start + length`) of the characters + * in `srcChars`, using bitwise comparison. * @param srcChars The text to search for. - * @param srcLength the number of characters in srcChars + * @param srcLength the number of characters in `srcChars` * @param start The offset at which searching will start. * @param length The number of characters to search - * @return The offset into this of the start of srcChars, + * @return The offset into this of the start of `srcChars`, * or -1 if not found. * @stable ICU 2.0 */ - inline int32_t lastIndexOf(const UChar *srcChars, + inline int32_t lastIndexOf(ConstChar16Ptr srcChars, int32_t srcLength, int32_t start, int32_t length) const; /** * Locate in this the last occurrence in the range - * [start, start + length) of the characters - * in srcChars in the range - * [srcStart, srcStart + srcLength), + * [`start`, `start + length`) of the characters + * in `srcChars` in the range + * [`srcStart`, `srcStart + srcLength`), * using bitwise comparison. * @param srcChars The text to search for. - * @param srcStart the offset into srcChars at which + * @param srcStart the offset into `srcChars` at which * to start matching - * @param srcLength the number of characters in srcChars to match + * @param srcLength the number of characters in `srcChars` to match * @param start the offset into this at which to start matching * @param length the number of characters in this to search - * @return The offset into this of the start of text, + * @return The offset into this of the start of `text`, * or -1 if not found. * @stable ICU 2.0 */ - int32_t lastIndexOf(const UChar *srcChars, + int32_t lastIndexOf(const char16_t *srcChars, int32_t srcStart, int32_t srcLength, int32_t start, int32_t length) const; /** - * Locate in this the last occurrence of the BMP code point c, + * Locate in this the last occurrence of the BMP code point `c`, * using bitwise comparison. * @param c The code unit to search for. - * @return The offset into this of c, or -1 if not found. + * @return The offset into this of `c`, or -1 if not found. * @stable ICU 2.0 */ - inline int32_t lastIndexOf(UChar c) const; + inline int32_t lastIndexOf(char16_t c) const; /** - * Locate in this the last occurrence of the code point c, + * Locate in this the last occurrence of the code point `c`, * using bitwise comparison. * * @param c The code point to search for. - * @return The offset into this of c, or -1 if not found. + * @return The offset into this of `c`, or -1 if not found. * @stable ICU 2.0 */ inline int32_t lastIndexOf(UChar32 c) const; /** - * Locate in this the last occurrence of the BMP code point c - * starting at offset start, using bitwise comparison. + * Locate in this the last occurrence of the BMP code point `c` + * starting at offset `start`, using bitwise comparison. * @param c The code unit to search for. * @param start The offset at which searching will start. - * @return The offset into this of c, or -1 if not found. + * @return The offset into this of `c`, or -1 if not found. * @stable ICU 2.0 */ - inline int32_t lastIndexOf(UChar c, + inline int32_t lastIndexOf(char16_t c, int32_t start) const; /** - * Locate in this the last occurrence of the code point c - * starting at offset start, using bitwise comparison. + * Locate in this the last occurrence of the code point `c` + * starting at offset `start`, using bitwise comparison. * * @param c The code point to search for. * @param start The offset at which searching will start. - * @return The offset into this of c, or -1 if not found. + * @return The offset into this of `c`, or -1 if not found. * @stable ICU 2.0 */ inline int32_t lastIndexOf(UChar32 c, int32_t start) const; /** - * Locate in this the last occurrence of the BMP code point c - * in the range [start, start + length), + * Locate in this the last occurrence of the BMP code point `c` + * in the range [`start`, `start + length`), * using bitwise comparison. * @param c The code unit to search for. * @param start the offset into this at which to start matching * @param length the number of characters in this to search - * @return The offset into this of c, or -1 if not found. + * @return The offset into this of `c`, or -1 if not found. * @stable ICU 2.0 */ - inline int32_t lastIndexOf(UChar c, + inline int32_t lastIndexOf(char16_t c, int32_t start, int32_t length) const; /** - * Locate in this the last occurrence of the code point c - * in the range [start, start + length), + * Locate in this the last occurrence of the code point `c` + * in the range [`start`, `start + length`), * using bitwise comparison. * * @param c The code point to search for. * @param start the offset into this at which to start matching * @param length the number of characters in this to search - * @return The offset into this of c, or -1 if not found. + * @return The offset into this of `c`, or -1 if not found. * @stable ICU 2.0 */ inline int32_t lastIndexOf(UChar32 c, @@ -1272,32 +1321,32 @@ class U_COMMON_API UnicodeString : public Replaceable /* Character access */ /** - * Return the code unit at offset offset. + * Return the code unit at offset `offset`. * If the offset is not valid (0..length()-1) then U+ffff is returned. * @param offset a valid offset into the text - * @return the code unit at offset offset + * @return the code unit at offset `offset` * or 0xffff if the offset is not valid for this string * @stable ICU 2.0 */ - inline UChar charAt(int32_t offset) const; + inline char16_t charAt(int32_t offset) const; /** - * Return the code unit at offset offset. + * Return the code unit at offset `offset`. * If the offset is not valid (0..length()-1) then U+ffff is returned. * @param offset a valid offset into the text - * @return the code unit at offset offset + * @return the code unit at offset `offset` * @stable ICU 2.0 */ - inline UChar operator[] (int32_t offset) const; + inline char16_t operator[] (int32_t offset) const; /** * Return the code point that contains the code unit - * at offset offset. + * at offset `offset`. * If the offset is not valid (0..length()-1) then U+ffff is returned. * @param offset a valid offset into the text * that indicates the text offset of any of the code units * that will be assembled into a code point (21-bit value) and returned - * @return the code point of text at offset + * @return the code point of text at `offset` * or 0xffff if the offset is not valid for this string * @stable ICU 2.0 */ @@ -1354,33 +1403,33 @@ class U_COMMON_API UnicodeString : public Replaceable * This behaves like CharacterIterator::move32(delta, kCurrent). * * Behavior for out-of-bounds indexes: - * moveIndex32 pins the input index to 0..length(), i.e., + * `moveIndex32` pins the input index to 0..length(), i.e., * if the input index<0 then it is pinned to 0; * if it is index>length() then it is pinned to length(). - * Afterwards, the index is moved by delta code points + * Afterwards, the index is moved by `delta` code points * forward or backward, * but no further backward than to 0 and no further forward than to length(). * The resulting index return value will be in between 0 and length(), inclusively. * * Examples: - *
        -   * // s has code points 'a' U+10000 'b' U+10ffff U+2029
        -   * UnicodeString s=UNICODE_STRING("a\\U00010000b\\U0010ffff\\u2029", 31).unescape();
        +   * \code
        +   *     // s has code points 'a' U+10000 'b' U+10ffff U+2029
        +   *     UnicodeString s(u"a\U00010000b\U0010ffff\u2029");
            *
        -   * // initial index: position of U+10000
        -   * int32_t index=1;
        +   *     // initial index: position of U+10000
        +   *     int32_t index=1;
            *
        -   * // the following examples will all result in index==4, position of U+10ffff
        +   *     // the following examples will all result in index==4, position of U+10ffff
            *
        -   * // skip 2 code points from some position in the string
        -   * index=s.moveIndex32(index, 2); // skips U+10000 and 'b'
        +   *     // skip 2 code points from some position in the string
        +   *     index=s.moveIndex32(index, 2); // skips U+10000 and 'b'
            *
        -   * // go to the 3rd code point from the start of s (0-based)
        -   * index=s.moveIndex32(0, 3); // skips 'a', U+10000, and 'b'
        +   *     // go to the 3rd code point from the start of s (0-based)
        +   *     index=s.moveIndex32(0, 3); // skips 'a', U+10000, and 'b'
            *
        -   * // go to the next-to-last code point of s
        -   * index=s.moveIndex32(s.length(), -2); // backward-skips U+2029 and U+10ffff
        -   * 
        + * // go to the next-to-last code point of s + * index=s.moveIndex32(s.length(), -2); // backward-skips U+2029 and U+10ffff + * \endcode * * @param index input code unit index * @param delta (signed) code point count to move the index forward or backward @@ -1394,22 +1443,22 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Copy the characters in the range - * [start, start + length) into the array dst, - * beginning at dstStart. - * If the string aliases to dst itself as an external buffer, + * [`start`, `start + length`) into the array `dst`, + * beginning at `dstStart`. + * If the string aliases to `dst` itself as an external buffer, * then extract() will not copy the contents. * * @param start offset of first character which will be copied into the array * @param length the number of characters to extract - * @param dst array in which to copy characters. The length of dst - * must be at least (dstStart + length). - * @param dstStart the offset in dst where the first character + * @param dst array in which to copy characters. The length of `dst` + * must be at least (`dstStart + length`). + * @param dstStart the offset in `dst` where the first character * will be extracted * @stable ICU 2.0 */ inline void extract(int32_t start, int32_t length, - UChar *dst, + Char16Ptr dst, int32_t dstStart = 0) const; /** @@ -1424,27 +1473,26 @@ class U_COMMON_API UnicodeString : public Replaceable * If the string itself does not fit into dest * (length()>destCapacity) then the error code is set to U_BUFFER_OVERFLOW_ERROR. * - * If the string aliases to dest itself as an external buffer, + * If the string aliases to `dest` itself as an external buffer, * then extract() will not copy the contents. * * @param dest Destination string buffer. - * @param destCapacity Number of UChars available at dest. + * @param destCapacity Number of char16_ts available at dest. * @param errorCode ICU error code. * @return length() * @stable ICU 2.0 */ int32_t - extract(UChar *dest, int32_t destCapacity, + extract(Char16Ptr dest, int32_t destCapacity, UErrorCode &errorCode) const; /** * Copy the characters in the range - * [start, start + length) into the UnicodeString - * target. + * [`start`, `start + length`) into the UnicodeString + * `target`. * @param start offset of first character which will be copied * @param length the number of characters to extract * @param target UnicodeString into which to copy characters. - * @return A reference to target * @stable ICU 2.0 */ inline void extract(int32_t start, @@ -1452,28 +1500,27 @@ class U_COMMON_API UnicodeString : public Replaceable UnicodeString& target) const; /** - * Copy the characters in the range [start, limit) - * into the array dst, beginning at dstStart. + * Copy the characters in the range [`start`, `limit`) + * into the array `dst`, beginning at `dstStart`. * @param start offset of first character which will be copied into the array * @param limit offset immediately following the last character to be copied - * @param dst array in which to copy characters. The length of dst - * must be at least (dstStart + (limit - start)). - * @param dstStart the offset in dst where the first character + * @param dst array in which to copy characters. The length of `dst` + * must be at least (`dstStart + (limit - start)`). + * @param dstStart the offset in `dst` where the first character * will be extracted * @stable ICU 2.0 */ inline void extractBetween(int32_t start, int32_t limit, - UChar *dst, + char16_t *dst, int32_t dstStart = 0) const; /** - * Copy the characters in the range [start, limit) - * into the UnicodeString target. Replaceable API. + * Copy the characters in the range [`start`, `limit`) + * into the UnicodeString `target`. Replaceable API. * @param start offset of first character which will be copied * @param limit offset immediately following the last character to be copied * @param target UnicodeString into which to copy characters. - * @return A reference to target * @stable ICU 2.0 */ virtual void extractBetween(int32_t start, @@ -1481,12 +1528,12 @@ class U_COMMON_API UnicodeString : public Replaceable UnicodeString& target) const; /** - * Copy the characters in the range - * [start, start + length) into an array of characters. + * Copy the characters in the range + * [`start`, `start + startLength`) into an array of characters. * All characters must be invariant (see utypes.h). * Use US_INV as the last, signature-distinguishing parameter. * - * This function does not write any more than targetLength + * This function does not write any more than `targetCapacity` * characters but returns the length of the entire output string * so that one can allocate a larger buffer and call the function again * if necessary. @@ -1511,9 +1558,9 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Copy the characters in the range - * [start, start + length) into an array of characters + * [`start`, `start + length`) into an array of characters * in the platform's default codepage. - * This function does not write any more than targetLength + * This function does not write any more than `targetLength` * characters but returns the length of the entire output string * so that one can allocate a larger buffer and call the function again * if necessary. @@ -1523,8 +1570,8 @@ class U_COMMON_API UnicodeString : public Replaceable * @param startLength the number of characters to extract * @param target the target buffer for extraction * @param targetLength the length of the target buffer - * If target is NULL, then the number of bytes required for - * target is returned. + * If `target` is NULL, then the number of bytes required for + * `target` is returned. * @return the output string length, not including the terminating NUL * @stable ICU 2.0 */ @@ -1539,7 +1586,7 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Copy the characters in the range - * [start, start + length) into an array of characters + * [`start`, `start + length`) into an array of characters * in a specified codepage. * The output string is NUL-terminated. * @@ -1553,11 +1600,11 @@ class U_COMMON_API UnicodeString : public Replaceable * @param target the target buffer for extraction * @param codepage the desired codepage for the characters. 0 has * the special meaning of the default codepage - * If codepage is an empty string (""), + * If `codepage` is an empty string (`""`), * then a simple conversion is performed on the codepage-invariant * subset ("invariant characters") of the platform encoding. See utypes.h. - * If target is NULL, then the number of bytes required for - * target is returned. It is assumed that the target is big enough + * If `target` is NULL, then the number of bytes required for + * `target` is returned. It is assumed that the target is big enough * to fit all of the characters. * @return the output string length, not including the terminating NUL * @stable ICU 2.0 @@ -1569,9 +1616,9 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Copy the characters in the range - * [start, start + length) into an array of characters + * [`start`, `start + length`) into an array of characters * in a specified codepage. - * This function does not write any more than targetLength + * This function does not write any more than `targetLength` * characters but returns the length of the entire output string * so that one can allocate a larger buffer and call the function again * if necessary. @@ -1588,11 +1635,11 @@ class U_COMMON_API UnicodeString : public Replaceable * @param targetLength the length of the target buffer * @param codepage the desired codepage for the characters. 0 has * the special meaning of the default codepage - * If codepage is an empty string (""), + * If `codepage` is an empty string (`""`), * then a simple conversion is performed on the codepage-invariant * subset ("invariant characters") of the platform encoding. See utypes.h. - * If target is NULL, then the number of bytes required for - * target is returned. + * If `target` is NULL, then the number of bytes required for + * `target` is returned. * @return the output string length, not including the terminating NUL * @stable ICU 2.0 */ @@ -1665,8 +1712,6 @@ class U_COMMON_API UnicodeString : public Replaceable */ void toUTF8(ByteSink &sink) const; -#if U_HAVE_STD_STRING - /** * Convert the UnicodeString to UTF-8 and append the result * to a standard string. @@ -1681,13 +1726,11 @@ class U_COMMON_API UnicodeString : public Replaceable */ template StringClass &toUTF8String(StringClass &result) const { - StringByteSink sbs(&result); + StringByteSink sbs(&result, length()); toUTF8(sbs); return result; } -#endif - /** * Convert the UnicodeString to UTF-32. * Unpaired surrogates are replaced with U+FFFD. @@ -1709,7 +1752,7 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Return the length of the UnicodeString object. - * The length is the number of UChar code units are in the UnicodeString. + * The length is the number of char16_t code units are in the UnicodeString. * If you want the number of code points, please use countChar32(). * @return the length of the UnicodeString object * @see countChar32 @@ -1718,14 +1761,14 @@ class U_COMMON_API UnicodeString : public Replaceable inline int32_t length(void) const; /** - * Count Unicode code points in the length UChar code units of the string. - * A code point may occupy either one or two UChar code units. + * Count Unicode code points in the length char16_t code units of the string. + * A code point may occupy either one or two char16_t code units. * Counting code points involves reading all code units. * * This functions is basically the inverse of moveIndex32(). * * @param start the index of the first code unit to check - * @param length the number of UChar code units to check + * @param length the number of char16_t code units to check * @return the number of code points in the specified code units * @see length * @stable ICU 2.0 @@ -1734,7 +1777,7 @@ class U_COMMON_API UnicodeString : public Replaceable countChar32(int32_t start=0, int32_t length=INT32_MAX) const; /** - * Check if the length UChar code units of the string + * Check if the length char16_t code units of the string * contain more Unicode code points than a certain number. * This is more efficient than counting all code points in this part of the string * and comparing that number with a threshold. @@ -1742,10 +1785,10 @@ class U_COMMON_API UnicodeString : public Replaceable * falls within a certain range, and * never needs to count more than 'number+1' code points. * Logically equivalent to (countChar32(start, length)>number). - * A Unicode code point may occupy either one or two UChar code units. + * A Unicode code point may occupy either one or two char16_t code units. * * @param start the index of the first code unit to check (0 for the entire string) - * @param length the number of UChar code units to check + * @param length the number of char16_t code units to check * (use INT32_MAX for the entire string; remember that start/length * values are pinned) * @param number The number of code points in the (sub)string is compared against @@ -1771,7 +1814,7 @@ class U_COMMON_API UnicodeString : public Replaceable * This is useful together with the getBuffer functions. * See there for details. * - * @return the number of UChars available in the internal buffer + * @return the number of char16_ts available in the internal buffer * @see getBuffer * @stable ICU 2.0 */ @@ -1809,17 +1852,28 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Assignment operator. Replace the characters in this UnicodeString - * with the characters from srcText. + * with the characters from `srcText`. + * + * Starting with ICU 2.4, the assignment operator and the copy constructor + * allocate a new buffer and copy the buffer contents even for readonly aliases. + * By contrast, the fastCopyFrom() function implements the old, + * more efficient but less safe behavior + * of making this string also a readonly alias to the same buffer. + * + * If the source object has an "open" buffer from getBuffer(minCapacity), + * then the copy is an empty string. + * * @param srcText The text containing the characters to replace * @return a reference to this * @stable ICU 2.0 + * @see fastCopyFrom */ UnicodeString &operator=(const UnicodeString &srcText); /** * Almost the same as the assignment operator. * Replace the characters in this UnicodeString - * with the characters from srcText. + * with the characters from `srcText`. * * This function works the same as the assignment operator * for all strings except for ones that are readonly aliases. @@ -1834,24 +1888,55 @@ class U_COMMON_API UnicodeString : public Replaceable * including its contents, for example for strings from resource bundles * or aliases to string constants. * + * If the source object has an "open" buffer from getBuffer(minCapacity), + * then the copy is an empty string. + * * @param src The text containing the characters to replace. * @return a reference to this * @stable ICU 2.4 */ UnicodeString &fastCopyFrom(const UnicodeString &src); + /** + * Move assignment operator; might leave src in bogus state. + * This string will have the same contents and state that the source string had. + * The behavior is undefined if *this and src are the same object. + * @param src source string + * @return *this + * @stable ICU 56 + */ + UnicodeString &operator=(UnicodeString &&src) U_NOEXCEPT; + + /** + * Swap strings. + * @param other other string + * @stable ICU 56 + */ + void swap(UnicodeString &other) U_NOEXCEPT; + + /** + * Non-member UnicodeString swap function. + * @param s1 will get s2's contents and state + * @param s2 will get s1's contents and state + * @stable ICU 56 + */ + friend inline void U_EXPORT2 + swap(UnicodeString &s1, UnicodeString &s2) U_NOEXCEPT { + s1.swap(s2); + } + /** * Assignment operator. Replace the characters in this UnicodeString - * with the code unit ch. + * with the code unit `ch`. * @param ch the code unit to replace * @return a reference to this * @stable ICU 2.0 */ - inline UnicodeString& operator= (UChar ch); + inline UnicodeString& operator= (char16_t ch); /** * Assignment operator. Replace the characters in this UnicodeString - * with the code point ch. + * with the code point `ch`. * @param ch the code point to replace * @return a reference to this * @stable ICU 2.0 @@ -1860,11 +1945,11 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Set the text in the UnicodeString object to the characters - * in srcText in the range - * [srcStart, srcText.length()). - * srcText is not modified. + * in `srcText` in the range + * [`srcStart`, `srcText.length()`). + * `srcText` is not modified. * @param srcText the source for the new characters - * @param srcStart the offset into srcText where new characters + * @param srcStart the offset into `srcText` where new characters * will be obtained * @return a reference to this * @stable ICU 2.2 @@ -1874,13 +1959,13 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Set the text in the UnicodeString object to the characters - * in srcText in the range - * [srcStart, srcStart + srcLength). - * srcText is not modified. + * in `srcText` in the range + * [`srcStart`, `srcStart + srcLength`). + * `srcText` is not modified. * @param srcText the source for the new characters - * @param srcStart the offset into srcText where new characters + * @param srcStart the offset into `srcText` where new characters * will be obtained - * @param srcLength the number of characters in srcText in the + * @param srcLength the number of characters in `srcText` in the * replace string. * @return a reference to this * @stable ICU 2.0 @@ -1891,8 +1976,8 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Set the text in the UnicodeString object to the characters in - * srcText. - * srcText is not modified. + * `srcText`. + * `srcText` is not modified. * @param srcText the source for the new characters * @return a reference to this * @stable ICU 2.0 @@ -1901,37 +1986,37 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Set the characters in the UnicodeString object to the characters - * in srcChars. srcChars is not modified. + * in `srcChars`. `srcChars` is not modified. * @param srcChars the source for the new characters * @param srcLength the number of Unicode characters in srcChars. * @return a reference to this * @stable ICU 2.0 */ - inline UnicodeString& setTo(const UChar *srcChars, + inline UnicodeString& setTo(const char16_t *srcChars, int32_t srcLength); /** * Set the characters in the UnicodeString object to the code unit - * srcChar. + * `srcChar`. * @param srcChar the code unit which becomes the UnicodeString's character * content * @return a reference to this * @stable ICU 2.0 */ - UnicodeString& setTo(UChar srcChar); + inline UnicodeString& setTo(char16_t srcChar); /** * Set the characters in the UnicodeString object to the code point - * srcChar. + * `srcChar`. * @param srcChar the code point which becomes the UnicodeString's character * content * @return a reference to this * @stable ICU 2.0 */ - UnicodeString& setTo(UChar32 srcChar); + inline UnicodeString& setTo(UChar32 srcChar); /** - * Aliasing setTo() function, analogous to the readonly-aliasing UChar* constructor. + * Aliasing setTo() function, analogous to the readonly-aliasing char16_t* constructor. * The text will be used for the UnicodeString object, but * it will not be released when the UnicodeString is destroyed. * This has copy-on-write semantics: @@ -1944,21 +2029,21 @@ class U_COMMON_API UnicodeString : public Replaceable * When using fastCopyFrom(), the text will be aliased again, * so that both strings then alias the same readonly-text. * - * @param isTerminated specifies if text is NUL-terminated. - * This must be true if textLength==-1. + * @param isTerminated specifies if `text` is `NUL`-terminated. + * This must be true if `textLength==-1`. * @param text The characters to alias for the UnicodeString. - * @param textLength The number of Unicode characters in text to alias. + * @param textLength The number of Unicode characters in `text` to alias. * If -1, then this constructor will determine the length - * by calling u_strlen(). + * by calling `u_strlen()`. * @return a reference to this * @stable ICU 2.0 */ UnicodeString &setTo(UBool isTerminated, - const UChar *text, + ConstChar16Ptr text, int32_t textLength); /** - * Aliasing setTo() function, analogous to the writable-aliasing UChar* constructor. + * Aliasing setTo() function, analogous to the writable-aliasing char16_t* constructor. * The text will be used for the UnicodeString object, but * it will not be released when the UnicodeString is destroyed. * This has write-through semantics: @@ -1967,16 +2052,16 @@ class U_COMMON_API UnicodeString : public Replaceable * a new buffer will be allocated and the contents copied as with regularly * constructed strings. * In an assignment to another UnicodeString, the buffer will be copied. - * The extract(UChar *dst) function detects whether the dst pointer is the same + * The extract(Char16Ptr dst) function detects whether the dst pointer is the same * as the string buffer itself and will in this case not copy the contents. * * @param buffer The characters to alias for the UnicodeString. - * @param buffLength The number of Unicode characters in buffer to alias. - * @param buffCapacity The size of buffer in UChars. + * @param buffLength The number of Unicode characters in `buffer` to alias. + * @param buffCapacity The size of `buffer` in char16_ts. * @return a reference to this * @stable ICU 2.0 */ - UnicodeString &setTo(UChar *buffer, + UnicodeString &setTo(char16_t *buffer, int32_t buffLength, int32_t buffCapacity); @@ -2012,7 +2097,7 @@ class U_COMMON_API UnicodeString : public Replaceable * s.truncate(0); // set to an empty string (complete truncation), or * s=UnicodeString(); // assign an empty string, or * s.setTo((UChar32)-1); // set to a pseudo code point that is out of range, or - * static const UChar nul=0; + * static const char16_t nul=0; * s.setTo(&nul, 0); // set to an empty C Unicode string * } * \endcode @@ -2030,22 +2115,22 @@ class U_COMMON_API UnicodeString : public Replaceable * @stable ICU 2.0 */ UnicodeString& setCharAt(int32_t offset, - UChar ch); + char16_t ch); /* Append operations */ /** - * Append operator. Append the code unit ch to the UnicodeString + * Append operator. Append the code unit `ch` to the UnicodeString * object. * @param ch the code unit to be appended * @return a reference to this * @stable ICU 2.0 */ - inline UnicodeString& operator+= (UChar ch); + inline UnicodeString& operator+= (char16_t ch); /** - * Append operator. Append the code point ch to the UnicodeString + * Append operator. Append the code point `ch` to the UnicodeString * object. * @param ch the code point to be appended * @return a reference to this @@ -2054,8 +2139,8 @@ class U_COMMON_API UnicodeString : public Replaceable inline UnicodeString& operator+= (UChar32 ch); /** - * Append operator. Append the characters in srcText to the - * UnicodeString object. srcText is not modified. + * Append operator. Append the characters in `srcText` to the + * UnicodeString object. `srcText` is not modified. * @param srcText the source for the new characters * @return a reference to this * @stable ICU 2.0 @@ -2064,14 +2149,14 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Append the characters - * in srcText in the range - * [srcStart, srcStart + srcLength) to the - * UnicodeString object at offset start. srcText + * in `srcText` in the range + * [`srcStart`, `srcStart + srcLength`) to the + * UnicodeString object at offset `start`. `srcText` * is not modified. * @param srcText the source for the new characters - * @param srcStart the offset into srcText where new characters + * @param srcStart the offset into `srcText` where new characters * will be obtained - * @param srcLength the number of characters in srcText in + * @param srcLength the number of characters in `srcText` in * the append string * @return a reference to this * @stable ICU 2.0 @@ -2081,8 +2166,8 @@ class U_COMMON_API UnicodeString : public Replaceable int32_t srcLength); /** - * Append the characters in srcText to the UnicodeString object. - * srcText is not modified. + * Append the characters in `srcText` to the UnicodeString object. + * `srcText` is not modified. * @param srcText the source for the new characters * @return a reference to this * @stable ICU 2.0 @@ -2090,44 +2175,44 @@ class U_COMMON_API UnicodeString : public Replaceable inline UnicodeString& append(const UnicodeString& srcText); /** - * Append the characters in srcChars in the range - * [srcStart, srcStart + srcLength) to the UnicodeString + * Append the characters in `srcChars` in the range + * [`srcStart`, `srcStart + srcLength`) to the UnicodeString * object at offset - * start. srcChars is not modified. + * `start`. `srcChars` is not modified. * @param srcChars the source for the new characters - * @param srcStart the offset into srcChars where new characters + * @param srcStart the offset into `srcChars` where new characters * will be obtained - * @param srcLength the number of characters in srcChars in - * the append string; can be -1 if srcChars is NUL-terminated + * @param srcLength the number of characters in `srcChars` in + * the append string; can be -1 if `srcChars` is NUL-terminated * @return a reference to this * @stable ICU 2.0 */ - inline UnicodeString& append(const UChar *srcChars, + inline UnicodeString& append(const char16_t *srcChars, int32_t srcStart, int32_t srcLength); /** - * Append the characters in srcChars to the UnicodeString object - * at offset start. srcChars is not modified. + * Append the characters in `srcChars` to the UnicodeString object + * at offset `start`. `srcChars` is not modified. * @param srcChars the source for the new characters - * @param srcLength the number of Unicode characters in srcChars; - * can be -1 if srcChars is NUL-terminated + * @param srcLength the number of Unicode characters in `srcChars`; + * can be -1 if `srcChars` is NUL-terminated * @return a reference to this * @stable ICU 2.0 */ - inline UnicodeString& append(const UChar *srcChars, + inline UnicodeString& append(ConstChar16Ptr srcChars, int32_t srcLength); /** - * Append the code unit srcChar to the UnicodeString object. + * Append the code unit `srcChar` to the UnicodeString object. * @param srcChar the code unit to append * @return a reference to this * @stable ICU 2.0 */ - inline UnicodeString& append(UChar srcChar); + inline UnicodeString& append(char16_t srcChar); /** - * Append the code point srcChar to the UnicodeString object. + * Append the code point `srcChar` to the UnicodeString object. * @param srcChar the code point to append * @return a reference to this * @stable ICU 2.0 @@ -2138,14 +2223,14 @@ class U_COMMON_API UnicodeString : public Replaceable /* Insert operations */ /** - * Insert the characters in srcText in the range - * [srcStart, srcStart + srcLength) into the UnicodeString - * object at offset start. srcText is not modified. + * Insert the characters in `srcText` in the range + * [`srcStart`, `srcStart + srcLength`) into the UnicodeString + * object at offset `start`. `srcText` is not modified. * @param start the offset where the insertion begins * @param srcText the source for the new characters - * @param srcStart the offset into srcText where new characters + * @param srcStart the offset into `srcText` where new characters * will be obtained - * @param srcLength the number of characters in srcText in + * @param srcLength the number of characters in `srcText` in * the insert string * @return a reference to this * @stable ICU 2.0 @@ -2156,8 +2241,8 @@ class U_COMMON_API UnicodeString : public Replaceable int32_t srcLength); /** - * Insert the characters in srcText into the UnicodeString object - * at offset start. srcText is not modified. + * Insert the characters in `srcText` into the UnicodeString object + * at offset `start`. `srcText` is not modified. * @param start the offset where the insertion begins * @param srcText the source for the new characters * @return a reference to this @@ -2167,26 +2252,26 @@ class U_COMMON_API UnicodeString : public Replaceable const UnicodeString& srcText); /** - * Insert the characters in srcChars in the range - * [srcStart, srcStart + srcLength) into the UnicodeString - * object at offset start. srcChars is not modified. + * Insert the characters in `srcChars` in the range + * [`srcStart`, `srcStart + srcLength`) into the UnicodeString + * object at offset `start`. `srcChars` is not modified. * @param start the offset at which the insertion begins * @param srcChars the source for the new characters - * @param srcStart the offset into srcChars where new characters + * @param srcStart the offset into `srcChars` where new characters * will be obtained - * @param srcLength the number of characters in srcChars + * @param srcLength the number of characters in `srcChars` * in the insert string * @return a reference to this * @stable ICU 2.0 */ inline UnicodeString& insert(int32_t start, - const UChar *srcChars, + const char16_t *srcChars, int32_t srcStart, int32_t srcLength); /** - * Insert the characters in srcChars into the UnicodeString object - * at offset start. srcChars is not modified. + * Insert the characters in `srcChars` into the UnicodeString object + * at offset `start`. `srcChars` is not modified. * @param start the offset where the insertion begins * @param srcChars the source for the new characters * @param srcLength the number of Unicode characters in srcChars. @@ -2194,23 +2279,23 @@ class U_COMMON_API UnicodeString : public Replaceable * @stable ICU 2.0 */ inline UnicodeString& insert(int32_t start, - const UChar *srcChars, + ConstChar16Ptr srcChars, int32_t srcLength); /** - * Insert the code unit srcChar into the UnicodeString object at - * offset start. + * Insert the code unit `srcChar` into the UnicodeString object at + * offset `start`. * @param start the offset at which the insertion occurs * @param srcChar the code unit to insert * @return a reference to this * @stable ICU 2.0 */ inline UnicodeString& insert(int32_t start, - UChar srcChar); + char16_t srcChar); /** - * Insert the code point srcChar into the UnicodeString object at - * offset start. + * Insert the code point `srcChar` into the UnicodeString object at + * offset `start`. * @param start the offset at which the insertion occurs * @param srcChar the code point to insert * @return a reference to this @@ -2224,22 +2309,22 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Replace the characters in the range - * [start, start + length) with the characters in - * srcText in the range - * [srcStart, srcStart + srcLength). - * srcText is not modified. + * [`start`, `start + length`) with the characters in + * `srcText` in the range + * [`srcStart`, `srcStart + srcLength`). + * `srcText` is not modified. * @param start the offset at which the replace operation begins * @param length the number of characters to replace. The character at - * start + length is not modified. + * `start + length` is not modified. * @param srcText the source for the new characters - * @param srcStart the offset into srcText where new characters + * @param srcStart the offset into `srcText` where new characters * will be obtained - * @param srcLength the number of characters in srcText in + * @param srcLength the number of characters in `srcText` in * the replace string * @return a reference to this * @stable ICU 2.0 */ - UnicodeString& replace(int32_t start, + inline UnicodeString& replace(int32_t start, int32_t length, const UnicodeString& srcText, int32_t srcStart, @@ -2247,50 +2332,50 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Replace the characters in the range - * [start, start + length) - * with the characters in srcText. srcText is + * [`start`, `start + length`) + * with the characters in `srcText`. `srcText` is * not modified. * @param start the offset at which the replace operation begins * @param length the number of characters to replace. The character at - * start + length is not modified. + * `start + length` is not modified. * @param srcText the source for the new characters * @return a reference to this * @stable ICU 2.0 */ - UnicodeString& replace(int32_t start, + inline UnicodeString& replace(int32_t start, int32_t length, const UnicodeString& srcText); /** * Replace the characters in the range - * [start, start + length) with the characters in - * srcChars in the range - * [srcStart, srcStart + srcLength). srcChars + * [`start`, `start + length`) with the characters in + * `srcChars` in the range + * [`srcStart`, `srcStart + srcLength`). `srcChars` * is not modified. * @param start the offset at which the replace operation begins * @param length the number of characters to replace. The character at - * start + length is not modified. + * `start + length` is not modified. * @param srcChars the source for the new characters - * @param srcStart the offset into srcChars where new characters + * @param srcStart the offset into `srcChars` where new characters * will be obtained - * @param srcLength the number of characters in srcChars + * @param srcLength the number of characters in `srcChars` * in the replace string * @return a reference to this * @stable ICU 2.0 */ - UnicodeString& replace(int32_t start, + inline UnicodeString& replace(int32_t start, int32_t length, - const UChar *srcChars, + const char16_t *srcChars, int32_t srcStart, int32_t srcLength); /** * Replace the characters in the range - * [start, start + length) with the characters in - * srcChars. srcChars is not modified. + * [`start`, `start + length`) with the characters in + * `srcChars`. `srcChars` is not modified. * @param start the offset at which the replace operation begins * @param length number of characters to replace. The character at - * start + length is not modified. + * `start + length` is not modified. * @param srcChars the source for the new characters * @param srcLength the number of Unicode characters in srcChars * @return a reference to this @@ -2298,31 +2383,31 @@ class U_COMMON_API UnicodeString : public Replaceable */ inline UnicodeString& replace(int32_t start, int32_t length, - const UChar *srcChars, + ConstChar16Ptr srcChars, int32_t srcLength); /** * Replace the characters in the range - * [start, start + length) with the code unit - * srcChar. + * [`start`, `start + length`) with the code unit + * `srcChar`. * @param start the offset at which the replace operation begins * @param length the number of characters to replace. The character at - * start + length is not modified. + * `start + length` is not modified. * @param srcChar the new code unit * @return a reference to this * @stable ICU 2.0 */ inline UnicodeString& replace(int32_t start, int32_t length, - UChar srcChar); + char16_t srcChar); /** * Replace the characters in the range - * [start, start + length) with the code point - * srcChar. + * [`start`, `start + length`) with the code point + * `srcChar`. * @param start the offset at which the replace operation begins * @param length the number of characters to replace. The character at - * start + length is not modified. + * `start + length` is not modified. * @param srcChar the new code point * @return a reference to this * @stable ICU 2.0 @@ -2330,8 +2415,8 @@ class U_COMMON_API UnicodeString : public Replaceable UnicodeString& replace(int32_t start, int32_t length, UChar32 srcChar); /** - * Replace the characters in the range [start, limit) - * with the characters in srcText. srcText is not modified. + * Replace the characters in the range [`start`, `limit`) + * with the characters in `srcText`. `srcText` is not modified. * @param start the offset at which the replace operation begins * @param limit the offset immediately following the replace range * @param srcText the source for the new characters @@ -2343,16 +2428,16 @@ class U_COMMON_API UnicodeString : public Replaceable const UnicodeString& srcText); /** - * Replace the characters in the range [start, limit) - * with the characters in srcText in the range - * [srcStart, srcLimit). srcText is not modified. + * Replace the characters in the range [`start`, `limit`) + * with the characters in `srcText` in the range + * [`srcStart`, `srcLimit`). `srcText` is not modified. * @param start the offset at which the replace operation begins * @param limit the offset immediately following the replace range * @param srcText the source for the new characters - * @param srcStart the offset into srcChars where new characters + * @param srcStart the offset into `srcChars` where new characters * will be obtained * @param srcLimit the offset immediately following the range to copy - * in srcText + * in `srcText` * @return a reference to this * @stable ICU 2.0 */ @@ -2364,12 +2449,9 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Replace a substring of this object with the given text. - * @param start the beginning index, inclusive; 0 <= start - * <= limit. - * @param limit the ending index, exclusive; start <= limit - * <= length(). - * @param text the text to replace characters start - * to limit - 1 + * @param start the beginning index, inclusive; `0 <= start <= limit`. + * @param limit the ending index, exclusive; `start <= limit <= length()`. + * @param text the text to replace characters `start` to `limit - 1` * @stable ICU 2.0 */ virtual void handleReplaceBetween(int32_t start, @@ -2388,14 +2470,12 @@ class U_COMMON_API UnicodeString : public Replaceable * information. This method is used to duplicate or reorder substrings. * The destination index must not overlap the source range. * - * @param start the beginning index, inclusive; 0 <= start <= - * limit. - * @param limit the ending index, exclusive; start <= limit <= - * length(). + * @param start the beginning index, inclusive; `0 <= start <= limit`. + * @param limit the ending index, exclusive; `start <= limit <= length()`. * @param dest the destination index. The characters from - * start..limit-1 will be copied to dest. - * Implementations of this method may assume that dest <= start || - * dest >= limit. + * `start..limit-1` will be copied to `dest`. + * Implementations of this method may assume that `dest <= start || + * dest >= limit`. * @stable ICU 2.0 */ virtual void copy(int32_t start, int32_t limit, int32_t dest); @@ -2416,7 +2496,7 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Replace all occurrences of characters in oldText with characters * in newText - * in the range [start, start + length). + * in the range [`start`, `start + length`). * @param start the start of the range in which replace will performed * @param length the length of the range in which replace will be performed * @param oldText the text containing the search text @@ -2431,18 +2511,18 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Replace all occurrences of characters in oldText in the range - * [oldStart, oldStart + oldLength) with the characters + * [`oldStart`, `oldStart + oldLength`) with the characters * in newText in the range - * [newStart, newStart + newLength) - * in the range [start, start + length). + * [`newStart`, `newStart + newLength`) + * in the range [`start`, `start + length`). * @param start the start of the range in which replace will performed * @param length the length of the range in which replace will be performed * @param oldText the text containing the search text - * @param oldStart the start of the search range in oldText - * @param oldLength the length of the search range in oldText + * @param oldStart the start of the search range in `oldText` + * @param oldLength the length of the search range in `oldText` * @param newText the text containing the replacement text - * @param newStart the start of the replacement range in newText - * @param newLength the length of the replacement range in newText + * @param newStart the start of the replacement range in `newText` + * @param newLength the length of the replacement range in `newText` * @return a reference to this * @stable ICU 2.0 */ @@ -2467,7 +2547,7 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Remove the characters in the range - * [start, start + length) from the UnicodeString object. + * [`start`, `start + length`) from the UnicodeString object. * @param start the offset of the first character to remove * @param length the number of characters to remove * @return a reference to this @@ -2478,7 +2558,7 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Remove the characters in the range - * [start, limit) from the UnicodeString object. + * [`start`, `limit`) from the UnicodeString object. * @param start the offset of the first character to remove * @param limit the offset immediately following the range to remove * @return a reference to this @@ -2489,8 +2569,8 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Retain only the characters in the range - * [start, limit) from the UnicodeString object. - * Removes characters before start and at and after limit. + * [`start`, `limit`) from the UnicodeString object. + * Removes characters before `start` and at and after `limit`. * @param start the offset of the first character to retain * @param limit the offset immediately following the range to retain * @return a reference to this @@ -2501,7 +2581,7 @@ class U_COMMON_API UnicodeString : public Replaceable /* Length operations */ /** - * Pad the start of this UnicodeString with the character padChar. + * Pad the start of this UnicodeString with the character `padChar`. * If the length of this UnicodeString is less than targetLength, * length() - targetLength copies of padChar will be added to the * beginning of this UnicodeString. @@ -2512,10 +2592,10 @@ class U_COMMON_API UnicodeString : public Replaceable * @stable ICU 2.0 */ UBool padLeading(int32_t targetLength, - UChar padChar = 0x0020); + char16_t padChar = 0x0020); /** - * Pad the end of this UnicodeString with the character padChar. + * Pad the end of this UnicodeString with the character `padChar`. * If the length of this UnicodeString is less than targetLength, * length() - targetLength copies of padChar will be added to the * end of this UnicodeString. @@ -2526,10 +2606,10 @@ class U_COMMON_API UnicodeString : public Replaceable * @stable ICU 2.0 */ UBool padTrailing(int32_t targetLength, - UChar padChar = 0x0020); + char16_t padChar = 0x0020); /** - * Truncate this UnicodeString to the targetLength. + * Truncate this UnicodeString to the `targetLength`. * @param targetLength the desired length of this UnicodeString. * @return TRUE if the text was truncated, FALSE otherwise * @stable ICU 2.0 @@ -2554,7 +2634,7 @@ class U_COMMON_API UnicodeString : public Replaceable inline UnicodeString& reverse(void); /** - * Reverse the range [start, start + length) in + * Reverse the range [`start`, `start + length`) in * this UnicodeString. * @param start the start of the range to reverse * @param length the number of characters to to reverse @@ -2681,11 +2761,11 @@ class U_COMMON_API UnicodeString : public Replaceable * break iterator is opened. * Otherwise the provided iterator is set to the string's text. * @param locale The locale to consider. + * @param options Options bit set, usually 0. See U_TITLECASE_NO_LOWERCASE, + * U_TITLECASE_NO_BREAK_ADJUSTMENT, U_TITLECASE_ADJUST_TO_CASED, + * U_TITLECASE_WHOLE_STRING, U_TITLECASE_SENTENCES. * @param options Options bit set, see ucasemap_open(). * @return A reference to this. - * @see U_TITLECASE_NO_LOWERCASE - * @see U_TITLECASE_NO_BREAK_ADJUSTMENT - * @see ucasemap_open * @stable ICU 3.8 */ UnicodeString &toTitle(BreakIterator *titleIter, const Locale &locale, uint32_t options); @@ -2713,7 +2793,7 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Get a read/write pointer to the internal buffer. - * The buffer is guaranteed to be large enough for at least minCapacity UChars, + * The buffer is guaranteed to be large enough for at least minCapacity char16_ts, * writable, and is still owned by the UnicodeString object. * Calls to getBuffer(minCapacity) must not be nested, and * must be matched with calls to releaseBuffer(newLength). @@ -2739,22 +2819,22 @@ class U_COMMON_API UnicodeString : public Replaceable * If the length() was greater than minCapacity, then any contents after minCapacity * may be lost. * The buffer contents is not NUL-terminated by getBuffer(). - * If length()(s.length(). + * `(s.length() < s.getCapacity() && buffer[s.length()]==0)`. * (See getTerminatedBuffer().) * * The buffer may reside in read-only memory. Its contents must not * be modified. * * @return a read-only pointer to the internal string buffer, - * or 0 if the string is empty or bogus + * or nullptr if the string is empty or bogus * * @see getBuffer(int32_t minCapacity) * @see getTerminatedBuffer() * @stable ICU 2.0 */ - inline const UChar *getBuffer() const; + inline const char16_t *getBuffer() const; /** * Get a read-only pointer to the internal buffer, @@ -2843,7 +2923,7 @@ class U_COMMON_API UnicodeString : public Replaceable * @see getBuffer() * @stable ICU 2.2 */ - const UChar *getTerminatedBuffer(); + const char16_t *getTerminatedBuffer(); //======================================== // Constructors @@ -2855,8 +2935,8 @@ class U_COMMON_API UnicodeString : public Replaceable inline UnicodeString(); /** - * Construct a UnicodeString with capacity to hold capacity UChars - * @param capacity the number of UChars this UnicodeString should hold + * Construct a UnicodeString with capacity to hold `capacity` char16_ts + * @param capacity the number of char16_ts this UnicodeString should hold * before a resize is necessary; if count is greater than 0 and count * code points c take up more space than capacity, then capacity is adjusted * accordingly. @@ -2868,21 +2948,21 @@ class U_COMMON_API UnicodeString : public Replaceable UnicodeString(int32_t capacity, UChar32 c, int32_t count); /** - * Single UChar (code unit) constructor. + * Single char16_t (code unit) constructor. * * It is recommended to mark this constructor "explicit" by - * -DUNISTR_FROM_CHAR_EXPLICIT=explicit + * `-DUNISTR_FROM_CHAR_EXPLICIT=explicit` * on the compiler command line or similar. * @param ch the character to place in the UnicodeString * @stable ICU 2.0 */ - UNISTR_FROM_CHAR_EXPLICIT UnicodeString(UChar ch); + UNISTR_FROM_CHAR_EXPLICIT UnicodeString(char16_t ch); /** * Single UChar32 (code point) constructor. * * It is recommended to mark this constructor "explicit" by - * -DUNISTR_FROM_CHAR_EXPLICIT=explicit + * `-DUNISTR_FROM_CHAR_EXPLICIT=explicit` * on the compiler command line or similar. * @param ch the character to place in the UnicodeString * @stable ICU 2.0 @@ -2890,29 +2970,106 @@ class U_COMMON_API UnicodeString : public Replaceable UNISTR_FROM_CHAR_EXPLICIT UnicodeString(UChar32 ch); /** - * UChar* constructor. + * char16_t* constructor. * * It is recommended to mark this constructor "explicit" by - * -DUNISTR_FROM_STRING_EXPLICIT=explicit + * `-DUNISTR_FROM_STRING_EXPLICIT=explicit` * on the compiler command line or similar. - * @param text The characters to place in the UnicodeString. text + * @param text The characters to place in the UnicodeString. `text` * must be NULL (U+0000) terminated. * @stable ICU 2.0 */ - UNISTR_FROM_STRING_EXPLICIT UnicodeString(const UChar *text); + UNISTR_FROM_STRING_EXPLICIT UnicodeString(const char16_t *text); + +#if !U_CHAR16_IS_TYPEDEF + /** + * uint16_t * constructor. + * Delegates to UnicodeString(const char16_t *). + * + * It is recommended to mark this constructor "explicit" by + * `-DUNISTR_FROM_STRING_EXPLICIT=explicit` + * on the compiler command line or similar. + * @param text NUL-terminated UTF-16 string + * @stable ICU 59 + */ + UNISTR_FROM_STRING_EXPLICIT UnicodeString(const uint16_t *text) : + UnicodeString(ConstChar16Ptr(text)) {} +#endif + +#if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN) + /** + * wchar_t * constructor. + * (Only defined if U_SIZEOF_WCHAR_T==2.) + * Delegates to UnicodeString(const char16_t *). + * + * It is recommended to mark this constructor "explicit" by + * `-DUNISTR_FROM_STRING_EXPLICIT=explicit` + * on the compiler command line or similar. + * @param text NUL-terminated UTF-16 string + * @stable ICU 59 + */ + UNISTR_FROM_STRING_EXPLICIT UnicodeString(const wchar_t *text) : + UnicodeString(ConstChar16Ptr(text)) {} +#endif + + /** + * nullptr_t constructor. + * Effectively the same as the default constructor, makes an empty string object. + * + * It is recommended to mark this constructor "explicit" by + * `-DUNISTR_FROM_STRING_EXPLICIT=explicit` + * on the compiler command line or similar. + * @param text nullptr + * @stable ICU 59 + */ + UNISTR_FROM_STRING_EXPLICIT inline UnicodeString(const std::nullptr_t text); /** - * UChar* constructor. + * char16_t* constructor. * @param text The characters to place in the UnicodeString. - * @param textLength The number of Unicode characters in text + * @param textLength The number of Unicode characters in `text` * to copy. * @stable ICU 2.0 */ - UnicodeString(const UChar *text, + UnicodeString(const char16_t *text, int32_t textLength); +#if !U_CHAR16_IS_TYPEDEF /** - * Readonly-aliasing UChar* constructor. + * uint16_t * constructor. + * Delegates to UnicodeString(const char16_t *, int32_t). + * @param text UTF-16 string + * @param length string length + * @stable ICU 59 + */ + UnicodeString(const uint16_t *text, int32_t length) : + UnicodeString(ConstChar16Ptr(text), length) {} +#endif + +#if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN) + /** + * wchar_t * constructor. + * (Only defined if U_SIZEOF_WCHAR_T==2.) + * Delegates to UnicodeString(const char16_t *, int32_t). + * @param text NUL-terminated UTF-16 string + * @param length string length + * @stable ICU 59 + */ + UnicodeString(const wchar_t *text, int32_t length) : + UnicodeString(ConstChar16Ptr(text), length) {} +#endif + + /** + * nullptr_t constructor. + * Effectively the same as the default constructor, makes an empty string object. + * @param text nullptr + * @param length ignored + * @stable ICU 59 + */ + inline UnicodeString(const std::nullptr_t text, int32_t length); + + /** + * Readonly-aliasing char16_t* constructor. * The text will be used for the UnicodeString object, but * it will not be released when the UnicodeString is destroyed. * This has copy-on-write semantics: @@ -2925,20 +3082,20 @@ class U_COMMON_API UnicodeString : public Replaceable * When using fastCopyFrom(), the text will be aliased again, * so that both strings then alias the same readonly-text. * - * @param isTerminated specifies if text is NUL-terminated. - * This must be true if textLength==-1. + * @param isTerminated specifies if `text` is `NUL`-terminated. + * This must be true if `textLength==-1`. * @param text The characters to alias for the UnicodeString. - * @param textLength The number of Unicode characters in text to alias. + * @param textLength The number of Unicode characters in `text` to alias. * If -1, then this constructor will determine the length - * by calling u_strlen(). + * by calling `u_strlen()`. * @stable ICU 2.0 */ UnicodeString(UBool isTerminated, - const UChar *text, + ConstChar16Ptr text, int32_t textLength); /** - * Writable-aliasing UChar* constructor. + * Writable-aliasing char16_t* constructor. * The text will be used for the UnicodeString object, but * it will not be released when the UnicodeString is destroyed. * This has write-through semantics: @@ -2947,15 +3104,52 @@ class U_COMMON_API UnicodeString : public Replaceable * a new buffer will be allocated and the contents copied as with regularly * constructed strings. * In an assignment to another UnicodeString, the buffer will be copied. - * The extract(UChar *dst) function detects whether the dst pointer is the same + * The extract(Char16Ptr dst) function detects whether the dst pointer is the same * as the string buffer itself and will in this case not copy the contents. * * @param buffer The characters to alias for the UnicodeString. - * @param buffLength The number of Unicode characters in buffer to alias. - * @param buffCapacity The size of buffer in UChars. + * @param buffLength The number of Unicode characters in `buffer` to alias. + * @param buffCapacity The size of `buffer` in char16_ts. * @stable ICU 2.0 */ - UnicodeString(UChar *buffer, int32_t buffLength, int32_t buffCapacity); + UnicodeString(char16_t *buffer, int32_t buffLength, int32_t buffCapacity); + +#if !U_CHAR16_IS_TYPEDEF + /** + * Writable-aliasing uint16_t * constructor. + * Delegates to UnicodeString(const char16_t *, int32_t, int32_t). + * @param buffer writable buffer of/for UTF-16 text + * @param buffLength length of the current buffer contents + * @param buffCapacity buffer capacity + * @stable ICU 59 + */ + UnicodeString(uint16_t *buffer, int32_t buffLength, int32_t buffCapacity) : + UnicodeString(Char16Ptr(buffer), buffLength, buffCapacity) {} +#endif + +#if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN) + /** + * Writable-aliasing wchar_t * constructor. + * (Only defined if U_SIZEOF_WCHAR_T==2.) + * Delegates to UnicodeString(const char16_t *, int32_t, int32_t). + * @param buffer writable buffer of/for UTF-16 text + * @param buffLength length of the current buffer contents + * @param buffCapacity buffer capacity + * @stable ICU 59 + */ + UnicodeString(wchar_t *buffer, int32_t buffLength, int32_t buffCapacity) : + UnicodeString(Char16Ptr(buffer), buffLength, buffCapacity) {} +#endif + + /** + * Writable-aliasing nullptr_t constructor. + * Effectively the same as the default constructor, makes an empty string object. + * @param buffer nullptr + * @param buffLength ignored + * @param buffCapacity ignored + * @stable ICU 59 + */ + inline UnicodeString(std::nullptr_t buffer, int32_t buffLength, int32_t buffCapacity); #if U_CHARSET_IS_UTF8 || !UCONFIG_NO_CONVERSION @@ -2970,7 +3164,7 @@ class U_COMMON_API UnicodeString : public Replaceable * UNICODE_STRING_SIMPLE. * * It is recommended to mark this constructor "explicit" by - * -DUNISTR_FROM_STRING_EXPLICIT=explicit + * `-DUNISTR_FROM_STRING_EXPLICIT=explicit` * on the compiler command line or similar. * @param codepageData an array of bytes, null-terminated, * in the platform's default codepage. @@ -2985,7 +3179,7 @@ class U_COMMON_API UnicodeString : public Replaceable * Uses the default converter (and thus depends on the ICU conversion code) * unless U_CHARSET_IS_UTF8 is set to 1. * @param codepageData an array of bytes in the platform's default codepage. - * @param dataLength The number of bytes in codepageData. + * @param dataLength The number of bytes in `codepageData`. * @stable ICU 2.0 */ UnicodeString(const char *codepageData, int32_t dataLength); @@ -2997,11 +3191,11 @@ class U_COMMON_API UnicodeString : public Replaceable /** * char* constructor. * @param codepageData an array of bytes, null-terminated - * @param codepage the encoding of codepageData. The special - * value 0 for codepage indicates that the text is in the + * @param codepage the encoding of `codepageData`. The special + * value 0 for `codepage` indicates that the text is in the * platform's default codepage. * - * If codepage is an empty string (""), + * If `codepage` is an empty string (`""`), * then a simple conversion is performed on the codepage-invariant * subset ("invariant characters") of the platform encoding. See utypes.h. * Recommendation: For invariant-character strings use the constructor @@ -3016,11 +3210,11 @@ class U_COMMON_API UnicodeString : public Replaceable /** * char* constructor. * @param codepageData an array of bytes. - * @param dataLength The number of bytes in codepageData. - * @param codepage the encoding of codepageData. The special - * value 0 for codepage indicates that the text is in the + * @param dataLength The number of bytes in `codepageData`. + * @param codepage the encoding of `codepageData`. The special + * value 0 for `codepage` indicates that the text is in the * platform's default codepage. - * If codepage is an empty string (""), + * If `codepage` is an empty string (`""`), * then a simple conversion is performed on the codepage-invariant * subset ("invariant characters") of the platform encoding. See utypes.h. * Recommendation: For invariant-character strings use the constructor @@ -3071,12 +3265,11 @@ class U_COMMON_API UnicodeString : public Replaceable * * For example: * \code - * void fn(const char *s) { - * UnicodeString ustr(s, -1, US_INV); - * // use ustr ... - * } + * void fn(const char *s) { + * UnicodeString ustr(s, -1, US_INV); + * // use ustr ... + * } * \endcode - * * @param src String using only invariant characters. * @param length Length of src, or -1 if NUL-terminated. * @param inv Signature-distinguishing paramater, use US_INV. @@ -3089,15 +3282,34 @@ class U_COMMON_API UnicodeString : public Replaceable /** * Copy constructor. + * + * Starting with ICU 2.4, the assignment operator and the copy constructor + * allocate a new buffer and copy the buffer contents even for readonly aliases. + * By contrast, the fastCopyFrom() function implements the old, + * more efficient but less safe behavior + * of making this string also a readonly alias to the same buffer. + * + * If the source object has an "open" buffer from getBuffer(minCapacity), + * then the copy is an empty string. + * * @param that The UnicodeString object to copy. * @stable ICU 2.0 + * @see fastCopyFrom */ UnicodeString(const UnicodeString& that); + /** + * Move constructor; might leave src in bogus state. + * This string will have the same contents and state that the source string had. + * @param src source string + * @stable ICU 56 + */ + UnicodeString(UnicodeString &&src) U_NOEXCEPT; + /** * 'Substring' constructor from tail of source string. * @param src The UnicodeString object to copy. - * @param srcStart The offset into src at which to start copying. + * @param srcStart The offset into `src` at which to start copying. * @stable ICU 2.2 */ UnicodeString(const UnicodeString& src, int32_t srcStart); @@ -3105,8 +3317,8 @@ class U_COMMON_API UnicodeString : public Replaceable /** * 'Substring' constructor from subrange of source string. * @param src The UnicodeString object to copy. - * @param srcStart The offset into src at which to start copying. - * @param srcLength The number of characters from src to copy. + * @param srcStart The offset into `src` at which to start copying. + * @param srcLength The number of characters from `src` to copy. * @stable ICU 2.2 */ UnicodeString(const UnicodeString& src, int32_t srcStart, int32_t srcLength); @@ -3147,7 +3359,7 @@ class U_COMMON_API UnicodeString : public Replaceable * @see toUTF8String * @stable ICU 4.2 */ - static UnicodeString fromUTF8(const StringPiece &utf8); + static UnicodeString fromUTF8(StringPiece utf8); /** * Create a UnicodeString from a UTF-32 string. @@ -3178,7 +3390,7 @@ class U_COMMON_API UnicodeString : public Replaceable * * \\a => U+0007, \\b => U+0008, \\t => U+0009, \\n => U+000A, * \\v => U+000B, \\f => U+000C, \\r => U+000D, \\e => U+001B, - * \\" => U+0022, \\' => U+0027, \\? => U+003F, \\\\ => U+005C + * \\" => U+0022, \\' => U+0027, \\? => U+003F, \\\\ => U+005C * * Anything else following a backslash is generically escaped. For * example, "[a\\-z]" returns "[a-z]". @@ -3251,7 +3463,7 @@ class U_COMMON_API UnicodeString : public Replaceable * UnicodeString::charAt() to be inline again (see jitterbug 709). * @stable ICU 2.4 */ - virtual UChar getCharAt(int32_t offset) const; + virtual char16_t getCharAt(int32_t offset) const; /** * The change in Replaceable to use virtual getChar32At() allows @@ -3262,7 +3474,7 @@ class U_COMMON_API UnicodeString : public Replaceable private: // For char* constructors. Could be made public. - UnicodeString &setToUTF8(const StringPiece &utf8); + UnicodeString &setToUTF8(StringPiece utf8); // For extract(char*). // We could make a toUTF8(target, capacity, errorCode) public but not // this version: New API will be cleaner if we make callers create substrings @@ -3287,7 +3499,7 @@ class U_COMMON_API UnicodeString : public Replaceable int8_t doCompare(int32_t start, int32_t length, - const UChar *srcChars, + const char16_t *srcChars, int32_t srcStart, int32_t srcLength) const; @@ -3300,7 +3512,7 @@ class U_COMMON_API UnicodeString : public Replaceable int8_t doCompareCodePointOrder(int32_t start, int32_t length, - const UChar *srcChars, + const char16_t *srcChars, int32_t srcStart, int32_t srcLength) const; @@ -3315,12 +3527,12 @@ class U_COMMON_API UnicodeString : public Replaceable int8_t doCaseCompare(int32_t start, int32_t length, - const UChar *srcChars, + const char16_t *srcChars, int32_t srcStart, int32_t srcLength, uint32_t options) const; - int32_t doIndexOf(UChar c, + int32_t doIndexOf(char16_t c, int32_t start, int32_t length) const; @@ -3328,7 +3540,7 @@ class U_COMMON_API UnicodeString : public Replaceable int32_t start, int32_t length) const; - int32_t doLastIndexOf(UChar c, + int32_t doLastIndexOf(char16_t c, int32_t start, int32_t length) const; @@ -3338,14 +3550,14 @@ class U_COMMON_API UnicodeString : public Replaceable void doExtract(int32_t start, int32_t length, - UChar *dst, + char16_t *dst, int32_t dstStart) const; inline void doExtract(int32_t start, int32_t length, UnicodeString& target) const; - inline UChar doCharAt(int32_t offset) const; + inline char16_t doCharAt(int32_t offset) const; UnicodeString& doReplace(int32_t start, int32_t length, @@ -3355,10 +3567,13 @@ class U_COMMON_API UnicodeString : public Replaceable UnicodeString& doReplace(int32_t start, int32_t length, - const UChar *srcChars, + const char16_t *srcChars, int32_t srcStart, int32_t srcLength); + UnicodeString& doAppend(const UnicodeString& src, int32_t srcStart, int32_t srcLength); + UnicodeString& doAppend(const char16_t *srcChars, int32_t srcStart, int32_t srcLength); + UnicodeString& doReverse(int32_t start, int32_t length); @@ -3367,8 +3582,8 @@ class U_COMMON_API UnicodeString : public Replaceable // get pointer to start of array // these do not check for kOpenGetBuffer, unlike the public getBuffer() function - inline UChar* getArrayStart(void); - inline const UChar* getArrayStart(void) const; + inline char16_t* getArrayStart(void); + inline const char16_t* getArrayStart(void) const; inline UBool hasShortLength() const; inline int32_t getShortLength() const; @@ -3385,7 +3600,7 @@ class U_COMMON_API UnicodeString : public Replaceable inline void setShortLength(int32_t len); inline void setLength(int32_t len); inline void setToEmpty(); - inline void setArray(UChar *array, int32_t len, int32_t capacity); // sets length but not flags + inline void setArray(char16_t *array, int32_t len, int32_t capacity); // sets length but not flags // allocate the array; result may be the stack buffer // sets refCount to 1 if appropriate @@ -3403,6 +3618,9 @@ class U_COMMON_API UnicodeString : public Replaceable // implements assigment operator, copy constructor, and fastCopyFrom() UnicodeString ©From(const UnicodeString &src, UBool fastCopy=FALSE); + // Copies just the fields without memory management. + void copyFieldsFrom(UnicodeString &src, UBool setSrcToBogus) U_NOEXCEPT; + // Pin start and limit to acceptable values. inline void pinIndex(int32_t& start) const; inline void pinIndices(int32_t& start, @@ -3420,9 +3638,9 @@ class U_COMMON_API UnicodeString : public Replaceable * Real constructor for converting from codepage data. * It assumes that it is called with !fRefCounted. * - * If codepage==0, then the default converter + * If `codepage==0`, then the default converter * is used for the platform encoding. - * If codepage is an empty string (""), + * If `codepage` is an empty string (`""`), * then a simple conversion is performed on the codepage-invariant * subset ("invariant characters") of the platform encoding. See utypes.h. */ @@ -3465,7 +3683,11 @@ class U_COMMON_API UnicodeString : public Replaceable * as in ustr_imp.h for ustrcase_map(). */ UnicodeString & - caseMap(const UCaseMap *csm, UStringCaseMapper *stringCaseMapper); + caseMap(int32_t caseLocale, uint32_t options, +#if !UCONFIG_NO_BREAK_ITERATION + BreakIterator *iter, +#endif + UStringCaseMapper *stringCaseMapper); // ref counting void addRef(void); @@ -3474,11 +3696,13 @@ class U_COMMON_API UnicodeString : public Replaceable // constants enum { - // Set the stack buffer size so that sizeof(UnicodeString) is, - // naturally (without padding), a multiple of sizeof(pointer). - US_STACKBUF_SIZE= sizeof(void *)==4 ? 13 : 15, // Size of stack buffer for short strings + /** + * Size of stack buffer for short strings. + * Must be at least U16_MAX_LENGTH for the single-code point constructor to work. + * @see UNISTR_OBJECT_SIZE + */ + US_STACKBUF_SIZE=(int32_t)(UNISTR_OBJECT_SIZE-sizeof(void *)-2)/U_SIZEOF_UCHAR, kInvalidUChar=0xffff, // U+FFFF returned by charAt(invalid index) - kGrowSize=128, // grow size for this buffer kInvalidHashCode=0, // invalid hash code kEmptyHashCode=1, // hash code for empty string @@ -3503,7 +3727,6 @@ class U_COMMON_API UnicodeString : public Replaceable kWritableAlias=0 }; - friend class StringThreadTest; friend class UnicodeStringAppendable; union StackBufferOrFields; // forward declaration necessary before friend declaration @@ -3544,9 +3767,10 @@ class U_COMMON_API UnicodeString : public Replaceable * (Padding at the end of fFields is ok: * As long as it is no larger than fStackFields, it is not wasted space.) * - * For some of the history of the UnicodeString class fields layout, - * see ICU ticket #11336 "UnicodeString: recombine stack buffer arrays" - * and ticket #8322 "why is sizeof(UnicodeString)==48?". + * For some of the history of the UnicodeString class fields layout, see + * - ICU ticket #11551 "longer UnicodeString contents in stack buffer" + * - ICU ticket #11336 "UnicodeString: recombine stack buffer arrays" + * - ICU ticket #8322 "why is sizeof(UnicodeString)==48?" */ // (implicit) *vtable; union StackBufferOrFields { @@ -3554,13 +3778,15 @@ class U_COMMON_API UnicodeString : public Replaceable // Each struct of the union must begin with fLengthAndFlags. struct { int16_t fLengthAndFlags; // bit fields: see constants above - UChar fBuffer[US_STACKBUF_SIZE]; // buffer for short strings + char16_t fBuffer[US_STACKBUF_SIZE]; // buffer for short strings } fStackFields; struct { int16_t fLengthAndFlags; // bit fields: see constants above - UChar *fArray; // the Unicode data - int32_t fCapacity; // capacity of fArray (in UChars) int32_t fLength; // number of characters in fArray if >127; else undefined + int32_t fCapacity; // capacity of fArray (in char16_ts) + // array pointer last to minimize padding for machines with P128 data model + // or pointer sizes that are not a power of 2 + char16_t *fArray; // the Unicode data } fFields; } fUnion; }; @@ -3613,13 +3839,13 @@ UnicodeString::pinIndices(int32_t& start, } } -inline UChar* +inline char16_t* UnicodeString::getArrayStart() { return (fUnion.fFields.fLengthAndFlags&kUsingStackBuffer) ? fUnion.fStackFields.fBuffer : fUnion.fFields.fArray; } -inline const UChar* +inline const char16_t* UnicodeString::getArrayStart() const { return (fUnion.fFields.fLengthAndFlags&kUsingStackBuffer) ? fUnion.fStackFields.fBuffer : fUnion.fFields.fArray; @@ -3634,6 +3860,18 @@ UnicodeString::UnicodeString() { fUnion.fStackFields.fLengthAndFlags=kShortString; } +inline UnicodeString::UnicodeString(const std::nullptr_t /*text*/) { + fUnion.fStackFields.fLengthAndFlags=kShortString; +} + +inline UnicodeString::UnicodeString(const std::nullptr_t /*text*/, int32_t /*length*/) { + fUnion.fStackFields.fLengthAndFlags=kShortString; +} + +inline UnicodeString::UnicodeString(std::nullptr_t /*buffer*/, int32_t /*buffLength*/, int32_t /*buffCapacity*/) { + fUnion.fStackFields.fLengthAndFlags=kShortString; +} + //======================================== // Read-only implementation methods //======================================== @@ -3680,10 +3918,10 @@ UnicodeString::isBufferWritable() const (!(fUnion.fFields.fLengthAndFlags&kRefCounted) || refCount()==1)); } -inline const UChar * +inline const char16_t * UnicodeString::getBuffer() const { if(fUnion.fFields.fLengthAndFlags&(kIsBogus|kOpenGetBuffer)) { - return 0; + return nullptr; } else if(fUnion.fFields.fLengthAndFlags&kUsingStackBuffer) { return fUnion.fStackFields.fBuffer; } else { @@ -3751,7 +3989,7 @@ UnicodeString::compare(int32_t start, { return doCompare(start, _length, srcText, 0, srcText.length()); } inline int8_t -UnicodeString::compare(const UChar *srcChars, +UnicodeString::compare(ConstChar16Ptr srcChars, int32_t srcLength) const { return doCompare(0, length(), srcChars, 0, srcLength); } @@ -3766,13 +4004,13 @@ UnicodeString::compare(int32_t start, inline int8_t UnicodeString::compare(int32_t start, int32_t _length, - const UChar *srcChars) const + const char16_t *srcChars) const { return doCompare(start, _length, srcChars, 0, _length); } inline int8_t UnicodeString::compare(int32_t start, int32_t _length, - const UChar *srcChars, + const char16_t *srcChars, int32_t srcStart, int32_t srcLength) const { return doCompare(start, _length, srcChars, srcStart, srcLength); } @@ -3812,7 +4050,7 @@ UnicodeString::compareCodePointOrder(int32_t start, { return doCompareCodePointOrder(start, _length, srcText, 0, srcText.length()); } inline int8_t -UnicodeString::compareCodePointOrder(const UChar *srcChars, +UnicodeString::compareCodePointOrder(ConstChar16Ptr srcChars, int32_t srcLength) const { return doCompareCodePointOrder(0, length(), srcChars, 0, srcLength); } @@ -3827,13 +4065,13 @@ UnicodeString::compareCodePointOrder(int32_t start, inline int8_t UnicodeString::compareCodePointOrder(int32_t start, int32_t _length, - const UChar *srcChars) const + const char16_t *srcChars) const { return doCompareCodePointOrder(start, _length, srcChars, 0, _length); } inline int8_t UnicodeString::compareCodePointOrder(int32_t start, int32_t _length, - const UChar *srcChars, + const char16_t *srcChars, int32_t srcStart, int32_t srcLength) const { return doCompareCodePointOrder(start, _length, srcChars, srcStart, srcLength); } @@ -3877,7 +4115,7 @@ UnicodeString::caseCompare(int32_t start, } inline int8_t -UnicodeString::caseCompare(const UChar *srcChars, +UnicodeString::caseCompare(ConstChar16Ptr srcChars, int32_t srcLength, uint32_t options) const { return doCaseCompare(0, length(), srcChars, 0, srcLength, options); @@ -3896,7 +4134,7 @@ UnicodeString::caseCompare(int32_t start, inline int8_t UnicodeString::caseCompare(int32_t start, int32_t _length, - const UChar *srcChars, + const char16_t *srcChars, uint32_t options) const { return doCaseCompare(start, _length, srcChars, 0, _length, options); } @@ -3904,7 +4142,7 @@ UnicodeString::caseCompare(int32_t start, inline int8_t UnicodeString::caseCompare(int32_t start, int32_t _length, - const UChar *srcChars, + const char16_t *srcChars, int32_t srcStart, int32_t srcLength, uint32_t options) const { @@ -3955,7 +4193,7 @@ UnicodeString::indexOf(const UnicodeString& text, { return indexOf(text, 0, text.length(), start, _length); } inline int32_t -UnicodeString::indexOf(const UChar *srcChars, +UnicodeString::indexOf(const char16_t *srcChars, int32_t srcLength, int32_t start) const { pinIndex(start); @@ -3963,14 +4201,14 @@ UnicodeString::indexOf(const UChar *srcChars, } inline int32_t -UnicodeString::indexOf(const UChar *srcChars, +UnicodeString::indexOf(ConstChar16Ptr srcChars, int32_t srcLength, int32_t start, int32_t _length) const { return indexOf(srcChars, 0, srcLength, start, _length); } inline int32_t -UnicodeString::indexOf(UChar c, +UnicodeString::indexOf(char16_t c, int32_t start, int32_t _length) const { return doIndexOf(c, start, _length); } @@ -3982,7 +4220,7 @@ UnicodeString::indexOf(UChar32 c, { return doIndexOf(c, start, _length); } inline int32_t -UnicodeString::indexOf(UChar c) const +UnicodeString::indexOf(char16_t c) const { return doIndexOf(c, 0, length()); } inline int32_t @@ -3990,7 +4228,7 @@ UnicodeString::indexOf(UChar32 c) const { return indexOf(c, 0, length()); } inline int32_t -UnicodeString::indexOf(UChar c, +UnicodeString::indexOf(char16_t c, int32_t start) const { pinIndex(start); return doIndexOf(c, start, length() - start); @@ -4004,14 +4242,14 @@ UnicodeString::indexOf(UChar32 c, } inline int32_t -UnicodeString::lastIndexOf(const UChar *srcChars, +UnicodeString::lastIndexOf(ConstChar16Ptr srcChars, int32_t srcLength, int32_t start, int32_t _length) const { return lastIndexOf(srcChars, 0, srcLength, start, _length); } inline int32_t -UnicodeString::lastIndexOf(const UChar *srcChars, +UnicodeString::lastIndexOf(const char16_t *srcChars, int32_t srcLength, int32_t start) const { pinIndex(start); @@ -4052,7 +4290,7 @@ UnicodeString::lastIndexOf(const UnicodeString& text) const { return lastIndexOf(text, 0, text.length(), 0, length()); } inline int32_t -UnicodeString::lastIndexOf(UChar c, +UnicodeString::lastIndexOf(char16_t c, int32_t start, int32_t _length) const { return doLastIndexOf(c, start, _length); } @@ -4065,7 +4303,7 @@ UnicodeString::lastIndexOf(UChar32 c, } inline int32_t -UnicodeString::lastIndexOf(UChar c) const +UnicodeString::lastIndexOf(char16_t c) const { return doLastIndexOf(c, 0, length()); } inline int32_t @@ -4074,7 +4312,7 @@ UnicodeString::lastIndexOf(UChar32 c) const { } inline int32_t -UnicodeString::lastIndexOf(UChar c, +UnicodeString::lastIndexOf(char16_t c, int32_t start) const { pinIndex(start); return doLastIndexOf(c, start, length() - start); @@ -4098,17 +4336,17 @@ UnicodeString::startsWith(const UnicodeString& srcText, { return doCompare(0, srcLength, srcText, srcStart, srcLength) == 0; } inline UBool -UnicodeString::startsWith(const UChar *srcChars, int32_t srcLength) const { +UnicodeString::startsWith(ConstChar16Ptr srcChars, int32_t srcLength) const { if(srcLength < 0) { - srcLength = u_strlen(srcChars); + srcLength = u_strlen(toUCharPtr(srcChars)); } return doCompare(0, srcLength, srcChars, 0, srcLength) == 0; } inline UBool -UnicodeString::startsWith(const UChar *srcChars, int32_t srcStart, int32_t srcLength) const { +UnicodeString::startsWith(const char16_t *srcChars, int32_t srcStart, int32_t srcLength) const { if(srcLength < 0) { - srcLength = u_strlen(srcChars); + srcLength = u_strlen(toUCharPtr(srcChars)); } return doCompare(0, srcLength, srcChars, srcStart, srcLength) == 0; } @@ -4128,21 +4366,21 @@ UnicodeString::endsWith(const UnicodeString& srcText, } inline UBool -UnicodeString::endsWith(const UChar *srcChars, +UnicodeString::endsWith(ConstChar16Ptr srcChars, int32_t srcLength) const { if(srcLength < 0) { - srcLength = u_strlen(srcChars); + srcLength = u_strlen(toUCharPtr(srcChars)); } return doCompare(length() - srcLength, srcLength, srcChars, 0, srcLength) == 0; } inline UBool -UnicodeString::endsWith(const UChar *srcChars, +UnicodeString::endsWith(const char16_t *srcChars, int32_t srcStart, int32_t srcLength) const { if(srcLength < 0) { - srcLength = u_strlen(srcChars + srcStart); + srcLength = u_strlen(toUCharPtr(srcChars + srcStart)); } return doCompare(length() - srcLength, srcLength, srcChars, srcStart, srcLength) == 0; @@ -4168,14 +4406,14 @@ UnicodeString::replace(int32_t start, inline UnicodeString& UnicodeString::replace(int32_t start, int32_t _length, - const UChar *srcChars, + ConstChar16Ptr srcChars, int32_t srcLength) { return doReplace(start, _length, srcChars, 0, srcLength); } inline UnicodeString& UnicodeString::replace(int32_t start, int32_t _length, - const UChar *srcChars, + const char16_t *srcChars, int32_t srcStart, int32_t srcLength) { return doReplace(start, _length, srcChars, srcStart, srcLength); } @@ -4183,7 +4421,7 @@ UnicodeString::replace(int32_t start, inline UnicodeString& UnicodeString::replace(int32_t start, int32_t _length, - UChar srcChar) + char16_t srcChar) { return doReplace(start, _length, &srcChar, 0, 1); } inline UnicodeString& @@ -4226,7 +4464,7 @@ UnicodeString::doExtract(int32_t start, inline void UnicodeString::extract(int32_t start, int32_t _length, - UChar *target, + Char16Ptr target, int32_t targetStart) const { doExtract(start, _length, target, targetStart); } @@ -4254,7 +4492,7 @@ UnicodeString::extract(int32_t start, inline void UnicodeString::extractBetween(int32_t start, int32_t limit, - UChar *dst, + char16_t *dst, int32_t dstStart) const { pinIndex(start); pinIndex(limit); @@ -4266,7 +4504,7 @@ UnicodeString::tempSubStringBetween(int32_t start, int32_t limit) const { return tempSubString(start, limit - start); } -inline UChar +inline char16_t UnicodeString::doCharAt(int32_t offset) const { if((uint32_t)offset < (uint32_t)length()) { @@ -4276,11 +4514,11 @@ UnicodeString::doCharAt(int32_t offset) const } } -inline UChar +inline char16_t UnicodeString::charAt(int32_t offset) const { return doCharAt(offset); } -inline UChar +inline char16_t UnicodeString::operator[] (int32_t offset) const { return doCharAt(offset); } @@ -4321,14 +4559,14 @@ UnicodeString::setToEmpty() { } inline void -UnicodeString::setArray(UChar *array, int32_t len, int32_t capacity) { +UnicodeString::setArray(char16_t *array, int32_t len, int32_t capacity) { setLength(len); fUnion.fFields.fArray = array; fUnion.fFields.fCapacity = capacity; } inline UnicodeString& -UnicodeString::operator= (UChar ch) +UnicodeString::operator= (char16_t ch) { return doReplace(0, length(), &ch, 0, 1); } inline UnicodeString& @@ -4360,7 +4598,7 @@ UnicodeString::setTo(const UnicodeString& srcText) } inline UnicodeString& -UnicodeString::setTo(const UChar *srcChars, +UnicodeString::setTo(const char16_t *srcChars, int32_t srcLength) { unBogus(); @@ -4368,7 +4606,7 @@ UnicodeString::setTo(const UChar *srcChars, } inline UnicodeString& -UnicodeString::setTo(UChar srcChar) +UnicodeString::setTo(char16_t srcChar) { unBogus(); return doReplace(0, length(), &srcChar, 0, 1); @@ -4385,30 +4623,30 @@ inline UnicodeString& UnicodeString::append(const UnicodeString& srcText, int32_t srcStart, int32_t srcLength) -{ return doReplace(length(), 0, srcText, srcStart, srcLength); } +{ return doAppend(srcText, srcStart, srcLength); } inline UnicodeString& UnicodeString::append(const UnicodeString& srcText) -{ return doReplace(length(), 0, srcText, 0, srcText.length()); } +{ return doAppend(srcText, 0, srcText.length()); } inline UnicodeString& -UnicodeString::append(const UChar *srcChars, +UnicodeString::append(const char16_t *srcChars, int32_t srcStart, int32_t srcLength) -{ return doReplace(length(), 0, srcChars, srcStart, srcLength); } +{ return doAppend(srcChars, srcStart, srcLength); } inline UnicodeString& -UnicodeString::append(const UChar *srcChars, +UnicodeString::append(ConstChar16Ptr srcChars, int32_t srcLength) -{ return doReplace(length(), 0, srcChars, 0, srcLength); } +{ return doAppend(srcChars, 0, srcLength); } inline UnicodeString& -UnicodeString::append(UChar srcChar) -{ return doReplace(length(), 0, &srcChar, 0, 1); } +UnicodeString::append(char16_t srcChar) +{ return doAppend(&srcChar, 0, 1); } inline UnicodeString& -UnicodeString::operator+= (UChar ch) -{ return doReplace(length(), 0, &ch, 0, 1); } +UnicodeString::operator+= (char16_t ch) +{ return doAppend(&ch, 0, 1); } inline UnicodeString& UnicodeString::operator+= (UChar32 ch) { @@ -4417,7 +4655,7 @@ UnicodeString::operator+= (UChar32 ch) { inline UnicodeString& UnicodeString::operator+= (const UnicodeString& srcText) -{ return doReplace(length(), 0, srcText, 0, srcText.length()); } +{ return doAppend(srcText, 0, srcText.length()); } inline UnicodeString& UnicodeString::insert(int32_t start, @@ -4433,20 +4671,20 @@ UnicodeString::insert(int32_t start, inline UnicodeString& UnicodeString::insert(int32_t start, - const UChar *srcChars, + const char16_t *srcChars, int32_t srcStart, int32_t srcLength) { return doReplace(start, 0, srcChars, srcStart, srcLength); } inline UnicodeString& UnicodeString::insert(int32_t start, - const UChar *srcChars, + ConstChar16Ptr srcChars, int32_t srcLength) { return doReplace(start, 0, srcChars, 0, srcLength); } inline UnicodeString& UnicodeString::insert(int32_t start, - UChar srcChar) + char16_t srcChar) { return doReplace(start, 0, &srcChar, 0, 1); } inline UnicodeString& @@ -4514,5 +4752,6 @@ UnicodeString::reverse(int32_t start, { return doReverse(start, _length); } U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unorm.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unorm.h index fbb7b49b36..3839de1295 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unorm.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unorm.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* -* Copyright (c) 1996-2010, International Business Machines Corporation +* Copyright (c) 1996-2016, International Business Machines Corporation * and others. All Rights Reserved. ******************************************************************************* * File unorm.h @@ -24,14 +26,15 @@ /** * \file - * \brief C API: Unicode Normalization + * \brief C API: Unicode Normalization * - *

        Unicode normalization API

        + * Old Unicode normalization API. * - * Note: This API has been replaced by the unorm2.h API and is only available + * This API has been replaced by the unorm2.h API and is only available * for backward compatibility. The functions here simply delegate to the * unorm2.h functions, for example unorm2_getInstance() and unorm2_normalize(). * There is one exception: The new API does not provide a replacement for unorm_compare(). + * Its declaration has been moved to unorm2.h. * * unorm_normalize transforms Unicode text into an equivalent composed or * decomposed form, allowing for easier sorting and searching of text. @@ -57,7 +60,7 @@ * * To a user of your program, however, both of these sequences should be * treated as the same "user-level" character "A with acute accent". When you are searching or - * comparing text, you must ensure that these two sequences are treated + * comparing text, you must ensure that these two sequences are treated * equivalently. In addition, you must handle characters with more than one * accent. Sometimes the order of a character's combining accents is * significant, while in other cases accent sequences in different orders are @@ -85,8 +88,8 @@ * will often want to use these mappings. * * unorm_normalize helps solve these problems by transforming text into the - * canonical composed and decomposed forms as shown in the first example above. - * In addition, you can have it perform compatibility decompositions so that + * canonical composed and decomposed forms as shown in the first example above. + * In addition, you can have it perform compatibility decompositions so that * you can treat compatibility characters the same as their equivalents. * Finally, unorm_normalize rearranges accents into the proper canonical * order, so that you do not have to worry about accent rearrangement on your @@ -126,43 +129,47 @@ * For more usage examples, see the Unicode Standard Annex. */ +// Do not conditionalize the following enum with #ifndef U_HIDE_DEPRECATED_API, +// it is needed for layout of Normalizer object. /** * Constants for normalization modes. - * @stable ICU 2.0 + * @deprecated ICU 56 Use unorm2.h instead. */ typedef enum { - /** No decomposition/composition. @stable ICU 2.0 */ - UNORM_NONE = 1, - /** Canonical decomposition. @stable ICU 2.0 */ + /** No decomposition/composition. @deprecated ICU 56 Use unorm2.h instead. */ + UNORM_NONE = 1, + /** Canonical decomposition. @deprecated ICU 56 Use unorm2.h instead. */ UNORM_NFD = 2, - /** Compatibility decomposition. @stable ICU 2.0 */ + /** Compatibility decomposition. @deprecated ICU 56 Use unorm2.h instead. */ UNORM_NFKD = 3, - /** Canonical decomposition followed by canonical composition. @stable ICU 2.0 */ + /** Canonical decomposition followed by canonical composition. @deprecated ICU 56 Use unorm2.h instead. */ UNORM_NFC = 4, - /** Default normalization. @stable ICU 2.0 */ - UNORM_DEFAULT = UNORM_NFC, - /** Compatibility decomposition followed by canonical composition. @stable ICU 2.0 */ + /** Default normalization. @deprecated ICU 56 Use unorm2.h instead. */ + UNORM_DEFAULT = UNORM_NFC, + /** Compatibility decomposition followed by canonical composition. @deprecated ICU 56 Use unorm2.h instead. */ UNORM_NFKC =5, - /** "Fast C or D" form. @stable ICU 2.0 */ + /** "Fast C or D" form. @deprecated ICU 56 Use unorm2.h instead. */ UNORM_FCD = 6, - /** One more than the highest normalization mode constant. @stable ICU 2.0 */ + /** One more than the highest normalization mode constant. @deprecated ICU 56 Use unorm2.h instead. */ UNORM_MODE_COUNT } UNormalizationMode; +#ifndef U_HIDE_DEPRECATED_API + /** * Constants for options flags for normalization. * Use 0 for default options, * including normalization according to the Unicode version * that is currently supported by ICU (see u_getUnicodeVersion). - * @stable ICU 2.6 + * @deprecated ICU 56 Use unorm2.h instead. */ enum { /** * Options bit set value to select Unicode 3.2 normalization * (except NormalizationCorrections). * At most one Unicode version can be selected at a time. - * @stable ICU 2.6 + * @deprecated ICU 56 Use unorm2.h instead. */ UNORM_UNICODE_3_2=0x20 }; @@ -180,7 +187,7 @@ enum { * internal normalization functions.) * * @see unorm_compare - * @stable ICU 2.6 + * @deprecated ICU 56 Use unorm2.h instead. */ #define UNORM_COMPARE_NORM_OPTIONS_SHIFT 20 @@ -192,7 +199,7 @@ enum { * * @param source The string to normalize. * @param sourceLength The length of source, or -1 if NUL-terminated. - * @param mode The normalization mode; one of UNORM_NONE, + * @param mode The normalization mode; one of UNORM_NONE, * UNORM_NFD, UNORM_NFC, UNORM_NFKC, UNORM_NFKD, UNORM_DEFAULT. * @param options The normalization options, ORed together (0 for no options). * @param result A pointer to a buffer to receive the result string. @@ -201,23 +208,23 @@ enum { * @param status A pointer to a UErrorCode to receive any errors. * @return The total buffer size needed; if greater than resultLength, * the output was truncated, and the error code is set to U_BUFFER_OVERFLOW_ERROR. - * @stable ICU 2.0 + * @deprecated ICU 56 Use unorm2.h instead. */ -U_STABLE int32_t U_EXPORT2 +U_DEPRECATED int32_t U_EXPORT2 unorm_normalize(const UChar *source, int32_t sourceLength, UNormalizationMode mode, int32_t options, UChar *result, int32_t resultLength, UErrorCode *status); /** - * Performing quick check on a string, to quickly determine if the string is + * Performing quick check on a string, to quickly determine if the string is * in a particular normalization format. * Three types of result can be returned UNORM_YES, UNORM_NO or * UNORM_MAYBE. Result UNORM_YES indicates that the argument * string is in the desired normalized format, UNORM_NO determines that - * argument string is not in the desired normalized format. A - * UNORM_MAYBE result indicates that a more thorough check is required, - * the user may have to put the string in its normalized form and compare the + * argument string is not in the desired normalized format. A + * UNORM_MAYBE result indicates that a more thorough check is required, + * the user may have to put the string in its normalized form and compare the * results. * * @param source string for determining if it is in a normalized format @@ -227,9 +234,9 @@ unorm_normalize(const UChar *source, int32_t sourceLength, * @return UNORM_YES, UNORM_NO or UNORM_MAYBE * * @see unorm_isNormalized - * @stable ICU 2.0 + * @deprecated ICU 56 Use unorm2.h instead. */ -U_STABLE UNormalizationCheckResult U_EXPORT2 +U_DEPRECATED UNormalizationCheckResult U_EXPORT2 unorm_quickCheck(const UChar *source, int32_t sourcelength, UNormalizationMode mode, UErrorCode *status); @@ -248,10 +255,10 @@ unorm_quickCheck(const UChar *source, int32_t sourcelength, * * @see unorm_quickCheck * @see unorm_isNormalized - * @stable ICU 2.6 + * @deprecated ICU 56 Use unorm2.h instead. */ -U_STABLE UNormalizationCheckResult U_EXPORT2 -unorm_quickCheckWithOptions(const UChar *src, int32_t srcLength, +U_DEPRECATED UNormalizationCheckResult U_EXPORT2 +unorm_quickCheckWithOptions(const UChar *src, int32_t srcLength, UNormalizationMode mode, int32_t options, UErrorCode *pErrorCode); @@ -274,9 +281,9 @@ unorm_quickCheckWithOptions(const UChar *src, int32_t srcLength, * "mode" normalization form. * * @see unorm_quickCheck - * @stable ICU 2.2 + * @deprecated ICU 56 Use unorm2.h instead. */ -U_STABLE UBool U_EXPORT2 +U_DEPRECATED UBool U_EXPORT2 unorm_isNormalized(const UChar *src, int32_t srcLength, UNormalizationMode mode, UErrorCode *pErrorCode); @@ -296,9 +303,9 @@ unorm_isNormalized(const UChar *src, int32_t srcLength, * * @see unorm_quickCheck * @see unorm_isNormalized - * @stable ICU 2.6 + * @deprecated ICU 56 Use unorm2.h instead. */ -U_STABLE UBool U_EXPORT2 +U_DEPRECATED UBool U_EXPORT2 unorm_isNormalizedWithOptions(const UChar *src, int32_t srcLength, UNormalizationMode mode, int32_t options, UErrorCode *pErrorCode); @@ -374,9 +381,9 @@ unorm_isNormalizedWithOptions(const UChar *src, int32_t srcLength, * @see unorm_previous * @see unorm_normalize * - * @stable ICU 2.1 + * @deprecated ICU 56 Use unorm2.h instead. */ -U_STABLE int32_t U_EXPORT2 +U_DEPRECATED int32_t U_EXPORT2 unorm_next(UCharIterator *src, UChar *dest, int32_t destCapacity, UNormalizationMode mode, int32_t options, @@ -407,9 +414,9 @@ unorm_next(UCharIterator *src, * @see unorm_next * @see unorm_normalize * - * @stable ICU 2.1 + * @deprecated ICU 56 Use unorm2.h instead. */ -U_STABLE int32_t U_EXPORT2 +U_DEPRECATED int32_t U_EXPORT2 unorm_previous(UCharIterator *src, UChar *dest, int32_t destCapacity, UNormalizationMode mode, int32_t options, @@ -451,111 +458,15 @@ unorm_previous(UCharIterator *src, * @see unorm_next * @see unorm_previous * - * @stable ICU 2.1 + * @deprecated ICU 56 Use unorm2.h instead. */ -U_STABLE int32_t U_EXPORT2 +U_DEPRECATED int32_t U_EXPORT2 unorm_concatenate(const UChar *left, int32_t leftLength, const UChar *right, int32_t rightLength, UChar *dest, int32_t destCapacity, UNormalizationMode mode, int32_t options, UErrorCode *pErrorCode); -/** - * Option bit for unorm_compare: - * Both input strings are assumed to fulfill FCD conditions. - * @stable ICU 2.2 - */ -#define UNORM_INPUT_IS_FCD 0x20000 - -/** - * Option bit for unorm_compare: - * Perform case-insensitive comparison. - * @stable ICU 2.2 - */ -#define U_COMPARE_IGNORE_CASE 0x10000 - -#ifndef U_COMPARE_CODE_POINT_ORDER -/* see also unistr.h and ustring.h */ -/** - * Option bit for u_strCaseCompare, u_strcasecmp, unorm_compare, etc: - * Compare strings in code point order instead of code unit order. - * @stable ICU 2.2 - */ -#define U_COMPARE_CODE_POINT_ORDER 0x8000 -#endif - -/** - * Compare two strings for canonical equivalence. - * Further options include case-insensitive comparison and - * code point order (as opposed to code unit order). - * - * Canonical equivalence between two strings is defined as their normalized - * forms (NFD or NFC) being identical. - * This function compares strings incrementally instead of normalizing - * (and optionally case-folding) both strings entirely, - * improving performance significantly. - * - * Bulk normalization is only necessary if the strings do not fulfill the FCD - * conditions. Only in this case, and only if the strings are relatively long, - * is memory allocated temporarily. - * For FCD strings and short non-FCD strings there is no memory allocation. - * - * Semantically, this is equivalent to - * strcmp[CodePointOrder](NFD(foldCase(NFD(s1))), NFD(foldCase(NFD(s2)))) - * where code point order and foldCase are all optional. - * - * UAX 21 2.5 Caseless Matching specifies that for a canonical caseless match - * the case folding must be performed first, then the normalization. - * - * @param s1 First source string. - * @param length1 Length of first source string, or -1 if NUL-terminated. - * - * @param s2 Second source string. - * @param length2 Length of second source string, or -1 if NUL-terminated. - * - * @param options A bit set of options: - * - U_FOLD_CASE_DEFAULT or 0 is used for default options: - * Case-sensitive comparison in code unit order, and the input strings - * are quick-checked for FCD. - * - * - UNORM_INPUT_IS_FCD - * Set if the caller knows that both s1 and s2 fulfill the FCD conditions. - * If not set, the function will quickCheck for FCD - * and normalize if necessary. - * - * - U_COMPARE_CODE_POINT_ORDER - * Set to choose code point order instead of code unit order - * (see u_strCompare for details). - * - * - U_COMPARE_IGNORE_CASE - * Set to compare strings case-insensitively using case folding, - * instead of case-sensitively. - * If set, then the following case folding options are used. - * - * - Options as used with case-insensitive comparisons, currently: - * - * - U_FOLD_CASE_EXCLUDE_SPECIAL_I - * (see u_strCaseCompare for details) - * - * - regular normalization options shifted left by UNORM_COMPARE_NORM_OPTIONS_SHIFT - * - * @param pErrorCode ICU error code in/out parameter. - * Must fulfill U_SUCCESS before the function call. - * @return <0 or 0 or >0 as usual for string comparisons - * - * @see unorm_normalize - * @see UNORM_FCD - * @see u_strCompare - * @see u_strCaseCompare - * - * @stable ICU 2.2 - */ -U_STABLE int32_t U_EXPORT2 -unorm_compare(const UChar *s1, int32_t length1, - const UChar *s2, int32_t length2, - uint32_t options, - UErrorCode *pErrorCode); - +#endif /* U_HIDE_DEPRECATED_API */ #endif /* #if !UCONFIG_NO_NORMALIZATION */ - #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unorm2.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unorm2.h index 7152fc1094..39889bdf71 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unorm2.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unorm2.h @@ -1,12 +1,14 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * -* Copyright (C) 2009-2013, International Business Machines +* Copyright (C) 2009-2015, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* * file name: unorm2.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -30,6 +32,7 @@ #include "unicode/utypes.h" #include "unicode/localpointer.h" +#include "unicode/stringoptions.h" #include "unicode/uset.h" /** @@ -259,7 +262,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUNormalizer2Pointer, UNormalizer2, unorm2_close U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Writes the normalized form of the source string to the destination string @@ -524,5 +527,77 @@ unorm2_hasBoundaryAfter(const UNormalizer2 *norm2, UChar32 c); U_STABLE UBool U_EXPORT2 unorm2_isInert(const UNormalizer2 *norm2, UChar32 c); +/** + * Compares two strings for canonical equivalence. + * Further options include case-insensitive comparison and + * code point order (as opposed to code unit order). + * + * Canonical equivalence between two strings is defined as their normalized + * forms (NFD or NFC) being identical. + * This function compares strings incrementally instead of normalizing + * (and optionally case-folding) both strings entirely, + * improving performance significantly. + * + * Bulk normalization is only necessary if the strings do not fulfill the FCD + * conditions. Only in this case, and only if the strings are relatively long, + * is memory allocated temporarily. + * For FCD strings and short non-FCD strings there is no memory allocation. + * + * Semantically, this is equivalent to + * strcmp[CodePointOrder](NFD(foldCase(NFD(s1))), NFD(foldCase(NFD(s2)))) + * where code point order and foldCase are all optional. + * + * UAX 21 2.5 Caseless Matching specifies that for a canonical caseless match + * the case folding must be performed first, then the normalization. + * + * @param s1 First source string. + * @param length1 Length of first source string, or -1 if NUL-terminated. + * + * @param s2 Second source string. + * @param length2 Length of second source string, or -1 if NUL-terminated. + * + * @param options A bit set of options: + * - U_FOLD_CASE_DEFAULT or 0 is used for default options: + * Case-sensitive comparison in code unit order, and the input strings + * are quick-checked for FCD. + * + * - UNORM_INPUT_IS_FCD + * Set if the caller knows that both s1 and s2 fulfill the FCD conditions. + * If not set, the function will quickCheck for FCD + * and normalize if necessary. + * + * - U_COMPARE_CODE_POINT_ORDER + * Set to choose code point order instead of code unit order + * (see u_strCompare for details). + * + * - U_COMPARE_IGNORE_CASE + * Set to compare strings case-insensitively using case folding, + * instead of case-sensitively. + * If set, then the following case folding options are used. + * + * - Options as used with case-insensitive comparisons, currently: + * + * - U_FOLD_CASE_EXCLUDE_SPECIAL_I + * (see u_strCaseCompare for details) + * + * - regular normalization options shifted left by UNORM_COMPARE_NORM_OPTIONS_SHIFT + * + * @param pErrorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return <0 or 0 or >0 as usual for string comparisons + * + * @see unorm_normalize + * @see UNORM_FCD + * @see u_strCompare + * @see u_strCaseCompare + * + * @stable ICU 2.2 + */ +U_STABLE int32_t U_EXPORT2 +unorm_compare(const UChar *s1, int32_t length1, + const UChar *s2, int32_t length2, + uint32_t options, + UErrorCode *pErrorCode); + #endif /* !UCONFIG_NO_NORMALIZATION */ #endif /* __UNORM2_H__ */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unum.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unum.h index af6dadbf82..e1908cf5d3 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unum.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unum.h @@ -1,3 +1,5 @@ +// © 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. @@ -23,12 +25,17 @@ #include "unicode/parseerr.h" #include "unicode/uformattable.h" #include "unicode/udisplaycontext.h" +#include "unicode/ufieldpositer.h" /** * \file - * \brief C API: NumberFormat + * \brief C API: Compatibility APIs for number formatting. * *

        Number Format C API

        + * + *

        IMPORTANT: New users with are strongly encouraged to + * see if unumberformatter.h fits their use case. Although not deprecated, + * this header is provided for backwards compatibility only. * * Number Format C API Provides functions for * formatting and parsing a number. Also provides methods for @@ -112,7 +119,7 @@ *

        * You can also control the display of numbers with such function as * unum_getAttributes() and unum_setAttributes(), which let you set the - * miminum fraction digits, grouping, etc. + * minimum fraction digits, grouping, etc. * @see UNumberFormatAttributes for more details *

        * You can also use forms of the parse and format methods with @@ -123,7 +130,7 @@ *

      *

      * It is also possible to change or set the symbols used for a particular - * locale like the currency symbol, the grouping seperator , monetary seperator + * locale like the currency symbol, the grouping separator , monetary separator * etc by making use of functions unum_setSymbols() and unum_getSymbols(). */ @@ -148,7 +155,11 @@ typedef enum UNumberFormatStyle { */ UNUM_DECIMAL=1, /** - * Currency format with a currency symbol, e.g., "$1.00". + * Currency format (generic). + * Defaults to UNUM_CURRENCY_STANDARD style + * (using currency symbol, e.g., "$1.00", with non-accounting + * style for negative values e.g. using minus sign). + * The specific style may be specified using the -cf- locale key. * @stable ICU 2.0 */ UNUM_CURRENCY=2, @@ -205,39 +216,45 @@ typedef enum UNumberFormatStyle { /** * Currency format for accounting, e.g., "($3.00)" for * negative currency amount instead of "-$3.00" ({@link #UNUM_CURRENCY}). + * Overrides any style specified using -cf- key in locale. * @stable ICU 53 */ UNUM_CURRENCY_ACCOUNTING=12, -#ifndef U_HIDE_DRAFT_API /** * Currency format with a currency symbol given CASH usage, e.g., * "NT$3" instead of "NT$3.23". - * @draft ICU 54 + * @stable ICU 54 */ UNUM_CASH_CURRENCY=13, -#endif /* U_HIDE_DRAFT_API */ -#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, -#endif /* U_HIDE_DRAFT_API */ + /** + * 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. + * @stable ICU 56 + */ + UNUM_CURRENCY_STANDARD=16, +#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=16, + UNUM_FORMAT_STYLE_COUNT=17, +#endif /* U_HIDE_DEPRECATED_API */ /** * Default format @@ -251,8 +268,13 @@ typedef enum UNumberFormatStyle { UNUM_IGNORE = UNUM_PATTERN_DECIMAL } UNumberFormatStyle; -/** The possible number format rounding modes. - * @stable ICU 2.0 +/** The possible number format rounding modes. + * + *

      + * For more detail on rounding modes, see: + * http://userguide.icu-project.org/formatparse/numbers/rounding-modes + * + * @stable ICU 2.0 */ typedef enum UNumberFormatRoundingMode { UNUM_ROUND_CEILING, @@ -313,7 +335,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 */ @@ -347,8 +375,20 @@ typedef enum UNumberFormatFields { UNUM_PERMILL_FIELD, /** @stable ICU 49 */ UNUM_SIGN_FIELD, - /** @stable ICU 49 */ - UNUM_FIELD_COUNT +#ifndef U_HIDE_DRAFT_API + /** @draft ICU 64 */ + UNUM_MEASURE_UNIT_FIELD, + /** @draft ICU 64 */ + UNUM_COMPACT_FIELD, +#endif /* U_HIDE_DRAFT_API */ + +#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 = UNUM_SIGN_FIELD + 3 +#endif /* U_HIDE_DEPRECATED_API */ } UNumberFormatFields; @@ -367,6 +407,10 @@ typedef enum UNumberFormatFields { * number format is opened using the given pattern, which must conform * to the syntax described in DecimalFormat or RuleBasedNumberFormat, * respectively. + * + *

      NOTE:: New users with are strongly encouraged to + * use unumf_openWithSkeletonAndLocale instead of unum_open. + * * @param pattern A pattern specifying the format to use. * This parameter is ignored unless the style is * UNUM_PATTERN_DECIMAL or UNUM_PATTERN_RULEBASED. @@ -420,7 +464,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUNumberFormatPointer, UNumberFormat, unum_close U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Open a copy of a UNumberFormat. @@ -530,6 +574,57 @@ unum_formatDouble( const UNumberFormat* fmt, UFieldPosition *pos, /* 0 if ignore */ UErrorCode* status); +/** +* Format a double using a UNumberFormat according to the UNumberFormat's locale, +* and initialize a UFieldPositionIterator that enumerates the subcomponents of +* the resulting string. +* +* @param format +* The formatter to use. +* @param number +* The number to format. +* @param result +* A pointer to a buffer to receive the NULL-terminated formatted +* number. If the formatted number fits into dest but cannot be +* NULL-terminated (length == resultLength) then the error code is set +* to U_STRING_NOT_TERMINATED_WARNING. If the formatted number doesn't +* fit into result then the error code is set to +* U_BUFFER_OVERFLOW_ERROR. +* @param resultLength +* The maximum size of result. +* @param fpositer +* A pointer to a UFieldPositionIterator created by {@link #ufieldpositer_open} +* (may be NULL if field position information is not needed, but in this +* case it's preferable to use {@link #unum_formatDouble}). Iteration +* information already present in the UFieldPositionIterator is deleted, +* and the iterator is reset to apply to the fields in the formatted +* string created by this function call. The field values and indexes +* returned by {@link #ufieldpositer_next} represent fields denoted by +* the UNumberFormatFields enum. Fields are not returned in a guaranteed +* order. Fields cannot overlap, but they may nest. For example, 1234 +* could format as "1,234" which might consist of a grouping separator +* field for ',' and an integer field encompassing the entire string. +* @param status +* A pointer to an UErrorCode to receive any errors +* @return +* The total buffer size needed; if greater than resultLength, the +* output was truncated. +* @see unum_formatDouble +* @see unum_parse +* @see unum_parseDouble +* @see UFieldPositionIterator +* @see UNumberFormatFields +* @stable ICU 59 +*/ +U_STABLE int32_t U_EXPORT2 +unum_formatDoubleForFields(const UNumberFormat* format, + double number, + UChar* result, + int32_t resultLength, + UFieldPositionIterator* fpositer, + UErrorCode* status); + + /** * Format a decimal number using a UNumberFormat. * The number will be formatted according to the UNumberFormat's locale. @@ -806,7 +901,7 @@ unum_parseToUFormattable(const UNumberFormat* fmt, * @param localized TRUE if the pattern is localized, FALSE otherwise. * @param pattern The new pattern * @param patternLength The length of pattern, or -1 if null-terminated. - * @param parseError A pointer to UParseError to recieve information + * @param parseError A pointer to UParseError to receive information * about errors occurred during parsing, or NULL if no parse error * information is desired. * @param status A pointer to an input-output UErrorCode. @@ -861,6 +956,9 @@ typedef enum UNumberFormatAttributeValue { UNUM_YES = 1, /** @internal */ UNUM_MAYBE = 2 +#else + /** @internal */ + UNUM_FORMAT_ATTRIBUTE_VALUE_HIDDEN #endif /* U_HIDE_INTERNAL_API */ } UNumberFormatAttributeValue; #endif @@ -917,7 +1015,7 @@ typedef enum UNumberFormatAttribute { * This is an internal ICU API. Do not use. * @internal */ - UNUM_PARSE_ALL_INPUT = UNUM_LENIENT_PARSE + 1, + UNUM_PARSE_ALL_INPUT = 20, #endif /** * Scale, which adjusts the position of the @@ -927,30 +1025,50 @@ typedef enum UNumberFormatAttribute { *

      Example: setting the scale to 3, 123 formats as "123,000" *

      Example: setting the scale to -4, 123 formats as "0.0123" * + * This setting is analogous to getMultiplierScale() and setMultiplierScale() in decimfmt.h. + * * @stable ICU 51 */ - UNUM_SCALE = UNUM_LENIENT_PARSE + 2, + UNUM_SCALE = 21, +#ifndef U_HIDE_DRAFT_API + /** + * Minimum grouping digits; most commonly set to 2 to print "1000" instead of "1,000". + * See DecimalFormat::getMinimumGroupingDigits(). + * + * For better control over grouping strategies, use UNumberFormatter. + * + * @draft ICU 64 + */ + UNUM_MINIMUM_GROUPING_DIGITS = 22, +#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_INTERNAL_API - /** Count of "regular" numeric attributes. + /** Apple addition for . + * In open-source ICU 60 and earlier, unum_formatDouble pinned + * double to string conversion at DBL_DIG=15 (from ) + * significant digits; beginning in ICU 61, several extra digit + * digits could be produced. However, by default Apple ICU + * still pins to 15 digits if UNUM_SIGNIFICANT_DIGITS_USED is + * false and UNUM_MAX_FRACTION_DIGITS > 15; this is to improve + * compatibility with Numbers. This default can be overriden + * by setting UNUM_FORMAT_WITH_FULL_PRECISION to true. * @internal */ - UNUM_NUMERIC_ATTRIBUTE_COUNT = UNUM_LENIENT_PARSE + 3, + UNUM_FORMAT_WITH_FULL_PRECISION = 48, #endif /* U_HIDE_INTERNAL_API */ -#ifndef U_HIDE_DRAFT_API /** * if this attribute is set to 0, it is set to UNUM_CURRENCY_STANDARD purpose, * otherwise it is UNUM_CURRENCY_CASH purpose * Default: 0 (UNUM_CURRENCY_STANDARD purpose) - * @draft ICU 54 + * @stable ICU 54 */ - UNUM_CURRENCY_USAGE = UNUM_LENIENT_PARSE + 4, -#endif /* U_HIDE_DRAFT_API */ + UNUM_CURRENCY_USAGE = 23, - /* The following cannot be #ifndef U_HIDE_INTERNAL_API, needed in .h file variable declararions */ +#ifndef U_HIDE_INTERNAL_API /** One below the first bitfield-boolean item. * All items after this one are stored in boolean form. * @internal */ UNUM_MAX_NONBOOLEAN_ATTRIBUTE = 0x0FFF, +#endif /* U_HIDE_INTERNAL_API */ /** If 1, specifies that if setting the "max integer digits" attribute would truncate a value, set an error status rather than silently truncating. * For example, formatting the value 1234 with 4 max int digits would succeed, but formatting 12345 would fail. There is no effect on parsing. @@ -964,24 +1082,45 @@ typedef enum UNumberFormatAttribute { * Default: 0 (unset) * @stable ICU 50 */ - UNUM_PARSE_NO_EXPONENT, + UNUM_PARSE_NO_EXPONENT = 0x1001, -#ifndef U_HIDE_DRAFT_API /** * if this attribute is set to 1, specifies that, if the pattern contains a * decimal mark the input is required to have one. If this attribute is set to 0, * specifies that input does not have to contain a decimal mark. * Has no effect on formatting. * Default: 0 (unset) - * @draft ICU 54 + * @stable ICU 54 */ - UNUM_PARSE_DECIMAL_MARK_REQUIRED = UNUM_PARSE_NO_EXPONENT+1, -#endif /* U_HIDE_DRAFT_API */ + UNUM_PARSE_DECIMAL_MARK_REQUIRED = 0x1002, + +#ifndef U_HIDE_DRAFT_API - /* The following cannot be #ifndef U_HIDE_INTERNAL_API, needed in .h file variable declararions */ - /** Limit of boolean attributes. + /** + * Parsing: if set to 1, parsing is sensitive to case (lowercase/uppercase). + * + * @draft ICU 64 + */ + UNUM_PARSE_CASE_SENSITIVE = 0x1003, + + /** + * Formatting: if set to 1, whether to show the plus sign on non-negative numbers. + * + * For better control over sign display, use UNumberFormatter. + * + * @draft ICU 64 + */ + UNUM_SIGN_ALWAYS_SHOWN = 0x1004, + +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_INTERNAL_API + /** Limit of boolean attributes. (value should + * not depend on U_HIDE conditionals) * @internal */ - UNUM_LIMIT_BOOLEAN_ATTRIBUTE = UNUM_PARSE_NO_EXPONENT+2 + UNUM_LIMIT_BOOLEAN_ATTRIBUTE = 0x1005, +#endif /* U_HIDE_INTERNAL_API */ + } UNumberFormatAttribute; /** @@ -992,7 +1131,7 @@ typedef enum UNumberFormatAttribute { * UNUM_DECIMAL_ALWAYS_SHOWN, UNUM_MAX_INTEGER_DIGITS, UNUM_MIN_INTEGER_DIGITS, UNUM_INTEGER_DIGITS, * UNUM_MAX_FRACTION_DIGITS, UNUM_MIN_FRACTION_DIGITS, UNUM_FRACTION_DIGITS, UNUM_MULTIPLIER, * UNUM_GROUPING_SIZE, UNUM_ROUNDING_MODE, UNUM_FORMAT_WIDTH, UNUM_PADDING_POSITION, UNUM_SECONDARY_GROUPING_SIZE, -* UNUM_SCALE. +* UNUM_SCALE, UNUM_MINIMUM_GROUPING_DIGITS. * @return The value of attr. * @see unum_setAttribute * @see unum_getDoubleAttribute @@ -1015,7 +1154,7 @@ unum_getAttribute(const UNumberFormat* fmt, * UNUM_DECIMAL_ALWAYS_SHOWN, UNUM_MAX_INTEGER_DIGITS, UNUM_MIN_INTEGER_DIGITS, UNUM_INTEGER_DIGITS, * UNUM_MAX_FRACTION_DIGITS, UNUM_MIN_FRACTION_DIGITS, UNUM_FRACTION_DIGITS, UNUM_MULTIPLIER, * UNUM_GROUPING_SIZE, UNUM_ROUNDING_MODE, UNUM_FORMAT_WIDTH, UNUM_PADDING_POSITION, UNUM_SECONDARY_GROUPING_SIZE, -* UNUM_LENIENT_PARSE, or UNUM_SCALE. +* UNUM_LENIENT_PARSE, UNUM_SCALE, UNUM_MINIMUM_GROUPING_DIGITS. * @param newValue The new value of attr. * @see unum_getAttribute * @see unum_getDoubleAttribute @@ -1254,15 +1393,18 @@ typedef enum UNumberFormatSymbol { */ UNUM_NINE_DIGIT_SYMBOL = 26, -#ifndef U_HIDE_DRAFT_API /** Multiplication sign - * @draft ICU 54 + * @stable ICU 54 */ UNUM_EXPONENT_MULTIPLICATION_SYMBOL = 27, -#endif /* U_HIDE_DRAFT_API */ - /** 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/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unumberformatter.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unumberformatter.h new file mode 100644 index 0000000000..e4c21a4e4a --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unumberformatter.h @@ -0,0 +1,713 @@ +// © 2018 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING +#ifndef __UNUMBERFORMATTER_H__ +#define __UNUMBERFORMATTER_H__ + +#include "unicode/parseerr.h" +#include "unicode/ufieldpositer.h" +#include "unicode/umisc.h" +#include "unicode/uformattedvalue.h" + + +/** + * \file + * \brief C-compatible API for localized number formatting; not recommended for C++. + * + * This is the C-compatible version of the NumberFormatter API introduced in ICU 60. C++ users should + * include unicode/numberformatter.h and use the proper C++ APIs. + * + * The C API accepts a number skeleton string for specifying the settings for formatting, which covers a + * very large subset of all possible number formatting features. For more information on number skeleton + * strings, see unicode/numberformatter.h. + * + * When using UNumberFormatter, which is treated as immutable, the results are exported to a mutable + * UFormattedNumber object, which you subsequently use for populating your string buffer or iterating over + * the fields. + * + * Example code: + *

      + * // Setup:
      + * UErrorCode ec = U_ZERO_ERROR;
      + * UNumberFormatter* uformatter = unumf_openForSkeletonAndLocale(u"precision-integer", -1, "en", &ec);
      + * UFormattedNumber* uresult = unumf_openResult(&ec);
      + * if (U_FAILURE(ec)) { return; }
      + *
      + * // Format a double:
      + * unumf_formatDouble(uformatter, 5142.3, uresult, &ec);
      + * if (U_FAILURE(ec)) { return; }
      + *
      + * // Export the string to a malloc'd buffer:
      + * int32_t len = unumf_resultToString(uresult, NULL, 0, &ec);
      + * // at this point, ec == U_BUFFER_OVERFLOW_ERROR
      + * ec = U_ZERO_ERROR;
      + * UChar* buffer = (UChar*) malloc((len+1)*sizeof(UChar));
      + * unumf_resultToString(uresult, buffer, len+1, &ec);
      + * if (U_FAILURE(ec)) { return; }
      + * // buffer should equal "5,142"
      + *
      + * // Cleanup:
      + * unumf_close(uformatter);
      + * unumf_closeResult(uresult);
      + * free(buffer);
      + * 
      + * + * If you are a C++ user linking against the C libraries, you can use the LocalPointer versions of these + * APIs. The following example uses LocalPointer with the decimal number and field position APIs: + * + *
      + * // Setup:
      + * LocalUNumberFormatterPointer uformatter(unumf_openForSkeletonAndLocale(u"percent", -1, "en", &ec));
      + * LocalUFormattedNumberPointer uresult(unumf_openResult(&ec));
      + * if (U_FAILURE(ec)) { return; }
      + *
      + * // Format a decimal number:
      + * unumf_formatDecimal(uformatter.getAlias(), "9.87E-3", -1, uresult.getAlias(), &ec);
      + * if (U_FAILURE(ec)) { return; }
      + *
      + * // Get the location of the percent sign:
      + * UFieldPosition ufpos = {UNUM_PERCENT_FIELD, 0, 0};
      + * unumf_resultNextFieldPosition(uresult.getAlias(), &ufpos, &ec);
      + * // ufpos should contain beginIndex=7 and endIndex=8 since the string is "0.00987%"
      + *
      + * // No need to do any cleanup since we are using LocalPointer.
      + * 
      + */ + + +#ifndef U_HIDE_DRAFT_API +/** + * An enum declaring how to render units, including currencies. Example outputs when formatting 123 USD and 123 + * meters in en-CA: + * + *

      + *

        + *
      • NARROW*: "$123.00" and "123 m" + *
      • SHORT: "US$ 123.00" and "123 m" + *
      • FULL_NAME: "123.00 US dollars" and "123 meters" + *
      • ISO_CODE: "USD 123.00" and undefined behavior + *
      • HIDDEN: "123.00" and "123" + *
      + * + *

      + * This enum is similar to {@link UMeasureFormatWidth}. + * + * @draft ICU 60 + */ +typedef enum UNumberUnitWidth { + /** + * Print an abbreviated version of the unit name. Similar to SHORT, but always use the shortest available + * abbreviation or symbol. This option can be used when the context hints at the identity of the unit. For more + * information on the difference between NARROW and SHORT, see SHORT. + * + *

      + * In CLDR, this option corresponds to the "Narrow" format for measure units and the "¤¤¤¤¤" placeholder for + * currencies. + * + * @draft ICU 60 + */ + UNUM_UNIT_WIDTH_NARROW, + + /** + * Print an abbreviated version of the unit name. Similar to NARROW, but use a slightly wider abbreviation or + * symbol when there may be ambiguity. This is the default behavior. + * + *

      + * For example, in es-US, the SHORT form for Fahrenheit is "{0} °F", but the NARROW form is "{0}°", + * since Fahrenheit is the customary unit for temperature in that locale. + * + *

      + * In CLDR, this option corresponds to the "Short" format for measure units and the "¤" placeholder for + * currencies. + * + * @draft ICU 60 + */ + UNUM_UNIT_WIDTH_SHORT, + + /** + * Print the full name of the unit, without any abbreviations. + * + *

      + * In CLDR, this option corresponds to the default format for measure units and the "¤¤¤" placeholder for + * currencies. + * + * @draft ICU 60 + */ + UNUM_UNIT_WIDTH_FULL_NAME, + + /** + * Use the three-digit ISO XXX code in place of the symbol for displaying currencies. The behavior of this + * option is currently undefined for use with measure units. + * + *

      + * In CLDR, this option corresponds to the "¤¤" placeholder for currencies. + * + * @draft ICU 60 + */ + UNUM_UNIT_WIDTH_ISO_CODE, + + /** + * Format the number according to the specified unit, but do not display the unit. For currencies, apply + * monetary symbols and formats as with SHORT, but omit the currency symbol. For measure units, the behavior is + * equivalent to not specifying the unit at all. + * + * @draft ICU 60 + */ + UNUM_UNIT_WIDTH_HIDDEN, + + /** + * One more than the highest UNumberUnitWidth value. + * + * @internal ICU 60: The numeric value may change over time; see ICU ticket #12420. + */ + UNUM_UNIT_WIDTH_COUNT +} UNumberUnitWidth; +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API +/** + * An enum declaring the strategy for when and how to display grouping separators (i.e., the + * separator, often a comma or period, after every 2-3 powers of ten). The choices are several + * pre-built strategies for different use cases that employ locale data whenever possible. Example + * outputs for 1234 and 1234567 in en-IN: + * + *

        + *
      • OFF: 1234 and 12345 + *
      • MIN2: 1234 and 12,34,567 + *
      • AUTO: 1,234 and 12,34,567 + *
      • ON_ALIGNED: 1,234 and 12,34,567 + *
      • THOUSANDS: 1,234 and 1,234,567 + *
      + * + *

      + * The default is AUTO, which displays grouping separators unless the locale data says that grouping + * is not customary. To force grouping for all numbers greater than 1000 consistently across locales, + * use ON_ALIGNED. On the other hand, to display grouping less frequently than the default, use MIN2 + * or OFF. See the docs of each option for details. + * + *

      + * Note: This enum specifies the strategy for grouping sizes. To set which character to use as the + * grouping separator, use the "symbols" setter. + * + * @draft ICU 63 + */ +typedef enum UNumberGroupingStrategy { + /** + * Do not display grouping separators in any locale. + * + * @draft ICU 61 + */ + UNUM_GROUPING_OFF, + + /** + * Display grouping using locale defaults, except do not show grouping on values smaller than + * 10000 (such that there is a minimum of two digits before the first separator). + * + *

      + * Note that locales may restrict grouping separators to be displayed only on 1 million or + * greater (for example, ee and hu) or disable grouping altogether (for example, bg currency). + * + *

      + * Locale data is used to determine whether to separate larger numbers into groups of 2 + * (customary in South Asia) or groups of 3 (customary in Europe and the Americas). + * + * @draft ICU 61 + */ + UNUM_GROUPING_MIN2, + + /** + * Display grouping using the default strategy for all locales. This is the default behavior. + * + *

      + * Note that locales may restrict grouping separators to be displayed only on 1 million or + * greater (for example, ee and hu) or disable grouping altogether (for example, bg currency). + * + *

      + * Locale data is used to determine whether to separate larger numbers into groups of 2 + * (customary in South Asia) or groups of 3 (customary in Europe and the Americas). + * + * @draft ICU 61 + */ + UNUM_GROUPING_AUTO, + + /** + * Always display the grouping separator on values of at least 1000. + * + *

      + * This option ignores the locale data that restricts or disables grouping, described in MIN2 and + * AUTO. This option may be useful to normalize the alignment of numbers, such as in a + * spreadsheet. + * + *

      + * Locale data is used to determine whether to separate larger numbers into groups of 2 + * (customary in South Asia) or groups of 3 (customary in Europe and the Americas). + * + * @draft ICU 61 + */ + UNUM_GROUPING_ON_ALIGNED, + + /** + * Use the Western defaults: groups of 3 and enabled for all numbers 1000 or greater. Do not use + * locale data for determining the grouping strategy. + * + * @draft ICU 61 + */ + UNUM_GROUPING_THOUSANDS + +#ifndef U_HIDE_INTERNAL_API + , + /** + * One more than the highest UNumberGroupingStrategy value. + * + * @internal ICU 62: The numeric value may change over time; see ICU ticket #12420. + */ + UNUM_GROUPING_COUNT +#endif /* U_HIDE_INTERNAL_API */ + +} UNumberGroupingStrategy; + + +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API +/** + * An enum declaring how to denote positive and negative numbers. Example outputs when formatting + * 123, 0, and -123 in en-US: + * + *

        + *
      • AUTO: "123", "0", and "-123" + *
      • ALWAYS: "+123", "+0", and "-123" + *
      • NEVER: "123", "0", and "123" + *
      • ACCOUNTING: "$123", "$0", and "($123)" + *
      • ACCOUNTING_ALWAYS: "+$123", "+$0", and "($123)" + *
      • EXCEPT_ZERO: "+123", "0", and "-123" + *
      • ACCOUNTING_EXCEPT_ZERO: "+$123", "$0", and "($123)" + *
      + * + *

      + * The exact format, including the position and the code point of the sign, differ by locale. + * + * @draft ICU 60 + */ +typedef enum UNumberSignDisplay { + /** + * Show the minus sign on negative numbers, and do not show the sign on positive numbers. This is the default + * behavior. + * + * @draft ICU 60 + */ + UNUM_SIGN_AUTO, + + /** + * Show the minus sign on negative numbers and the plus sign on positive numbers, including zero. + * To hide the sign on zero, see {@link UNUM_SIGN_EXCEPT_ZERO}. + * + * @draft ICU 60 + */ + UNUM_SIGN_ALWAYS, + + /** + * Do not show the sign on positive or negative numbers. + * + * @draft ICU 60 + */ + UNUM_SIGN_NEVER, + + /** + * Use the locale-dependent accounting format on negative numbers, and do not show the sign on positive numbers. + * + *

      + * The accounting format is defined in CLDR and varies by locale; in many Western locales, the format is a pair + * of parentheses around the number. + * + *

      + * Note: Since CLDR defines the accounting format in the monetary context only, this option falls back to the + * AUTO sign display strategy when formatting without a currency unit. This limitation may be lifted in the + * future. + * + * @draft ICU 60 + */ + UNUM_SIGN_ACCOUNTING, + + /** + * Use the locale-dependent accounting format on negative numbers, and show the plus sign on + * positive numbers, including zero. For more information on the accounting format, see the + * ACCOUNTING sign display strategy. To hide the sign on zero, see + * {@link UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO}. + * + * @draft ICU 60 + */ + UNUM_SIGN_ACCOUNTING_ALWAYS, + + /** + * Show the minus sign on negative numbers and the plus sign on positive numbers. Do not show a + * sign on zero. + * + * @draft ICU 61 + */ + UNUM_SIGN_EXCEPT_ZERO, + + /** + * Use the locale-dependent accounting format on negative numbers, and show the plus sign on + * positive numbers. Do not show a sign on zero. For more information on the accounting format, + * see the ACCOUNTING sign display strategy. + * + * @draft ICU 61 + */ + UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO, + + /** + * One more than the highest UNumberSignDisplay value. + * + * @internal ICU 60: The numeric value may change over time; see ICU ticket #12420. + */ + UNUM_SIGN_COUNT +} UNumberSignDisplay; +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API +/** + * An enum declaring how to render the decimal separator. + * + *

      + *

        + *
      • UNUM_DECIMAL_SEPARATOR_AUTO: "1", "1.1" + *
      • UNUM_DECIMAL_SEPARATOR_ALWAYS: "1.", "1.1" + *
      + * + * @draft ICU 60 + */ +typedef enum UNumberDecimalSeparatorDisplay { + /** + * Show the decimal separator when there are one or more digits to display after the separator, and do not show + * it otherwise. This is the default behavior. + * + * @draft ICU 60 + */ + UNUM_DECIMAL_SEPARATOR_AUTO, + + /** + * Always show the decimal separator, even if there are no digits to display after the separator. + * + * @draft ICU 60 + */ + UNUM_DECIMAL_SEPARATOR_ALWAYS, + + /** + * One more than the highest UNumberDecimalSeparatorDisplay value. + * + * @internal ICU 60: The numeric value may change over time; see ICU ticket #12420. + */ + UNUM_DECIMAL_SEPARATOR_COUNT +} UNumberDecimalSeparatorDisplay; +#endif /* U_HIDE_DRAFT_API */ + +struct UNumberFormatter; +/** + * C-compatible version of icu::number::LocalizedNumberFormatter. + * + * NOTE: This is a C-compatible API; C++ users should build against numberformatter.h instead. + * + * @stable ICU 62 + */ +typedef struct UNumberFormatter UNumberFormatter; + +struct UFormattedNumber; +/** + * C-compatible version of icu::number::FormattedNumber. + * + * NOTE: This is a C-compatible API; C++ users should build against numberformatter.h instead. + * + * @stable ICU 62 + */ +typedef struct UFormattedNumber UFormattedNumber; + + +/** + * Creates a new UNumberFormatter for the given skeleton string and locale. This is currently the only + * method for creating a new UNumberFormatter. + * + * Objects of type UNumberFormatter returned by this method are threadsafe. + * + * For more details on skeleton strings, see the documentation in numberformatter.h. For more details on + * the usage of this API, see the documentation at the top of unumberformatter.h. + * + * NOTE: This is a C-compatible API; C++ users should build against numberformatter.h instead. + * + * @param skeleton The skeleton string, like u"percent precision-integer" + * @param skeletonLen The number of UChars in the skeleton string, or -1 it it is NUL-terminated. + * @param locale The NUL-terminated locale ID. + * @param ec Set if an error occurs. + * @stable ICU 62 + */ +U_STABLE UNumberFormatter* U_EXPORT2 +unumf_openForSkeletonAndLocale(const UChar* skeleton, int32_t skeletonLen, const char* locale, + UErrorCode* ec); + + +#ifndef U_HIDE_DRAFT_API +/** + * Like unumf_openForSkeletonAndLocale, but accepts a UParseError, which will be populated with the + * location of a skeleton syntax error if such a syntax error exists. + * + * @param skeleton The skeleton string, like u"percent precision-integer" + * @param skeletonLen The number of UChars in the skeleton string, or -1 it it is NUL-terminated. + * @param locale The NUL-terminated locale ID. + * @param perror A parse error struct populated if an error occurs when parsing. Can be NULL. + * If no error occurs, perror->offset will be set to -1. + * @param ec Set if an error occurs. + * @draft ICU 64 + */ +U_DRAFT UNumberFormatter* U_EXPORT2 +unumf_openForSkeletonAndLocaleWithError( + const UChar* skeleton, int32_t skeletonLen, const char* locale, UParseError* perror, UErrorCode* ec); +#endif // U_HIDE_DRAFT_API + + +/** + * Creates an object to hold the result of a UNumberFormatter + * operation. The object can be used repeatedly; it is cleared whenever + * passed to a format function. + * + * @param ec Set if an error occurs. + * @stable ICU 62 + */ +U_STABLE UFormattedNumber* U_EXPORT2 +unumf_openResult(UErrorCode* ec); + + +/** + * Uses a UNumberFormatter to format an integer to a UFormattedNumber. A string, field position, and other + * information can be retrieved from the UFormattedNumber. + * + * The UNumberFormatter can be shared between threads. Each thread should have its own local + * UFormattedNumber, however, for storing the result of the formatting operation. + * + * NOTE: This is a C-compatible API; C++ users should build against numberformatter.h instead. + * + * @param uformatter A formatter object created by unumf_openForSkeletonAndLocale or similar. + * @param value The number to be formatted. + * @param uresult The object that will be mutated to store the result; see unumf_openResult. + * @param ec Set if an error occurs. + * @stable ICU 62 + */ +U_STABLE void U_EXPORT2 +unumf_formatInt(const UNumberFormatter* uformatter, int64_t value, UFormattedNumber* uresult, + UErrorCode* ec); + + +/** + * Uses a UNumberFormatter to format a double to a UFormattedNumber. A string, field position, and other + * information can be retrieved from the UFormattedNumber. + * + * The UNumberFormatter can be shared between threads. Each thread should have its own local + * UFormattedNumber, however, for storing the result of the formatting operation. + * + * NOTE: This is a C-compatible API; C++ users should build against numberformatter.h instead. + * + * @param uformatter A formatter object created by unumf_openForSkeletonAndLocale or similar. + * @param value The number to be formatted. + * @param uresult The object that will be mutated to store the result; see unumf_openResult. + * @param ec Set if an error occurs. + * @stable ICU 62 + */ +U_STABLE void U_EXPORT2 +unumf_formatDouble(const UNumberFormatter* uformatter, double value, UFormattedNumber* uresult, + UErrorCode* ec); + + +/** + * Uses a UNumberFormatter to format a decimal number to a UFormattedNumber. A string, field position, and + * other information can be retrieved from the UFormattedNumber. + * + * The UNumberFormatter can be shared between threads. Each thread should have its own local + * UFormattedNumber, however, for storing the result of the formatting operation. + * + * The syntax of the unformatted number is a "numeric string" as defined in the Decimal Arithmetic + * Specification, available at http://speleotrove.com/decimal + * + * NOTE: This is a C-compatible API; C++ users should build against numberformatter.h instead. + * + * @param uformatter A formatter object created by unumf_openForSkeletonAndLocale or similar. + * @param value The numeric string to be formatted. + * @param valueLen The length of the numeric string, or -1 if it is NUL-terminated. + * @param uresult The object that will be mutated to store the result; see unumf_openResult. + * @param ec Set if an error occurs. + * @stable ICU 62 + */ +U_STABLE void U_EXPORT2 +unumf_formatDecimal(const UNumberFormatter* uformatter, const char* value, int32_t valueLen, + UFormattedNumber* uresult, UErrorCode* ec); + +#ifndef U_HIDE_DRAFT_API +/** + * Returns a representation of a UFormattedNumber as a UFormattedValue, + * which can be subsequently passed to any API requiring that type. + * + * The returned object is owned by the UFormattedNumber and is valid + * only as long as the UFormattedNumber is present and unchanged in memory. + * + * You can think of this method as a cast between types. + * + * @param uresult The object containing the formatted string. + * @param ec Set if an error occurs. + * @return A UFormattedValue owned by the input object. + * @draft ICU 64 + */ +U_DRAFT const UFormattedValue* U_EXPORT2 +unumf_resultAsValue(const UFormattedNumber* uresult, UErrorCode* ec); +#endif /* U_HIDE_DRAFT_API */ + + +/** + * Extracts the result number string out of a UFormattedNumber to a UChar buffer if possible. + * If bufferCapacity is greater than the required length, a terminating NUL is written. + * If bufferCapacity is less than the required length, an error code is set. + * + * Also see ufmtval_getString, which returns a NUL-terminated string: + * + * int32_t len; + * const UChar* str = ufmtval_getString(unumf_resultAsValue(uresult, &ec), &len, &ec); + * + * NOTE: This is a C-compatible API; C++ users should build against numberformatter.h instead. + * + * @param uresult The object containing the formatted number. + * @param buffer Where to save the string output. + * @param bufferCapacity The number of UChars available in the buffer. + * @param ec Set if an error occurs. + * @return The required length. + * @stable ICU 62 + */ +U_STABLE int32_t U_EXPORT2 +unumf_resultToString(const UFormattedNumber* uresult, UChar* buffer, int32_t bufferCapacity, + UErrorCode* ec); + + +/** + * Determines the start and end indices of the next occurrence of the given field in the + * output string. This allows you to determine the locations of, for example, the integer part, + * fraction part, or symbols. + * + * This is a simpler but less powerful alternative to {@link ufmtval_nextPosition}. + * + * If a field occurs just once, calling this method will find that occurrence and return it. If a + * field occurs multiple times, this method may be called repeatedly with the following pattern: + * + *
      + * UFieldPosition ufpos = {UNUM_GROUPING_SEPARATOR_FIELD, 0, 0};
      + * while (unumf_resultNextFieldPosition(uresult, ufpos, &ec)) {
      + *   // do something with ufpos.
      + * }
      + * 
      + * + * This method is useful if you know which field to query. If you want all available field position + * information, use unumf_resultGetAllFieldPositions(). + * + * NOTE: All fields of the UFieldPosition must be initialized before calling this method. + * + * @param uresult The object containing the formatted number. + * @param ufpos + * Input+output variable. On input, the "field" property determines which field to look up, + * and the "endIndex" property determines where to begin the search. On output, the + * "beginIndex" field is set to the beginning of the first occurrence of the field after the + * input "endIndex", and "endIndex" is set to the end of that occurrence of the field + * (exclusive index). If a field position is not found, the FieldPosition is not changed and + * the method returns FALSE. + * @param ec Set if an error occurs. + * @stable ICU 62 + */ +U_STABLE UBool U_EXPORT2 +unumf_resultNextFieldPosition(const UFormattedNumber* uresult, UFieldPosition* ufpos, UErrorCode* ec); + + +/** + * Populates the given iterator with all fields in the formatted output string. This allows you to + * determine the locations of the integer part, fraction part, and sign. + * + * This is an alternative to the more powerful {@link ufmtval_nextPosition} API. + * + * If you need information on only one field, use {@link ufmtval_nextPosition} or + * {@link unumf_resultNextFieldPosition}. + * + * @param uresult The object containing the formatted number. + * @param ufpositer + * A pointer to a UFieldPositionIterator created by {@link #ufieldpositer_open}. Iteration + * information already present in the UFieldPositionIterator is deleted, and the iterator is reset + * to apply to the fields in the formatted string created by this function call. The field values + * and indexes returned by {@link #ufieldpositer_next} represent fields denoted by + * the UNumberFormatFields enum. Fields are not returned in a guaranteed order. Fields cannot + * overlap, but they may nest. For example, 1234 could format as "1,234" which might consist of a + * grouping separator field for ',' and an integer field encompassing the entire string. + * @param ec Set if an error occurs. + * @stable ICU 62 + */ +U_STABLE void U_EXPORT2 +unumf_resultGetAllFieldPositions(const UFormattedNumber* uresult, UFieldPositionIterator* ufpositer, + UErrorCode* ec); + + +/** + * Releases the UNumberFormatter created by unumf_openForSkeletonAndLocale(). + * + * @param uformatter An object created by unumf_openForSkeletonAndLocale(). + * @stable ICU 62 + */ +U_STABLE void U_EXPORT2 +unumf_close(UNumberFormatter* uformatter); + + +/** + * Releases the UFormattedNumber created by unumf_openResult(). + * + * @param uresult An object created by unumf_openResult(). + * @stable ICU 62 + */ +U_STABLE void U_EXPORT2 +unumf_closeResult(UFormattedNumber* uresult); + + +#if U_SHOW_CPLUSPLUS_API +U_NAMESPACE_BEGIN + +/** + * \class LocalUNumberFormatterPointer + * "Smart pointer" class; closes a UNumberFormatter via unumf_close(). + * For most methods see the LocalPointerBase base class. + * + * Usage: + *
      + * LocalUNumberFormatterPointer uformatter(unumf_openForSkeletonAndLocale(...));
      + * // no need to explicitly call unumf_close()
      + * 
      + * + * @see LocalPointerBase + * @see LocalPointer + * @stable ICU 62 + */ +U_DEFINE_LOCAL_OPEN_POINTER(LocalUNumberFormatterPointer, UNumberFormatter, unumf_close); + +/** + * \class LocalUFormattedNumberPointer + * "Smart pointer" class; closes a UFormattedNumber via unumf_closeResult(). + * For most methods see the LocalPointerBase base class. + * + * Usage: + *
      + * LocalUFormattedNumberPointer uformatter(unumf_openResult(...));
      + * // no need to explicitly call unumf_closeResult()
      + * 
      + * + * @see LocalPointerBase + * @see LocalPointer + * @stable ICU 62 + */ +U_DEFINE_LOCAL_OPEN_POINTER(LocalUFormattedNumberPointer, UFormattedNumber, unumf_closeResult); + +U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API + +#endif //__UNUMBERFORMATTER_H__ +#endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unumsys.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unumsys.h index f5a2c43e92..07ed6f0f8e 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unumsys.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/unumsys.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************************** * Copyright (C) 2013-2014, International Business Machines @@ -98,11 +100,12 @@ U_NAMESPACE_BEGIN U_DEFINE_LOCAL_OPEN_POINTER(LocalUNumberingSystemPointer, UNumberingSystem, unumsys_close); U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Returns an enumeration over the names of all of the predefined numbering systems known * to ICU. + * The numbering system names will be in alphabetical (invariant) order. * @param status A pointer to a UErrorCode to receive any errors. * @return A pointer to a UEnumeration that must be closed with uenum_close(), * or NULL if an error occurred. diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uobject.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uobject.h index 54ceace626..b1d7d2e1cc 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uobject.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uobject.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * @@ -6,7 +8,7 @@ * ****************************************************************************** * file name: uobject.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -18,6 +20,7 @@ #define __UOBJECT_H__ #include "unicode/utypes.h" +#include "unicode/platform.h" /** * \file @@ -25,9 +28,10 @@ */ /** - * @{ * \def U_NO_THROW - * Define this to define the throw() specification so + * Since ICU 64, use U_NOEXCEPT instead. + * + * Previously, define this to define the throw() specification so * certain functions do not throw any exceptions * * UMemory operator new methods should have the throw() specification @@ -36,14 +40,12 @@ * constructor is still called, and if the constructor references member * data, (which it typically does), the result is a segmentation violation. * - * @stable ICU 4.2 + * @stable ICU 4.2. Since ICU 64, Use U_NOEXCEPT instead. See ICU-20422. */ #ifndef U_NO_THROW #define U_NO_THROW throw() #endif -/** @} */ - /*===========================================================================*/ /* UClassID-based RTTI */ /*===========================================================================*/ @@ -90,6 +92,7 @@ */ typedef void* UClassID; +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -126,14 +129,14 @@ class U_COMMON_API UMemory { * for ICU4C C++ classes * @stable ICU 2.4 */ - static void * U_EXPORT2 operator new(size_t size) U_NO_THROW; + static void * U_EXPORT2 operator new(size_t size) U_NOEXCEPT; /** * Override for ICU4C C++ memory management. * See new(). * @stable ICU 2.4 */ - static void * U_EXPORT2 operator new[](size_t size) U_NO_THROW; + static void * U_EXPORT2 operator new[](size_t size) U_NOEXCEPT; /** * Override for ICU4C C++ memory management. @@ -143,14 +146,14 @@ class U_COMMON_API UMemory { * for ICU4C C++ classes * @stable ICU 2.4 */ - static void U_EXPORT2 operator delete(void *p) U_NO_THROW; + static void U_EXPORT2 operator delete(void *p) U_NOEXCEPT; /** * Override for ICU4C C++ memory management. * See delete(). * @stable ICU 2.4 */ - static void U_EXPORT2 operator delete[](void *p) U_NO_THROW; + static void U_EXPORT2 operator delete[](void *p) U_NOEXCEPT; #if U_HAVE_PLACEMENT_NEW /** @@ -158,14 +161,14 @@ class U_COMMON_API UMemory { * See new(). * @stable ICU 2.6 */ - static inline void * U_EXPORT2 operator new(size_t, void *ptr) U_NO_THROW { return ptr; } + static inline void * U_EXPORT2 operator new(size_t, void *ptr) U_NOEXCEPT { return ptr; } /** * Override for ICU4C C++ memory management for STL. * See delete(). * @stable ICU 2.6 */ - static inline void U_EXPORT2 operator delete(void *, void *) U_NO_THROW {} + static inline void U_EXPORT2 operator delete(void *, void *) U_NOEXCEPT {} #endif /* U_HAVE_PLACEMENT_NEW */ #if U_HAVE_DEBUG_LOCATION_NEW /** @@ -175,7 +178,7 @@ class U_COMMON_API UMemory { * @param file The file where the allocation was requested * @param line The line where the allocation was requested */ - static void * U_EXPORT2 operator new(size_t size, const char* file, int line) U_NO_THROW; + static void * U_EXPORT2 operator new(size_t size, const char* file, int line) U_NOEXCEPT; /** * This method provides a matching delete for the MFC debug new * @@ -183,7 +186,7 @@ class U_COMMON_API UMemory { * @param file The file where the allocation was requested * @param line The line where the allocation was requested */ - static void U_EXPORT2 operator delete(void* p, const char* file, int line) U_NO_THROW; + static void U_EXPORT2 operator delete(void* p, const char* file, int line) U_NOEXCEPT; #endif /* U_HAVE_DEBUG_LOCATION_NEW */ #endif /* U_OVERRIDE_CXX_ALLOCATION */ @@ -316,5 +319,6 @@ class U_COMMON_API UObject : public UMemory { #endif /* U_HIDE_INTERNAL_API */ U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/upluralrules.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/upluralrules.h index 5bcadd4bda..2554ae0ea0 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/upluralrules.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/upluralrules.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************************** * Copyright (C) 2010-2013, International Business Machines @@ -13,6 +15,13 @@ #if !UCONFIG_NO_FORMATTING #include "unicode/localpointer.h" +#include "unicode/uenum.h" +#ifndef U_HIDE_INTERNAL_API +#include "unicode/unum.h" +#endif /* U_HIDE_INTERNAL_API */ + +// Forward-declaration +struct UFormattedNumber; /** * \file @@ -52,11 +61,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 @@ -79,7 +90,7 @@ typedef struct UPluralRules UPluralRules; /**< C typedef for struct UPluralRule * @return A UPluralRules for the specified locale, or NULL if an error occurred. * @stable ICU 4.8 */ -U_STABLE UPluralRules* U_EXPORT2 +U_CAPI UPluralRules* U_EXPORT2 uplrules_open(const char *locale, UErrorCode *status); /** @@ -91,7 +102,7 @@ uplrules_open(const char *locale, UErrorCode *status); * @return A UPluralRules for the specified locale, or NULL if an error occurred. * @stable ICU 50 */ -U_DRAFT UPluralRules* U_EXPORT2 +U_CAPI UPluralRules* U_EXPORT2 uplrules_openForType(const char *locale, UPluralType type, UErrorCode *status); /** @@ -99,7 +110,7 @@ uplrules_openForType(const char *locale, UPluralType type, UErrorCode *status); * @param uplrules The UPluralRules object to close. * @stable ICU 4.8 */ -U_STABLE void U_EXPORT2 +U_CAPI void U_EXPORT2 uplrules_close(UPluralRules *uplrules); @@ -120,26 +131,94 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUPluralRulesPointer, UPluralRules, uplrules_clo U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** - * Given a number, returns the keyword of the first rule that + * Given a floating-point number, returns the keyword of the first rule that * applies to the number, according to the supplied UPluralRules object. * @param uplrules The UPluralRules object specifying the rules. * @param number The number for which the rule has to be determined. - * @param keyword The keyword of the rule that applies to number. - * @param capacity The capacity of keyword. + * @param keyword An output buffer to write the keyword of the rule that + * applies to number. + * @param capacity The capacity of the keyword buffer. * @param status A pointer to a UErrorCode to receive any errors. - * @return The length of keyword. + * @return The length of the keyword. * @stable ICU 4.8 */ -U_STABLE int32_t U_EXPORT2 +U_CAPI int32_t U_EXPORT2 uplrules_select(const UPluralRules *uplrules, double number, UChar *keyword, int32_t capacity, UErrorCode *status); +#ifndef U_HIDE_DRAFT_API +/** + * Given a formatted number, returns the keyword of the first rule + * that applies to the number, according to the supplied UPluralRules object. + * + * A UFormattedNumber allows you to specify an exponent or trailing zeros, + * which can affect the plural category. To get a UFormattedNumber, see + * {@link UNumberFormatter}. + * + * @param uplrules The UPluralRules object specifying the rules. + * @param number The formatted number for which the rule has to be determined. + * @param keyword The destination buffer for the keyword of the rule that + * applies to number. + * @param capacity The capacity of the keyword buffer. + * @param status A pointer to a UErrorCode to receive any errors. + * @return The length of the keyword. + * @draft ICU 64 + */ +U_CAPI int32_t U_EXPORT2 +uplrules_selectFormatted(const UPluralRules *uplrules, + const struct UFormattedNumber* number, + UChar *keyword, int32_t capacity, + UErrorCode *status); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_INTERNAL_API +/** + * Given a number, returns the keyword of the first rule that applies to the + * number, according to the UPluralRules object and given the number format + * specified by the UNumberFormat object. + * Note: This internal preview interface may be removed in the future if + * an architecturally cleaner solution reaches stable status. + * @param uplrules The UPluralRules object specifying the rules. + * @param number The number for which the rule has to be determined. + * @param fmt The UNumberFormat specifying how the number will be formatted + * (this can affect the plural form, e.g. "1 dollar" vs "1.0 dollars"). + * If this is NULL, the function behaves like uplrules_select. + * @param keyword An output buffer to write the keyword of the rule that + * applies to number. + * @param capacity The capacity of the keyword buffer. + * @param status A pointer to a UErrorCode to receive any errors. + * @return The length of keyword. + * @internal ICU 59 technology preview, may be removed in the future + */ +U_INTERNAL int32_t U_EXPORT2 +uplrules_selectWithFormat(const UPluralRules *uplrules, + double number, + const UNumberFormat *fmt, + UChar *keyword, int32_t capacity, + UErrorCode *status); + +#endif /* U_HIDE_INTERNAL_API */ + +/** + * Creates a string enumeration of all plural rule keywords used in this + * UPluralRules object. The rule "other" is always present by default. + * @param uplrules The UPluralRules object specifying the rules for + * a given locale. + * @param status A pointer to a UErrorCode to receive any errors. + * @return a string enumeration over plural rule keywords, or NULL + * upon error. The caller is responsible for closing the result. + * @stable ICU 59 + */ +U_STABLE UEnumeration* U_EXPORT2 +uplrules_getKeywords(const UPluralRules *uplrules, + UErrorCode *status); + #endif /* #if !UCONFIG_NO_FORMATTING */ #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/urbtok.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/urbtok.h index 936dddeafa..bab4034130 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/urbtok.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/urbtok.h @@ -1,6 +1,6 @@ /* ****************************************************************************** -* Copyright (C) 2006-2008 Apple Inc. All Rights Reserved. +* Copyright (C) 2006-2008, 2017-2018 Apple Inc. All Rights Reserved. ****************************************************************************** */ @@ -11,16 +11,65 @@ #if !UCONFIG_NO_BREAK_ITERATION -#include "unicode/utext.h" #include "unicode/ubrk.h" #include "unicode/parseerr.h" - +/** + * The interfaces here are meant to extend the functionality of the standard + * ubrk_* interfaces in ubrk.h to allow for faster batch tokenization. This + * was primarily intended for Spotlight and related processes. There are two + * versions of these: + * + * The versions prefixed urbtok_ extend the standard ICU RuleBasedBreakIterator + * class. These are intended to fully support all of the current rule syntax used + * by that class, and should urbtok_tokenize give results equivalent to a loop using a + * combination of the standard functions ubrk_next to get the next break (determining + * the length of the previous token) and ubrk_getRuleStatusVec to get a flag value + * formed as the bitwise OR of all of the values in the returnend vector, skipping all + * tokens whose flag value is -1. urbtok_tokenize is faster than such a loop since it + * assumes only one pass over the text in the forward direction, and shut skips caching + * of breaks positions and makes other simplifying assumptions. However, it may not be + * fast enough fo Spotlight. + * + * Thus we also include the versions prefixed by urbtok57_, which use a legacy ICU 57 + * version of RuleBasedBreakIterator and an Apple subclass RuleBasedTokenizer. These + * versions do not support any RuleBasedBreakIterator rule sytax enhancements from + * later than ICU 57. + * + * The two different sets of functions should not be mixed; urbtok57_getBinaryRules + * should only be used with a UBreakIterator created using urbtok57_openRules; + * urbtok57_tokenize should only be used with a UBreakIterator created using + * urbtok57_openRules or urbtok_openBinaryRules[NoCopy], etc. Similarly, the + * urbtok_ functions should only be used with other urbtok_ functions. + */ + +/** + * struct for returning token results + */ typedef struct RuleBasedTokenRange { signed long location; signed long length; } RuleBasedTokenRange; +/** + * Open a new UBreakIterator for locating text boundaries for a specified locale. + * A UBreakIterator may be used for detecting character, line, word, + * and sentence breaks in text. + * @param type The type of UBreakIterator to open: one of UBRK_CHARACTER, UBRK_WORD, + * UBRK_LINE, UBRK_SENTENCE + * @param locale The locale specifying the text-breaking conventions. Note that + * locale keys such as "lb" and "ss" may be used to modify text break behavior, + * see general discussion of BreakIterator C API. + * @param status A UErrorCode to receive any errors. + * @return A UBreakIterator for the specified type and locale. + * @see ubrk_open + * @internal + */ +U_INTERNAL UBreakIterator* U_EXPORT2 +urbtok_open(UBreakIteratorType type, + const char *locale, + UErrorCode *status); + /** * Open a new UBreakIterator for tokenizing text using specified breaking rules. * The rule syntax is ... (TBD) @@ -90,6 +139,12 @@ urbtok_getBinaryRules(UBreakIterator *bi, /** * Tokenize text using a rule-based tokenizer. + * This is primarily intended for speedy batch tokenization using very simple rules. + * It does not currently implement support for all of the features of ICU break rules + * (adding that would reduce performance). If you need support for all of the ICU rule + * features, please use the standard ubrk_* interfaces; instead of urbtok_tokenize, + * use a loop with ubrk_next and ubrk_getRuleStatus. + * * @param bi The tokenizer to use. * @param maxTokens The maximum number of tokens to return. * @param outTokens An array of RuleBasedTokenRange to fill in with the tokens. @@ -121,6 +176,95 @@ urbtok_swapBinaryRules(const uint8_t *rules, UErrorCode *status); + +/** + * Open a new UBreakIterator for tokenizing text using specified breaking rules. + * The rule syntax is ... (TBD) + * @param rules A set of rules specifying the text breaking conventions. + * @param rulesLength The number of characters in rules, or -1 if null-terminated. + * @param parseErr Receives position and context information for any syntax errors + * detected while parsing the rules. + * @param status A UErrorCode to receive any errors. + * @return A UBreakIterator for the specified rules. + * @see ubrk_open + * @internal + */ +U_INTERNAL UBreakIterator* U_EXPORT2 +urbtok57_openRules(const UChar *rules, + int32_t rulesLength, + UParseError *parseErr, + UErrorCode *status); + +/** + * Open a new UBreakIterator for tokenizing text using specified breaking rules. + * @param rules A set of rules specifying the text breaking conventions. The binary rules + * must be at least 32-bit aligned. Note: This version makes a copy of the + * rules, so after calling this function the caller can close or release + * the rules that were passed to this function. The copy created by this + * call will be freed when ubrk_close() is called on the UBreakIterator*. + * @param status A UErrorCode to receive any errors. + * @return A UBreakIterator for the specified rules. + * @see ubrk_open + * @internal + */ +U_INTERNAL UBreakIterator* U_EXPORT2 +urbtok57_openBinaryRules(const uint8_t *rules, + UErrorCode *status); + +/** + * Open a new UBreakIterator for tokenizing text using specified breaking rules. + * @param rules A set of rules specifying the text breaking conventions. The binary rules + * must be at least 32-bit aligned. Note: This version does NOT make a copy + * of the rules, so after calling this function the caller must not close or + * release the rules passed to this function until after they are finished + * with this UBreakIterator* (and any others created using the same rules) + * and have called ubrk_close() to close the UBreakIterator* (and any others + * using the same rules). + * @param status A UErrorCode to receive any errors. + * @return A UBreakIterator for the specified rules. + * @see ubrk_open + * @internal + */ +U_INTERNAL UBreakIterator* U_EXPORT2 +urbtok57_openBinaryRulesNoCopy(const uint8_t *rules, + UErrorCode *status); + +/** + * Get the (native-endian) binary break rules for this tokenizer. + * @param bi The tokenizer to use. + * @param buffer The output buffer for the rules. You can pass 0 to get the required size. + * @param buffSize The size of the output buffer. + * @param status A UErrorCode to receive any errors. + * @return The actual size of the binary rules, whether they fit the buffer or not. + * @internal + */ +U_INTERNAL uint32_t U_EXPORT2 +urbtok57_getBinaryRules(UBreakIterator *bi, + uint8_t *buffer, + uint32_t buffSize, + UErrorCode *status); + +/** + * Tokenize text using a rule-based tokenizer. + * This is primarily intended for speedy batch tokenization using very simple rules. + * It does not currently implement support for all of the features of ICU break rules + * (adding that would reduce performance). If you need support for all of the ICU rule + * features, please use the standard Apple urbtok_tokenize, or a loop with standard + * ICU interfaes ubrk_next and ubrk_getRuleStatusVec. + * + * @param bi The tokenizer to use. + * @param maxTokens The maximum number of tokens to return. + * @param outTokens An array of RuleBasedTokenRange to fill in with the tokens. + * @param outTokenFlags An (optional) array of uint32_t to fill in with token flags. + * @return The number of tokens returned, 0 if done. + * @internal + */ +U_INTERNAL int32_t U_EXPORT2 +urbtok57_tokenize(UBreakIterator *bi, + int32_t maxTokens, + RuleBasedTokenRange *outTokens, + unsigned long *outTokenFlags); + #endif /* #if !UCONFIG_NO_BREAK_ITERATION */ #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uregex.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uregex.h index b1b5d65d15..27aa3e8667 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uregex.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uregex.h @@ -1,10 +1,12 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** -* Copyright (C) 2004-2015, International Business Machines +* Copyright (C) 2004-2016, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * file name: uregex.h -* encoding: US-ASCII +* encoding: UTF-8 * indentation:4 * * created on: 2004mar09 @@ -165,6 +167,7 @@ uregex_openUText(UText *pattern, UParseError *pe, UErrorCode *status); +#if !UCONFIG_NO_CONVERSION /** * Open (compile) an ICU regular expression. The resulting regular expression * handle can then be used to perform various matching operations. @@ -188,7 +191,6 @@ uregex_openUText(UText *pattern, * * @stable ICU 3.0 */ -#if !UCONFIG_NO_CONVERSION U_STABLE URegularExpression * U_EXPORT2 uregex_openC( const char *pattern, uint32_t flags, @@ -225,7 +227,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalURegularExpressionPointer, URegularExpression, U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Make a copy of a compiled regular expression. Cloning a regular @@ -487,7 +489,7 @@ uregex_matches64(URegularExpression *regexp, * *

      If the match succeeds then more information can be obtained via the * uregexp_start(), uregexp_end(), - * and uregexp_group() functions.

      + * and uregex_group() functions.

      * * @param regexp The compiled regular expression. * @param startIndex The input string (native) index at which to begin matching, or @@ -516,7 +518,7 @@ uregex_lookingAt(URegularExpression *regexp, * *

      If the match succeeds then more information can be obtained via the * uregexp_start(), uregexp_end(), - * and uregexp_group() functions.

      + * and uregex_group() functions.

      * * @param regexp The compiled regular expression. * @param startIndex The input string (native) index at which to begin matching, or @@ -607,7 +609,6 @@ U_STABLE int32_t U_EXPORT2 uregex_groupCount(URegularExpression *regexp, UErrorCode *status); -#ifndef U_HIDE_DRAFT_API /** * Get the group number corresponding to a named capture group. * The returned number can be used with any function that access @@ -622,9 +623,9 @@ uregex_groupCount(URegularExpression *regexp, * nul-terminated string. * @param status A pointer to a UErrorCode to receive any errors. * - * @draft ICU 55 + * @stable ICU 55 */ -U_DRAFT int32_t U_EXPORT2 +U_STABLE int32_t U_EXPORT2 uregex_groupNumberFromName(URegularExpression *regexp, const UChar *groupName, int32_t nameLength, @@ -646,14 +647,13 @@ uregex_groupNumberFromName(URegularExpression *regexp, * nul-terminated. * @param status A pointer to a UErrorCode to receive any errors. * - * @draft ICU 55 + * @stable ICU 55 */ -U_DRAFT int32_t U_EXPORT2 +U_STABLE int32_t U_EXPORT2 uregex_groupNumberFromCName(URegularExpression *regexp, const char *groupName, int32_t nameLength, UErrorCode *status); -#endif /* U_HIDE_DRAFT_API */ /** Extract the string for the specified matching expression or subexpression. * Group #0 is the complete string of matched text. diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uregion.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uregion.h index 99b381ffd4..a5de49674b 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uregion.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uregion.h @@ -1,3 +1,5 @@ +// © 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/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ureldatefmt.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ureldatefmt.h new file mode 100644 index 0000000000..a276f3c9c1 --- /dev/null +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ureldatefmt.h @@ -0,0 +1,517 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* +***************************************************************************************** +* Copyright (C) 2016, International Business Machines +* Corporation and others. All Rights Reserved. +***************************************************************************************** +*/ + +#ifndef URELDATEFMT_H +#define URELDATEFMT_H + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION + +#include "unicode/unum.h" +#include "unicode/udisplaycontext.h" +#include "unicode/localpointer.h" +#include "unicode/uformattedvalue.h" + +/** + * \file + * \brief C API: URelativeDateTimeFormatter, relative date formatting of unit + numeric offset. + * + * Provides simple formatting of relative dates, in two ways + *
        + *
      • relative dates with a quantity e.g "in 5 days"
      • + *
      • relative dates without a quantity e.g "next Tuesday"
      • + *
      + *

      + * This does not provide compound formatting for multiple units, + * other than the ability to combine a time string with a relative date, + * as in "next Tuesday at 3:45 PM". It also does not provide support + * for determining which unit to use, such as deciding between "in 7 days" + * and "in 1 week". + * + * @stable ICU 57 + */ + +/** + * The formatting style + * @stable ICU 54 + */ +typedef enum UDateRelativeDateTimeFormatterStyle { + /** + * Everything spelled out. + * @stable ICU 54 + */ + UDAT_STYLE_LONG, + + /** + * Abbreviations used when possible. + * @stable ICU 54 + */ + UDAT_STYLE_SHORT, + + /** + * Use the shortest possible form. + * @stable ICU 54 + */ + UDAT_STYLE_NARROW, + +#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; + +/** + * Represents the unit for formatting a relative date. e.g "in 5 days" + * or "next year" + * @stable ICU 57 + */ +typedef enum URelativeDateTimeUnit { + /** + * Specifies that relative unit is year, e.g. "last year", + * "in 5 years". + * @stable ICU 57 + */ + UDAT_REL_UNIT_YEAR, + /** + * Specifies that relative unit is quarter, e.g. "last quarter", + * "in 5 quarters". + * @stable ICU 57 + */ + UDAT_REL_UNIT_QUARTER, + /** + * Specifies that relative unit is month, e.g. "last month", + * "in 5 months". + * @stable ICU 57 + */ + UDAT_REL_UNIT_MONTH, + /** + * Specifies that relative unit is week, e.g. "last week", + * "in 5 weeks". + * @stable ICU 57 + */ + UDAT_REL_UNIT_WEEK, + /** + * Specifies that relative unit is day, e.g. "yesterday", + * "in 5 days". + * @stable ICU 57 + */ + UDAT_REL_UNIT_DAY, + /** + * Specifies that relative unit is hour, e.g. "1 hour ago", + * "in 5 hours". + * @stable ICU 57 + */ + UDAT_REL_UNIT_HOUR, + /** + * Specifies that relative unit is minute, e.g. "1 minute ago", + * "in 5 minutes". + * @stable ICU 57 + */ + UDAT_REL_UNIT_MINUTE, + /** + * Specifies that relative unit is second, e.g. "1 second ago", + * "in 5 seconds". + * @stable ICU 57 + */ + UDAT_REL_UNIT_SECOND, + /** + * Specifies that relative unit is Sunday, e.g. "last Sunday", + * "this Sunday", "next Sunday", "in 5 Sundays". + * @stable ICU 57 + */ + UDAT_REL_UNIT_SUNDAY, + /** + * Specifies that relative unit is Monday, e.g. "last Monday", + * "this Monday", "next Monday", "in 5 Mondays". + * @stable ICU 57 + */ + UDAT_REL_UNIT_MONDAY, + /** + * Specifies that relative unit is Tuesday, e.g. "last Tuesday", + * "this Tuesday", "next Tuesday", "in 5 Tuesdays". + * @stable ICU 57 + */ + UDAT_REL_UNIT_TUESDAY, + /** + * Specifies that relative unit is Wednesday, e.g. "last Wednesday", + * "this Wednesday", "next Wednesday", "in 5 Wednesdays". + * @stable ICU 57 + */ + UDAT_REL_UNIT_WEDNESDAY, + /** + * Specifies that relative unit is Thursday, e.g. "last Thursday", + * "this Thursday", "next Thursday", "in 5 Thursdays". + * @stable ICU 57 + */ + UDAT_REL_UNIT_THURSDAY, + /** + * Specifies that relative unit is Friday, e.g. "last Friday", + * "this Friday", "next Friday", "in 5 Fridays". + * @stable ICU 57 + */ + UDAT_REL_UNIT_FRIDAY, + /** + * Specifies that relative unit is Saturday, e.g. "last Saturday", + * "this Saturday", "next Saturday", "in 5 Saturdays". + * @stable ICU 57 + */ + UDAT_REL_UNIT_SATURDAY, +#ifndef U_HIDE_DEPRECATED_API + /** + * 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; + +#ifndef U_HIDE_DRAFT_API +/** + * FieldPosition and UFieldPosition selectors for format fields + * defined by RelativeDateTimeFormatter. + * @draft ICU 64 + */ +typedef enum URelativeDateTimeFormatterField { + /** + * Represents a literal text string, like "tomorrow" or "days ago". + * @draft ICU 64 + */ + UDAT_REL_LITERAL_FIELD, + /** + * Represents a number quantity, like "3" in "3 days ago". + * @draft ICU 64 + */ + UDAT_REL_NUMERIC_FIELD, +} URelativeDateTimeFormatterField; +#endif // U_HIDE_DRAFT_API + + +/** + * Opaque URelativeDateTimeFormatter object for use in C programs. + * @stable ICU 57 + */ +struct URelativeDateTimeFormatter; +typedef struct URelativeDateTimeFormatter URelativeDateTimeFormatter; /**< C typedef for struct URelativeDateTimeFormatter. @stable ICU 57 */ + + +/** + * Open a new URelativeDateTimeFormatter object for a given locale using the + * specified width and capitalizationContext, along with a number formatter + * (if desired) to override the default formatter that would be used for + * display of numeric field offsets. The default formatter typically rounds + * toward 0 and has a minimum of 0 fraction digits and a maximum of 3 + * fraction digits (i.e. it will show as many decimal places as necessary + * up to 3, without showing trailing 0s). + * + * @param locale + * The locale + * @param nfToAdopt + * A number formatter to set for this URelativeDateTimeFormatter + * object (instead of the default decimal formatter). Ownership of + * this UNumberFormat object will pass to the URelativeDateTimeFormatter + * object (the URelativeDateTimeFormatter adopts the UNumberFormat), + * which becomes responsible for closing it. If the caller wishes to + * retain ownership of the UNumberFormat object, the caller must clone + * it (with unum_clone) and pass the clone to ureldatefmt_open. May be + * NULL to use the default decimal formatter. + * @param width + * The width - wide, short, narrow, etc. + * @param capitalizationContext + * A value from UDisplayContext that pertains to capitalization, e.g. + * UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE. + * @param status + * A pointer to a UErrorCode to receive any errors. + * @return + * A pointer to a URelativeDateTimeFormatter object for the specified locale, + * or NULL if an error occurred. + * @stable ICU 57 + */ +U_STABLE URelativeDateTimeFormatter* U_EXPORT2 +ureldatefmt_open( const char* locale, + UNumberFormat* nfToAdopt, + UDateRelativeDateTimeFormatterStyle width, + UDisplayContext capitalizationContext, + UErrorCode* status ); + +/** + * Close a URelativeDateTimeFormatter object. Once closed it may no longer be used. + * @param reldatefmt + * The URelativeDateTimeFormatter object to close. + * @stable ICU 57 + */ +U_STABLE void U_EXPORT2 +ureldatefmt_close(URelativeDateTimeFormatter *reldatefmt); + +#ifndef U_HIDE_DRAFT_API +struct UFormattedRelativeDateTime; +/** + * Opaque struct to contain the results of a URelativeDateTimeFormatter operation. + * @draft ICU 64 + */ +typedef struct UFormattedRelativeDateTime UFormattedRelativeDateTime; + +/** + * Creates an object to hold the result of a URelativeDateTimeFormatter + * operation. The object can be used repeatedly; it is cleared whenever + * passed to a format function. + * + * @param ec Set if an error occurs. + * @return A pointer needing ownership. + * @draft ICU 64 + */ +U_DRAFT UFormattedRelativeDateTime* U_EXPORT2 +ureldatefmt_openResult(UErrorCode* ec); + +/** + * Returns a representation of a UFormattedRelativeDateTime as a UFormattedValue, + * which can be subsequently passed to any API requiring that type. + * + * The returned object is owned by the UFormattedRelativeDateTime and is valid + * only as long as the UFormattedRelativeDateTime is present and unchanged in memory. + * + * You can think of this method as a cast between types. + * + * @param ufrdt The object containing the formatted string. + * @param ec Set if an error occurs. + * @return A UFormattedValue owned by the input object. + * @draft ICU 64 + */ +U_DRAFT const UFormattedValue* U_EXPORT2 +ureldatefmt_resultAsValue(const UFormattedRelativeDateTime* ufrdt, UErrorCode* ec); + +/** + * Releases the UFormattedRelativeDateTime created by ureldatefmt_openResult. + * + * @param ufrdt The object to release. + * @draft ICU 64 + */ +U_DRAFT void U_EXPORT2 +ureldatefmt_closeResult(UFormattedRelativeDateTime* ufrdt); +#endif /* U_HIDE_DRAFT_API */ + + +#if U_SHOW_CPLUSPLUS_API + +U_NAMESPACE_BEGIN + +/** + * \class LocalURelativeDateTimeFormatterPointer + * "Smart pointer" class, closes a URelativeDateTimeFormatter via ureldatefmt_close(). + * For most methods see the LocalPointerBase base class. + * + * @see LocalPointerBase + * @see LocalPointer + * @stable ICU 57 + */ +U_DEFINE_LOCAL_OPEN_POINTER(LocalURelativeDateTimeFormatterPointer, URelativeDateTimeFormatter, ureldatefmt_close); + +#ifndef U_HIDE_DRAFT_API +/** + * \class LocalUFormattedRelativeDateTimePointer + * "Smart pointer" class, closes a UFormattedRelativeDateTime via ureldatefmt_closeResult(). + * For most methods see the LocalPointerBase base class. + * + * @see LocalPointerBase + * @see LocalPointer + * @draft ICU 64 + */ +U_DEFINE_LOCAL_OPEN_POINTER(LocalUFormattedRelativeDateTimePointer, UFormattedRelativeDateTime, ureldatefmt_closeResult); +#endif /* U_HIDE_DRAFT_API */ + +U_NAMESPACE_END + +#endif // U_SHOW_CPLUSPLUS_API + +/** + * Format a combination of URelativeDateTimeUnit and numeric + * offset using a numeric style, e.g. "1 week ago", "in 1 week", + * "5 weeks ago", "in 5 weeks". + * + * @param reldatefmt + * The URelativeDateTimeFormatter object specifying the + * format conventions. + * @param offset + * The signed offset for the specified unit. This will + * be formatted according to this object's UNumberFormat + * object. + * @param unit + * The unit to use when formatting the relative + * date, e.g. UDAT_REL_UNIT_WEEK, UDAT_REL_UNIT_FRIDAY. + * @param result + * A pointer to a buffer to receive the formatted result. + * @param resultCapacity + * The maximum size of result. + * @param status + * A pointer to a UErrorCode to receive any errors. In + * case of error status, the contents of result are + * undefined. + * @return + * The length of the formatted result; may be greater + * than resultCapacity, in which case an error is returned. + * @stable ICU 57 + */ +U_STABLE int32_t U_EXPORT2 +ureldatefmt_formatNumeric( const URelativeDateTimeFormatter* reldatefmt, + double offset, + URelativeDateTimeUnit unit, + UChar* result, + int32_t resultCapacity, + UErrorCode* status); + +#ifndef U_HIDE_DRAFT_API +/** + * Format a combination of URelativeDateTimeUnit and numeric + * offset using a numeric style, e.g. "1 week ago", "in 1 week", + * "5 weeks ago", "in 5 weeks". + * + * @param reldatefmt + * The URelativeDateTimeFormatter object specifying the + * format conventions. + * @param offset + * The signed offset for the specified unit. This will + * be formatted according to this object's UNumberFormat + * object. + * @param unit + * The unit to use when formatting the relative + * date, e.g. UDAT_REL_UNIT_WEEK, UDAT_REL_UNIT_FRIDAY. + * @param result + * A pointer to a UFormattedRelativeDateTime to populate. + * @param status + * A pointer to a UErrorCode to receive any errors. In + * case of error status, the contents of result are + * undefined. + * @draft ICU 64 + */ +U_DRAFT void U_EXPORT2 +ureldatefmt_formatNumericToResult( + const URelativeDateTimeFormatter* reldatefmt, + double offset, + URelativeDateTimeUnit unit, + UFormattedRelativeDateTime* result, + UErrorCode* status); +#endif /* U_HIDE_DRAFT_API */ + +/** + * Format a combination of URelativeDateTimeUnit and numeric offset + * using a text style if possible, e.g. "last week", "this week", + * "next week", "yesterday", "tomorrow". Falls back to numeric + * style if no appropriate text term is available for the specified + * offset in the object's locale. + * + * @param reldatefmt + * The URelativeDateTimeFormatter object specifying the + * format conventions. + * @param offset + * The signed offset for the specified unit. + * @param unit + * The unit to use when formatting the relative + * date, e.g. UDAT_REL_UNIT_WEEK, UDAT_REL_UNIT_FRIDAY. + * @param result + * A pointer to a buffer to receive the formatted result. + * @param resultCapacity + * The maximum size of result. + * @param status + * A pointer to a UErrorCode to receive any errors. In + * case of error status, the contents of result are + * undefined. + * @return + * The length of the formatted result; may be greater + * than resultCapacity, in which case an error is returned. + * @stable ICU 57 + */ +U_STABLE int32_t U_EXPORT2 +ureldatefmt_format( const URelativeDateTimeFormatter* reldatefmt, + double offset, + URelativeDateTimeUnit unit, + UChar* result, + int32_t resultCapacity, + UErrorCode* status); + +#ifndef U_HIDE_DRAFT_API +/** + * Format a combination of URelativeDateTimeUnit and numeric offset + * using a text style if possible, e.g. "last week", "this week", + * "next week", "yesterday", "tomorrow". Falls back to numeric + * style if no appropriate text term is available for the specified + * offset in the object's locale. + * + * This method populates a UFormattedRelativeDateTime, which exposes more + * information than the string populated by format(). + * + * @param reldatefmt + * The URelativeDateTimeFormatter object specifying the + * format conventions. + * @param offset + * The signed offset for the specified unit. + * @param unit + * The unit to use when formatting the relative + * date, e.g. UDAT_REL_UNIT_WEEK, UDAT_REL_UNIT_FRIDAY. + * @param result + * A pointer to a UFormattedRelativeDateTime to populate. + * @param status + * A pointer to a UErrorCode to receive any errors. In + * case of error status, the contents of result are + * undefined. + * @draft ICU 64 + */ +U_DRAFT void U_EXPORT2 +ureldatefmt_formatToResult( + const URelativeDateTimeFormatter* reldatefmt, + double offset, + URelativeDateTimeUnit unit, + UFormattedRelativeDateTime* result, + UErrorCode* status); +#endif /* U_HIDE_DRAFT_API */ + +/** + * Combines a relative date string and a time string in this object's + * locale. This is done with the same date-time separator used for the + * default calendar in this locale to produce a result such as + * "yesterday at 3:45 PM". + * + * @param reldatefmt + * The URelativeDateTimeFormatter object specifying the format conventions. + * @param relativeDateString + * The relative date string. + * @param relativeDateStringLen + * The length of relativeDateString; may be -1 if relativeDateString + * is zero-terminated. + * @param timeString + * The time string. + * @param timeStringLen + * The length of timeString; may be -1 if timeString is zero-terminated. + * @param result + * A pointer to a buffer to receive the formatted result. + * @param resultCapacity + * The maximum size of result. + * @param status + * A pointer to a UErrorCode to receive any errors. In case of error status, + * the contents of result are undefined. + * @return + * The length of the formatted result; may be greater than resultCapacity, + * in which case an error is returned. + * @stable ICU 57 + */ +U_STABLE int32_t U_EXPORT2 +ureldatefmt_combineDateAndTime( const URelativeDateTimeFormatter* reldatefmt, + const UChar * relativeDateString, + int32_t relativeDateStringLen, + const UChar * timeString, + int32_t timeStringLen, + UChar* result, + int32_t resultCapacity, + UErrorCode* status ); + +#endif /* !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION */ + +#endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/urename.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/urename.h index 313f271ab3..eaf56c9614 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/urename.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/urename.h @@ -1,11 +1,13 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* -* Copyright (C) 2002-2015, International Business Machines +* Copyright (C) 2002-2016, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* * * file name: urename.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -31,6 +33,9 @@ #if !U_DISABLE_RENAMING +// Disable Renaming for Visual Studio's IntelliSense feature, so that 'Go-to-Definition' (F12) will work. +#if !(defined(_MSC_VER) && defined(__INTELLISENSE__)) + /* We need the U_ICU_ENTRY_POINT_RENAME definition. There's a default one in unicode/uvernum.h we can use, but we will give the platform a chance to define it first. Normally (if utypes.h or umachine.h was included first) this will not be necessary as it will already be defined. @@ -98,13 +103,19 @@ #define _UTF16BEData U_ICU_ENTRY_POINT_RENAME(_UTF16BEData) #define _UTF16Data U_ICU_ENTRY_POINT_RENAME(_UTF16Data) #define _UTF16LEData U_ICU_ENTRY_POINT_RENAME(_UTF16LEData) +#define _UTF16v2Data U_ICU_ENTRY_POINT_RENAME(_UTF16v2Data) #define _UTF32BEData U_ICU_ENTRY_POINT_RENAME(_UTF32BEData) #define _UTF32Data U_ICU_ENTRY_POINT_RENAME(_UTF32Data) #define _UTF32LEData U_ICU_ENTRY_POINT_RENAME(_UTF32LEData) #define _UTF7Data U_ICU_ENTRY_POINT_RENAME(_UTF7Data) #define _UTF8Data U_ICU_ENTRY_POINT_RENAME(_UTF8Data) +#define _isUnicodeLocaleTypeSubtag U_ICU_ENTRY_POINT_RENAME(_isUnicodeLocaleTypeSubtag) +#define allowedHourFormatsCleanup U_ICU_ENTRY_POINT_RENAME(allowedHourFormatsCleanup) #define cmemory_cleanup U_ICU_ENTRY_POINT_RENAME(cmemory_cleanup) +#define dayPeriodRulesCleanup U_ICU_ENTRY_POINT_RENAME(dayPeriodRulesCleanup) +#define deleteAllowedHourFormats U_ICU_ENTRY_POINT_RENAME(deleteAllowedHourFormats) #define gTimeZoneFilesInitOnce U_ICU_ENTRY_POINT_RENAME(gTimeZoneFilesInitOnce) +#define initNumsysNames U_ICU_ENTRY_POINT_RENAME(initNumsysNames) #define izrule_clone U_ICU_ENTRY_POINT_RENAME(izrule_clone) #define izrule_close U_ICU_ENTRY_POINT_RENAME(izrule_close) #define izrule_equals U_ICU_ENTRY_POINT_RENAME(izrule_equals) @@ -119,20 +130,11 @@ #define izrule_getStaticClassID U_ICU_ENTRY_POINT_RENAME(izrule_getStaticClassID) #define izrule_isEquivalentTo U_ICU_ENTRY_POINT_RENAME(izrule_isEquivalentTo) #define izrule_open U_ICU_ENTRY_POINT_RENAME(izrule_open) -#define le_close U_ICU_ENTRY_POINT_RENAME(le_close) -#define le_create U_ICU_ENTRY_POINT_RENAME(le_create) -#define le_getCharIndices U_ICU_ENTRY_POINT_RENAME(le_getCharIndices) -#define le_getCharIndicesWithBase U_ICU_ENTRY_POINT_RENAME(le_getCharIndicesWithBase) -#define le_getGlyphCount U_ICU_ENTRY_POINT_RENAME(le_getGlyphCount) -#define le_getGlyphPosition U_ICU_ENTRY_POINT_RENAME(le_getGlyphPosition) -#define le_getGlyphPositions U_ICU_ENTRY_POINT_RENAME(le_getGlyphPositions) -#define le_getGlyphs U_ICU_ENTRY_POINT_RENAME(le_getGlyphs) -#define le_layoutChars U_ICU_ENTRY_POINT_RENAME(le_layoutChars) -#define le_reset U_ICU_ENTRY_POINT_RENAME(le_reset) #define locale_getKeywords U_ICU_ENTRY_POINT_RENAME(locale_getKeywords) #define locale_getKeywordsStart U_ICU_ENTRY_POINT_RENAME(locale_getKeywordsStart) #define locale_get_default U_ICU_ENTRY_POINT_RENAME(locale_get_default) #define locale_set_default U_ICU_ENTRY_POINT_RENAME(locale_set_default) +#define numSysCleanup U_ICU_ENTRY_POINT_RENAME(numSysCleanup) #define pl_addFontRun U_ICU_ENTRY_POINT_RENAME(pl_addFontRun) #define pl_addLocaleRun U_ICU_ENTRY_POINT_RENAME(pl_addLocaleRun) #define pl_addValueRun U_ICU_ENTRY_POINT_RENAME(pl_addValueRun) @@ -257,12 +259,14 @@ #define u_fstropen U_ICU_ENTRY_POINT_RENAME(u_fstropen) #define u_fungetc U_ICU_ENTRY_POINT_RENAME(u_fungetc) #define u_getBidiPairedBracket U_ICU_ENTRY_POINT_RENAME(u_getBidiPairedBracket) +#define u_getBinaryPropertySet U_ICU_ENTRY_POINT_RENAME(u_getBinaryPropertySet) #define u_getCombiningClass U_ICU_ENTRY_POINT_RENAME(u_getCombiningClass) #define u_getDataDirectory U_ICU_ENTRY_POINT_RENAME(u_getDataDirectory) #define u_getDataVersion U_ICU_ENTRY_POINT_RENAME(u_getDataVersion) #define u_getDefaultConverter U_ICU_ENTRY_POINT_RENAME(u_getDefaultConverter) #define u_getFC_NFKC_Closure U_ICU_ENTRY_POINT_RENAME(u_getFC_NFKC_Closure) #define u_getISOComment U_ICU_ENTRY_POINT_RENAME(u_getISOComment) +#define u_getIntPropertyMap U_ICU_ENTRY_POINT_RENAME(u_getIntPropertyMap) #define u_getIntPropertyMaxValue U_ICU_ENTRY_POINT_RENAME(u_getIntPropertyMaxValue) #define u_getIntPropertyMinValue U_ICU_ENTRY_POINT_RENAME(u_getIntPropertyMinValue) #define u_getIntPropertyValue U_ICU_ENTRY_POINT_RENAME(u_getIntPropertyValue) @@ -449,7 +453,6 @@ #define ubidi_getReorderingOptions U_ICU_ENTRY_POINT_RENAME(ubidi_getReorderingOptions) #define ubidi_getResultLength U_ICU_ENTRY_POINT_RENAME(ubidi_getResultLength) #define ubidi_getRuns U_ICU_ENTRY_POINT_RENAME(ubidi_getRuns) -#define ubidi_getSingleton U_ICU_ENTRY_POINT_RENAME(ubidi_getSingleton) #define ubidi_getText U_ICU_ENTRY_POINT_RENAME(ubidi_getText) #define ubidi_getVisualIndex U_ICU_ENTRY_POINT_RENAME(ubidi_getVisualIndex) #define ubidi_getVisualMap U_ICU_ENTRY_POINT_RENAME(ubidi_getVisualMap) @@ -474,6 +477,9 @@ #define ubidi_setReorderingOptions U_ICU_ENTRY_POINT_RENAME(ubidi_setReorderingOptions) #define ubidi_writeReordered U_ICU_ENTRY_POINT_RENAME(ubidi_writeReordered) #define ubidi_writeReverse U_ICU_ENTRY_POINT_RENAME(ubidi_writeReverse) +#define ubiditransform_close U_ICU_ENTRY_POINT_RENAME(ubiditransform_close) +#define ubiditransform_open U_ICU_ENTRY_POINT_RENAME(ubiditransform_open) +#define ubiditransform_transform U_ICU_ENTRY_POINT_RENAME(ubiditransform_transform) #define ublock_getCode U_ICU_ENTRY_POINT_RENAME(ublock_getCode) #define ubrk_close U_ICU_ENTRY_POINT_RENAME(ubrk_close) #define ubrk_countAvailable U_ICU_ENTRY_POINT_RENAME(ubrk_countAvailable) @@ -481,6 +487,7 @@ #define ubrk_first U_ICU_ENTRY_POINT_RENAME(ubrk_first) #define ubrk_following U_ICU_ENTRY_POINT_RENAME(ubrk_following) #define ubrk_getAvailable U_ICU_ENTRY_POINT_RENAME(ubrk_getAvailable) +#define ubrk_getBinaryRules U_ICU_ENTRY_POINT_RENAME(ubrk_getBinaryRules) #define ubrk_getLocaleByType U_ICU_ENTRY_POINT_RENAME(ubrk_getLocaleByType) #define ubrk_getRuleStatus U_ICU_ENTRY_POINT_RENAME(ubrk_getRuleStatus) #define ubrk_getRuleStatusVec U_ICU_ENTRY_POINT_RENAME(ubrk_getRuleStatusVec) @@ -488,6 +495,7 @@ #define ubrk_last U_ICU_ENTRY_POINT_RENAME(ubrk_last) #define ubrk_next U_ICU_ENTRY_POINT_RENAME(ubrk_next) #define ubrk_open U_ICU_ENTRY_POINT_RENAME(ubrk_open) +#define ubrk_openBinaryRules U_ICU_ENTRY_POINT_RENAME(ubrk_openBinaryRules) #define ubrk_openRules U_ICU_ENTRY_POINT_RENAME(ubrk_openRules) #define ubrk_preceding U_ICU_ENTRY_POINT_RENAME(ubrk_preceding) #define ubrk_previous U_ICU_ENTRY_POINT_RENAME(ubrk_previous) @@ -549,7 +557,7 @@ #define ucase_addStringCaseClosure U_ICU_ENTRY_POINT_RENAME(ucase_addStringCaseClosure) #define ucase_fold U_ICU_ENTRY_POINT_RENAME(ucase_fold) #define ucase_getCaseLocale U_ICU_ENTRY_POINT_RENAME(ucase_getCaseLocale) -#define ucase_getSingleton U_ICU_ENTRY_POINT_RENAME(ucase_getSingleton) +#define ucase_getTrie U_ICU_ENTRY_POINT_RENAME(ucase_getTrie) #define ucase_getType U_ICU_ENTRY_POINT_RENAME(ucase_getType) #define ucase_getTypeOrIgnorable U_ICU_ENTRY_POINT_RENAME(ucase_getTypeOrIgnorable) #define ucase_hasBinaryProperty U_ICU_ENTRY_POINT_RENAME(ucase_hasBinaryProperty) @@ -577,6 +585,18 @@ #define ucasemap_utf8ToLower U_ICU_ENTRY_POINT_RENAME(ucasemap_utf8ToLower) #define ucasemap_utf8ToTitle U_ICU_ENTRY_POINT_RENAME(ucasemap_utf8ToTitle) #define ucasemap_utf8ToUpper U_ICU_ENTRY_POINT_RENAME(ucasemap_utf8ToUpper) +#define ucfpos_close U_ICU_ENTRY_POINT_RENAME(ucfpos_close) +#define ucfpos_constrainCategory U_ICU_ENTRY_POINT_RENAME(ucfpos_constrainCategory) +#define ucfpos_constrainField U_ICU_ENTRY_POINT_RENAME(ucfpos_constrainField) +#define ucfpos_getCategory U_ICU_ENTRY_POINT_RENAME(ucfpos_getCategory) +#define ucfpos_getField U_ICU_ENTRY_POINT_RENAME(ucfpos_getField) +#define ucfpos_getIndexes U_ICU_ENTRY_POINT_RENAME(ucfpos_getIndexes) +#define ucfpos_getInt64IterationContext U_ICU_ENTRY_POINT_RENAME(ucfpos_getInt64IterationContext) +#define ucfpos_matchesField U_ICU_ENTRY_POINT_RENAME(ucfpos_matchesField) +#define ucfpos_open U_ICU_ENTRY_POINT_RENAME(ucfpos_open) +#define ucfpos_reset U_ICU_ENTRY_POINT_RENAME(ucfpos_reset) +#define ucfpos_setInt64IterationContext U_ICU_ENTRY_POINT_RENAME(ucfpos_setInt64IterationContext) +#define ucfpos_setState U_ICU_ENTRY_POINT_RENAME(ucfpos_setState) #define uchar_addPropertyStarts U_ICU_ENTRY_POINT_RENAME(uchar_addPropertyStarts) #define uchar_swapNames U_ICU_ENTRY_POINT_RENAME(uchar_swapNames) #define ucln_cleanupOne U_ICU_ENTRY_POINT_RENAME(ucln_cleanupOne) @@ -613,6 +633,7 @@ #define ucnv_createConverterFromPackage U_ICU_ENTRY_POINT_RENAME(ucnv_createConverterFromPackage) #define ucnv_createConverterFromSharedData U_ICU_ENTRY_POINT_RENAME(ucnv_createConverterFromSharedData) #define ucnv_detectUnicodeSignature U_ICU_ENTRY_POINT_RENAME(ucnv_detectUnicodeSignature) +#define ucnv_enableCleanup U_ICU_ENTRY_POINT_RENAME(ucnv_enableCleanup) #define ucnv_extContinueMatchFromU U_ICU_ENTRY_POINT_RENAME(ucnv_extContinueMatchFromU) #define ucnv_extContinueMatchToU U_ICU_ENTRY_POINT_RENAME(ucnv_extContinueMatchToU) #define ucnv_extGetUnicodeSet U_ICU_ENTRY_POINT_RENAME(ucnv_extGetUnicodeSet) @@ -762,6 +783,20 @@ #define ucol_swap U_ICU_ENTRY_POINT_RENAME(ucol_swap) #define ucol_swapInverseUCA U_ICU_ENTRY_POINT_RENAME(ucol_swapInverseUCA) #define ucol_tertiaryOrder U_ICU_ENTRY_POINT_RENAME(ucol_tertiaryOrder) +#define ucpmap_get U_ICU_ENTRY_POINT_RENAME(ucpmap_get) +#define ucpmap_getRange U_ICU_ENTRY_POINT_RENAME(ucpmap_getRange) +#define ucptrie_close U_ICU_ENTRY_POINT_RENAME(ucptrie_close) +#define ucptrie_get U_ICU_ENTRY_POINT_RENAME(ucptrie_get) +#define ucptrie_getRange U_ICU_ENTRY_POINT_RENAME(ucptrie_getRange) +#define ucptrie_getType U_ICU_ENTRY_POINT_RENAME(ucptrie_getType) +#define ucptrie_getValueWidth U_ICU_ENTRY_POINT_RENAME(ucptrie_getValueWidth) +#define ucptrie_internalGetRange U_ICU_ENTRY_POINT_RENAME(ucptrie_internalGetRange) +#define ucptrie_internalSmallIndex U_ICU_ENTRY_POINT_RENAME(ucptrie_internalSmallIndex) +#define ucptrie_internalSmallU8Index U_ICU_ENTRY_POINT_RENAME(ucptrie_internalSmallU8Index) +#define ucptrie_internalU8PrevIndex U_ICU_ENTRY_POINT_RENAME(ucptrie_internalU8PrevIndex) +#define ucptrie_openFromBinary U_ICU_ENTRY_POINT_RENAME(ucptrie_openFromBinary) +#define ucptrie_swap U_ICU_ENTRY_POINT_RENAME(ucptrie_swap) +#define ucptrie_toBinary U_ICU_ENTRY_POINT_RENAME(ucptrie_toBinary) #define ucsdet_close U_ICU_ENTRY_POINT_RENAME(ucsdet_close) #define ucsdet_detect U_ICU_ENTRY_POINT_RENAME(ucsdet_detect) #define ucsdet_detectAll U_ICU_ENTRY_POINT_RENAME(ucsdet_detectAll) @@ -861,6 +896,7 @@ #define udatpg_getBestPatternWithOptions U_ICU_ENTRY_POINT_RENAME(udatpg_getBestPatternWithOptions) #define udatpg_getDateTimeFormat U_ICU_ENTRY_POINT_RENAME(udatpg_getDateTimeFormat) #define udatpg_getDecimal U_ICU_ENTRY_POINT_RENAME(udatpg_getDecimal) +#define udatpg_getFieldDisplayName U_ICU_ENTRY_POINT_RENAME(udatpg_getFieldDisplayName) #define udatpg_getPatternForSkeleton U_ICU_ENTRY_POINT_RENAME(udatpg_getPatternForSkeleton) #define udatpg_getSkeleton U_ICU_ENTRY_POINT_RENAME(udatpg_getSkeleton) #define udatpg_open U_ICU_ENTRY_POINT_RENAME(udatpg_open) @@ -875,8 +911,12 @@ #define udatpg_setDecimal U_ICU_ENTRY_POINT_RENAME(udatpg_setDecimal) #define udict_swap U_ICU_ENTRY_POINT_RENAME(udict_swap) #define udtitvfmt_close U_ICU_ENTRY_POINT_RENAME(udtitvfmt_close) +#define udtitvfmt_closeResult U_ICU_ENTRY_POINT_RENAME(udtitvfmt_closeResult) #define udtitvfmt_format U_ICU_ENTRY_POINT_RENAME(udtitvfmt_format) +#define udtitvfmt_formatToResult U_ICU_ENTRY_POINT_RENAME(udtitvfmt_formatToResult) #define udtitvfmt_open U_ICU_ENTRY_POINT_RENAME(udtitvfmt_open) +#define udtitvfmt_openResult U_ICU_ENTRY_POINT_RENAME(udtitvfmt_openResult) +#define udtitvfmt_resultAsValue U_ICU_ENTRY_POINT_RENAME(udtitvfmt_resultAsValue) #define uenum_close U_ICU_ENTRY_POINT_RENAME(uenum_close) #define uenum_count U_ICU_ENTRY_POINT_RENAME(uenum_count) #define uenum_next U_ICU_ENTRY_POINT_RENAME(uenum_next) @@ -916,6 +956,8 @@ #define ufmt_ptou U_ICU_ENTRY_POINT_RENAME(ufmt_ptou) #define ufmt_uto64 U_ICU_ENTRY_POINT_RENAME(ufmt_uto64) #define ufmt_utop U_ICU_ENTRY_POINT_RENAME(ufmt_utop) +#define ufmtval_getString U_ICU_ENTRY_POINT_RENAME(ufmtval_getString) +#define ufmtval_nextPosition U_ICU_ENTRY_POINT_RENAME(ufmtval_nextPosition) #define ugender_getInstance U_ICU_ENTRY_POINT_RENAME(ugender_getInstance) #define ugender_getListGender U_ICU_ENTRY_POINT_RENAME(ugender_getListGender) #define uhash_close U_ICU_ENTRY_POINT_RENAME(uhash_close) @@ -944,6 +986,7 @@ #define uhash_iget U_ICU_ENTRY_POINT_RENAME(uhash_iget) #define uhash_igeti U_ICU_ENTRY_POINT_RENAME(uhash_igeti) #define uhash_init U_ICU_ENTRY_POINT_RENAME(uhash_init) +#define uhash_initSize U_ICU_ENTRY_POINT_RENAME(uhash_initSize) #define uhash_iput U_ICU_ENTRY_POINT_RENAME(uhash_iput) #define uhash_iputi U_ICU_ENTRY_POINT_RENAME(uhash_iputi) #define uhash_iremove U_ICU_ENTRY_POINT_RENAME(uhash_iremove) @@ -1013,11 +1056,16 @@ #define ulist_getListSize U_ICU_ENTRY_POINT_RENAME(ulist_getListSize) #define ulist_getNext U_ICU_ENTRY_POINT_RENAME(ulist_getNext) #define ulist_next_keyword_value U_ICU_ENTRY_POINT_RENAME(ulist_next_keyword_value) +#define ulist_removeString U_ICU_ENTRY_POINT_RENAME(ulist_removeString) #define ulist_resetList U_ICU_ENTRY_POINT_RENAME(ulist_resetList) #define ulist_reset_keyword_values_iterator U_ICU_ENTRY_POINT_RENAME(ulist_reset_keyword_values_iterator) #define ulistfmt_close U_ICU_ENTRY_POINT_RENAME(ulistfmt_close) +#define ulistfmt_closeResult U_ICU_ENTRY_POINT_RENAME(ulistfmt_closeResult) #define ulistfmt_format U_ICU_ENTRY_POINT_RENAME(ulistfmt_format) +#define ulistfmt_formatStringsToResult U_ICU_ENTRY_POINT_RENAME(ulistfmt_formatStringsToResult) #define ulistfmt_open U_ICU_ENTRY_POINT_RENAME(ulistfmt_open) +#define ulistfmt_openResult U_ICU_ENTRY_POINT_RENAME(ulistfmt_openResult) +#define ulistfmt_resultAsValue U_ICU_ENTRY_POINT_RENAME(ulistfmt_resultAsValue) #define uloc_acceptLanguage U_ICU_ENTRY_POINT_RENAME(uloc_acceptLanguage) #define uloc_acceptLanguageFromHTTP U_ICU_ENTRY_POINT_RENAME(uloc_acceptLanguageFromHTTP) #define uloc_addLikelySubtags U_ICU_ENTRY_POINT_RENAME(uloc_addLikelySubtags) @@ -1075,15 +1123,30 @@ #define ulocdata_getPaperSize U_ICU_ENTRY_POINT_RENAME(ulocdata_getPaperSize) #define ulocdata_open U_ICU_ENTRY_POINT_RENAME(ulocdata_open) #define ulocdata_setNoSubstitute U_ICU_ENTRY_POINT_RENAME(ulocdata_setNoSubstitute) +#define ulocimp_addLikelySubtags U_ICU_ENTRY_POINT_RENAME(ulocimp_addLikelySubtags) +#define ulocimp_forLanguageTag U_ICU_ENTRY_POINT_RENAME(ulocimp_forLanguageTag) #define ulocimp_getCountry U_ICU_ENTRY_POINT_RENAME(ulocimp_getCountry) #define ulocimp_getLanguage U_ICU_ENTRY_POINT_RENAME(ulocimp_getLanguage) +#define ulocimp_getRegionForSupplementalData U_ICU_ENTRY_POINT_RENAME(ulocimp_getRegionForSupplementalData) #define ulocimp_getScript U_ICU_ENTRY_POINT_RENAME(ulocimp_getScript) +#define ulocimp_minimizeSubtags U_ICU_ENTRY_POINT_RENAME(ulocimp_minimizeSubtags) #define ulocimp_toBcpKey U_ICU_ENTRY_POINT_RENAME(ulocimp_toBcpKey) #define ulocimp_toBcpType U_ICU_ENTRY_POINT_RENAME(ulocimp_toBcpType) +#define ulocimp_toLanguageTag U_ICU_ENTRY_POINT_RENAME(ulocimp_toLanguageTag) #define ulocimp_toLegacyKey U_ICU_ENTRY_POINT_RENAME(ulocimp_toLegacyKey) #define ulocimp_toLegacyType U_ICU_ENTRY_POINT_RENAME(ulocimp_toLegacyType) +#define ultag_isExtensionSubtags U_ICU_ENTRY_POINT_RENAME(ultag_isExtensionSubtags) +#define ultag_isLanguageSubtag U_ICU_ENTRY_POINT_RENAME(ultag_isLanguageSubtag) +#define ultag_isPrivateuseValueSubtags U_ICU_ENTRY_POINT_RENAME(ultag_isPrivateuseValueSubtags) +#define ultag_isRegionSubtag U_ICU_ENTRY_POINT_RENAME(ultag_isRegionSubtag) +#define ultag_isScriptSubtag U_ICU_ENTRY_POINT_RENAME(ultag_isScriptSubtag) +#define ultag_isTransformedExtensionSubtags U_ICU_ENTRY_POINT_RENAME(ultag_isTransformedExtensionSubtags) +#define ultag_isUnicodeExtensionSubtags U_ICU_ENTRY_POINT_RENAME(ultag_isUnicodeExtensionSubtags) +#define ultag_isUnicodeLocaleAttribute U_ICU_ENTRY_POINT_RENAME(ultag_isUnicodeLocaleAttribute) +#define ultag_isUnicodeLocaleAttributes U_ICU_ENTRY_POINT_RENAME(ultag_isUnicodeLocaleAttributes) #define ultag_isUnicodeLocaleKey U_ICU_ENTRY_POINT_RENAME(ultag_isUnicodeLocaleKey) #define ultag_isUnicodeLocaleType U_ICU_ENTRY_POINT_RENAME(ultag_isUnicodeLocaleType) +#define ultag_isVariantSubtags U_ICU_ENTRY_POINT_RENAME(ultag_isVariantSubtags) #define umsg_applyPattern U_ICU_ENTRY_POINT_RENAME(umsg_applyPattern) #define umsg_autoQuoteApostrophe U_ICU_ENTRY_POINT_RENAME(umsg_autoQuoteApostrophe) #define umsg_clone U_ICU_ENTRY_POINT_RENAME(umsg_clone) @@ -1101,6 +1164,16 @@ #define umtx_condWait U_ICU_ENTRY_POINT_RENAME(umtx_condWait) #define umtx_lock U_ICU_ENTRY_POINT_RENAME(umtx_lock) #define umtx_unlock U_ICU_ENTRY_POINT_RENAME(umtx_unlock) +#define umutablecptrie_buildImmutable U_ICU_ENTRY_POINT_RENAME(umutablecptrie_buildImmutable) +#define umutablecptrie_clone U_ICU_ENTRY_POINT_RENAME(umutablecptrie_clone) +#define umutablecptrie_close U_ICU_ENTRY_POINT_RENAME(umutablecptrie_close) +#define umutablecptrie_fromUCPMap U_ICU_ENTRY_POINT_RENAME(umutablecptrie_fromUCPMap) +#define umutablecptrie_fromUCPTrie U_ICU_ENTRY_POINT_RENAME(umutablecptrie_fromUCPTrie) +#define umutablecptrie_get U_ICU_ENTRY_POINT_RENAME(umutablecptrie_get) +#define umutablecptrie_getRange U_ICU_ENTRY_POINT_RENAME(umutablecptrie_getRange) +#define umutablecptrie_open U_ICU_ENTRY_POINT_RENAME(umutablecptrie_open) +#define umutablecptrie_set U_ICU_ENTRY_POINT_RENAME(umutablecptrie_set) +#define umutablecptrie_setRange U_ICU_ENTRY_POINT_RENAME(umutablecptrie_setRange) #define uniset_getUnicode32Instance U_ICU_ENTRY_POINT_RENAME(uniset_getUnicode32Instance) #define unorm2_append U_ICU_ENTRY_POINT_RENAME(unorm2_append) #define unorm2_close U_ICU_ENTRY_POINT_RENAME(unorm2_close) @@ -1143,6 +1216,7 @@ #define unum_formatDecimal U_ICU_ENTRY_POINT_RENAME(unum_formatDecimal) #define unum_formatDouble U_ICU_ENTRY_POINT_RENAME(unum_formatDouble) #define unum_formatDoubleCurrency U_ICU_ENTRY_POINT_RENAME(unum_formatDoubleCurrency) +#define unum_formatDoubleForFields U_ICU_ENTRY_POINT_RENAME(unum_formatDoubleForFields) #define unum_formatInt64 U_ICU_ENTRY_POINT_RENAME(unum_formatInt64) #define unum_formatUFormattable U_ICU_ENTRY_POINT_RENAME(unum_formatUFormattable) #define unum_getAttribute U_ICU_ENTRY_POINT_RENAME(unum_getAttribute) @@ -1165,6 +1239,18 @@ #define unum_setSymbol U_ICU_ENTRY_POINT_RENAME(unum_setSymbol) #define unum_setTextAttribute U_ICU_ENTRY_POINT_RENAME(unum_setTextAttribute) #define unum_toPattern U_ICU_ENTRY_POINT_RENAME(unum_toPattern) +#define unumf_close U_ICU_ENTRY_POINT_RENAME(unumf_close) +#define unumf_closeResult U_ICU_ENTRY_POINT_RENAME(unumf_closeResult) +#define unumf_formatDecimal U_ICU_ENTRY_POINT_RENAME(unumf_formatDecimal) +#define unumf_formatDouble U_ICU_ENTRY_POINT_RENAME(unumf_formatDouble) +#define unumf_formatInt U_ICU_ENTRY_POINT_RENAME(unumf_formatInt) +#define unumf_openForSkeletonAndLocale U_ICU_ENTRY_POINT_RENAME(unumf_openForSkeletonAndLocale) +#define unumf_openForSkeletonAndLocaleWithError U_ICU_ENTRY_POINT_RENAME(unumf_openForSkeletonAndLocaleWithError) +#define unumf_openResult U_ICU_ENTRY_POINT_RENAME(unumf_openResult) +#define unumf_resultAsValue U_ICU_ENTRY_POINT_RENAME(unumf_resultAsValue) +#define unumf_resultGetAllFieldPositions U_ICU_ENTRY_POINT_RENAME(unumf_resultGetAllFieldPositions) +#define unumf_resultNextFieldPosition U_ICU_ENTRY_POINT_RENAME(unumf_resultNextFieldPosition) +#define unumf_resultToString U_ICU_ENTRY_POINT_RENAME(unumf_resultToString) #define unumsys_close U_ICU_ENTRY_POINT_RENAME(unumsys_close) #define unumsys_getDescription U_ICU_ENTRY_POINT_RENAME(unumsys_getDescription) #define unumsys_getName U_ICU_ENTRY_POINT_RENAME(unumsys_getName) @@ -1174,9 +1260,12 @@ #define unumsys_openAvailableNames U_ICU_ENTRY_POINT_RENAME(unumsys_openAvailableNames) #define unumsys_openByName U_ICU_ENTRY_POINT_RENAME(unumsys_openByName) #define uplrules_close U_ICU_ENTRY_POINT_RENAME(uplrules_close) +#define uplrules_getKeywords U_ICU_ENTRY_POINT_RENAME(uplrules_getKeywords) #define uplrules_open U_ICU_ENTRY_POINT_RENAME(uplrules_open) #define uplrules_openForType U_ICU_ENTRY_POINT_RENAME(uplrules_openForType) #define uplrules_select U_ICU_ENTRY_POINT_RENAME(uplrules_select) +#define uplrules_selectFormatted U_ICU_ENTRY_POINT_RENAME(uplrules_selectFormatted) +#define uplrules_selectWithFormat U_ICU_ENTRY_POINT_RENAME(uplrules_selectWithFormat) #define uplug_closeLibrary U_ICU_ENTRY_POINT_RENAME(uplug_closeLibrary) #define uplug_findLibrary U_ICU_ENTRY_POINT_RENAME(uplug_findLibrary) #define uplug_getConfiguration U_ICU_ENTRY_POINT_RENAME(uplug_getConfiguration) @@ -1200,8 +1289,10 @@ #define uplug_setPlugLevel U_ICU_ENTRY_POINT_RENAME(uplug_setPlugLevel) #define uplug_setPlugName U_ICU_ENTRY_POINT_RENAME(uplug_setPlugName) #define uplug_setPlugNoUnload U_ICU_ENTRY_POINT_RENAME(uplug_setPlugNoUnload) +#define uprops_addPropertyStarts U_ICU_ENTRY_POINT_RENAME(uprops_addPropertyStarts) #define uprops_getSource U_ICU_ENTRY_POINT_RENAME(uprops_getSource) #define upropsvec_addPropertyStarts U_ICU_ENTRY_POINT_RENAME(upropsvec_addPropertyStarts) +#define uprv_add32_overflow U_ICU_ENTRY_POINT_RENAME(uprv_add32_overflow) #define uprv_aestrncpy U_ICU_ENTRY_POINT_RENAME(uprv_aestrncpy) #define uprv_asciiFromEbcdic U_ICU_ENTRY_POINT_RENAME(uprv_asciiFromEbcdic) #define uprv_asciitolower U_ICU_ENTRY_POINT_RENAME(uprv_asciitolower) @@ -1213,9 +1304,11 @@ #define uprv_compareInvEbcdic U_ICU_ENTRY_POINT_RENAME(uprv_compareInvEbcdic) #define uprv_compareInvEbcdicAsAscii U_ICU_ENTRY_POINT_RENAME(uprv_compareInvEbcdicAsAscii) #define uprv_convertToLCID U_ICU_ENTRY_POINT_RENAME(uprv_convertToLCID) +#define uprv_convertToLCIDPlatform U_ICU_ENTRY_POINT_RENAME(uprv_convertToLCIDPlatform) #define uprv_convertToPosix U_ICU_ENTRY_POINT_RENAME(uprv_convertToPosix) #define uprv_copyAscii U_ICU_ENTRY_POINT_RENAME(uprv_copyAscii) #define uprv_copyEbcdic U_ICU_ENTRY_POINT_RENAME(uprv_copyEbcdic) +#define uprv_currencyLeads U_ICU_ENTRY_POINT_RENAME(uprv_currencyLeads) #define uprv_decContextClearStatus U_ICU_ENTRY_POINT_RENAME(uprv_decContextClearStatus) #define uprv_decContextDefault U_ICU_ENTRY_POINT_RENAME(uprv_decContextDefault) #define uprv_decContextGetRounding U_ICU_ENTRY_POINT_RENAME(uprv_decContextGetRounding) @@ -1309,7 +1402,6 @@ #define uprv_fmod U_ICU_ENTRY_POINT_RENAME(uprv_fmod) #define uprv_free U_ICU_ENTRY_POINT_RENAME(uprv_free) #define uprv_getCharNameCharacters U_ICU_ENTRY_POINT_RENAME(uprv_getCharNameCharacters) -#define uprv_getDefaultCodepage U_ICU_ENTRY_POINT_RENAME(uprv_getDefaultCodepage) #define uprv_getDefaultLocaleID U_ICU_ENTRY_POINT_RENAME(uprv_getDefaultLocaleID) #define uprv_getInfinity U_ICU_ENTRY_POINT_RENAME(uprv_getInfinity) #define uprv_getMaxCharNameLength U_ICU_ENTRY_POINT_RENAME(uprv_getMaxCharNameLength) @@ -1318,7 +1410,6 @@ #define uprv_getRawUTCtime U_ICU_ENTRY_POINT_RENAME(uprv_getRawUTCtime) #define uprv_getStaticCurrencyName U_ICU_ENTRY_POINT_RENAME(uprv_getStaticCurrencyName) #define uprv_getUTCtime U_ICU_ENTRY_POINT_RENAME(uprv_getUTCtime) -#define uprv_haveProperties U_ICU_ENTRY_POINT_RENAME(uprv_haveProperties) #define uprv_int32Comparator U_ICU_ENTRY_POINT_RENAME(uprv_int32Comparator) #define uprv_isASCIILetter U_ICU_ENTRY_POINT_RENAME(uprv_isASCIILetter) #define uprv_isInfinite U_ICU_ENTRY_POINT_RENAME(uprv_isInfinite) @@ -1336,6 +1427,7 @@ #define uprv_maximumPtr U_ICU_ENTRY_POINT_RENAME(uprv_maximumPtr) #define uprv_min U_ICU_ENTRY_POINT_RENAME(uprv_min) #define uprv_modf U_ICU_ENTRY_POINT_RENAME(uprv_modf) +#define uprv_mul32_overflow U_ICU_ENTRY_POINT_RENAME(uprv_mul32_overflow) #define uprv_parseCurrency U_ICU_ENTRY_POINT_RENAME(uprv_parseCurrency) #define uprv_pathIsAbsolute U_ICU_ENTRY_POINT_RENAME(uprv_pathIsAbsolute) #define uprv_pow U_ICU_ENTRY_POINT_RENAME(uprv_pow) @@ -1354,6 +1446,7 @@ #define uprv_toupper U_ICU_ENTRY_POINT_RENAME(uprv_toupper) #define uprv_trunc U_ICU_ENTRY_POINT_RENAME(uprv_trunc) #define uprv_tzname U_ICU_ENTRY_POINT_RENAME(uprv_tzname) +#define uprv_tzname_clear_cache U_ICU_ENTRY_POINT_RENAME(uprv_tzname_clear_cache) #define uprv_tzset U_ICU_ENTRY_POINT_RENAME(uprv_tzset) #define uprv_uint16Comparator U_ICU_ENTRY_POINT_RENAME(uprv_uint16Comparator) #define uprv_uint32Comparator U_ICU_ENTRY_POINT_RENAME(uprv_uint32Comparator) @@ -1445,11 +1538,22 @@ #define uregion_getRegionFromCode U_ICU_ENTRY_POINT_RENAME(uregion_getRegionFromCode) #define uregion_getRegionFromNumericCode U_ICU_ENTRY_POINT_RENAME(uregion_getRegionFromNumericCode) #define uregion_getType U_ICU_ENTRY_POINT_RENAME(uregion_getType) +#define ureldatefmt_close U_ICU_ENTRY_POINT_RENAME(ureldatefmt_close) +#define ureldatefmt_closeResult U_ICU_ENTRY_POINT_RENAME(ureldatefmt_closeResult) +#define ureldatefmt_combineDateAndTime U_ICU_ENTRY_POINT_RENAME(ureldatefmt_combineDateAndTime) +#define ureldatefmt_format U_ICU_ENTRY_POINT_RENAME(ureldatefmt_format) +#define ureldatefmt_formatNumeric U_ICU_ENTRY_POINT_RENAME(ureldatefmt_formatNumeric) +#define ureldatefmt_formatNumericToResult U_ICU_ENTRY_POINT_RENAME(ureldatefmt_formatNumericToResult) +#define ureldatefmt_formatToResult U_ICU_ENTRY_POINT_RENAME(ureldatefmt_formatToResult) +#define ureldatefmt_open U_ICU_ENTRY_POINT_RENAME(ureldatefmt_open) +#define ureldatefmt_openResult U_ICU_ENTRY_POINT_RENAME(ureldatefmt_openResult) +#define ureldatefmt_resultAsValue U_ICU_ENTRY_POINT_RENAME(ureldatefmt_resultAsValue) #define ures_close U_ICU_ENTRY_POINT_RENAME(ures_close) #define ures_copyResb U_ICU_ENTRY_POINT_RENAME(ures_copyResb) #define ures_countArrayItems U_ICU_ENTRY_POINT_RENAME(ures_countArrayItems) #define ures_findResource U_ICU_ENTRY_POINT_RENAME(ures_findResource) #define ures_findSubResource U_ICU_ENTRY_POINT_RENAME(ures_findSubResource) +#define ures_getAllItemsWithFallback U_ICU_ENTRY_POINT_RENAME(ures_getAllItemsWithFallback) #define ures_getBinary U_ICU_ENTRY_POINT_RENAME(ures_getBinary) #define ures_getByIndex U_ICU_ENTRY_POINT_RENAME(ures_getByIndex) #define ures_getByKey U_ICU_ENTRY_POINT_RENAME(ures_getByKey) @@ -1484,6 +1588,7 @@ #define ures_open U_ICU_ENTRY_POINT_RENAME(ures_open) #define ures_openAvailableLocales U_ICU_ENTRY_POINT_RENAME(ures_openAvailableLocales) #define ures_openDirect U_ICU_ENTRY_POINT_RENAME(ures_openDirect) +#define ures_openDirectFillIn U_ICU_ENTRY_POINT_RENAME(ures_openDirectFillIn) #define ures_openFillIn U_ICU_ENTRY_POINT_RENAME(ures_openFillIn) #define ures_openNoDefault U_ICU_ENTRY_POINT_RENAME(ures_openNoDefault) #define ures_openU U_ICU_ENTRY_POINT_RENAME(ures_openU) @@ -1597,13 +1702,20 @@ #define uspoof_areConfusableUTF8 U_ICU_ENTRY_POINT_RENAME(uspoof_areConfusableUTF8) #define uspoof_areConfusableUnicodeString U_ICU_ENTRY_POINT_RENAME(uspoof_areConfusableUnicodeString) #define uspoof_check U_ICU_ENTRY_POINT_RENAME(uspoof_check) +#define uspoof_check2 U_ICU_ENTRY_POINT_RENAME(uspoof_check2) +#define uspoof_check2UTF8 U_ICU_ENTRY_POINT_RENAME(uspoof_check2UTF8) +#define uspoof_check2UnicodeString U_ICU_ENTRY_POINT_RENAME(uspoof_check2UnicodeString) #define uspoof_checkUTF8 U_ICU_ENTRY_POINT_RENAME(uspoof_checkUTF8) #define uspoof_checkUnicodeString U_ICU_ENTRY_POINT_RENAME(uspoof_checkUnicodeString) #define uspoof_clone U_ICU_ENTRY_POINT_RENAME(uspoof_clone) #define uspoof_close U_ICU_ENTRY_POINT_RENAME(uspoof_close) +#define uspoof_closeCheckResult U_ICU_ENTRY_POINT_RENAME(uspoof_closeCheckResult) #define uspoof_getAllowedChars U_ICU_ENTRY_POINT_RENAME(uspoof_getAllowedChars) #define uspoof_getAllowedLocales U_ICU_ENTRY_POINT_RENAME(uspoof_getAllowedLocales) #define uspoof_getAllowedUnicodeSet U_ICU_ENTRY_POINT_RENAME(uspoof_getAllowedUnicodeSet) +#define uspoof_getCheckResultChecks U_ICU_ENTRY_POINT_RENAME(uspoof_getCheckResultChecks) +#define uspoof_getCheckResultNumerics U_ICU_ENTRY_POINT_RENAME(uspoof_getCheckResultNumerics) +#define uspoof_getCheckResultRestrictionLevel U_ICU_ENTRY_POINT_RENAME(uspoof_getCheckResultRestrictionLevel) #define uspoof_getChecks U_ICU_ENTRY_POINT_RENAME(uspoof_getChecks) #define uspoof_getInclusionSet U_ICU_ENTRY_POINT_RENAME(uspoof_getInclusionSet) #define uspoof_getInclusionUnicodeSet U_ICU_ENTRY_POINT_RENAME(uspoof_getInclusionUnicodeSet) @@ -1613,7 +1725,9 @@ #define uspoof_getSkeleton U_ICU_ENTRY_POINT_RENAME(uspoof_getSkeleton) #define uspoof_getSkeletonUTF8 U_ICU_ENTRY_POINT_RENAME(uspoof_getSkeletonUTF8) #define uspoof_getSkeletonUnicodeString U_ICU_ENTRY_POINT_RENAME(uspoof_getSkeletonUnicodeString) +#define uspoof_internalInitStatics U_ICU_ENTRY_POINT_RENAME(uspoof_internalInitStatics) #define uspoof_open U_ICU_ENTRY_POINT_RENAME(uspoof_open) +#define uspoof_openCheckResult U_ICU_ENTRY_POINT_RENAME(uspoof_openCheckResult) #define uspoof_openFromSerialized U_ICU_ENTRY_POINT_RENAME(uspoof_openFromSerialized) #define uspoof_openFromSource U_ICU_ENTRY_POINT_RENAME(uspoof_openFromSource) #define uspoof_serialize U_ICU_ENTRY_POINT_RENAME(uspoof_serialize) @@ -1631,12 +1745,14 @@ #define ustr_hashCharsN U_ICU_ENTRY_POINT_RENAME(ustr_hashCharsN) #define ustr_hashICharsN U_ICU_ENTRY_POINT_RENAME(ustr_hashICharsN) #define ustr_hashUCharsN U_ICU_ENTRY_POINT_RENAME(ustr_hashUCharsN) +#define ustrcase_getCaseLocale U_ICU_ENTRY_POINT_RENAME(ustrcase_getCaseLocale) +#define ustrcase_getTitleBreakIterator U_ICU_ENTRY_POINT_RENAME(ustrcase_getTitleBreakIterator) #define ustrcase_internalFold U_ICU_ENTRY_POINT_RENAME(ustrcase_internalFold) #define ustrcase_internalToLower U_ICU_ENTRY_POINT_RENAME(ustrcase_internalToLower) #define ustrcase_internalToTitle U_ICU_ENTRY_POINT_RENAME(ustrcase_internalToTitle) #define ustrcase_internalToUpper U_ICU_ENTRY_POINT_RENAME(ustrcase_internalToUpper) #define ustrcase_map U_ICU_ENTRY_POINT_RENAME(ustrcase_map) -#define ustrcase_setTempCaseMapLocale U_ICU_ENTRY_POINT_RENAME(ustrcase_setTempCaseMapLocale) +#define ustrcase_mapWithOverlap U_ICU_ENTRY_POINT_RENAME(ustrcase_mapWithOverlap) #define utext_char32At U_ICU_ENTRY_POINT_RENAME(utext_char32At) #define utext_clone U_ICU_ENTRY_POINT_RENAME(utext_clone) #define utext_close U_ICU_ENTRY_POINT_RENAME(utext_close) @@ -1681,7 +1797,6 @@ #define utrace_functionName U_ICU_ENTRY_POINT_RENAME(utrace_functionName) #define utrace_getFunctions U_ICU_ENTRY_POINT_RENAME(utrace_getFunctions) #define utrace_getLevel U_ICU_ENTRY_POINT_RENAME(utrace_getLevel) -#define utrace_level U_ICU_ENTRY_POINT_RENAME(utrace_level) #define utrace_setFunctions U_ICU_ENTRY_POINT_RENAME(utrace_setFunctions) #define utrace_setLevel U_ICU_ENTRY_POINT_RENAME(utrace_setLevel) #define utrace_vformat U_ICU_ENTRY_POINT_RENAME(utrace_vformat) @@ -1717,7 +1832,6 @@ #define utrie2_fromUTrie U_ICU_ENTRY_POINT_RENAME(utrie2_fromUTrie) #define utrie2_get32 U_ICU_ENTRY_POINT_RENAME(utrie2_get32) #define utrie2_get32FromLeadSurrogateCodeUnit U_ICU_ENTRY_POINT_RENAME(utrie2_get32FromLeadSurrogateCodeUnit) -#define utrie2_getVersion U_ICU_ENTRY_POINT_RENAME(utrie2_getVersion) #define utrie2_internalU8NextIndex U_ICU_ENTRY_POINT_RENAME(utrie2_internalU8NextIndex) #define utrie2_internalU8PrevIndex U_ICU_ENTRY_POINT_RENAME(utrie2_internalU8PrevIndex) #define utrie2_isFrozen U_ICU_ENTRY_POINT_RENAME(utrie2_isFrozen) @@ -1729,7 +1843,6 @@ #define utrie2_set32ForLeadSurrogateCodeUnit U_ICU_ENTRY_POINT_RENAME(utrie2_set32ForLeadSurrogateCodeUnit) #define utrie2_setRange32 U_ICU_ENTRY_POINT_RENAME(utrie2_setRange32) #define utrie2_swap U_ICU_ENTRY_POINT_RENAME(utrie2_swap) -#define utrie2_swapAnyVersion U_ICU_ENTRY_POINT_RENAME(utrie2_swapAnyVersion) #define utrie_clone U_ICU_ENTRY_POINT_RENAME(utrie_clone) #define utrie_close U_ICU_ENTRY_POINT_RENAME(utrie_close) #define utrie_defaultGetFoldingOffset U_ICU_ENTRY_POINT_RENAME(utrie_defaultGetFoldingOffset) @@ -1741,6 +1854,7 @@ #define utrie_set32 U_ICU_ENTRY_POINT_RENAME(utrie_set32) #define utrie_setRange32 U_ICU_ENTRY_POINT_RENAME(utrie_setRange32) #define utrie_swap U_ICU_ENTRY_POINT_RENAME(utrie_swap) +#define utrie_swapAnyVersion U_ICU_ENTRY_POINT_RENAME(utrie_swapAnyVersion) #define utrie_unserialize U_ICU_ENTRY_POINT_RENAME(utrie_unserialize) #define utrie_unserializeDummy U_ICU_ENTRY_POINT_RENAME(utrie_unserializeDummy) #define vzone_clone U_ICU_ENTRY_POINT_RENAME(vzone_clone) @@ -1790,6 +1904,7 @@ #define ztrans_setTime U_ICU_ENTRY_POINT_RENAME(ztrans_setTime) #define ztrans_setTo U_ICU_ENTRY_POINT_RENAME(ztrans_setTo) -#endif +#endif /* !(defined(_MSC_VER) && defined(__INTELLISENSE__)) */ +#endif /* U_DISABLE_RENAMING */ +#endif /* URENAME_H */ -#endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/urep.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/urep.h index c7b99476f0..932202ddb0 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/urep.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/urep.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 1997-2010, International Business Machines diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ures.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ures.h index c91f030b10..a5fe7deed8 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ures.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ures.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** -* Copyright (C) 1997-2012,2014, International Business Machines +* Copyright (C) 1997-2016, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * @@ -12,9 +14,9 @@ * 04/01/97 aliu Creation. * 02/22/99 damiba overhaul. * 04/04/99 helena Fixed internal header inclusion. -* 04/15/99 Madhu Updated Javadoc +* 04/15/99 Madhu Updated Javadoc * 06/14/99 stephen Removed functions taking a filename suffix. -* 07/20/99 stephen Language-independent ypedef to void* +* 07/20/99 stephen Language-independent typedef to void* * 11/09/99 weiv Added ures_getLocale() * 06/24/02 weiv Added support for resource sharing ****************************************************************************** @@ -29,7 +31,7 @@ /** * \file - * \brief C API: Resource Bundle + * \brief C API: Resource Bundle * *

      C API: Resource Bundle

      * @@ -40,7 +42,7 @@ *

      * Resource bundles in ICU4C are currently defined using text files which conform to the following * BNF definition. - * More on resource bundle concepts and syntax can be found in the + * More on resource bundle concepts and syntax can be found in the * Users Guide. *

      */ @@ -119,10 +121,14 @@ typedef enum { /** @deprecated ICU 2.6 Use the URES_ constant instead. */ RES_INT_VECTOR=URES_INT_VECTOR, /** @deprecated ICU 2.6 Not used. */ - RES_RESERVED=15, -#endif /* U_HIDE_DEPRECATED_API */ + RES_RESERVED=15, + /** + * One more than the highest normal UResType value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ URES_LIMIT = 16 +#endif // U_HIDE_DEPRECATED_API } UResType; /* @@ -132,17 +138,17 @@ typedef enum { /** * Opens a UResourceBundle, from which users can extract strings by using * their corresponding keys. - * Note that the caller is responsible of calling ures_close on each succesfully + * Note that the caller is responsible of calling ures_close on each successfully * opened resource bundle. - * @param packageName The packageName and locale together point to an ICU udata object, - * as defined by udata_open( packageName, "res", locale, err) + * @param packageName The packageName and locale together point to an ICU udata object, + * as defined by udata_open( packageName, "res", locale, err) * or equivalent. Typically, packageName will refer to a (.dat) file, or to * a package registered with udata_setAppData(). Using a full file or directory * pathname for packageName is deprecated. If NULL, ICU data will be used. * @param locale specifies the locale for which we want to open the resource * if NULL, the default locale will be used. If strlen(locale) == 0 * root locale will be used. - * + * * @param status fills in the outgoing error code. * The UErrorCode err parameter is used to return status information to the user. To * check whether the construction succeeded or not, you should check the value of @@ -150,39 +156,39 @@ typedef enum { * informational status results which still indicate success. U_USING_FALLBACK_WARNING * indicates that a fall back locale was used. For example, 'de_CH' was requested, * but nothing was found there, so 'de' was used. U_USING_DEFAULT_WARNING indicates that - * the default locale data or root locale data was used; neither the requested locale - * nor any of its fall back locales could be found. Please see the users guide for more + * the default locale data or root locale data was used; neither the requested locale + * nor any of its fall back locales could be found. Please see the users guide for more * information on this topic. * @return a newly allocated resource bundle. * @see ures_close * @stable ICU 2.0 */ -U_STABLE UResourceBundle* U_EXPORT2 +U_STABLE UResourceBundle* U_EXPORT2 ures_open(const char* packageName, - const char* locale, + const char* locale, UErrorCode* status); -/** This function does not care what kind of localeID is passed in. It simply opens a bundle with +/** This function does not care what kind of localeID is passed in. It simply opens a bundle with * that name. Fallback mechanism is disabled for the new bundle. If the requested bundle contains * an %%ALIAS directive, the results are undefined. - * @param packageName The packageName and locale together point to an ICU udata object, - * as defined by udata_open( packageName, "res", locale, err) + * @param packageName The packageName and locale together point to an ICU udata object, + * as defined by udata_open( packageName, "res", locale, err) * or equivalent. Typically, packageName will refer to a (.dat) file, or to * a package registered with udata_setAppData(). Using a full file or directory * pathname for packageName is deprecated. If NULL, ICU data will be used. * @param locale specifies the locale for which we want to open the resource * if NULL, the default locale will be used. If strlen(locale) == 0 * root locale will be used. - * + * * @param status fills in the outgoing error code. Either U_ZERO_ERROR or U_MISSING_RESOURCE_ERROR * @return a newly allocated resource bundle or NULL if it doesn't exist. * @see ures_close * @stable ICU 2.0 */ -U_STABLE UResourceBundle* U_EXPORT2 -ures_openDirect(const char* packageName, - const char* locale, +U_STABLE UResourceBundle* U_EXPORT2 +ures_openDirect(const char* packageName, + const char* locale, UErrorCode* status); /** @@ -190,8 +196,8 @@ ures_openDirect(const char* packageName, * This path will be converted to char * using the default converter, * then ures_open() is called. * - * @param packageName The packageName and locale together point to an ICU udata object, - * as defined by udata_open( packageName, "res", locale, err) + * @param packageName The packageName and locale together point to an ICU udata object, + * as defined by udata_open( packageName, "res", locale, err) * or equivalent. Typically, packageName will refer to a (.dat) file, or to * a package registered with udata_setAppData(). Using a full file or directory * pathname for packageName is deprecated. If NULL, ICU data will be used. @@ -203,21 +209,21 @@ ures_openDirect(const char* packageName, * @see ures_open * @stable ICU 2.0 */ -U_STABLE UResourceBundle* U_EXPORT2 -ures_openU(const UChar* packageName, - const char* locale, +U_STABLE UResourceBundle* U_EXPORT2 +ures_openU(const UChar* packageName, + const char* locale, UErrorCode* status); #ifndef U_HIDE_DEPRECATED_API /** * Returns the number of strings/arrays in resource bundles. - * Better to use ures_getSize, as this function will be deprecated. + * Better to use ures_getSize, as this function will be deprecated. * *@param resourceBundle resource bundle containing the desired strings *@param resourceKey key tagging the resource *@param err fills in the outgoing error code * could be U_MISSING_RESOURCE_ERROR if the key is not found - * could be a non-failing error + * could be a non-failing error * e.g.: U_USING_FALLBACK_WARNING,U_USING_FALLBACK_WARNING *@return: for Arrays: returns the number of resources in the array * Tables: returns the number of resources in the table @@ -225,7 +231,7 @@ ures_openU(const UChar* packageName, *@see ures_getSize * @deprecated ICU 2.8 User ures_getSize instead */ -U_DEPRECATED int32_t U_EXPORT2 +U_DEPRECATED int32_t U_EXPORT2 ures_countArrayItems(const UResourceBundle* resourceBundle, const char* resourceKey, UErrorCode* err); @@ -239,7 +245,7 @@ ures_countArrayItems(const UResourceBundle* resourceBundle, * @see ures_open * @stable ICU 2.0 */ -U_STABLE void U_EXPORT2 +U_STABLE void U_EXPORT2 ures_close(UResourceBundle* resourceBundle); #if U_SHOW_CPLUSPLUS_API @@ -259,7 +265,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUResourceBundlePointer, UResourceBundle, ures_c U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API #ifndef U_HIDE_DEPRECATED_API /** @@ -272,12 +278,12 @@ U_NAMESPACE_END * @see ures_getVersion * @deprecated ICU 2.8 Use ures_getVersion instead. */ -U_DEPRECATED const char* U_EXPORT2 +U_DEPRECATED const char* U_EXPORT2 ures_getVersionNumber(const UResourceBundle* resourceBundle); #endif /* U_HIDE_DEPRECATED_API */ /** - * Return the version number associated with this ResourceBundle as an + * Return the version number associated with this ResourceBundle as an * UVersionInfo array. * * @param resB The resource bundle for which the version is checked. @@ -285,30 +291,30 @@ ures_getVersionNumber(const UResourceBundle* resourceBundle); * as specified in the resource bundle or its parent. * @stable ICU 2.0 */ -U_STABLE void U_EXPORT2 -ures_getVersion(const UResourceBundle* resB, +U_STABLE void U_EXPORT2 +ures_getVersion(const UResourceBundle* resB, UVersionInfo versionInfo); #ifndef U_HIDE_DEPRECATED_API /** * Return the name of the Locale associated with this ResourceBundle. This API allows - * you to query for the real locale of the resource. For example, if you requested - * "en_US_CALIFORNIA" and only "en_US" bundle exists, "en_US" will be returned. + * you to query for the real locale of the resource. For example, if you requested + * "en_US_CALIFORNIA" and only "en_US" bundle exists, "en_US" will be returned. * For subresources, the locale where this resource comes from will be returned. - * If fallback has occured, getLocale will reflect this. + * If fallback has occurred, getLocale will reflect this. * * @param resourceBundle resource bundle in question * @param status just for catching illegal arguments * @return A Locale name * @deprecated ICU 2.8 Use ures_getLocaleByType instead. */ -U_DEPRECATED const char* U_EXPORT2 -ures_getLocale(const UResourceBundle* resourceBundle, +U_DEPRECATED const char* U_EXPORT2 +ures_getLocale(const UResourceBundle* resourceBundle, UErrorCode* status); #endif /* U_HIDE_DEPRECATED_API */ /** - * Return the name of the Locale associated with this ResourceBundle. + * Return the name of the Locale associated with this ResourceBundle. * You can choose between requested, valid and real locale. * * @param resourceBundle resource bundle in question @@ -319,33 +325,33 @@ ures_getLocale(const UResourceBundle* resourceBundle, * @return A Locale name * @stable ICU 2.8 */ -U_STABLE const char* U_EXPORT2 -ures_getLocaleByType(const UResourceBundle* resourceBundle, - ULocDataLocaleType type, +U_STABLE const char* U_EXPORT2 +ures_getLocaleByType(const UResourceBundle* resourceBundle, + ULocDataLocaleType type, UErrorCode* status); #ifndef U_HIDE_INTERNAL_API /** - * Same as ures_open() but uses the fill-in parameter instead of allocating - * a bundle, if r!=NULL. + * Same as ures_open() but uses the fill-in parameter instead of allocating a new bundle. + * * TODO need to revisit usefulness of this function * and usage model for fillIn parameters without knowing sizeof(UResourceBundle) - * @param r The resourcebundle to open - * @param packageName The packageName and locale together point to an ICU udata object, - * as defined by udata_open( packageName, "res", locale, err) + * @param r The existing UResourceBundle to fill in. If NULL then status will be + * set to U_ILLEGAL_ARGUMENT_ERROR. + * @param packageName The packageName and locale together point to an ICU udata object, + * as defined by udata_open( packageName, "res", locale, err) * or equivalent. Typically, packageName will refer to a (.dat) file, or to * a package registered with udata_setAppData(). Using a full file or directory * pathname for packageName is deprecated. If NULL, ICU data will be used. * @param localeID specifies the locale for which we want to open the resource - * @param status The error code - * @return a newly allocated resource bundle or NULL if it doesn't exist. + * @param status The error code. * @internal */ -U_INTERNAL void U_EXPORT2 -ures_openFillIn(UResourceBundle *r, +U_INTERNAL void U_EXPORT2 +ures_openFillIn(UResourceBundle *r, const char* packageName, - const char* localeID, + const char* localeID, UErrorCode* status); #endif /* U_HIDE_INTERNAL_API */ @@ -357,7 +363,7 @@ ures_openFillIn(UResourceBundle *r, * @param status fills in the outgoing error code * could be U_MISSING_RESOURCE_ERROR if the key is not found * Always check the value of status. Don't count on returning NULL. - * could be a non-failing error + * could be a non-failing error * e.g.: U_USING_FALLBACK_WARNING,U_USING_DEFAULT_WARNING * @return a pointer to a zero-terminated UChar array which lives in a memory mapped/DLL file. * @see ures_getBinary @@ -366,9 +372,9 @@ ures_openFillIn(UResourceBundle *r, * @see ures_getUInt * @stable ICU 2.0 */ -U_STABLE const UChar* U_EXPORT2 -ures_getString(const UResourceBundle* resourceBundle, - int32_t* len, +U_STABLE const UChar* U_EXPORT2 +ures_getString(const UResourceBundle* resourceBundle, + int32_t* len, UErrorCode* status); /** @@ -425,14 +431,14 @@ ures_getUTF8String(const UResourceBundle *resB, UErrorCode *status); /** - * Returns a binary data from a binary resource. + * Returns a binary data from a binary resource. * * @param resourceBundle a string resource * @param len fills in the length of resulting byte chunk * @param status fills in the outgoing error code * could be U_MISSING_RESOURCE_ERROR if the key is not found * Always check the value of status. Don't count on returning NULL. - * could be a non-failing error + * could be a non-failing error * e.g.: U_USING_FALLBACK_WARNING,U_USING_DEFAULT_WARNING * @return a pointer to a chunk of unsigned bytes which live in a memory mapped/DLL file. * @see ures_getString @@ -441,20 +447,20 @@ ures_getUTF8String(const UResourceBundle *resB, * @see ures_getUInt * @stable ICU 2.0 */ -U_STABLE const uint8_t* U_EXPORT2 -ures_getBinary(const UResourceBundle* resourceBundle, - int32_t* len, +U_STABLE const uint8_t* U_EXPORT2 +ures_getBinary(const UResourceBundle* resourceBundle, + int32_t* len, UErrorCode* status); /** - * Returns a 32 bit integer array from a resource. + * Returns a 32 bit integer array from a resource. * * @param resourceBundle an int vector resource * @param len fills in the length of resulting byte chunk * @param status fills in the outgoing error code * could be U_MISSING_RESOURCE_ERROR if the key is not found * Always check the value of status. Don't count on returning NULL. - * could be a non-failing error + * could be a non-failing error * e.g.: U_USING_FALLBACK_WARNING,U_USING_DEFAULT_WARNING * @return a pointer to a chunk of integers which live in a memory mapped/DLL file. * @see ures_getBinary @@ -463,19 +469,19 @@ ures_getBinary(const UResourceBundle* resourceBundle, * @see ures_getUInt * @stable ICU 2.0 */ -U_STABLE const int32_t* U_EXPORT2 -ures_getIntVector(const UResourceBundle* resourceBundle, - int32_t* len, +U_STABLE const int32_t* U_EXPORT2 +ures_getIntVector(const UResourceBundle* resourceBundle, + int32_t* len, UErrorCode* status); /** - * Returns an unsigned integer from a resource. + * Returns an unsigned integer from a resource. * This integer is originally 28 bits. * * @param resourceBundle a string resource * @param status fills in the outgoing error code * could be U_MISSING_RESOURCE_ERROR if the key is not found - * could be a non-failing error + * could be a non-failing error * e.g.: U_USING_FALLBACK_WARNING,U_USING_DEFAULT_WARNING * @return an integer value * @see ures_getInt @@ -484,18 +490,18 @@ ures_getIntVector(const UResourceBundle* resourceBundle, * @see ures_getString * @stable ICU 2.0 */ -U_STABLE uint32_t U_EXPORT2 -ures_getUInt(const UResourceBundle* resourceBundle, +U_STABLE uint32_t U_EXPORT2 +ures_getUInt(const UResourceBundle* resourceBundle, UErrorCode *status); /** - * Returns a signed integer from a resource. + * Returns a signed integer from a resource. * This integer is originally 28 bit and the sign gets propagated. * * @param resourceBundle a string resource * @param status fills in the outgoing error code * could be U_MISSING_RESOURCE_ERROR if the key is not found - * could be a non-failing error + * could be a non-failing error * e.g.: U_USING_FALLBACK_WARNING,U_USING_DEFAULT_WARNING * @return an integer value * @see ures_getUInt @@ -504,21 +510,21 @@ ures_getUInt(const UResourceBundle* resourceBundle, * @see ures_getString * @stable ICU 2.0 */ -U_STABLE int32_t U_EXPORT2 -ures_getInt(const UResourceBundle* resourceBundle, +U_STABLE int32_t U_EXPORT2 +ures_getInt(const UResourceBundle* resourceBundle, UErrorCode *status); /** - * Returns the size of a resource. Size for scalar types is always 1, + * Returns the size of a resource. Size for scalar types is always 1, * and for vector/table types is the number of child resources. - * @warning Integer array is treated as a scalar type. There are no + * @warning Integer array is treated as a scalar type. There are no * APIs to access individual members of an integer array. It * is always returned as a whole. * @param resourceBundle a resource * @return number of resources in a given resource. * @stable ICU 2.0 */ -U_STABLE int32_t U_EXPORT2 +U_STABLE int32_t U_EXPORT2 ures_getSize(const UResourceBundle *resourceBundle); /** @@ -529,21 +535,21 @@ ures_getSize(const UResourceBundle *resourceBundle); * @see UResType * @stable ICU 2.0 */ -U_STABLE UResType U_EXPORT2 +U_STABLE UResType U_EXPORT2 ures_getType(const UResourceBundle *resourceBundle); /** - * Returns the key associated with a given resource. Not all the resources have a key - only + * Returns the key associated with a given resource. Not all the resources have a key - only * those that are members of a table. * * @param resourceBundle a resource * @return a key associated to this resource, or NULL if it doesn't have a key * @stable ICU 2.0 */ -U_STABLE const char * U_EXPORT2 +U_STABLE const char * U_EXPORT2 ures_getKey(const UResourceBundle *resourceBundle); -/* ITERATION API +/* ITERATION API This API provides means for iterating through a resource */ @@ -553,7 +559,7 @@ ures_getKey(const UResourceBundle *resourceBundle); * @param resourceBundle a resource * @stable ICU 2.0 */ -U_STABLE void U_EXPORT2 +U_STABLE void U_EXPORT2 ures_resetIterator(UResourceBundle *resourceBundle); /** @@ -563,60 +569,60 @@ ures_resetIterator(UResourceBundle *resourceBundle); * @return TRUE if there are more elements, FALSE if there is no more elements * @stable ICU 2.0 */ -U_STABLE UBool U_EXPORT2 +U_STABLE UBool U_EXPORT2 ures_hasNext(const UResourceBundle *resourceBundle); /** - * Returns the next resource in a given resource or NULL if there are no more resources - * to iterate over. Features a fill-in parameter. + * Returns the next resource in a given resource or NULL if there are no more resources + * to iterate over. Features a fill-in parameter. * * @param resourceBundle a resource * @param fillIn if NULL a new UResourceBundle struct is allocated and must be closed by the caller. * Alternatively, you can supply a struct to be filled by this function. * @param status fills in the outgoing error code. You may still get a non NULL result even if an - * error occured. Check status instead. + * error occurred. Check status instead. * @return a pointer to a UResourceBundle struct. If fill in param was NULL, caller must close it * @stable ICU 2.0 */ -U_STABLE UResourceBundle* U_EXPORT2 -ures_getNextResource(UResourceBundle *resourceBundle, - UResourceBundle *fillIn, +U_STABLE UResourceBundle* U_EXPORT2 +ures_getNextResource(UResourceBundle *resourceBundle, + UResourceBundle *fillIn, UErrorCode *status); /** - * Returns the next string in a given resource or NULL if there are no more resources - * to iterate over. + * Returns the next string in a given resource or NULL if there are no more resources + * to iterate over. * * @param resourceBundle a resource * @param len fill in length of the string * @param key fill in for key associated with this string. NULL if no key - * @param status fills in the outgoing error code. If an error occured, we may return NULL, but don't + * @param status fills in the outgoing error code. If an error occurred, we may return NULL, but don't * count on it. Check status instead! * @return a pointer to a zero-terminated UChar array which lives in a memory mapped/DLL file. * @stable ICU 2.0 */ -U_STABLE const UChar* U_EXPORT2 -ures_getNextString(UResourceBundle *resourceBundle, - int32_t* len, - const char ** key, +U_STABLE const UChar* U_EXPORT2 +ures_getNextString(UResourceBundle *resourceBundle, + int32_t* len, + const char ** key, UErrorCode *status); /** - * Returns the resource in a given resource at the specified index. Features a fill-in parameter. + * Returns the resource in a given resource at the specified index. Features a fill-in parameter. * * @param resourceBundle the resource bundle from which to get a sub-resource * @param indexR an index to the wanted resource. * @param fillIn if NULL a new UResourceBundle struct is allocated and must be closed by the caller. * Alternatively, you can supply a struct to be filled by this function. * @param status fills in the outgoing error code. Don't count on NULL being returned if an error has - * occured. Check status instead. + * occurred. Check status instead. * @return a pointer to a UResourceBundle struct. If fill in param was NULL, caller must close it * @stable ICU 2.0 */ -U_STABLE UResourceBundle* U_EXPORT2 -ures_getByIndex(const UResourceBundle *resourceBundle, - int32_t indexR, - UResourceBundle *fillIn, +U_STABLE UResourceBundle* U_EXPORT2 +ures_getByIndex(const UResourceBundle *resourceBundle, + int32_t indexR, + UResourceBundle *fillIn, UErrorCode *status); /** @@ -625,15 +631,15 @@ ures_getByIndex(const UResourceBundle *resourceBundle, * @param resourceBundle a resource * @param indexS an index to the wanted string. * @param len fill in length of the string - * @param status fills in the outgoing error code. If an error occured, we may return NULL, but don't + * @param status fills in the outgoing error code. If an error occurred, we may return NULL, but don't * count on it. Check status instead! * @return a pointer to a zero-terminated UChar array which lives in a memory mapped/DLL file. * @stable ICU 2.0 */ -U_STABLE const UChar* U_EXPORT2 -ures_getStringByIndex(const UResourceBundle *resourceBundle, - int32_t indexS, - int32_t* len, +U_STABLE const UChar* U_EXPORT2 +ures_getStringByIndex(const UResourceBundle *resourceBundle, + int32_t indexS, + int32_t* len, UErrorCode *status); /** @@ -693,7 +699,7 @@ ures_getUTF8StringByIndex(const UResourceBundle *resB, /** * Returns a resource in a given resource that has a given key. This procedure works only with table - * resources. Features a fill-in parameter. + * resources. Features a fill-in parameter. * * @param resourceBundle a resource * @param key a key associated with the wanted resource @@ -703,28 +709,28 @@ ures_getUTF8StringByIndex(const UResourceBundle *resB, * @return a pointer to a UResourceBundle struct. If fill in param was NULL, caller must close it * @stable ICU 2.0 */ -U_STABLE UResourceBundle* U_EXPORT2 -ures_getByKey(const UResourceBundle *resourceBundle, - const char* key, - UResourceBundle *fillIn, +U_STABLE UResourceBundle* U_EXPORT2 +ures_getByKey(const UResourceBundle *resourceBundle, + const char* key, + UResourceBundle *fillIn, UErrorCode *status); /** * Returns a string in a given resource that has a given key. This procedure works only with table - * resources. + * resources. * * @param resB a resource * @param key a key associated with the wanted string * @param len fill in length of the string - * @param status fills in the outgoing error code. If an error occured, we may return NULL, but don't + * @param status fills in the outgoing error code. If an error occurred, we may return NULL, but don't * count on it. Check status instead! * @return a pointer to a zero-terminated UChar array which lives in a memory mapped/DLL file. * @stable ICU 2.0 */ -U_STABLE const UChar* U_EXPORT2 -ures_getStringByKey(const UResourceBundle *resB, - const char* key, - int32_t* len, +U_STABLE const UChar* U_EXPORT2 +ures_getStringByKey(const UResourceBundle *resB, + const char* key, + int32_t* len, UErrorCode *status); /** @@ -789,90 +795,105 @@ ures_getUTF8StringByKey(const UResourceBundle *resB, U_NAMESPACE_BEGIN /** - * returns a string from a string resource type + * Returns the string value from a string resource bundle. * - * @param resB a resource + * @param resB a resource, should have type URES_STRING * @param status: fills in the outgoing error code * could be U_MISSING_RESOURCE_ERROR if the key is not found - * could be a non-failing error + * could be a non-failing error * e.g.: U_USING_FALLBACK_WARNING,U_USING_DEFAULT_WARNING - * @return a UnicodeString object. If there is an error, string is bogus + * @return The string value, or a bogus string if there is a failure UErrorCode. * @stable ICU 2.0 */ -inline UnicodeString -ures_getUnicodeString(const UResourceBundle *resB, - UErrorCode* status) -{ +inline UnicodeString +ures_getUnicodeString(const UResourceBundle *resB, UErrorCode* status) { + UnicodeString result; int32_t len = 0; const UChar *r = ures_getString(resB, &len, status); - return UnicodeString(TRUE, r, len); + if(U_SUCCESS(*status)) { + result.setTo(TRUE, r, len); + } else { + result.setToBogus(); + } + return result; } /** - * Returns the next string in a resource or NULL if there are no more resources - * to iterate over. + * Returns the next string in a resource, or an empty string if there are no more resources + * to iterate over. + * Use ures_getNextString() instead to distinguish between + * the end of the iteration and a real empty string value. * * @param resB a resource * @param key fill in for key associated with this string * @param status fills in the outgoing error code - * @return an UnicodeString object. + * @return The string value, or a bogus string if there is a failure UErrorCode. * @stable ICU 2.0 */ -inline UnicodeString -ures_getNextUnicodeString(UResourceBundle *resB, - const char ** key, - UErrorCode* status) -{ +inline UnicodeString +ures_getNextUnicodeString(UResourceBundle *resB, const char ** key, UErrorCode* status) { + UnicodeString result; int32_t len = 0; const UChar* r = ures_getNextString(resB, &len, key, status); - return UnicodeString(TRUE, r, len); + if(U_SUCCESS(*status)) { + result.setTo(TRUE, r, len); + } else { + result.setToBogus(); + } + return result; } /** - * Returns the string in a given resource at the specified index. + * Returns the string in a given resource array or table at the specified index. * * @param resB a resource * @param indexS an index to the wanted string. * @param status fills in the outgoing error code - * @return an UnicodeString object. If there is an error, string is bogus + * @return The string value, or a bogus string if there is a failure UErrorCode. * @stable ICU 2.0 */ -inline UnicodeString -ures_getUnicodeStringByIndex(const UResourceBundle *resB, - int32_t indexS, - UErrorCode* status) -{ +inline UnicodeString +ures_getUnicodeStringByIndex(const UResourceBundle *resB, int32_t indexS, UErrorCode* status) { + UnicodeString result; int32_t len = 0; const UChar* r = ures_getStringByIndex(resB, indexS, &len, status); - return UnicodeString(TRUE, r, len); + if(U_SUCCESS(*status)) { + result.setTo(TRUE, r, len); + } else { + result.setToBogus(); + } + return result; } /** - * Returns a string in a resource that has a given key. This procedure works only with table - * resources. + * Returns a string in a resource that has a given key. + * This procedure works only with table resources. * * @param resB a resource * @param key a key associated with the wanted string * @param status fills in the outgoing error code - * @return an UnicodeString object. If there is an error, string is bogus + * @return The string value, or a bogus string if there is a failure UErrorCode. * @stable ICU 2.0 */ -inline UnicodeString -ures_getUnicodeStringByKey(const UResourceBundle *resB, - const char* key, - UErrorCode* status) -{ +inline UnicodeString +ures_getUnicodeStringByKey(const UResourceBundle *resB, const char* key, UErrorCode* status) { + UnicodeString result; int32_t len = 0; const UChar* r = ures_getStringByKey(resB, key, &len, status); - return UnicodeString(TRUE, r, len); + if(U_SUCCESS(*status)) { + result.setTo(TRUE, r, len); + } else { + result.setToBogus(); + } + return result; } U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** - * Create a string enumerator, owned by the caller, of all locales located within + * Create a string enumerator, owned by the caller, of all locales located within * the specified resource tree. * @param packageName name of the tree, such as (NULL) or U_ICUDATA_ALIAS or or "ICUDATA-coll" * This call is similar to uloc_getAvailable(). diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uscript.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uscript.h index b217c81472..0ba3cf0be6 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uscript.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uscript.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** - * Copyright (C) 1997-2015, International Business Machines + * Copyright (C) 1997-2016, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * @@ -32,13 +34,13 @@ * See UAX #24 Unicode Script Property (http://www.unicode.org/reports/tr24/) * and http://www.unicode.org/Public/UCD/latest/ucd/PropertyValueAliases.txt . * - * Starting with ICU 3.6, constants for most ISO 15924 script codes + * In addition, constants for many ISO 15924 script codes * are included, for use with language tags, CLDR data, and similar. * Some of those codes are not used in the Unicode Character Database (UCD). * For example, there are no characters that have a UCD script property value of * Hans or Hant. All Han ideographs have the Hani script property value in Unicode. * - * Private-use codes Qaaa..Qabx are not included. + * Private-use codes Qaaa..Qabx are not included, except as used in the UCD or in CLDR. * * Starting with ICU 55, script codes are only added when their scripts * have been or will certainly be encoded in Unicode, @@ -300,7 +302,7 @@ typedef enum UScriptCode { USCRIPT_REJANG = 110,/* Rjng */ /** @stable ICU 3.8 */ USCRIPT_SAURASHTRA = 111,/* Saur */ - /** @stable ICU 3.8 */ + /** Sutton SignWriting @stable ICU 3.8 */ USCRIPT_SIGN_WRITING = 112,/* Sgnw */ /** @stable ICU 3.8 */ USCRIPT_SUNDANESE = 113,/* Sund */ @@ -424,24 +426,70 @@ typedef enum UScriptCode { /** @stable ICU 54 */ USCRIPT_SIDDHAM = 166,/* Sidd */ - /** - * One higher than the last script code constant. - * This value increases as constants for script codes are added. - * - * There are constants for Unicode 7 script property values. - * There are constants for ISO 15924 script codes assigned on or before 2013-10-12. - * There are no constants for private use codes from Qaaa - Qabx - * except as used in the UCD. - * - * @stable ICU 2.2 - */ - USCRIPT_CODE_LIMIT = 167 + /** @stable ICU 58 */ + USCRIPT_ADLAM = 167,/* Adlm */ + /** @stable ICU 58 */ + USCRIPT_BHAIKSUKI = 168,/* Bhks */ + /** @stable ICU 58 */ + USCRIPT_MARCHEN = 169,/* Marc */ + /** @stable ICU 58 */ + USCRIPT_NEWA = 170,/* Newa */ + /** @stable ICU 58 */ + USCRIPT_OSAGE = 171,/* Osge */ + + /** @stable ICU 58 */ + USCRIPT_HAN_WITH_BOPOMOFO = 172,/* Hanb */ + /** @stable ICU 58 */ + USCRIPT_JAMO = 173,/* Jamo */ + /** @stable ICU 58 */ + USCRIPT_SYMBOLS_EMOJI = 174,/* Zsye */ + + /** @stable ICU 60 */ + USCRIPT_MASARAM_GONDI = 175,/* Gonm */ + /** @stable ICU 60 */ + USCRIPT_SOYOMBO = 176,/* Soyo */ + /** @stable ICU 60 */ + USCRIPT_ZANABAZAR_SQUARE = 177,/* Zanb */ + + /** @stable ICU 62 */ + USCRIPT_DOGRA = 178,/* Dogr */ + /** @stable ICU 62 */ + USCRIPT_GUNJALA_GONDI = 179,/* Gong */ + /** @stable ICU 62 */ + USCRIPT_MAKASAR = 180,/* Maka */ + /** @stable ICU 62 */ + USCRIPT_MEDEFAIDRIN = 181,/* Medf */ + /** @stable ICU 62 */ + USCRIPT_HANIFI_ROHINGYA = 182,/* Rohg */ + /** @stable ICU 62 */ + USCRIPT_SOGDIAN = 183,/* Sogd */ + /** @stable ICU 62 */ + USCRIPT_OLD_SOGDIAN = 184,/* Sogo */ + + /** @stable ICU 64 */ + USCRIPT_ELYMAIC = 185,/* Elym */ + /** @stable ICU 64 */ + USCRIPT_NYIAKENG_PUACHUE_HMONG = 186,/* Hmnp */ + /** @stable ICU 64 */ + USCRIPT_NANDINAGARI = 187,/* Nand */ + /** @stable ICU 64 */ + USCRIPT_WANCHO = 188,/* Wcho */ + +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UScriptCode value. + * The highest value is available via u_getIntPropertyMaxValue(UCHAR_SCRIPT). + * + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + USCRIPT_CODE_LIMIT = 189 +#endif // U_HIDE_DEPRECATED_API } UScriptCode; /** - * Gets the script codes associated with the given locale or ISO 15924 abbreviation or name. + * Gets the script codes associated with the given locale or ISO 15924 abbreviation or name. * Fills in USCRIPT_MALAYALAM given "Malayam" OR "Mlym". - * Fills in USCRIPT_LATIN given "en" OR "en_US" + * Fills in USCRIPT_LATIN given "en" OR "en_US" * If the required capacity is greater than the capacity of the destination buffer, * then the error code is set to U_BUFFER_OVERFLOW_ERROR and the required capacity is returned. * @@ -452,12 +500,12 @@ typedef enum UScriptCode { * @param nameOrAbbrOrLocale name of the script, as given in * PropertyValueAliases.txt, or ISO 15924 code or locale * @param fillIn the UScriptCode buffer to fill in the script code - * @param capacity the capacity (size) fo UScriptCode buffer passed in. + * @param capacity the capacity (size) of UScriptCode buffer passed in. * @param err the error status code. - * @return The number of script codes filled in the buffer passed in + * @return The number of script codes filled in the buffer passed in * @stable ICU 2.4 */ -U_STABLE int32_t U_EXPORT2 +U_STABLE int32_t U_EXPORT2 uscript_getCode(const char* nameOrAbbrOrLocale,UScriptCode* fillIn,int32_t capacity,UErrorCode *err); /** @@ -470,7 +518,7 @@ uscript_getCode(const char* nameOrAbbrOrLocale,UScriptCode* fillIn,int32_t capac * or NULL if scriptCode is invalid * @stable ICU 2.4 */ -U_STABLE const char* U_EXPORT2 +U_STABLE const char* U_EXPORT2 uscript_getName(UScriptCode scriptCode); /** @@ -482,18 +530,18 @@ uscript_getName(UScriptCode scriptCode); * @return short script name (4-letter code), or NULL if scriptCode is invalid * @stable ICU 2.4 */ -U_STABLE const char* U_EXPORT2 +U_STABLE const char* U_EXPORT2 uscript_getShortName(UScriptCode scriptCode); /** * Gets the script code associated with the given codepoint. - * Returns USCRIPT_MALAYALAM given 0x0D02 + * Returns USCRIPT_MALAYALAM given 0x0D02 * @param codepoint UChar32 codepoint * @param err the error status code. - * @return The UScriptCode, or 0 if codepoint is invalid + * @return The UScriptCode, or 0 if codepoint is invalid * @stable ICU 2.4 */ -U_STABLE UScriptCode U_EXPORT2 +U_STABLE UScriptCode U_EXPORT2 uscript_getScript(UChar32 codepoint, UErrorCode *err); /** @@ -503,9 +551,6 @@ uscript_getScript(UChar32 codepoint, UErrorCode *err); * * Some characters are commonly used in multiple scripts. * For more information, see UAX #24: http://www.unicode.org/reports/tr24/. - * - * The Script_Extensions property is provisional. It may be modified or removed - * in future versions of the Unicode Standard, and thus in ICU. * @param c code point * @param sc script code * @return TRUE if sc is in Script_Extensions(c) @@ -532,8 +577,6 @@ uscript_hasScript(UChar32 c, UScriptCode sc); * U_BUFFER_OVERFLOW_ERROR is set and the number of Script_Extensions is returned. * (Usual ICU buffer handling behavior.) * - * The Script_Extensions property is provisional. It may be modified or removed - * in future versions of the Unicode Standard, and thus in ICU. * @param c code point * @param scripts output script code array * @param capacity capacity of the scripts array @@ -605,7 +648,7 @@ U_NAMESPACE_END U_COMMON_API icu::UnicodeString U_EXPORT2 uscript_getSampleUnicodeString(UScriptCode script); -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Returns the script usage according to UAX #31 Unicode Identifier and Pattern Syntax. diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/usearch.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/usearch.h index 75521f528a..313c3b9a7d 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/usearch.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/usearch.h @@ -1,3 +1,5 @@ +// © 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; /** @@ -253,20 +257,21 @@ typedef enum { * match an e with the same diacritic or a plain e in the searched text. * * This option is similar to "asymmetric search" as described in - * - * UTS #10 Unicode Collation AlgorithmU_BUFFER_OVERFLOW_ERROR is set, then * the return value indicates the necessary destination buffer size. * @stable ICU 2.0 diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uspoof.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uspoof.h index 8d665e1b3e..b27a14237a 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uspoof.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uspoof.h @@ -1,10 +1,12 @@ +// © 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 -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -28,130 +30,342 @@ #if U_SHOW_CPLUSPLUS_API #include "unicode/unistr.h" #include "unicode/uniset.h" -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * \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). + *

      + * This class, based on Unicode Technical Report #36 and + * Unicode Technical Standard #39, has two main functions: + * + *

        + *
      1. Checking whether two strings are visually confusable with each other, such as "Harvest" and + * "Ηarvest", where the second string starts with the Greek capital letter Eta.
      2. + *
      3. Checking whether an individual string is likely to be an attempt at confusing the reader (spoof + * detection), such as "paypal" with some Latin characters substituted with Cyrillic look-alikes.
      4. + *
      + * + *

      + * Although originally designed as a method for flagging suspicious identifier strings such as URLs, + * USpoofChecker has a number of other practical use cases, such as preventing attempts to evade bad-word + * content filters. + * + *

      + * The functions of this class are exposed as C API, with a handful of syntactical conveniences for C++. + * + *

      Confusables

      + * + *

      + * The following example shows how to use USpoofChecker 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 + * + *

      + * The call to {@link uspoof_open} creates a USpoofChecker 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. + * + *

      + * 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 + * + * UTS 39 defines two strings to be confusable if they map to the same skeleton string. 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 + * + * 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; iNote: Since the Unicode confusables mapping table is frequently updated, confusable skeletons are not + * 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. + * + *

      Spoof Detection

      + * + * The following snippet shows a minimal example of using USpoofChecker 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 + * + * As in the case for confusability checking, it is good practice to create one USpoofChecker 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. + * + * 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. + * + * 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 + * + * 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: + * + *
        + *
      • RESTRICTION_LEVEL: flags strings that violate the + * Restriction Level test as specified in UTS + * 39; in most cases, this means flagging strings that contain characters from multiple different scripts.
      • + *
      • INVISIBLE: 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.
      • + *
      • CHAR_LIMIT: flags strings that contain characters outside of a specified set of acceptable + * characters. See {@link uspoof_setAllowedChars} and {@link uspoof_setAllowedLocales}.
      • + *
      • MIXED_NUMBERS: flags strings that contain digits from multiple different numbering systems.
      • + *
      + * + *

      + * 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 + * + * 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 + * + * 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. + * + * Note: The Restriction Level is the most powerful of the checks. The full logic is documented in + * UTS 39, but the basic idea is that strings + * are restricted to contain characters from only a single script, except that most scripts are allowed to have + * Latin characters interspersed. Although the default restriction level is HIGHLY_RESTRICTIVE, it is + * recommended that users set their restriction level to MODERATELY_RESTRICTIVE, 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. + * + *

      Additional Information

      + * + * A USpoofChecker instance 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 USpoofChecker are not thread safe.. + * + * @stable ICU 4.6 */ struct USpoofChecker; +/** + * @stable ICU 4.2 + */ typedef struct USpoofChecker USpoofChecker; /**< typedef for C of USpoofChecker */ +struct USpoofCheckResult; +/** + * @see uspoof_openCheckResult + * @stable ICU 58 + */ +typedef struct USpoofCheckResult USpoofCheckResult; + /** * 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 +374,59 @@ 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 not 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. */ + + /** + * 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 + * @stable ICU 58 + */ + USPOOF_CONFUSABLE = USPOOF_SINGLE_SCRIPT_CONFUSABLE | USPOOF_MIXED_SCRIPT_CONFUSABLE | USPOOF_WHOLE_SCRIPT_CONFUSABLE, + +#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(). @@ -211,7 +439,7 @@ typedef enum USpoofChecks { */ USPOOF_RESTRICTION_LEVEL = 16, -#ifndef U_HIDE_DEPRECATED_API +#ifndef U_HIDE_DEPRECATED_API /** Check that an identifier contains only characters from a * single script (plus chars from the common and inherited scripts.) * Applies to checks of a single identifier check only. @@ -219,7 +447,7 @@ typedef enum USpoofChecks { */ USPOOF_SINGLE_SCRIPT = USPOOF_RESTRICTION_LEVEL, #endif /* U_HIDE_DEPRECATED_API */ - + /** 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 @@ -229,97 +457,142 @@ 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 */ USPOOF_MIXED_NUMBERS = 128, +#ifndef U_HIDE_DRAFT_API + /** + * Check that an identifier does not have a combining character following a character in which that + * combining character would be hidden; for example 'i' followed by a U+0307 combining dot. + * + * More specifically, the following characters are forbidden from preceding a U+0307: + *
        + *
      • Those with the Soft_Dotted Unicode property (which includes 'i' and 'j')
      • + *
      • Latin lowercase letter 'l'
      • + *
      • Dotless 'i' and 'j' ('ı' and 'ȷ', U+0131 and U+0237)
      • + *
      • Any character whose confusable prototype ends with such a character + * (Soft_Dotted, 'l', 'ı', or 'ȷ')
      • + *
      + * In addition, combining characters are allowed between the above characters and U+0307 except those + * with combining class 0 or combining class "Above" (230, same class as U+0307). + * + * This list and the number of combing characters considered by this check may grow over time. + * + * @draft ICU 62 + */ + USPOOF_HIDDEN_OVERLAY = 256, +#endif /* U_HIDE_DRAFT_API */ + /** * Enable all spoof checks. - * + * * @stable ICU 4.6 */ USPOOF_ALL_CHECKS = 0xFFFF, /** * Enable the return of auxillary (non-error) information in the - * upper bits of the check results value. + * 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 */ USPOOF_AUX_INFO = 0x40000000 } 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: + *
        + *
      • Latin + Han + Bopomofo (or equivalently: Latn + Hanb)
      • + *
      • Latin + Han + Hiragana + Katakana (or equivalently: Latn + Jpan)
      • + *
      • Latin + Han + Hangul (or equivalently: Latn +Kore)
      • + *
      + * 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 */ USPOOF_MINIMALLY_RESTRICTIVE = 0x50000000, /** * Any valid identifiers, including characters outside of the Identifier Profile. - * + * * @stable ICU 51 */ 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; /** - * Create a Unicode Spoof Checker, configured to perform all + * Create a Unicode Spoof Checker, configured to perform all * checks except for USPOOF_LOCALE_LIMIT and USPOOF_CHAR_LIMIT. * Note that additional checks may be added in the future, * resulting in the changes to the default checking behavior. @@ -359,10 +632,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 +644,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 @@ -419,7 +691,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUSpoofCheckerPointer, USpoofChecker, uspoof_clo U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Clone a Spoof Checker. The clone will be set to perform the same checks @@ -435,8 +707,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: + * + *
      + * {@code
      + * uspoof_setChecks(USPOOF_CHAR_LIMIT | USPOOF_MIXED_NUMBERS);
      + * }
      + * 
      + * + * 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: + * + *
      + * {@code
      + * uspoof_setChecks(USPOOF_ALL_CHECKS & ~USPOOF_CONFUSABLE);
      + * }
      + * 
      + * + * 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. @@ -451,7 +748,7 @@ uspoof_setChecks(USpoofChecker *sc, int32_t checks, UErrorCode *status); /** * Get the set of checks that this Spoof Checker has been configured to perform. - * + * * @param sc The USpoofChecker * @param status The error code, set if this function encounters a problem. * @return The set of checks that this spoof checker will perform. @@ -464,19 +761,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 @@ -486,7 +786,7 @@ U_STABLE URestrictionLevel U_EXPORT2 uspoof_getRestrictionLevel(const USpoofChecker *sc); /** - * Limit characters that are acceptable in identifiers being checked to those + * Limit characters that are acceptable in identifiers being checked to those * normally used with the languages associated with the specified locales. * Any previously specified list of locales is replaced by the new settings. * @@ -499,7 +799,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,9 +811,9 @@ 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 sc The USpoofChecker * @param localesList A list list of locales, from which the language * and associated script are extracted. The locales * are comma-separated if there is more than one. @@ -537,18 +837,18 @@ uspoof_setAllowedLocales(USpoofChecker *sc, const char *localesList, UErrorCode * * uspoof_setAllowedChars() will reset the list of allowed to be empty. * - * The format of the returned list is the same as that supplied to - * uspoof_setAllowedLocales(), but returned list may not be identical - * to the originally specified string; the string may be reformatted, + * The format of the returned list is the same as that supplied to + * uspoof_setAllowedLocales(), but returned list may not be identical + * to the originally specified string; the string may be reformatted, * and information other than languages from * the originally specified locales may be omitted. * - * @param sc The USpoofChecker + * @param sc The USpoofChecker * @param status The error code, set if this function encounters a problem. * @return A string containing a list of locales corresponding * to the acceptable scripts, formatted like an * HTTP Accept Language value. - * + * * @stable ICU 4.2 */ U_STABLE const char * U_EXPORT2 @@ -564,7 +864,7 @@ uspoof_getAllowedLocales(USpoofChecker *sc, UErrorCode *status); * The USPOOF_CHAR_LIMIT test is automatically enabled for this * USpoofChecker by this function. * - * @param sc The USpoofChecker + * @param sc The USpoofChecker * @param chars A Unicode Set containing the list of * characters that are permitted. Ownership of the set * remains with the caller. The incoming set is cloned by @@ -591,7 +891,7 @@ uspoof_setAllowedChars(USpoofChecker *sc, const USet *chars, UErrorCode *status) * or if a new set of allowed characters is specified. * * - * @param sc The USpoofChecker + * @param sc The USpoofChecker * @param status The error code, set if this function encounters a problem. * @return A USet containing the characters that are permitted by * the USPOOF_CHAR_LIMIT test. @@ -611,7 +911,7 @@ uspoof_getAllowedChars(const USpoofChecker *sc, UErrorCode *status); * The USPOOF_CHAR_LIMIT test is automatically enabled for this * USoofChecker by this function. * - * @param sc The USpoofChecker + * @param sc The USpoofChecker * @param chars A Unicode Set containing the list of * characters that are permitted. Ownership of the set * remains with the caller. The incoming set is cloned by @@ -626,7 +926,7 @@ uspoof_setAllowedUnicodeSet(USpoofChecker *sc, const icu::UnicodeSet *chars, UEr /** * Get a UnicodeSet for the characters permitted in an identifier. - * This corresponds to the limits imposed by the Set Allowed Characters / + * This corresponds to the limits imposed by the Set Allowed Characters / * UnicodeSet functions. Limitations imposed by other checks will not be * reflected in the set returned by this function. * @@ -638,7 +938,7 @@ uspoof_setAllowedUnicodeSet(USpoofChecker *sc, const icu::UnicodeSet *chars, UEr * or if a new set of allowed characters is specified. * * - * @param sc The USpoofChecker + * @param sc The USpoofChecker * @param status The error code, set if this function encounters a problem. * @return A UnicodeSet containing the characters that are permitted by * the USPOOF_CHAR_LIMIT test. @@ -646,24 +946,29 @@ uspoof_setAllowedUnicodeSet(USpoofChecker *sc, const icu::UnicodeSet *chars, UEr */ U_STABLE const icu::UnicodeSet * U_EXPORT2 uspoof_getAllowedUnicodeSet(const USpoofChecker *sc, UErrorCode *status); -#endif +#endif // 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 + * + * \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 + * 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,11 +978,12 @@ 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 uspoof_check(const USpoofChecker *sc, - const UChar *id, int32_t length, + const UChar *id, int32_t length, int32_t *position, UErrorCode *status); @@ -686,16 +992,20 @@ uspoof_check(const USpoofChecker *sc, * 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 + * + * \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 + * @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 +1017,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 @@ -721,14 +1032,18 @@ uspoof_checkUTF8(const USpoofChecker *sc, * 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 + * + * \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,45 +1053,254 @@ 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 uspoof_checkUnicodeString(const USpoofChecker *sc, - const icu::UnicodeString &id, + const icu::UnicodeString &id, int32_t *position, UErrorCode *status); +#endif // U_SHOW_CPLUSPLUS_API -#endif + +/** + * 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 + * @stable ICU 58 + */ +U_STABLE 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 + * @stable ICU 58 + */ +U_STABLE 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 + * @stable ICU 58 + */ +U_STABLE int32_t U_EXPORT2 +uspoof_check2UnicodeString(const USpoofChecker *sc, + const icu::UnicodeString &id, + USpoofCheckResult* checkResult, + UErrorCode *status); +#endif // U_SHOW_CPLUSPLUS_API + +/** + * Create a USpoofCheckResult, used by the {@link uspoof_check2} class of functions to return + * information about the identifier. Information includes: + *
        + *
      • A bitmask of the checks that failed
      • + *
      • The identifier's restriction level (UTS 39 section 5.2)
      • + *
      • The set of numerics in the string (UTS 39 section 5.3)
      • + *
      + * 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 + * @stable ICU 58 + */ +U_STABLE 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 + * @stable ICU 58 + */ +U_STABLE void U_EXPORT2 +uspoof_closeCheckResult(USpoofCheckResult *checkResult); + +#if U_SHOW_CPLUSPLUS_API + +U_NAMESPACE_BEGIN + +/** + * \class LocalUSpoofCheckResultPointer + * "Smart pointer" class, closes a USpoofCheckResult via `uspoof_closeCheckResult()`. + * For most methods see the LocalPointerBase base class. + * + * @see LocalPointerBase + * @see LocalPointer + * @stable ICU 58 + */ + +/** + * \cond + * Note: Doxygen is giving a bogus warning on this U_DEFINE_LOCAL_OPEN_POINTER. + * For now, suppress with a Doxygen cond + */ +U_DEFINE_LOCAL_OPEN_POINTER(LocalUSpoofCheckResultPointer, USpoofCheckResult, uspoof_closeCheckResult); +/** \endcond */ + +U_NAMESPACE_END + +#endif // U_SHOW_CPLUSPLUS_API + +/** + * 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 + * @stable ICU 58 + */ +U_STABLE 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 + * @stable ICU 58 + */ +U_STABLE 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. + * @stable ICU 58 + */ +U_STABLE const USet* U_EXPORT2 +uspoof_getCheckResultNumerics(const USpoofCheckResult *checkResult, UErrorCode *status); /** * 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. - * - * 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 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: + * + *
        + *
      • {@link USPOOF_SINGLE_SCRIPT_CONFUSABLE}
      • + *
      • {@link USPOOF_MIXED_SCRIPT_CONFUSABLE}
      • + *
      • {@link USPOOF_WHOLE_SCRIPT_CONFUSABLE}
      • + *
      + * + * 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 - * @param id1 The first of the two identifiers to be compared for + * @param id1 The first of the two identifiers to be compared for * confusability. The strings are in UTF-16 format. * @param length1 the length of the first identifer, expressed in - * 16 bit UTF-16 code units, or -1 if the string is + * 16 bit UTF-16 code units, or -1 if the string is * nul terminated. - * @param id2 The second of the two identifiers to be compared for + * @param id2 The second of the two identifiers to be compared for * confusability. The identifiers are in UTF-16 format. * @param length2 The length of the second identifiers, expressed in - * 16 bit UTF-16 code units, or -1 if the string is + * 16 bit UTF-16 code units, or -1 if the string is * nul terminated. * @param status The error code, set if an error occurred while attempting to * perform the check. @@ -786,6 +1310,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,19 +1322,16 @@ 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 + * @param id1 The first of the two identifiers to be compared for * confusability. The strings are in UTF-8 format. - * @param length1 the length of the first identifiers, in bytes, or -1 + * @param length1 the length of the first identifiers, in bytes, or -1 * if the string is nul terminated. - * @param id2 The second of the two identifiers to be compared for + * @param id2 The second of the two identifiers to be compared for * confusability. The strings are in UTF-8 format. - * @param length2 The length of the second string in bytes, or -1 + * @param length2 The length of the second string in bytes, or -1 * if the string is nul terminated. * @param status The error code, set if an error occurred while attempting to * perform the check. @@ -819,7 +1341,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,15 +1357,12 @@ 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 + * @param s1 The first of the two identifiers to be compared for * confusability. The strings are in UTF-8 format. - * @param s2 The second of the two identifiers to be compared for + * @param s2 The second of the two identifiers to be compared for * confusability. The strings are in UTF-8 format. * @param status The error code, set if an error occurred while attempting to * perform the check. @@ -850,134 +1372,133 @@ 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, const icu::UnicodeString &s1, const icu::UnicodeString &s2, UErrorCode *status); -#endif +#endif // 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 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, const UChar *id, int32_t length, UChar *dest, int32_t destCapacity, 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, const char *id, int32_t length, char *dest, int32_t destCapacity, UErrorCode *status); - + #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, const icu::UnicodeString &id, icu::UnicodeString &dest, UErrorCode *status); -#endif /* U_SHOW_CPLUSPLUS_API */ +#endif // U_SHOW_CPLUSPLUS_API /** * 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 +1512,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 +1529,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 +1544,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. @@ -1033,7 +1557,7 @@ uspoof_getInclusionUnicodeSet(UErrorCode *status); U_STABLE const icu::UnicodeSet * U_EXPORT2 uspoof_getRecommendedUnicodeSet(UErrorCode *status); -#endif /* U_SHOW_CPLUSPLUS_API */ +#endif // U_SHOW_CPLUSPLUS_API /** * Serialize the data for a spoof detector into a chunk of memory. @@ -1041,7 +1565,7 @@ uspoof_getRecommendedUnicodeSet(UErrorCode *status); * instantiate a new Spoof Detector. * * The serialized spoof checker includes only the data compiled from the - * Unicode data tables by uspoof_openFromSource(); it does not include + * Unicode data tables by uspoof_openFromSource(); it does not include * include any other state or configuration that may have been set. * * @param sc the Spoof Detector whose data is to be serialized. diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/usprep.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/usprep.h index 638c32ee16..8cb52f1ede 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/usprep.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/usprep.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -6,7 +8,7 @@ * ******************************************************************************* * file name: usprep.h - * encoding: US-ASCII + * encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -31,14 +33,14 @@ * StringPrep prepares Unicode strings for use in network protocols. * Profiles of StingPrep are set of rules and data according to with the * Unicode Strings are prepared. Each profiles contains tables which describe - * how a code point should be treated. The tables are broadly classied into + * how a code point should be treated. The tables are broadly classified into *
        - *
      • Unassinged Table: Contains code points that are unassigned + *
      • Unassigned Table: Contains code points that are unassigned * in the Unicode Version supported by StringPrep. Currently * RFC 3454 supports Unicode 3.2.
      • - *
      • Prohibited Table: Contains code points that are prohibted from + *
      • Prohibited Table: Contains code points that are prohibited from * the output of the StringPrep processing function.
      • - *
      • Mapping Table: Contains code ponts that are deleted from the output or case mapped.
      • + *
      • Mapping Table: Contains code points that are deleted from the output or case mapped.
      • *
      * * The procedure for preparing Unicode strings: @@ -224,11 +226,11 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUStringPrepProfilePointer, UStringPrepProfile, U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Prepare the input buffer for use in applications with the given profile. This operation maps, normalizes(NFKC), - * checks for prohited and BiDi characters in the order defined by RFC 3454 + * checks for prohibited and BiDi characters in the order defined by RFC 3454 * depending on the options specified in the profile. * * @param prep The profile to use diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ustdio.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ustdio.h index 16bcf35eec..a2ad3c2442 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ustdio.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ustdio.h @@ -1,7 +1,9 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * -* Copyright (C) 1998-2014, International Business Machines +* Copyright (C) 1998-2015, International Business Machines * Corporation and others. All Rights Reserved. * ****************************************************************************** @@ -243,7 +245,6 @@ u_fopen(const char *filename, const char *locale, const char *codepage); -#ifndef U_HIDE_DRAFT_API /** * Open a UFILE with a UChar* filename * A UFILE is a wrapper around a FILE* that is locale and codepage aware. @@ -259,14 +260,13 @@ u_fopen(const char *filename, * read from the file. If this paramter is NULL the system default codepage * will be used. * @return A new UFILE, or NULL if an error occurred. - * @draft ICU 54 + * @stable ICU 54 */ -U_DRAFT UFILE* U_EXPORT2 +U_STABLE UFILE* U_EXPORT2 u_fopen_u(const UChar *filename, const char *perm, const char *locale, const char *codepage); -#endif /* U_HIDE_DRAFT_API */ /** * Open a UFILE on top of an existing FILE* stream. The FILE* stream @@ -355,7 +355,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUFILEPointer, UFILE, u_fclose); U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Tests if the UFILE is at the end of the file stream. diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ustream.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ustream.h index 41ccf5ae03..f185c453f8 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ustream.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ustream.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2014 International Business Machines @@ -28,18 +30,13 @@ * C++ I/O stream API. */ -#if !defined(_MSC_VER) +#if defined(__GLIBCXX__) namespace std { class type_info; } // WORKAROUND: http://llvm.org/bugs/show_bug.cgi?id=13364 #endif -#if U_IOSTREAM_SOURCE >= 199711 -#if (__GNUC__ == 2) #include -#else -#include -#include -#endif +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN /** @@ -59,10 +56,10 @@ U_IO_API std::ostream & U_EXPORT2 operator<<(std::ostream& stream, const Unicode */ U_IO_API std::istream & U_EXPORT2 operator>>(std::istream& stream, UnicodeString& s); U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* No operator for UChar because it can conflict with wchar_t */ #endif -#endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ustring.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ustring.h index 6d141e8df6..b173907dbf 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ustring.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ustring.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1998-2014, International Business Machines @@ -401,7 +403,7 @@ u_strspn(const UChar *string, const UChar *matchSet); * @param saveState The current pointer within the original string, * which is set by this function. The saveState * parameter should the address of a local variable of type - * UChar *. (i.e. defined "Uhar *myLocalSaveState" and use + * UChar *. (i.e. defined "UChar *myLocalSaveState" and use * &myLocalSaveState for this parameter). * @return A pointer to the next token found in src, or NULL * when there are no more tokens. @@ -495,16 +497,6 @@ u_strCompare(const UChar *s1, int32_t length1, U_STABLE int32_t U_EXPORT2 u_strCompareIter(UCharIterator *iter1, UCharIterator *iter2, UBool codePointOrder); -#ifndef U_COMPARE_CODE_POINT_ORDER -/* see also unistr.h and unorm.h */ -/** - * Option bit for u_strCaseCompare, u_strcasecmp, unorm_compare, etc: - * Compare strings in code point order instead of code unit order. - * @stable ICU 2.2 - */ -#define U_COMPARE_CODE_POINT_ORDER 0x8000 -#endif - /** * Compare two strings case-insensitively using full case folding. * This is equivalent to @@ -892,7 +884,7 @@ u_memrchr32(const UChar *s, UChar32 c, int32_t count); * Unicode String literals in C. * We need one macro to declare a variable for the string * and to statically preinitialize it if possible, - * and a second macro to dynamically intialize such a string variable if necessary. + * and a second macro to dynamically initialize such a string variable if necessary. * * The macros are defined for maximum performance. * They work only for strings that contain "invariant characters", i.e., @@ -903,35 +895,32 @@ u_memrchr32(const UChar *s, UChar32 c, int32_t count); * parameters. * The string parameter must be a C string literal. * The length of the string, not including the terminating - * NUL, must be specified as a constant. + * `NUL`, must be specified as a constant. * The U_STRING_DECL macro should be invoked exactly once for one * such string variable before it is used. * * Usage: - *
      - *    U_STRING_DECL(ustringVar1, "Quick-Fox 2", 11);
      - *    U_STRING_DECL(ustringVar2, "jumps 5%", 8);
      - *    static UBool didInit=FALSE;
      - * 
      - *    int32_t function() {
      - *        if(!didInit) {
      - *            U_STRING_INIT(ustringVar1, "Quick-Fox 2", 11);
      - *            U_STRING_INIT(ustringVar2, "jumps 5%", 8);
      - *            didInit=TRUE;
      - *        }
      - *        return u_strcmp(ustringVar1, ustringVar2);
      - *    }
      - * 
      + * + * U_STRING_DECL(ustringVar1, "Quick-Fox 2", 11); + * U_STRING_DECL(ustringVar2, "jumps 5%", 8); + * static UBool didInit=FALSE; + * + * int32_t function() { + * if(!didInit) { + * U_STRING_INIT(ustringVar1, "Quick-Fox 2", 11); + * U_STRING_INIT(ustringVar2, "jumps 5%", 8); + * didInit=TRUE; + * } + * return u_strcmp(ustringVar1, ustringVar2); + * } * - * Note that the macros will NOT consistently work if their argument is another #define. - * The following will not work on all platforms, don't use it. + * Note that the macros will NOT consistently work if their argument is another #`define`. + * The following will not work on all platforms, don't use it. * - *
        *     #define GLUCK "Mr. Gluck"
        *     U_STRING_DECL(var, GLUCK, 9)
        *     U_STRING_INIT(var, GLUCK, 9)
      - * 
      - * + * * Instead, use the string literal "Mr. Gluck" as the argument to both macro * calls. * @@ -1697,4 +1686,36 @@ u_strFromJavaModifiedUTF8WithSub( UChar32 subchar, int32_t *pNumSubstitutions, UErrorCode *pErrorCode); +#ifndef U_HIDE_INTERNAL_API +/** + * Check whether the string is well-formed according to various criteria: + * - No code points that are defined as non-characters (e.g. 0xFFFF) or are undefined in + * the version of Unicode currently supported. + * - No isolated surrogate code points. + * - No overly-long sequences of non-starter combining marks, i.e. more than 30 characters + * in a row with non-zero combining class (which may have category Mn or Mc); this + * violates Stream-Safe Text Format per UAX #15. This test does not ensure that the + * string satisfies Stream-Safe Text Format (because it does not convert to NFKC first), + * but any string that fails this test is certainly not Stream-Safe. + * - No emoji variation selectors applied to non-emoji code points. This function may + * also check for other non-standard variation sequences. + * - No tag sequences that are ill-formed per definition ED-14a in UTS #51 (e.g. tag + * sequences must have an emoji base and a terminator). + * - Bidi controls do not lead to a bidi embedding level of greater than max_depth (125) + * approximately according to the algorithm in + * [https://www.unicode.org/reports/tr9/#Explicit_Levels_and_Directions] + * (we do not evaluate paragraph direction or FSI direction so may actually toerate a + * level or two beyond the official limit in some cases) + * + * @param s The input string. + * @param length The length of the string, or -1 if it is NUL-terminated. + * @return Boolean value for whether the string is well-formed according to the + * specified criteria. + * @internal Apple only + */ +U_INTERNAL UBool U_EXPORT2 +u_strIsWellFormed(const UChar *s, int32_t length); + +#endif /* U_HIDE_INTERNAL_API */ + #endif diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ustringtrie.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ustringtrie.h index 871d0f887a..fd85648225 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ustringtrie.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/ustringtrie.h @@ -1,10 +1,12 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2010-2012, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* * file name: udicttrie.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utext.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utext.h index d431913d35..921408ae1c 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utext.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utext.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -6,7 +8,7 @@ * ******************************************************************************* * file name: utext.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -142,7 +144,7 @@ #include "unicode/rep.h" #include "unicode/unistr.h" #include "unicode/chariter.h" -#endif +#endif // U_SHOW_CPLUSPLUS_API U_CDECL_BEGIN @@ -198,7 +200,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUTextPointer, UText, utext_close); U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Open a read-only UText implementation for UTF-8 strings. @@ -306,7 +308,7 @@ utext_openReplaceable(UText *ut, icu::Replaceable *rep, UErrorCode *status); U_STABLE UText * U_EXPORT2 utext_openCharacterIterator(UText *ut, icu::CharacterIterator *ci, UErrorCode *status); -#endif +#endif // U_SHOW_CPLUSPLUS_API /** @@ -387,7 +389,7 @@ utext_equals(const UText *a, const UText *b); /***************************************************************************** * - * Functions to work with the text represeted by a UText wrapper + * Functions to work with the text represented by a UText wrapper * *****************************************************************************/ @@ -431,7 +433,7 @@ utext_isLengthExpensive(const UText *ut); * * The iteration position will be set to the start of the returned code point. * - * This function is roughly equivalent to the the sequence + * This function is roughly equivalent to the sequence * utext_setNativeIndex(index); * utext_current32(); * (There is a subtle difference if the index is out of bounds by being less than zero - @@ -590,7 +592,7 @@ U_STABLE void U_EXPORT2 utext_setNativeIndex(UText *ut, int64_t nativeIndex); /** - * Move the iterator postion by delta code points. The number of code points + * Move the iterator position by delta code points. The number of code points * is a signed number; a negative delta will move the iterator backwards, * towards the start of the text. *

      @@ -609,7 +611,7 @@ U_STABLE UBool U_EXPORT2 utext_moveIndex32(UText *ut, int32_t delta); /** - * Get the native index of the character preceeding the current position. + * Get the native index of the character preceding the current position. * If the iteration position is already at the start of the text, zero * is returned. * The value returned is the same as that obtained from the following sequence, @@ -626,7 +628,7 @@ utext_moveIndex32(UText *ut, int32_t delta); * native index of the character most recently returned from utext_next(). * * @param ut the text to be accessed - * @return the native index of the character preceeding the current index position, + * @return the native index of the character preceding the current index position, * or zero if the current position is at the start of the text. * @stable ICU 3.6 */ @@ -653,10 +655,10 @@ utext_getPreviousNativeIndex(UText *ut); * @param ut the UText from which to extract data. * @param nativeStart the native index of the first character to extract.\ * If the specified index is out of range, - * it will be pinned to to be within 0 <= index <= textLength + * it will be pinned to be within 0 <= index <= textLength * @param nativeLimit the native string index of the position following the last * character to extract. If the specified index is out of range, - * it will be pinned to to be within 0 <= index <= textLength. + * it will be pinned to be within 0 <= index <= textLength. * nativeLimit must be >= nativeStart. * @param dest the UChar (UTF-16) buffer into which the extracted text is placed * @param destCapacity The size, in UChars, of the destination buffer. May be zero @@ -764,12 +766,24 @@ utext_extract(UText *ut, * * @stable ICU 3.8 */ +#if LOG_UTEXT_SETNATIVEINDEX +/* Add logging for */ #define UTEXT_SETNATIVEINDEX(ut, ix) \ { int64_t __offset = (ix) - (ut)->chunkNativeStart; \ - if (__offset>=0 && __offset<=(int64_t)(ut)->nativeIndexingLimit) { \ + if ((ut)->chunkContents!=0 && __offset>=0 && __offset<(int64_t)(ut)->nativeIndexingLimit && (ut)->chunkContents[__offset]<0xdc00) { \ (ut)->chunkOffset=(int32_t)__offset; \ + } else if ((ut)->chunkContents==0 && __offset>=0 && __offset<(int64_t)(ut)->nativeIndexingLimit) { \ + os_log(OS_LOG_DEFAULT, "# UTEXT_SETNATIVEINDEX (ut) %p, (ut)->chunkContents 0, __offset %lld", (ut), __offset); \ } else { \ utext_setNativeIndex((ut), (ix)); } } +#else +#define UTEXT_SETNATIVEINDEX(ut, ix) \ + { int64_t __offset = (ix) - (ut)->chunkNativeStart; \ + if ((ut)->chunkContents!=0 && __offset>=0 && __offset<(int64_t)(ut)->nativeIndexingLimit && (ut)->chunkContents[__offset]<0xdc00) { \ + (ut)->chunkOffset=(int32_t)__offset; \ + } else { \ + utext_setNativeIndex((ut), (ix)); } } +#endif @@ -904,7 +918,7 @@ utext_copy(UText *ut, * Caution: freezing a UText will disable changes made via the specific * frozen UText wrapper only; it will not have any effect on the ability to * directly modify the text by bypassing the UText. Any such backdoor modifications - * are always an error while UText access is occuring because the underlying + * are always an error while UText access is occurring because the underlying * text can get out of sync with UText's buffering. *

      * @@ -1052,7 +1066,7 @@ UTextAccess(UText *ut, int64_t nativeIndex, UBool forward); * be NUL-terminated if there is sufficient space in the destination buffer. * * @param ut the UText from which to extract data. - * @param nativeStart the native index of the first characer to extract. + * @param nativeStart the native index of the first character to extract. * @param nativeLimit the native string index of the position following the last * character to extract. * @param dest the UChar (UTF-16) buffer into which the extracted text is placed @@ -1209,7 +1223,7 @@ UTextClose(UText *ut); struct UTextFuncs { /** * (public) Function table size, sizeof(UTextFuncs) - * Intended for use should the table grow to accomodate added + * Intended for use should the table grow to accommodate added * functions in the future, to allow tests for older format * function tables that do not contain the extensions. * @@ -1343,7 +1357,7 @@ typedef struct UTextFuncs UTextFuncs; struct UText { /** * (private) Magic. Used to help detect when UText functions are handed - * invalid or unitialized UText structs. + * invalid or uninitialized UText structs. * utext_openXYZ() functions take an initialized, * but not necessarily open, UText struct as an * optional fill-in parameter. This magic field @@ -1365,7 +1379,7 @@ struct UText { /** - * Text provider properties. This set of flags is maintainted by the + * Text provider properties. This set of flags is maintained by the * text provider implementation. * @stable ICU 3.4 */ @@ -1450,7 +1464,7 @@ struct UText { void *pExtra; /** - * (protected) Pointer to string or text-containin object or similar. + * (protected) Pointer to string or text-containing object or similar. * This is the source of the text that this UText is wrapping, in a format * that is known to the text provider functions. * @stable ICU 3.4 @@ -1553,7 +1567,7 @@ struct UText { U_STABLE UText * U_EXPORT2 utext_setup(UText *ut, int32_t extraSpace, UErrorCode *status); -#ifndef U_HIDE_INTERNAL_API +// do not use #ifndef U_HIDE_INTERNAL_API around the following! /** * @internal * Value used to help identify correctly initialized UText structs. @@ -1562,7 +1576,6 @@ utext_setup(UText *ut, int32_t extraSpace, UErrorCode *status); enum { UTEXT_MAGIC = 0x345ad82c }; -#endif /* U_HIDE_INTERNAL_API */ /** * initializer to be used with local (stack) instances of a UText diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf.h index f5954fe9fe..ef512997f0 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -6,7 +8,7 @@ * ******************************************************************************* * file name: utf.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -21,9 +23,6 @@ * This file defines macros for checking whether a code point is * a surrogate or a non-character etc. * - * The UChar and UChar32 data types for Unicode code units and code points - * are defined in umachine.h because they can be machine-dependent. - * * If U_NO_DEFAULT_INCLUDE_UTF_HEADERS is 0 then utf.h is included by utypes.h * and itself includes utf8.h and utf16.h after some * common definitions. @@ -48,11 +47,11 @@ * but are optimized for the much more frequently occurring BMP code points. * * umachine.h defines UChar to be an unsigned 16-bit integer. - * Where available, UChar is defined to be a char16_t - * or a wchar_t (if that is an unsigned 16-bit type), otherwise uint16_t. + * Since ICU 59, ICU uses char16_t in C++, UChar only in C, + * and defines UChar=char16_t by default. See the UChar API docs for details. * * UChar32 is defined to be a signed 32-bit integer (int32_t), large enough for a 21-bit - * Unicode code point (Unicode scalar value, 0..0x10ffff). + * Unicode code point (Unicode scalar value, 0..0x10ffff) and U_SENTINEL (-1). * Before ICU 2.4, the definition of UChar32 was similarly platform-dependent as * the definition of UChar. For details see the documentation for UChar32 itself. * @@ -61,11 +60,20 @@ * For actual Unicode character properties see uchar.h. * * By default, string operations must be done with error checking in case - * a string is not well-formed UTF-16. - * The macros will detect if a surrogate code unit is unpaired + * a string is not well-formed UTF-16 or UTF-8. + * + * The U16_ macros detect if a surrogate code unit is unpaired * (lead unit without trail unit or vice versa) and just return the unit itself * as the code point. * + * The U8_ macros detect illegal byte sequences and return a negative value. + * Starting with ICU 60, the observable length of a single illegal byte sequence + * skipped by one of these macros follows the Unicode 6+ recommendation + * which is consistent with the W3C Encoding Standard. + * + * There are ..._OR_FFFD versions of both U16_ and U8_ macros + * that return U+FFFD for illegal code unit sequences. + * * The regular "safe" macros require that the initial, passed-in string index * is within bounds. They only check the index when they read more than one * code unit. This is usually done with code similar to the following loop: @@ -89,10 +97,7 @@ * The performance differences are much larger here because UTF-8 provides so * many opportunities for malformed sequences. * The unsafe UTF-8 macros are entirely implemented inside the macro definitions - * and are fast, while the safe UTF-8 macros call functions for all but the - * trivial (ASCII) cases. - * (ICU 3.6 optimizes U8_NEXT() and U8_APPEND() to handle most other common - * characters inline as well.) + * and are fast, while the safe UTF-8 macros call functions for some complicated cases. * * Unlike with UTF-16, malformed sequences cannot be expressed with distinct * code point values (0..U+10ffff). They are indicated with negative values instead. @@ -124,8 +129,7 @@ */ #define U_IS_UNICODE_NONCHAR(c) \ ((c)>=0xfdd0 && \ - ((uint32_t)(c)<=0xfdef || ((c)&0xfffe)==0xfffe) && \ - (uint32_t)(c)<=0x10ffff) + ((c)<=0xfdef || ((c)&0xfffe)==0xfffe) && (c)<=0x10ffff) /** * Is c a Unicode code point value (0..U+10ffff) @@ -146,9 +150,7 @@ */ #define U_IS_UNICODE_CHAR(c) \ ((uint32_t)(c)<0xd800 || \ - ((uint32_t)(c)>0xdfff && \ - (uint32_t)(c)<=0x10ffff && \ - !U_IS_UNICODE_NONCHAR(c))) + (0xdfff<(c) && (c)<=0x10ffff && !U_IS_UNICODE_NONCHAR(c))) /** * Is this code point a BMP code point (U+0000..U+ffff)? diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf16.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf16.h index bdd88a8b9c..aca51b56a7 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf16.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf16.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -6,7 +8,7 @@ * ******************************************************************************* * file name: utf16.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -183,8 +185,8 @@ * * The length can be negative for a NUL-terminated string. * - * If the offset points to a single, unpaired surrogate, then that itself - * will be returned as the code point. + * If the offset points to a single, unpaired surrogate, then + * c is set to that unpaired surrogate. * Iteration through a string is more efficient with U16_NEXT_UNSAFE or U16_NEXT. * * @param s const UChar * string @@ -211,6 +213,49 @@ } \ } +/** + * Get a code point from a string at a random-access offset, + * without changing the offset. + * "Safe" macro, handles unpaired surrogates and checks for string boundaries. + * + * The offset may point to either the lead or trail surrogate unit + * for a supplementary code point, in which case the macro will read + * the adjacent matching surrogate as well. + * + * The length can be negative for a NUL-terminated string. + * + * If the offset points to a single, unpaired surrogate, then + * c is set to U+FFFD. + * Iteration through a string is more efficient with U16_NEXT_UNSAFE or U16_NEXT_OR_FFFD. + * + * @param s const UChar * string + * @param start starting string offset (usually 0) + * @param i string offset, must be start<=i(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \ + (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \ + } else { \ + (c)=0xfffd; \ + } \ + } \ + } \ +} + /* definitions with forward iteration --------------------------------------- */ /** @@ -251,8 +296,7 @@ * for a supplementary code point, in which case the macro will read * the following trail surrogate as well. * If the offset points to a trail surrogate or - * to a single, unpaired lead surrogate, then that itself - * will be returned as the code point. + * to a single, unpaired lead surrogate, then c is set to that unpaired surrogate. * * @param s const UChar * string * @param i string offset, must be i(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \ + --(i); \ + (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \ + } else { \ + (c)=0xfffd; \ + } \ + } \ +} + /** * Move the string offset from one code point boundary to the previous one. * (Pre-decrementing backward iteration.) diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf32.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf32.h index bf63e69dba..8822c4dd09 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf32.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf32.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -6,7 +8,7 @@ * ******************************************************************************* * file name: utf32.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf8.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf8.h index 7bd0b0e852..3685ae3d71 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf8.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf8.h @@ -1,12 +1,14 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * -* Copyright (C) 1999-2014, International Business Machines +* Copyright (C) 1999-2015, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* * file name: utf8.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -39,52 +41,24 @@ /* internal definitions ----------------------------------------------------- */ -/** - * \var utf8_countTrailBytes - * Internal array with numbers of trail bytes for any given byte used in - * lead byte position. - * - * This is internal since it is not meant to be called directly by external clients; - * however it is called by public macros in this file and thus must remain stable, - * and should not be hidden when other internal functions are hidden (otherwise - * public macros would fail to compile). - * @internal - */ -#ifdef U_UTF8_IMPL -U_EXPORT const uint8_t -#elif defined(U_STATIC_IMPLEMENTATION) || defined(U_COMMON_IMPLEMENTATION) -U_CFUNC const uint8_t -#else -U_CFUNC U_IMPORT const uint8_t /* U_IMPORT2? */ /*U_IMPORT*/ -#endif -utf8_countTrailBytes[256]; - /** * Counts the trail bytes for a UTF-8 lead byte. - * Returns 0 for 0..0xbf as well as for 0xfe and 0xff. + * Returns 0 for 0..0xc1 as well as for 0xf5..0xff. + * leadByte might be evaluated multiple times. * * This is internal since it is not meant to be called directly by external clients; * however it is called by public macros in this file and thus must remain stable. * - * Note: Beginning with ICU 50, the implementation uses a multi-condition expression - * which was shown in 2012 (on x86-64) to compile to fast, branch-free code. - * leadByte is evaluated multiple times. - * - * The pre-ICU 50 implementation used the exported array utf8_countTrailBytes: - * #define U8_COUNT_TRAIL_BYTES(leadByte) (utf8_countTrailBytes[leadByte]) - * leadByte was evaluated exactly once. - * * @param leadByte The first byte of a UTF-8 sequence. Must be 0..0xff. * @internal */ #define U8_COUNT_TRAIL_BYTES(leadByte) \ - ((uint8_t)(leadByte)<0xf0 ? \ - ((uint8_t)(leadByte)>=0xc0)+((uint8_t)(leadByte)>=0xe0) : \ - (uint8_t)(leadByte)<0xfe ? 3+((uint8_t)(leadByte)>=0xf8)+((uint8_t)(leadByte)>=0xfc) : 0) + (U8_IS_LEAD(leadByte) ? \ + ((uint8_t)(leadByte)>=0xe0)+((uint8_t)(leadByte)>=0xf0)+1 : 0) /** * Counts the trail bytes for a UTF-8 lead byte of a valid UTF-8 sequence. - * The maximum supported lead byte is 0xf4 corresponding to U+10FFFF. + * Returns 0 for 0..0xc1. Undefined for 0xf5..0xff. * leadByte might be evaluated multiple times. * * This is internal since it is not meant to be called directly by external clients; @@ -94,7 +68,7 @@ utf8_countTrailBytes[256]; * @internal */ #define U8_COUNT_TRAIL_BYTES_UNSAFE(leadByte) \ - (((leadByte)>=0xc0)+((leadByte)>=0xe0)+((leadByte)>=0xf0)) + (((uint8_t)(leadByte)>=0xc2)+((uint8_t)(leadByte)>=0xe0)+((uint8_t)(leadByte)>=0xf0)) /** * Mask a UTF-8 lead byte, leave only the lower bits that form part of the code point value. @@ -105,6 +79,40 @@ utf8_countTrailBytes[256]; */ #define U8_MASK_LEAD_BYTE(leadByte, countTrailBytes) ((leadByte)&=(1<<(6-(countTrailBytes)))-1) +/** + * Internal bit vector for 3-byte UTF-8 validity check, for use in U8_IS_VALID_LEAD3_AND_T1. + * Each bit indicates whether one lead byte + first trail byte pair starts a valid sequence. + * Lead byte E0..EF bits 3..0 are used as byte index, + * first trail byte bits 7..5 are used as bit index into that byte. + * @see U8_IS_VALID_LEAD3_AND_T1 + * @internal + */ +#define U8_LEAD3_T1_BITS "\x20\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x10\x30\x30" + +/** + * Internal 3-byte UTF-8 validity check. + * Non-zero if lead byte E0..EF and first trail byte 00..FF start a valid sequence. + * @internal + */ +#define U8_IS_VALID_LEAD3_AND_T1(lead, t1) (U8_LEAD3_T1_BITS[(lead)&0xf]&(1<<((uint8_t)(t1)>>5))) + +/** + * Internal bit vector for 4-byte UTF-8 validity check, for use in U8_IS_VALID_LEAD4_AND_T1. + * Each bit indicates whether one lead byte + first trail byte pair starts a valid sequence. + * First trail byte bits 7..4 are used as byte index, + * lead byte F0..F4 bits 2..0 are used as bit index into that byte. + * @see U8_IS_VALID_LEAD4_AND_T1 + * @internal + */ +#define U8_LEAD4_T1_BITS "\x00\x00\x00\x00\x00\x00\x00\x00\x1E\x0F\x0F\x0F\x00\x00\x00\x00" + +/** + * Internal 4-byte UTF-8 validity check. + * Non-zero if lead byte F0..F4 and first trail byte 00..FF start a valid sequence. + * @internal + */ +#define U8_IS_VALID_LEAD4_AND_T1(lead, t1) (U8_LEAD4_T1_BITS[(uint8_t)(t1)>>4]&(1<<((lead)&7))) + /** * Function for handling "next code point" with error-checking. * @@ -164,20 +172,21 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i); #define U8_IS_SINGLE(c) (((c)&0x80)==0) /** - * Is this code unit (byte) a UTF-8 lead byte? + * Is this code unit (byte) a UTF-8 lead byte? (0xC2..0xF4) * @param c 8-bit code unit (byte) * @return TRUE or FALSE * @stable ICU 2.4 */ -#define U8_IS_LEAD(c) ((uint8_t)((c)-0xc0)<0x3e) +#define U8_IS_LEAD(c) ((uint8_t)((c)-0xc2)<=0x32) +// 0x32=0xf4-0xc2 /** - * Is this code unit (byte) a UTF-8 trail byte? + * Is this code unit (byte) a UTF-8 trail byte? (0x80..0xBF) * @param c 8-bit code unit (byte) * @return TRUE or FALSE * @stable ICU 2.4 */ -#define U8_IS_TRAIL(c) (((c)&0xc0)==0x80) +#define U8_IS_TRAIL(c) ((int8_t)(c)<-0x40) /** * How many code units (bytes) are used for the UTF-8 encoding @@ -305,7 +314,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i); */ #define U8_NEXT_UNSAFE(s, i, c) { \ (c)=(uint8_t)(s)[(i)++]; \ - if((c)>=0x80) { \ + if(!U8_IS_SINGLE(c)) { \ if((c)<0xe0) { \ (c)=(((c)&0x1f)<<6)|((s)[(i)++]&0x3f); \ } else if((c)<0xf0) { \ @@ -339,32 +348,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i); * @see U8_NEXT_UNSAFE * @stable ICU 2.4 */ -#define U8_NEXT(s, i, length, c) { \ - (c)=(uint8_t)(s)[(i)++]; \ - if((c)>=0x80) { \ - uint8_t __t1, __t2; \ - if( /* handle U+1000..U+CFFF inline */ \ - (0xe0<(c) && (c)<=0xec) && \ - (((i)+1)<(length) || (length)<0) && \ - (__t1=(uint8_t)((s)[i]-0x80))<=0x3f && \ - (__t2=(uint8_t)((s)[(i)+1]-0x80))<= 0x3f \ - ) { \ - /* no need for (c&0xf) because the upper bits are truncated after <<12 in the cast to (UChar) */ \ - (c)=(UChar)(((c)<<12)|(__t1<<6)|__t2); \ - (i)+=2; \ - } else if( /* handle U+0080..U+07FF inline */ \ - ((c)<0xe0 && (c)>=0xc2) && \ - ((i)!=(length)) && \ - (__t1=(uint8_t)((s)[i]-0x80))<=0x3f \ - ) { \ - (c)=(((c)&0x1f)<<6)|__t1; \ - ++(i); \ - } else { \ - /* function call for "complicated" and error cases */ \ - (c)=utf8_nextCharSafeBody((const uint8_t *)s, &(i), (length), c, -1); \ - } \ - } \ -} +#define U8_NEXT(s, i, length, c) U8_INTERNAL_NEXT_OR_SUB(s, i, length, c, U_SENTINEL) /** * Get a code point from a string at a code point boundary offset, @@ -390,29 +374,33 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i); * @see U8_NEXT * @stable ICU 51 */ -#define U8_NEXT_OR_FFFD(s, i, length, c) { \ +#define U8_NEXT_OR_FFFD(s, i, length, c) U8_INTERNAL_NEXT_OR_SUB(s, i, length, c, 0xfffd) + +/** @internal */ +#define U8_INTERNAL_NEXT_OR_SUB(s, i, length, c, sub) { \ (c)=(uint8_t)(s)[(i)++]; \ - if((c)>=0x80) { \ - uint8_t __t1, __t2; \ - if( /* handle U+1000..U+CFFF inline */ \ - (0xe0<(c) && (c)<=0xec) && \ - (((i)+1)<(length) || (length)<0) && \ - (__t1=(uint8_t)((s)[i]-0x80))<=0x3f && \ - (__t2=(uint8_t)((s)[(i)+1]-0x80))<= 0x3f \ - ) { \ - /* no need for (c&0xf) because the upper bits are truncated after <<12 in the cast to (UChar) */ \ - (c)=(UChar)(((c)<<12)|(__t1<<6)|__t2); \ - (i)+=2; \ - } else if( /* handle U+0080..U+07FF inline */ \ - ((c)<0xe0 && (c)>=0xc2) && \ - ((i)!=(length)) && \ - (__t1=(uint8_t)((s)[i]-0x80))<=0x3f \ - ) { \ - (c)=(((c)&0x1f)<<6)|__t1; \ - ++(i); \ + if(!U8_IS_SINGLE(c)) { \ + uint8_t __t = 0; \ + if((i)!=(length) && \ + /* fetch/validate/assemble all but last trail byte */ \ + ((c)>=0xe0 ? \ + ((c)<0xf0 ? /* U+0800..U+FFFF except surrogates */ \ + U8_LEAD3_T1_BITS[(c)&=0xf]&(1<<((__t=(s)[i])>>5)) && \ + (__t&=0x3f, 1) \ + : /* U+10000..U+10FFFF */ \ + ((c)-=0xf0)<=4 && \ + U8_LEAD4_T1_BITS[(__t=(s)[i])>>4]&(1<<(c)) && \ + ((c)=((c)<<6)|(__t&0x3f), ++(i)!=(length)) && \ + (__t=(s)[i]-0x80)<=0x3f) && \ + /* valid second-to-last trail byte */ \ + ((c)=((c)<<6)|__t, ++(i)!=(length)) \ + : /* U+0080..U+07FF */ \ + (c)>=0xc2 && ((c)&=0x1f, 1)) && \ + /* last trail byte */ \ + (__t=(s)[i]-0x80)<=0x3f && \ + ((c)=((c)<<6)|__t, ++(i), 1)) { \ } else { \ - /* function call for "complicated" and error cases */ \ - (c)=utf8_nextCharSafeBody((const uint8_t *)s, &(i), (length), c, -3); \ + (c)=(sub); /* ill-formed*/ \ } \ } \ } @@ -431,21 +419,22 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i); * @stable ICU 2.4 */ #define U8_APPEND_UNSAFE(s, i, c) { \ - if((uint32_t)(c)<=0x7f) { \ - (s)[(i)++]=(uint8_t)(c); \ + uint32_t __uc=(c); \ + if(__uc<=0x7f) { \ + (s)[(i)++]=(uint8_t)__uc; \ } else { \ - if((uint32_t)(c)<=0x7ff) { \ - (s)[(i)++]=(uint8_t)(((c)>>6)|0xc0); \ + if(__uc<=0x7ff) { \ + (s)[(i)++]=(uint8_t)((__uc>>6)|0xc0); \ } else { \ - if((uint32_t)(c)<=0xffff) { \ - (s)[(i)++]=(uint8_t)(((c)>>12)|0xe0); \ + if(__uc<=0xffff) { \ + (s)[(i)++]=(uint8_t)((__uc>>12)|0xe0); \ } else { \ - (s)[(i)++]=(uint8_t)(((c)>>18)|0xf0); \ - (s)[(i)++]=(uint8_t)((((c)>>12)&0x3f)|0x80); \ + (s)[(i)++]=(uint8_t)((__uc>>18)|0xf0); \ + (s)[(i)++]=(uint8_t)(((__uc>>12)&0x3f)|0x80); \ } \ - (s)[(i)++]=(uint8_t)((((c)>>6)&0x3f)|0x80); \ + (s)[(i)++]=(uint8_t)(((__uc>>6)&0x3f)|0x80); \ } \ - (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80); \ + (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \ } \ } @@ -467,17 +456,23 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i); * @stable ICU 2.4 */ #define U8_APPEND(s, i, capacity, c, isError) { \ - if((uint32_t)(c)<=0x7f) { \ - (s)[(i)++]=(uint8_t)(c); \ - } else if((uint32_t)(c)<=0x7ff && (i)+1<(capacity)) { \ - (s)[(i)++]=(uint8_t)(((c)>>6)|0xc0); \ - (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80); \ - } else if((uint32_t)(c)<=0xd7ff && (i)+2<(capacity)) { \ - (s)[(i)++]=(uint8_t)(((c)>>12)|0xe0); \ - (s)[(i)++]=(uint8_t)((((c)>>6)&0x3f)|0x80); \ - (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80); \ + uint32_t __uc=(c); \ + if(__uc<=0x7f) { \ + (s)[(i)++]=(uint8_t)__uc; \ + } else if(__uc<=0x7ff && (i)+1<(capacity)) { \ + (s)[(i)++]=(uint8_t)((__uc>>6)|0xc0); \ + (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \ + } else if((__uc<=0xd7ff || (0xe000<=__uc && __uc<=0xffff)) && (i)+2<(capacity)) { \ + (s)[(i)++]=(uint8_t)((__uc>>12)|0xe0); \ + (s)[(i)++]=(uint8_t)(((__uc>>6)&0x3f)|0x80); \ + (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \ + } else if(0xffff<__uc && __uc<=0x10ffff && (i)+3<(capacity)) { \ + (s)[(i)++]=(uint8_t)((__uc>>18)|0xf0); \ + (s)[(i)++]=(uint8_t)(((__uc>>12)&0x3f)|0x80); \ + (s)[(i)++]=(uint8_t)(((__uc>>6)&0x3f)|0x80); \ + (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \ } else { \ - (i)=utf8_appendCharSafeBody(s, (i), (capacity), c, &(isError)); \ + (isError)=TRUE; \ } \ } @@ -492,7 +487,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i); * @stable ICU 2.4 */ #define U8_FWD_1_UNSAFE(s, i) { \ - (i)+=1+U8_COUNT_TRAIL_BYTES_UNSAFE((uint8_t)(s)[i]); \ + (i)+=1+U8_COUNT_TRAIL_BYTES_UNSAFE((s)[i]); \ } /** @@ -509,15 +504,24 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i); * @stable ICU 2.4 */ #define U8_FWD_1(s, i, length) { \ - uint8_t __b=(uint8_t)(s)[(i)++]; \ - if(U8_IS_LEAD(__b)) { \ - uint8_t __count=U8_COUNT_TRAIL_BYTES(__b); \ - if((i)+__count>(length) && (length)>=0) { \ - __count=(uint8_t)((length)-(i)); \ - } \ - while(__count>0 && U8_IS_TRAIL((s)[i])) { \ - ++(i); \ - --__count; \ + uint8_t __b=(s)[(i)++]; \ + if(U8_IS_LEAD(__b) && (i)!=(length)) { \ + uint8_t __t1=(s)[i]; \ + if((0xe0<=__b && __b<0xf0)) { \ + if(U8_IS_VALID_LEAD3_AND_T1(__b, __t1) && \ + ++(i)!=(length) && U8_IS_TRAIL((s)[i])) { \ + ++(i); \ + } \ + } else if(__b<0xe0) { \ + if(U8_IS_TRAIL(__t1)) { \ + ++(i); \ + } \ + } else /* c>=0xf0 */ { \ + if(U8_IS_VALID_LEAD4_AND_T1(__b, __t1) && \ + ++(i)!=(length) && U8_IS_TRAIL((s)[i]) && \ + ++(i)!=(length) && U8_IS_TRAIL((s)[i])) { \ + ++(i); \ + } \ } \ } \ } @@ -588,12 +592,15 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i); * If the offset points to a UTF-8 trail byte, * then the offset is moved backward to the corresponding lead byte. * Otherwise, it is not modified. + * * "Safe" macro, checks for illegal sequences and for string boundaries. + * Unlike U8_TRUNCATE_IF_INCOMPLETE(), this macro always reads s[i]. * * @param s const uint8_t * string * @param start int32_t starting string offset (usually 0) * @param i int32_t string offset, must be start<=i * @see U8_SET_CP_START_UNSAFE + * @see U8_TRUNCATE_IF_INCOMPLETE * @stable ICU 2.4 */ #define U8_SET_CP_START(s, start, i) { \ @@ -602,6 +609,55 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i); } \ } +/** + * If the string ends with a UTF-8 byte sequence that is valid so far + * but incomplete, then reduce the length of the string to end before + * the lead byte of that incomplete sequence. + * For example, if the string ends with E1 80, the length is reduced by 2. + * + * In all other cases (the string ends with a complete sequence, or it is not + * possible for any further trail byte to extend the trailing sequence) + * the length remains unchanged. + * + * Useful for processing text split across multiple buffers + * (save the incomplete sequence for later) + * and for optimizing iteration + * (check for string length only once per character). + * + * "Safe" macro, checks for illegal sequences and for string boundaries. + * Unlike U8_SET_CP_START(), this macro never reads s[length]. + * + * (In UTF-16, simply check for U16_IS_LEAD(last code unit).) + * + * @param s const uint8_t * string + * @param start int32_t starting string offset (usually 0) + * @param length int32_t string length (usually start<=length) + * @see U8_SET_CP_START + * @stable ICU 61 + */ +#define U8_TRUNCATE_IF_INCOMPLETE(s, start, length) \ + if((length)>(start)) { \ + uint8_t __b1=s[(length)-1]; \ + if(U8_IS_SINGLE(__b1)) { \ + /* common ASCII character */ \ + } else if(U8_IS_LEAD(__b1)) { \ + --(length); \ + } else if(U8_IS_TRAIL(__b1) && ((length)-2)>=(start)) { \ + uint8_t __b2=s[(length)-2]; \ + if(0xe0<=__b2 && __b2<=0xf4) { \ + if(__b2<0xf0 ? U8_IS_VALID_LEAD3_AND_T1(__b2, __b1) : \ + U8_IS_VALID_LEAD4_AND_T1(__b2, __b1)) { \ + (length)-=2; \ + } \ + } else if(U8_IS_TRAIL(__b2) && ((length)-3)>=(start)) { \ + uint8_t __b3=s[(length)-3]; \ + if(0xf0<=__b3 && __b3<=0xf4 && U8_IS_VALID_LEAD4_AND_T1(__b3, __b2)) { \ + (length)-=3; \ + } \ + } \ + } \ + } + /* definitions with backward iteration -------------------------------------- */ /** @@ -631,7 +687,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i); /* c is a trail byte */ \ (c)&=0x3f; \ for(;;) { \ - __b=(uint8_t)(s)[--(i)]; \ + __b=(s)[--(i)]; \ if(__b>=0xc0) { \ U8_MASK_LEAD_BYTE(__b, __count); \ (c)|=(UChar32)__b<<__shift; \ @@ -667,7 +723,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i); */ #define U8_PREV(s, start, i, c) { \ (c)=(uint8_t)(s)[--(i)]; \ - if((c)>=0x80) { \ + if(!U8_IS_SINGLE(c)) { \ (c)=utf8_prevCharSafeBody((const uint8_t *)s, start, &(i), c, -1); \ } \ } @@ -698,7 +754,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i); */ #define U8_PREV_OR_FFFD(s, start, i, c) { \ (c)=(uint8_t)(s)[--(i)]; \ - if((c)>=0x80) { \ + if(!U8_IS_SINGLE(c)) { \ (c)=utf8_prevCharSafeBody((const uint8_t *)s, start, &(i), c, -3); \ } \ } @@ -815,7 +871,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i); * @stable ICU 2.4 */ #define U8_SET_CP_LIMIT(s, start, i, length) { \ - if((start)<(i) && ((i)<(length) || ((length)<0 && (s)[i]!=0))) { \ + if((start)<(i) && ((i)<(length) || (length)<0)) { \ U8_BACK_1(s, start, i); \ U8_FWD_1(s, i, length); \ } \ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf_old.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf_old.h index f9125b1dd2..55c17c01df 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf_old.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utf_old.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -6,7 +8,7 @@ * ******************************************************************************* * file name: utf_old.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -15,12 +17,12 @@ */ /** - * \file + * \file * \brief C API: Deprecated macros for Unicode string handling */ /** - * + * * The macros in utf_old.h are all deprecated and their use discouraged. * Some of the design principles behind the set of UTF macros * have changed or proved impractical. @@ -143,7 +145,22 @@ #ifndef __UTF_OLD_H__ #define __UTF_OLD_H__ -#ifndef U_HIDE_DEPRECATED_API +/** + * \def U_HIDE_OBSOLETE_UTF_OLD_H + * + * Hides the obsolete definitions in unicode/utf_old.h. + * Recommended to be set to 1 at compile time to make sure + * the long-deprecated macros are no longer used. + * + * For reasons for the deprecation see the utf_old.h file comments. + * + * @internal + */ +#ifndef U_HIDE_OBSOLETE_UTF_OLD_H +# define U_HIDE_OBSOLETE_UTF_OLD_H 0 +#endif + +#if !defined(U_HIDE_DEPRECATED_API) && !U_HIDE_OBSOLETE_UTF_OLD_H #include "unicode/utf.h" #include "unicode/utf8.h" @@ -265,6 +282,25 @@ typedef int32_t UTextOffset; /* Formerly utf8.h ---------------------------------------------------------- */ +/** +* \var utf8_countTrailBytes +* Internal array with numbers of trail bytes for any given byte used in +* lead byte position. +* +* This is internal since it is not meant to be called directly by external clients; +* however it is called by public macros in this file and thus must remain stable, +* and should not be hidden when other internal functions are hidden (otherwise +* public macros would fail to compile). +* @internal +*/ +#ifdef U_UTF8_IMPL +// No forward declaration if compiling utf_impl.cpp, which defines utf8_countTrailBytes. +#elif defined(U_STATIC_IMPLEMENTATION) || defined(U_COMMON_IMPLEMENTATION) +U_CFUNC const uint8_t utf8_countTrailBytes[]; +#else +U_CFUNC U_IMPORT const uint8_t utf8_countTrailBytes[]; /* U_IMPORT2? */ /*U_IMPORT*/ +#endif + /** * Count the trail bytes for a UTF-8 lead byte. * @deprecated ICU 2.4. Renamed to U8_COUNT_TRAIL_BYTES, see utf_old.h. @@ -1163,7 +1199,6 @@ typedef int32_t UTextOffset; */ #define UTF_SET_CHAR_LIMIT(s, start, i, length) U16_SET_CP_LIMIT(s, start, i, length) -#endif /* U_HIDE_DEPRECATED_API */ +#endif // !U_HIDE_DEPRECATED_API && !U_HIDE_OBSOLETE_UTF_OLD_H #endif - diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utmscale.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utmscale.h index 472d776a62..d8b8a2e668 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utmscale.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utmscale.h @@ -1,3 +1,5 @@ +// © 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 @@ -281,10 +283,14 @@ typedef enum UDateTimeScale { */ UDTS_UNIX_MICROSECONDS_TIME, +#ifndef U_HIDE_DEPRECATED_API /** * The first unused time scale value. The limit of this enum + * @deprecated ICU 59 The numeric value may change over time, see ICU ticket #12420. */ UDTS_MAX_SCALE +#endif /* U_HIDE_DEPRECATED_API */ + } UDateTimeScale; /** @@ -421,12 +427,15 @@ typedef enum UTimeScaleValue { #endif /* U_HIDE_INTERNAL_API */ +#ifndef U_HIDE_DEPRECATED_API /** * The number of time scale values, in other words limit of this enum. * * @see utmscale_getTimeScaleValue + * @deprecated ICU 59 The numeric value may change over time, see ICU ticket #12420. */ UTSV_MAX_SCALE_VALUE=11 +#endif /* U_HIDE_DEPRECATED_API */ } UTimeScaleValue; diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utrace.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utrace.h index 2621cf9c85..66269784db 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utrace.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utrace.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -6,7 +8,7 @@ * ******************************************************************************* * file name: utrace.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -64,7 +66,13 @@ typedef enum UTraceFunctionNumber { UTRACE_FUNCTION_START=0, UTRACE_U_INIT=UTRACE_FUNCTION_START, UTRACE_U_CLEANUP, +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal collation trace location. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UTRACE_FUNCTION_LIMIT, +#endif // U_HIDE_DEPRECATED_API UTRACE_CONVERSION_START=0x1000, UTRACE_UCNV_OPEN=UTRACE_CONVERSION_START, @@ -75,7 +83,13 @@ typedef enum UTraceFunctionNumber { UTRACE_UCNV_FLUSH_CACHE, UTRACE_UCNV_LOAD, UTRACE_UCNV_UNLOAD, +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal collation trace location. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UTRACE_CONVERSION_LIMIT, +#endif // U_HIDE_DEPRECATED_API UTRACE_COLLATION_START=0x2000, UTRACE_UCOL_OPEN=UTRACE_COLLATION_START, @@ -87,7 +101,13 @@ typedef enum UTraceFunctionNumber { UTRACE_UCOL_STRCOLLITER, UTRACE_UCOL_OPEN_FROM_SHORT_STRING, UTRACE_UCOL_STRCOLLUTF8, /**< @stable ICU 50 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal collation trace location. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UTRACE_COLLATION_LIMIT +#endif // U_HIDE_DEPRECATED_API } UTraceFunctionNumber; /** @@ -163,7 +183,7 @@ UTraceData(const void *context, int32_t fnNumber, int32_t level, * tracing functions must themselves filter by checking that the * current thread is the desired thread. * - * @param context an uninterpretted pointer. Whatever is passed in + * @param context an uninterpreted pointer. Whatever is passed in * here will in turn be passed to each of the tracing * functions UTraceEntry, UTraceExit and UTraceData. * ICU does not use or alter this pointer. @@ -300,7 +320,7 @@ utrace_getFunctions(const void **context, * human readable form. Note that a UTraceData function may choose * to not format the data; it could, for example, save it in * in the raw form it was received (more compact), leaving - * formatting for a later trace analyis tool. + * formatting for a later trace analysis tool. * @param outBuf pointer to a buffer to receive the formatted output. Output * will be nul terminated if there is space in the buffer - * if the length of the requested output < the output buffer size. diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utrans.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utrans.h index e3fe1629c8..6114d956b8 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utrans.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utrans.h @@ -1,3 +1,5 @@ +// © 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 @@ -254,7 +256,7 @@ U_DEFINE_LOCAL_OPEN_POINTER(LocalUTransliteratorPointer, UTransliterator, utrans U_NAMESPACE_END -#endif +#endif // U_SHOW_CPLUSPLUS_API /** * Return the programmatic identifier for this transliterator. @@ -380,7 +382,7 @@ utrans_openIDs(UErrorCode *pErrorCode); U_STABLE void U_EXPORT2 utrans_trans(const UTransliterator* trans, UReplaceable* rep, - UReplaceableCallbacks* repFunc, + const UReplaceableCallbacks* repFunc, int32_t start, int32_t* limit, UErrorCode* status); @@ -431,7 +433,7 @@ utrans_trans(const UTransliterator* trans, U_STABLE void U_EXPORT2 utrans_transIncremental(const UTransliterator* trans, UReplaceable* rep, - UReplaceableCallbacks* repFunc, + const UReplaceableCallbacks* repFunc, UTransPosition* pos, UErrorCode* status); diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utypes.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utypes.h index 5b4d19f8ef..753ce44a8f 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utypes.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/utypes.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** -* Copyright (C) 1996-2015, International Business Machines +* Copyright (C) 1996-2016, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * @@ -61,13 +63,29 @@ */ #ifdef __cplusplus # ifndef U_SHOW_CPLUSPLUS_API -# define U_SHOW_CPLUSPLUS_API 1 +# define U_SHOW_CPLUSPLUS_API 0 # endif #else # undef U_SHOW_CPLUSPLUS_API # define U_SHOW_CPLUSPLUS_API 0 #endif + +/* + * Apple-specific warning if U_SHOW_CPLUSPLUS_API set and the compile + * is not for a build of ICU itself (ICU_DATA_DIR is always defined + * for ICU builds, and is unlikely to be defined for client builds). + * Windows VSC compliler does not like #warning, skip for it. + */ +#if U_SHOW_CPLUSPLUS_API +#ifndef ICU_DATA_DIR +#if U_PLATFORM!=U_PF_WINDOWS +#warning Do not set U_SHOW_CPLUSPLUS_API for code that ships with the OS, it is only for local tools. +#warning ICU C++ functionality may not be used by any OS client, it is not binary compatible across updates. +#endif +#endif +#endif + /** @{ API visibility control */ /** @@ -145,7 +163,7 @@ /** * U_ICU_ENTRY_POINT is the name of the DLL entry point to the ICU data library. * Defined as a literal, not a string. - * Tricky Preprocessor use - ## operator replaces macro paramters with the literal string + * Tricky Preprocessor use - ## operator replaces macro parameters with the literal string * from the corresponding macro invocation, _before_ other macro substitutions. * Need a nested \#defines to get the actual version numbers rather than * the literal text U_ICU_VERSION_MAJOR_NUM into the name. @@ -178,12 +196,12 @@ /** * \def NULL - * Define NULL if necessary, to 0 for C++ and to ((void *)0) for C. + * Define NULL if necessary, to nullptr for C++ and to ((void *)0) for C. * @stable ICU 2.0 */ #ifndef NULL #ifdef __cplusplus -#define NULL 0 +#define NULL nullptr #else #define NULL ((void *)0) #endif @@ -294,6 +312,11 @@ typedef double UDate; * @stable ICU 3.4 */ +#ifdef U_IN_DOXYGEN +// This definition is required when generating the API docs. +#define U_COMBINED_IMPLEMENTATION 1 +#endif + #if defined(U_COMBINED_IMPLEMENTATION) #define U_DATA_API U_EXPORT #define U_COMMON_API U_EXPORT @@ -379,88 +402,6 @@ typedef double UDate; #define U_STANDARD_CPP_NAMESPACE #endif - -/*===========================================================================*/ -/* Global delete operator */ -/*===========================================================================*/ - -/* - * The ICU4C library must not use the global new and delete operators. - * These operators here are defined to enable testing for this. - * See Jitterbug 2581 for details of why this is necessary. - * - * Verification that ICU4C's memory usage is correct, i.e., - * that global new/delete are not used: - * - * a) Check for imports of global new/delete (see uobject.cpp for details) - * b) Verify that new is never imported. - * c) Verify that delete is only imported from object code for interface/mixin classes. - * d) Add global delete and delete[] only for the ICU4C library itself - * and define them in a way that crashes or otherwise easily shows a problem. - * - * The following implements d). - * The operator implementations crash; this is intentional and used for library debugging. - * - * Note: This is currently only done on Windows because - * some Linux/Unix compilers have problems with defining global new/delete. - * On Windows, it is _MSC_VER>=1200 for MSVC 6.0 and higher. - */ -#if defined(__cplusplus) && U_DEBUG && U_OVERRIDE_CXX_ALLOCATION && (_MSC_VER>=1200) && !defined(U_STATIC_IMPLEMENTATION) && (defined(U_COMMON_IMPLEMENTATION) || defined(U_I18N_IMPLEMENTATION) || defined(U_IO_IMPLEMENTATION) || defined(U_LAYOUT_IMPLEMENTATION) || defined(U_LAYOUTEX_IMPLEMENTATION)) - -#ifndef U_HIDE_INTERNAL_API -/** - * Global operator new, defined only inside ICU4C, must not be used. - * Crashes intentionally. - * @internal - */ -inline void * -operator new(size_t /*size*/) { - char *q=NULL; - *q=5; /* break it */ - return q; -} - -#ifdef _Ret_bytecap_ -/* This is only needed to suppress a Visual C++ 2008 warning for operator new[]. */ -_Ret_bytecap_(_Size) -#endif -/** - * Global operator new[], defined only inside ICU4C, must not be used. - * Crashes intentionally. - * @internal - */ -inline void * -operator new[](size_t /*size*/) { - char *q=NULL; - *q=5; /* break it */ - return q; -} - -/** - * Global operator delete, defined only inside ICU4C, must not be used. - * Crashes intentionally. - * @internal - */ -inline void -operator delete(void * /*p*/) { - char *q=NULL; - *q=5; /* break it */ -} - -/** - * Global operator delete[], defined only inside ICU4C, must not be used. - * Crashes intentionally. - * @internal - */ -inline void -operator delete[](void * /*p*/) { - char *q=NULL; - *q=5; /* break it */ -} - -#endif /* U_HIDE_INTERNAL_API */ -#endif - /*===========================================================================*/ /* UErrorCode */ /*===========================================================================*/ @@ -505,8 +446,13 @@ typedef enum UErrorCode { U_PLUGIN_CHANGED_LEVEL_WARNING = -120, /**< A plugin caused a level change. May not be an error, but later plugins may not load. */ - U_ERROR_WARNING_LIMIT, /**< This must always be the last warning value to indicate the limit for UErrorCode warnings (last warning code +1) */ - +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UErrorCode warning value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + U_ERROR_WARNING_LIMIT, +#endif // U_HIDE_DEPRECATED_API U_ZERO_ERROR = 0, /**< No error, no warning. */ @@ -527,14 +473,14 @@ typedef enum UErrorCode { U_BUFFER_OVERFLOW_ERROR = 15, /**< A result would not fit in the supplied buffer */ U_UNSUPPORTED_ERROR = 16, /**< Requested operation not supported in current context */ U_RESOURCE_TYPE_MISMATCH = 17, /**< an operation is requested over a resource that does not support it */ - U_ILLEGAL_ESCAPE_SEQUENCE = 18, /**< ISO-2022 illlegal escape sequence */ + U_ILLEGAL_ESCAPE_SEQUENCE = 18, /**< ISO-2022 illegal escape sequence */ U_UNSUPPORTED_ESCAPE_SEQUENCE = 19, /**< ISO-2022 unsupported escape sequence */ U_NO_SPACE_AVAILABLE = 20, /**< No space available for in-buffer expansion for Arabic shaping */ U_CE_NOT_FOUND_ERROR = 21, /**< Currently used only while setting variable top, but can be used generally */ U_PRIMARY_TOO_LONG_ERROR = 22, /**< User tried to set variable top to a primary that is longer than two bytes */ U_STATE_TOO_OLD_ERROR = 23, /**< ICU cannot construct a service from this state, as it is no longer supported */ U_TOO_MANY_ALIASES_ERROR = 24, /**< There are too many aliases in the path to the requested resource. - It is very possible that a circular alias definition has occured */ + It is very possible that a circular alias definition has occurred */ U_ENUM_OUT_OF_SYNC_ERROR = 25, /**< UEnumeration out of sync with underlying collection */ U_INVARIANT_CONVERSION_ERROR = 26, /**< Unable to convert a UChar* string to char* with the invariant converter. */ U_INVALID_STATE_ERROR = 27, /**< Requested operation can not be completed with ICU in its current state */ @@ -542,9 +488,16 @@ typedef enum UErrorCode { U_USELESS_COLLATOR_ERROR = 29, /**< Collator is options only and no base is specified */ U_NO_WRITE_PERMISSION = 30, /**< Attempt to modify read-only or constant data. */ - U_STANDARD_ERROR_LIMIT, /**< This must always be the last value to indicate the limit for standard errors */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest standard error code. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + U_STANDARD_ERROR_LIMIT, +#endif // U_HIDE_DEPRECATED_API + /* - * the error code range 0x10000 0x10100 are reserved for Transliterator + * Error codes in the range 0x10000 0x10100 are reserved for Transliterator. */ U_BAD_VARIABLE_DEFINITION=0x10000,/**< Missing '$' or duplicate variable name */ U_PARSE_ERROR_START = 0x10000, /**< Start of Transliterator errors */ @@ -573,7 +526,7 @@ typedef enum UErrorCode { U_MULTIPLE_COMPOUND_FILTERS, /**< More than one compound filter */ U_INVALID_RBT_SYNTAX, /**< A "::id" rule was passed to the RuleBasedTransliterator parser */ U_INVALID_PROPERTY_PATTERN, /**< UNUSED as of ICU 2.4 */ - U_MALFORMED_PRAGMA, /**< A 'use' pragma is invlalid */ + U_MALFORMED_PRAGMA, /**< A 'use' pragma is invalid */ U_UNCLOSED_SEGMENT, /**< A closing ')' is missing */ U_ILLEGAL_CHAR_IN_SEGMENT, /**< UNUSED as of ICU 2.4 */ U_VARIABLE_RANGE_EXHAUSTED, /**< Too many stand-ins generated for the given variable range */ @@ -582,10 +535,16 @@ typedef enum UErrorCode { U_INTERNAL_TRANSLITERATOR_ERROR, /**< Internal transliterator system error */ U_INVALID_ID, /**< A "::id" rule specifies an unknown transliterator */ U_INVALID_FUNCTION, /**< A "&fn()" rule specifies an unknown transliterator */ - U_PARSE_ERROR_LIMIT, /**< The limit for Transliterator errors */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal Transliterator error code. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + U_PARSE_ERROR_LIMIT, +#endif // U_HIDE_DEPRECATED_API /* - * the error code range 0x10100 0x10200 are reserved for formatting API parsing error + * Error codes in the range 0x10100 0x10200 are reserved for the formatting API. */ U_UNEXPECTED_TOKEN=0x10100, /**< Syntax error in format pattern */ U_FMT_PARSE_ERROR_START=0x10100, /**< Start of format library errors */ @@ -607,17 +566,25 @@ typedef enum UErrorCode { U_DEFAULT_KEYWORD_MISSING, /**< Missing DEFAULT rule in plural rules */ U_DECIMAL_NUMBER_SYNTAX_ERROR, /**< Decimal number syntax error */ U_FORMAT_INEXACT_ERROR, /**< Cannot format a number exactly and rounding mode is ROUND_UNNECESSARY @stable ICU 4.8 */ - U_FMT_PARSE_ERROR_LIMIT, /**< The limit for format library errors */ + U_NUMBER_ARG_OUTOFBOUNDS_ERROR, /**< The argument to a NumberFormatter helper method was out of bounds; the bounds are usually 0 to 999. @stable ICU 61 */ + U_NUMBER_SKELETON_SYNTAX_ERROR, /**< The number skeleton passed to C++ NumberFormatter or C UNumberFormatter was invalid or contained a syntax error. @stable ICU 62 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal formatting API error code. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + U_FMT_PARSE_ERROR_LIMIT = 0x10114, +#endif // U_HIDE_DEPRECATED_API /* - * the error code range 0x10200 0x102ff are reserved for Break Iterator related error + * Error codes in the range 0x10200 0x102ff are reserved for BreakIterator. */ U_BRK_INTERNAL_ERROR=0x10200, /**< An internal error (bug) was detected. */ U_BRK_ERROR_START=0x10200, /**< Start of codes indicating Break Iterator failures */ U_BRK_HEX_DIGITS_EXPECTED, /**< Hex digits expected as part of a escaped char in a rule. */ U_BRK_SEMICOLON_EXPECTED, /**< Missing ';' at the end of a RBBI rule. */ U_BRK_RULE_SYNTAX, /**< Syntax error in RBBI rule. */ - U_BRK_UNCLOSED_SET, /**< UnicodeSet witing an RBBI rule missing a closing ']'. */ + U_BRK_UNCLOSED_SET, /**< UnicodeSet writing an RBBI rule missing a closing ']'. */ U_BRK_ASSIGN_ERROR, /**< Syntax error in RBBI rule assignment statement. */ U_BRK_VARIABLE_REDFINITION, /**< RBBI rule $Variable redefined. */ U_BRK_MISMATCHED_PAREN, /**< Mis-matched parentheses in an RBBI rule. */ @@ -626,11 +593,17 @@ typedef enum UErrorCode { U_BRK_INIT_ERROR, /**< Initialization failure. Probable missing ICU Data. */ U_BRK_RULE_EMPTY_SET, /**< Rule contains an empty Unicode Set. */ U_BRK_UNRECOGNIZED_OPTION, /**< !!option in RBBI rules not recognized. */ - U_BRK_MALFORMED_RULE_TAG, /**< The {nnn} tag on a rule is mal formed */ - U_BRK_ERROR_LIMIT, /**< This must always be the last value to indicate the limit for Break Iterator failures */ + U_BRK_MALFORMED_RULE_TAG, /**< The {nnn} tag on a rule is malformed */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal BreakIterator error code. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + U_BRK_ERROR_LIMIT, +#endif // U_HIDE_DEPRECATED_API /* - * The error codes in the range 0x10300-0x103ff are reserved for regular expression related errrs + * Error codes in the range 0x10300-0x103ff are reserved for regular expression related errors. */ U_REGEX_INTERNAL_ERROR=0x10300, /**< An internal error (bug) was detected. */ U_REGEX_ERROR_START=0x10300, /**< Start of codes indicating Regexp failures */ @@ -655,14 +628,18 @@ typedef enum UErrorCode { U_REGEX_STACK_OVERFLOW, /**< Regular expression backtrack stack overflow. */ U_REGEX_TIME_OUT, /**< Maximum allowed match time exceeded */ U_REGEX_STOPPED_BY_CALLER, /**< Matching operation aborted by user callback fn. */ -#ifndef U_HIDE_DRAFT_API - U_REGEX_PATTERN_TOO_BIG, /**< Pattern exceeds limits on size or complexity. @draft ICU 55 */ - U_REGEX_INVALID_CAPTURE_GROUP_NAME, /**< Invalid capture group name. @draft ICU 55 */ -#endif /* U_HIDE_DRAFT_API */ - U_REGEX_ERROR_LIMIT=U_REGEX_STOPPED_BY_CALLER+3, /**< This must always be the last value to indicate the limit for regexp errors */ + U_REGEX_PATTERN_TOO_BIG, /**< Pattern exceeds limits on size or complexity. @stable ICU 55 */ + U_REGEX_INVALID_CAPTURE_GROUP_NAME, /**< Invalid capture group name. @stable ICU 55 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal regular expression error code. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + U_REGEX_ERROR_LIMIT=U_REGEX_STOPPED_BY_CALLER+3, +#endif // U_HIDE_DEPRECATED_API /* - * The error code in the range 0x10400-0x104ff are reserved for IDNA related error codes + * Error codes in the range 0x10400-0x104ff are reserved for IDNA related error codes. */ U_IDNA_PROHIBITED_ERROR=0x10400, U_IDNA_ERROR_START=0x10400, @@ -674,7 +651,13 @@ typedef enum UErrorCode { U_IDNA_LABEL_TOO_LONG_ERROR, U_IDNA_ZERO_LENGTH_LABEL_ERROR, U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR, +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal IDNA error code. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ U_IDNA_ERROR_LIMIT, +#endif // U_HIDE_DEPRECATED_API /* * Aliases for StringPrep */ @@ -683,14 +666,26 @@ typedef enum UErrorCode { U_STRINGPREP_CHECK_BIDI_ERROR = U_IDNA_CHECK_BIDI_ERROR, /* - * The error code in the range 0x10500-0x105ff are reserved for Plugin related error codes + * Error codes in the range 0x10500-0x105ff are reserved for Plugin related error codes. */ U_PLUGIN_ERROR_START=0x10500, /**< Start of codes indicating plugin failures */ U_PLUGIN_TOO_HIGH=0x10500, /**< The plugin's level is too high to be loaded right now. */ U_PLUGIN_DIDNT_SET_LEVEL, /**< The plugin didn't call uplug_setPlugLevel in response to a QUERY */ - U_PLUGIN_ERROR_LIMIT, /**< This must always be the last value to indicate the limit for plugin errors */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal plug-in error code. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + U_PLUGIN_ERROR_LIMIT, +#endif // U_HIDE_DEPRECATED_API - U_ERROR_LIMIT=U_PLUGIN_ERROR_LIMIT /**< This must always be the last value to indicate the limit for UErrorCode (last error code +1) */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal error code. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + U_ERROR_LIMIT=U_PLUGIN_ERROR_LIMIT +#endif // U_HIDE_DEPRECATED_API } UErrorCode; /* Use the following to determine if an UErrorCode represents */ diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uvernum.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uvernum.h index 3e2eff631c..7c114be2cc 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uvernum.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uvernum.h @@ -1,11 +1,13 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* -* Copyright (C) 2000-2015, International Business Machines +* Copyright (C) 2000-2016, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* * * file name: uvernum.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -32,13 +34,14 @@ * by running the UNIX makefile target 'update-windows-makefiles' in icu/source. * * - * source/common/common.vcproj - update 'Output file name' on the link tab so + * source/common/common_uwp.vcxproj + * source/common/common.vcxproj - update 'Output file name' on the link tab so * that it contains the new major/minor combination - * source/i18n/i18n.vcproj - same as for the common.vcproj - * source/layout/layout.vcproj - same as for the common.vcproj + * source/i18n/i18n.vcxproj - same as for the common.vcxproj + * source/i18n/i18n_uwp.vcxproj - same as for the common_uwp.vcxproj * source/layoutex/layoutex.vcproj - same - * source/stubdata/stubdata.vcproj - same as for the common.vcproj - * source/io/io.vcproj - same as for the common.vcproj + * source/stubdata/stubdata.vcproj - same as for the common.vcxproj + * source/io/io.vcproj - same as for the common.vcxproj * source/data/makedata.mak - change U_ICUDATA_NAME so that it contains * the new major/minor combination and the Unicode version. */ @@ -51,19 +54,19 @@ * @stable ICU 2.4 */ #define U_COPYRIGHT_STRING \ - " Copyright (C) 2015, International Business Machines Corporation and others. All Rights Reserved. " + " Copyright (C) 2016 and later: Unicode, Inc. and others. License & terms of use: http://www.unicode.org/copyright.html " /** The current ICU major version as an integer. * This value will change in the subsequent releases of ICU * @stable ICU 2.4 */ -#define U_ICU_VERSION_MAJOR_NUM 55 +#define U_ICU_VERSION_MAJOR_NUM 64 /** The current ICU minor version as an integer. * This value will change in the subsequent releases of ICU * @stable ICU 2.6 */ -#define U_ICU_VERSION_MINOR_NUM 1 +#define U_ICU_VERSION_MINOR_NUM 2 /** The current ICU patchlevel version as an integer. * This value will change in the subsequent releases of ICU @@ -83,7 +86,7 @@ * This value will change in the subsequent releases of ICU * @stable ICU 2.6 */ -#define U_ICU_VERSION_SUFFIX _55 +#define U_ICU_VERSION_SUFFIX _64 /** * \def U_DEF2_ICU_ENTRY_POINT_RENAME @@ -100,16 +103,34 @@ * \def U_ICU_ENTRY_POINT_RENAME * @stable ICU 4.2 */ +/** + * Disable the version suffix. Use the custom suffix if exists. + * \def U_DISABLE_VERSION_SUFFIX + * @internal + */ +#ifndef U_DISABLE_VERSION_SUFFIX +#define U_DISABLE_VERSION_SUFFIX 0 +#endif #ifndef U_ICU_ENTRY_POINT_RENAME #ifdef U_HAVE_LIB_SUFFIX -#define U_DEF_ICU_ENTRY_POINT_RENAME(x,y,z) x ## y ## z -#define U_DEF2_ICU_ENTRY_POINT_RENAME(x,y,z) U_DEF_ICU_ENTRY_POINT_RENAME(x,y,z) -#define U_ICU_ENTRY_POINT_RENAME(x) U_DEF2_ICU_ENTRY_POINT_RENAME(x,U_ICU_VERSION_SUFFIX,U_LIB_SUFFIX_C_NAME) +# if !U_DISABLE_VERSION_SUFFIX +# define U_DEF_ICU_ENTRY_POINT_RENAME(x,y,z) x ## y ## z +# define U_DEF2_ICU_ENTRY_POINT_RENAME(x,y,z) U_DEF_ICU_ENTRY_POINT_RENAME(x,y,z) +# define U_ICU_ENTRY_POINT_RENAME(x) U_DEF2_ICU_ENTRY_POINT_RENAME(x,U_ICU_VERSION_SUFFIX,U_LIB_SUFFIX_C_NAME) +# else +# define U_DEF_ICU_ENTRY_POINT_RENAME(x,y) x ## y +# define U_DEF2_ICU_ENTRY_POINT_RENAME(x,y) U_DEF_ICU_ENTRY_POINT_RENAME(x,y) +# define U_ICU_ENTRY_POINT_RENAME(x) U_DEF2_ICU_ENTRY_POINT_RENAME(x,U_LIB_SUFFIX_C_NAME) +# endif #else -#define U_DEF_ICU_ENTRY_POINT_RENAME(x,y) x ## y -#define U_DEF2_ICU_ENTRY_POINT_RENAME(x,y) U_DEF_ICU_ENTRY_POINT_RENAME(x,y) -#define U_ICU_ENTRY_POINT_RENAME(x) U_DEF2_ICU_ENTRY_POINT_RENAME(x,U_ICU_VERSION_SUFFIX) +# if !U_DISABLE_VERSION_SUFFIX +# define U_DEF_ICU_ENTRY_POINT_RENAME(x,y) x ## y +# define U_DEF2_ICU_ENTRY_POINT_RENAME(x,y) U_DEF_ICU_ENTRY_POINT_RENAME(x,y) +# define U_ICU_ENTRY_POINT_RENAME(x) U_DEF2_ICU_ENTRY_POINT_RENAME(x,U_ICU_VERSION_SUFFIX) +# else +# define U_ICU_ENTRY_POINT_RENAME(x) x +# endif #endif #endif @@ -118,19 +139,26 @@ * This value will change in the subsequent releases of ICU * @stable ICU 2.4 */ -#define U_ICU_VERSION "55.1" +#define U_ICU_VERSION "64.2" -/** The current ICU library major/minor version as a string without dots, for library name suffixes. - * This value will change in the subsequent releases of ICU - * @stable ICU 2.6 +/** + * The current ICU library major version number as a string, for library name suffixes. + * This value will change in subsequent releases of ICU. + * + * Until ICU 4.8, this was the combination of the single-digit major and minor ICU version numbers + * into one string without dots ("48"). + * Since ICU 49, it is the double-digit major ICU version number. + * See http://userguide.icu-project.org/design#TOC-Version-Numbers-in-ICU + * + * @stable ICU 2.6 */ -#define U_ICU_VERSION_SHORT "55" +#define U_ICU_VERSION_SHORT "64" #ifndef U_HIDE_INTERNAL_API /** Data version in ICU4C. * @internal ICU 4.4 Internal Use Only **/ -#define U_ICU_DATA_VERSION "55.1" +#define U_ICU_DATA_VERSION "64.2" #endif /* U_HIDE_INTERNAL_API */ /*=========================================================================== diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uversion.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uversion.h index 74e3091055..4aaa8b4d60 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uversion.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/uversion.h @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2000-2011, International Business Machines @@ -5,7 +7,7 @@ ******************************************************************************* * * file name: uversion.h -* encoding: US-ASCII +* encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * @@ -103,7 +105,7 @@ typedef uint8_t UVersionInfo[U_MAX_VERSION_LENGTH]; * @stable ICU 2.4 */ -/* Define namespace symbols if the compiler supports it. */ +/* Define C++ namespace symbols. */ #ifdef __cplusplus # if U_DISABLE_RENAMING # define U_ICU_NAMESPACE icu @@ -120,7 +122,13 @@ typedef uint8_t UVersionInfo[U_MAX_VERSION_LENGTH]; # define U_NAMESPACE_QUALIFIER U_ICU_NAMESPACE:: # ifndef U_USING_ICU_NAMESPACE -# define U_USING_ICU_NAMESPACE 1 +# if defined(U_COMBINED_IMPLEMENTATION) || defined(U_COMMON_IMPLEMENTATION) || \ + defined(U_I18N_IMPLEMENTATION) || defined(U_IO_IMPLEMENTATION) || \ + defined(U_LAYOUTEX_IMPLEMENTATION) || defined(U_TOOLUTIL_IMPLEMENTATION) +# define U_USING_ICU_NAMESPACE 0 +# else +# define U_USING_ICU_NAMESPACE 0 +# endif # endif # if U_USING_ICU_NAMESPACE U_NAMESPACE_USE diff --git a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/vtzone.h b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/vtzone.h index 92817ba16b..cf2101d808 100644 --- a/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/vtzone.h +++ b/bootstrap/x86_64-apple-darwin/usr/local/include/unicode/vtzone.h @@ -1,3 +1,5 @@ +// © 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 @@ -18,6 +20,7 @@ #include "unicode/basictz.h" +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class VTZWriter; @@ -448,6 +451,7 @@ class U_I18N_API VTimeZone : public BasicTimeZone { }; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */