packages feed

text-icu 0.7.0.1 → 0.7.1.0

raw patch · 14 files changed

+1084/−18 lines, 14 filesnew-uploaderPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Data.Text.ICU.Break: instance Enum Line
- Data.Text.ICU.Break: instance Enum Word
- Data.Text.ICU.Break: instance Eq Line
- Data.Text.ICU.Break: instance Eq Word
- Data.Text.ICU.Break: instance NFData Line
- Data.Text.ICU.Break: instance NFData Word
- Data.Text.ICU.Break: instance Show Line
- Data.Text.ICU.Break: instance Show Word
- Data.Text.ICU.Char: instance Bounded BlockCode
- Data.Text.ICU.Char: instance Enum BlockCode
- Data.Text.ICU.Char: instance Enum Bool_
- Data.Text.ICU.Char: instance Enum Decomposition
- Data.Text.ICU.Char: instance Enum Direction
- Data.Text.ICU.Char: instance Enum EastAsianWidth
- Data.Text.ICU.Char: instance Enum GeneralCategory
- Data.Text.ICU.Char: instance Enum GraphemeClusterBreak
- Data.Text.ICU.Char: instance Enum HangulSyllableType
- Data.Text.ICU.Char: instance Enum JoiningGroup
- Data.Text.ICU.Char: instance Enum JoiningType
- Data.Text.ICU.Char: instance Enum LineBreak
- Data.Text.ICU.Char: instance Enum NumericType
- Data.Text.ICU.Char: instance Enum SentenceBreak
- Data.Text.ICU.Char: instance Enum WordBreak
- Data.Text.ICU.Char: instance Eq BlockCode
- Data.Text.ICU.Char: instance Eq Bool_
- Data.Text.ICU.Char: instance Eq Decomposition
- Data.Text.ICU.Char: instance Eq Direction
- Data.Text.ICU.Char: instance Eq EastAsianWidth
- Data.Text.ICU.Char: instance Eq GeneralCategory
- Data.Text.ICU.Char: instance Eq GraphemeClusterBreak
- Data.Text.ICU.Char: instance Eq HangulSyllableType
- Data.Text.ICU.Char: instance Eq JoiningGroup
- Data.Text.ICU.Char: instance Eq JoiningType
- Data.Text.ICU.Char: instance Eq LineBreak
- Data.Text.ICU.Char: instance Eq NumericType
- Data.Text.ICU.Char: instance Eq SentenceBreak
- Data.Text.ICU.Char: instance Eq WordBreak
- Data.Text.ICU.Char: instance NFData BidiClass_
- Data.Text.ICU.Char: instance NFData BlockCode
- Data.Text.ICU.Char: instance NFData Block_
- Data.Text.ICU.Char: instance NFData Bool_
- Data.Text.ICU.Char: instance NFData CanonicalCombiningClass_
- Data.Text.ICU.Char: instance NFData Decomposition
- Data.Text.ICU.Char: instance NFData Decomposition_
- Data.Text.ICU.Char: instance NFData Direction
- Data.Text.ICU.Char: instance NFData EastAsianWidth
- Data.Text.ICU.Char: instance NFData EastAsianWidth_
- Data.Text.ICU.Char: instance NFData GeneralCategory
- Data.Text.ICU.Char: instance NFData GeneralCategory_
- Data.Text.ICU.Char: instance NFData GraphemeClusterBreak
- Data.Text.ICU.Char: instance NFData GraphemeClusterBreak_
- Data.Text.ICU.Char: instance NFData HangulSyllableType
- Data.Text.ICU.Char: instance NFData HangulSyllableType_
- Data.Text.ICU.Char: instance NFData JoiningGroup
- Data.Text.ICU.Char: instance NFData JoiningGroup_
- Data.Text.ICU.Char: instance NFData JoiningType
- Data.Text.ICU.Char: instance NFData JoiningType_
- Data.Text.ICU.Char: instance NFData LeadCanonicalCombiningClass_
- Data.Text.ICU.Char: instance NFData LineBreak
- Data.Text.ICU.Char: instance NFData LineBreak_
- Data.Text.ICU.Char: instance NFData NFCQuickCheck_
- Data.Text.ICU.Char: instance NFData NFDQuickCheck_
- Data.Text.ICU.Char: instance NFData NFKCQuickCheck_
- Data.Text.ICU.Char: instance NFData NFKDQuickCheck_
- Data.Text.ICU.Char: instance NFData NumericType
- Data.Text.ICU.Char: instance NFData NumericType_
- Data.Text.ICU.Char: instance NFData SentenceBreak
- Data.Text.ICU.Char: instance NFData SentenceBreak_
- Data.Text.ICU.Char: instance NFData TrailingCanonicalCombiningClass_
- Data.Text.ICU.Char: instance NFData WordBreak
- Data.Text.ICU.Char: instance NFData WordBreak_
- Data.Text.ICU.Char: instance Property BidiClass_ Direction
- Data.Text.ICU.Char: instance Property Block_ BlockCode
- Data.Text.ICU.Char: instance Property Bool_ Bool
- Data.Text.ICU.Char: instance Property CanonicalCombiningClass_ Int
- Data.Text.ICU.Char: instance Property Decomposition_ (Maybe Decomposition)
- Data.Text.ICU.Char: instance Property EastAsianWidth_ EastAsianWidth
- Data.Text.ICU.Char: instance Property GeneralCategory_ GeneralCategory
- Data.Text.ICU.Char: instance Property GraphemeClusterBreak_ (Maybe GraphemeClusterBreak)
- Data.Text.ICU.Char: instance Property HangulSyllableType_ (Maybe HangulSyllableType)
- Data.Text.ICU.Char: instance Property JoiningGroup_ (Maybe JoiningGroup)
- Data.Text.ICU.Char: instance Property JoiningType_ (Maybe JoiningType)
- Data.Text.ICU.Char: instance Property LeadCanonicalCombiningClass_ Int
- Data.Text.ICU.Char: instance Property LineBreak_ (Maybe LineBreak)
- Data.Text.ICU.Char: instance Property NFCQuickCheck_ (Maybe Bool)
- Data.Text.ICU.Char: instance Property NFDQuickCheck_ (Maybe Bool)
- Data.Text.ICU.Char: instance Property NFKCQuickCheck_ (Maybe Bool)
- Data.Text.ICU.Char: instance Property NFKDQuickCheck_ (Maybe Bool)
- Data.Text.ICU.Char: instance Property NumericType_ (Maybe NumericType)
- Data.Text.ICU.Char: instance Property SentenceBreak_ (Maybe SentenceBreak)
- Data.Text.ICU.Char: instance Property TrailingCanonicalCombiningClass_ Int
- Data.Text.ICU.Char: instance Property WordBreak_ (Maybe WordBreak)
- Data.Text.ICU.Char: instance Show BidiClass_
- Data.Text.ICU.Char: instance Show BlockCode
- Data.Text.ICU.Char: instance Show Bool_
- Data.Text.ICU.Char: instance Show CanonicalCombiningClass_
- Data.Text.ICU.Char: instance Show Decomposition
- Data.Text.ICU.Char: instance Show Decomposition_
- Data.Text.ICU.Char: instance Show Direction
- Data.Text.ICU.Char: instance Show EastAsianWidth
- Data.Text.ICU.Char: instance Show EastAsianWidth_
- Data.Text.ICU.Char: instance Show GeneralCategory
- Data.Text.ICU.Char: instance Show GeneralCategory_
- Data.Text.ICU.Char: instance Show GraphemeClusterBreak
- Data.Text.ICU.Char: instance Show GraphemeClusterBreak_
- Data.Text.ICU.Char: instance Show HangulSyllableType
- Data.Text.ICU.Char: instance Show HangulSyllableType_
- Data.Text.ICU.Char: instance Show JoiningGroup
- Data.Text.ICU.Char: instance Show JoiningGroup_
- Data.Text.ICU.Char: instance Show JoiningType
- Data.Text.ICU.Char: instance Show JoiningType_
- Data.Text.ICU.Char: instance Show LeadCanonicalCombiningClass_
- Data.Text.ICU.Char: instance Show LineBreak
- Data.Text.ICU.Char: instance Show LineBreak_
- Data.Text.ICU.Char: instance Show NFCQuickCheck_
- Data.Text.ICU.Char: instance Show NFDQuickCheck_
- Data.Text.ICU.Char: instance Show NFKCQuickCheck_
- Data.Text.ICU.Char: instance Show NFKDQuickCheck_
- Data.Text.ICU.Char: instance Show NumericType
- Data.Text.ICU.Char: instance Show NumericType_
- Data.Text.ICU.Char: instance Show SentenceBreak
- Data.Text.ICU.Char: instance Show SentenceBreak_
- Data.Text.ICU.Char: instance Show TrailingCanonicalCombiningClass_
- Data.Text.ICU.Char: instance Show WordBreak
- Data.Text.ICU.Char: instance Show WordBreak_
- Data.Text.ICU.Char: instance Typeable BidiClass_
- Data.Text.ICU.Char: instance Typeable BlockCode
- Data.Text.ICU.Char: instance Typeable Bool_
- Data.Text.ICU.Char: instance Typeable CanonicalCombiningClass_
- Data.Text.ICU.Char: instance Typeable Decomposition
- Data.Text.ICU.Char: instance Typeable Decomposition_
- Data.Text.ICU.Char: instance Typeable Direction
- Data.Text.ICU.Char: instance Typeable EastAsianWidth
- Data.Text.ICU.Char: instance Typeable EastAsianWidth_
- Data.Text.ICU.Char: instance Typeable GeneralCategory
- Data.Text.ICU.Char: instance Typeable GeneralCategory_
- Data.Text.ICU.Char: instance Typeable GraphemeClusterBreak
- Data.Text.ICU.Char: instance Typeable GraphemeClusterBreak_
- Data.Text.ICU.Char: instance Typeable HangulSyllableType
- Data.Text.ICU.Char: instance Typeable HangulSyllableType_
- Data.Text.ICU.Char: instance Typeable JoiningGroup
- Data.Text.ICU.Char: instance Typeable JoiningGroup_
- Data.Text.ICU.Char: instance Typeable JoiningType
- Data.Text.ICU.Char: instance Typeable JoiningType_
- Data.Text.ICU.Char: instance Typeable LeadCanonicalCombiningClass_
- Data.Text.ICU.Char: instance Typeable LineBreak
- Data.Text.ICU.Char: instance Typeable LineBreak_
- Data.Text.ICU.Char: instance Typeable NFCQuickCheck_
- Data.Text.ICU.Char: instance Typeable NFDQuickCheck_
- Data.Text.ICU.Char: instance Typeable NFKCQuickCheck_
- Data.Text.ICU.Char: instance Typeable NFKDQuickCheck_
- Data.Text.ICU.Char: instance Typeable NumericType
- Data.Text.ICU.Char: instance Typeable NumericType_
- Data.Text.ICU.Char: instance Typeable SentenceBreak
- Data.Text.ICU.Char: instance Typeable SentenceBreak_
- Data.Text.ICU.Char: instance Typeable TrailingCanonicalCombiningClass_
- Data.Text.ICU.Char: instance Typeable WordBreak
- Data.Text.ICU.Char: instance Typeable WordBreak_
- Data.Text.ICU.Collate: instance Bounded AlternateHandling
- Data.Text.ICU.Collate: instance Bounded CaseFirst
- Data.Text.ICU.Collate: instance Bounded Strength
- Data.Text.ICU.Collate: instance Enum AlternateHandling
- Data.Text.ICU.Collate: instance Enum CaseFirst
- Data.Text.ICU.Collate: instance Enum Strength
- Data.Text.ICU.Collate: instance Eq AlternateHandling
- Data.Text.ICU.Collate: instance Eq Attribute
- Data.Text.ICU.Collate: instance Eq CaseFirst
- Data.Text.ICU.Collate: instance Eq Strength
- Data.Text.ICU.Collate: instance NFData AlternateHandling
- Data.Text.ICU.Collate: instance NFData Attribute
- Data.Text.ICU.Collate: instance NFData CaseFirst
- Data.Text.ICU.Collate: instance NFData Strength
- Data.Text.ICU.Collate: instance Show AlternateHandling
- Data.Text.ICU.Collate: instance Show Attribute
- Data.Text.ICU.Collate: instance Show CaseFirst
- Data.Text.ICU.Collate: instance Show Strength
- Data.Text.ICU.Collate: instance Typeable AlternateHandling
- Data.Text.ICU.Collate: instance Typeable Attribute
- Data.Text.ICU.Collate: instance Typeable CaseFirst
- Data.Text.ICU.Collate: instance Typeable Strength
- Data.Text.ICU.Normalize: instance Enum CompareOption
- Data.Text.ICU.Normalize: instance Enum NormalizationMode
- Data.Text.ICU.Normalize: instance Eq CompareOption
- Data.Text.ICU.Normalize: instance Eq NormalizationMode
- Data.Text.ICU.Normalize: instance Show CompareOption
- Data.Text.ICU.Normalize: instance Show NormalizationMode
- Data.Text.ICU.Normalize: instance Typeable CompareOption
- Data.Text.ICU.Normalize: instance Typeable NormalizationMode
- Data.Text.ICU.Regex: instance Show Regex
+ Data.Text.ICU: ASCII :: RestrictionLevel
+ Data.Text.ICU: AllChecks :: SpoofCheck
+ Data.Text.ICU: AnyCase :: SpoofCheck
+ Data.Text.ICU: AuxInfo :: SpoofCheck
+ Data.Text.ICU: CharLimit :: SpoofCheck
+ Data.Text.ICU: CheckFailed :: [SpoofCheck] -> SpoofCheckResult
+ Data.Text.ICU: CheckFailedWithRestrictionLevel :: [SpoofCheck] -> RestrictionLevel -> SpoofCheckResult
+ Data.Text.ICU: CheckOK :: SpoofCheckResult
+ Data.Text.ICU: HighlyRestrictive :: RestrictionLevel
+ Data.Text.ICU: Invisible :: SpoofCheck
+ Data.Text.ICU: MinimallyRestrictive :: RestrictionLevel
+ Data.Text.ICU: MixedNumbers :: SpoofCheck
+ Data.Text.ICU: MixedScriptConfusable :: SpoofCheck
+ Data.Text.ICU: ModeratelyRestrictive :: RestrictionLevel
+ Data.Text.ICU: RestrictionLevel :: SpoofCheck
+ Data.Text.ICU: SingleScriptConfusable :: SpoofCheck
+ Data.Text.ICU: SingleScriptRestrictive :: RestrictionLevel
+ Data.Text.ICU: SpoofParams :: Maybe [SpoofCheck] -> Maybe RestrictionLevel -> Maybe [String] -> SpoofParams
+ Data.Text.ICU: Unrestrictive :: RestrictionLevel
+ Data.Text.ICU: WholeScriptConfusable :: SpoofCheck
+ Data.Text.ICU: [failedChecks] :: SpoofCheckResult -> [SpoofCheck]
+ Data.Text.ICU: [failedLevel] :: SpoofCheckResult -> RestrictionLevel
+ Data.Text.ICU: [level] :: SpoofParams -> Maybe RestrictionLevel
+ Data.Text.ICU: [locales] :: SpoofParams -> Maybe [String]
+ Data.Text.ICU: [spoofChecks] :: SpoofParams -> Maybe [SpoofCheck]
+ Data.Text.ICU: areConfusable :: Spoof -> Text -> Text -> SpoofCheckResult
+ Data.Text.ICU: data RestrictionLevel
+ Data.Text.ICU: data Spoof
+ Data.Text.ICU: data SpoofCheck
+ Data.Text.ICU: data SpoofCheckResult
+ Data.Text.ICU: data SpoofParams
+ Data.Text.ICU: getAllowedLocales :: Spoof -> [String]
+ Data.Text.ICU: getChecks :: Spoof -> [SpoofCheck]
+ Data.Text.ICU: getRestrictionLevel :: Spoof -> Maybe RestrictionLevel
+ Data.Text.ICU: getSkeleton :: Spoof -> Maybe SkeletonTypeOverride -> Text -> Text
+ Data.Text.ICU: serialize :: Spoof -> ByteString
+ Data.Text.ICU: spoof :: Spoof
+ Data.Text.ICU: spoofCheck :: Spoof -> Text -> SpoofCheckResult
+ Data.Text.ICU: spoofFromSerialized :: ByteString -> SpoofParams -> Spoof
+ Data.Text.ICU: spoofFromSource :: (ByteString, ByteString) -> SpoofParams -> Spoof
+ Data.Text.ICU: spoofWithParams :: SpoofParams -> Spoof
+ Data.Text.ICU.Break: instance Control.DeepSeq.NFData Data.Text.ICU.Break.Line
+ Data.Text.ICU.Break: instance Control.DeepSeq.NFData Data.Text.ICU.Break.Word
+ Data.Text.ICU.Break: instance GHC.Classes.Eq Data.Text.ICU.Break.Line
+ Data.Text.ICU.Break: instance GHC.Classes.Eq Data.Text.ICU.Break.Word
+ Data.Text.ICU.Break: instance GHC.Enum.Enum Data.Text.ICU.Break.Line
+ Data.Text.ICU.Break: instance GHC.Enum.Enum Data.Text.ICU.Break.Word
+ Data.Text.ICU.Break: instance GHC.Show.Show Data.Text.ICU.Break.Line
+ Data.Text.ICU.Break: instance GHC.Show.Show Data.Text.ICU.Break.Word
+ Data.Text.ICU.Char: Ahom :: BlockCode
+ Data.Text.ICU.Char: AnatolianHieroglyphs :: BlockCode
+ Data.Text.ICU.Char: BPTClose :: BidiPairedBracketType
+ Data.Text.ICU.Char: BPTNone :: BidiPairedBracketType
+ Data.Text.ICU.Char: BPTOpen :: BidiPairedBracketType
+ Data.Text.ICU.Char: BassaVah :: BlockCode
+ Data.Text.ICU.Char: BidiPairedBracketType :: BidiPairedBracketType_
+ Data.Text.ICU.Char: CJKUnifiedIdeographsExtensionE :: BlockCode
+ Data.Text.ICU.Char: CaseIgnorable :: Bool_
+ Data.Text.ICU.Char: Cased :: Bool_
+ Data.Text.ICU.Char: CaucasianAlbanian :: BlockCode
+ Data.Text.ICU.Char: ChangesWhenCasefolded :: Bool_
+ Data.Text.ICU.Char: ChangesWhenCasemapped :: Bool_
+ Data.Text.ICU.Char: ChangesWhenLowercased :: Bool_
+ Data.Text.ICU.Char: ChangesWhenNFKCCasefolded :: Bool_
+ Data.Text.ICU.Char: ChangesWhenTitlecased :: Bool_
+ Data.Text.ICU.Char: ChangesWhenUppercased :: Bool_
+ Data.Text.ICU.Char: CherokeeSupplement :: BlockCode
+ Data.Text.ICU.Char: CloseParenthesis :: LineBreak
+ Data.Text.ICU.Char: CombiningDiacriticalMarksExtended :: BlockCode
+ Data.Text.ICU.Char: ConditionalJapaneseStarter :: LineBreak
+ Data.Text.ICU.Char: CopticEpactNumbers :: BlockCode
+ Data.Text.ICU.Char: DoubleQuote :: WordBreak
+ Data.Text.ICU.Char: Duployan :: BlockCode
+ Data.Text.ICU.Char: EarlyDynasticCuneiform :: BlockCode
+ Data.Text.ICU.Char: Elbasan :: BlockCode
+ Data.Text.ICU.Char: FarsiYeh :: JoiningGroup
+ Data.Text.ICU.Char: GeometricShapesExtended :: BlockCode
+ Data.Text.ICU.Char: Grantha :: BlockCode
+ Data.Text.ICU.Char: Hatran :: BlockCode
+ Data.Text.ICU.Char: HebrewLetter :: WordBreak
+ Data.Text.ICU.Char: Khojki :: BlockCode
+ Data.Text.ICU.Char: Khudawadi :: BlockCode
+ Data.Text.ICU.Char: LBHebrewLetter :: LineBreak
+ Data.Text.ICU.Char: LBRegionalIndicator :: LineBreak
+ Data.Text.ICU.Char: LatinExtendedE :: BlockCode
+ Data.Text.ICU.Char: LinearA :: BlockCode
+ Data.Text.ICU.Char: Mahajani :: BlockCode
+ Data.Text.ICU.Char: Manichaean :: BlockCode
+ Data.Text.ICU.Char: ManichaeanAleph :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanAyin :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanBeth :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanDaleth :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanDhamedh :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanFive :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanGimel :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanHeth :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanHundred :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanKaph :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanLamedh :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanMem :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanNun :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanOne :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanPe :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanQoph :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanResh :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanSadhe :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanSamekh :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanTaw :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanTen :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanTeth :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanThamedh :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanTwenty :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanWaw :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanYodh :: JoiningGroup
+ Data.Text.ICU.Char: ManichaeanZayin :: JoiningGroup
+ Data.Text.ICU.Char: MendeKikakui :: BlockCode
+ Data.Text.ICU.Char: Modi :: BlockCode
+ Data.Text.ICU.Char: Mro :: BlockCode
+ Data.Text.ICU.Char: Multani :: BlockCode
+ Data.Text.ICU.Char: MyanmarExtendedB :: BlockCode
+ Data.Text.ICU.Char: Nabataean :: BlockCode
+ Data.Text.ICU.Char: Nya :: JoiningGroup
+ Data.Text.ICU.Char: OldHungarian :: BlockCode
+ Data.Text.ICU.Char: OldNorthArabian :: BlockCode
+ Data.Text.ICU.Char: OldPermic :: BlockCode
+ Data.Text.ICU.Char: OrnamentalDingbats :: BlockCode
+ Data.Text.ICU.Char: PahawhHmong :: BlockCode
+ Data.Text.ICU.Char: Palmyrene :: BlockCode
+ Data.Text.ICU.Char: PauCinHau :: BlockCode
+ Data.Text.ICU.Char: PsalterPahlavi :: BlockCode
+ Data.Text.ICU.Char: RegionalIndicator :: WordBreak
+ Data.Text.ICU.Char: RohingyaYeh :: JoiningGroup
+ Data.Text.ICU.Char: ShorthandFormatControls :: BlockCode
+ Data.Text.ICU.Char: Siddham :: BlockCode
+ Data.Text.ICU.Char: SingleQuote :: WordBreak
+ Data.Text.ICU.Char: SinhalaArchaicNumbers :: BlockCode
+ Data.Text.ICU.Char: StraightWaw :: JoiningGroup
+ Data.Text.ICU.Char: SupplementalArrowsC :: BlockCode
+ Data.Text.ICU.Char: SupplementalSymbolsAndPictographs :: BlockCode
+ Data.Text.ICU.Char: SuttonSignwriting :: BlockCode
+ Data.Text.ICU.Char: Tirhuta :: BlockCode
+ Data.Text.ICU.Char: WarangCiti :: BlockCode
+ Data.Text.ICU.Char: data BidiPairedBracketType
+ Data.Text.ICU.Char: data BidiPairedBracketType_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.BidiClass_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.BidiPairedBracketType
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.BidiPairedBracketType_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.BlockCode
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.Block_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.Bool_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.CanonicalCombiningClass_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.Decomposition
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.Decomposition_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.Direction
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.EastAsianWidth
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.EastAsianWidth_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.GeneralCategory
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.GeneralCategory_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.GraphemeClusterBreak
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.GraphemeClusterBreak_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.HangulSyllableType
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.HangulSyllableType_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.JoiningGroup
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.JoiningGroup_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.JoiningType
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.JoiningType_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.LeadCanonicalCombiningClass_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.LineBreak
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.LineBreak_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.NFCQuickCheck_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.NFDQuickCheck_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.NFKCQuickCheck_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.NFKDQuickCheck_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.NumericType
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.NumericType_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.SentenceBreak
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.SentenceBreak_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.TrailingCanonicalCombiningClass_
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.WordBreak
+ Data.Text.ICU.Char: instance Control.DeepSeq.NFData Data.Text.ICU.Char.WordBreak_
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.BidiClass_ Data.Text.ICU.Char.Direction
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.BidiPairedBracketType_ (GHC.Maybe.Maybe Data.Text.ICU.Char.BidiPairedBracketType)
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.Block_ Data.Text.ICU.Char.BlockCode
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.Bool_ GHC.Types.Bool
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.CanonicalCombiningClass_ GHC.Types.Int
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.Decomposition_ (GHC.Maybe.Maybe Data.Text.ICU.Char.Decomposition)
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.EastAsianWidth_ Data.Text.ICU.Char.EastAsianWidth
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.GeneralCategory_ Data.Text.ICU.Char.GeneralCategory
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.GraphemeClusterBreak_ (GHC.Maybe.Maybe Data.Text.ICU.Char.GraphemeClusterBreak)
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.HangulSyllableType_ (GHC.Maybe.Maybe Data.Text.ICU.Char.HangulSyllableType)
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.JoiningGroup_ (GHC.Maybe.Maybe Data.Text.ICU.Char.JoiningGroup)
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.JoiningType_ (GHC.Maybe.Maybe Data.Text.ICU.Char.JoiningType)
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.LeadCanonicalCombiningClass_ GHC.Types.Int
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.LineBreak_ (GHC.Maybe.Maybe Data.Text.ICU.Char.LineBreak)
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.NFCQuickCheck_ (GHC.Maybe.Maybe GHC.Types.Bool)
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.NFDQuickCheck_ (GHC.Maybe.Maybe GHC.Types.Bool)
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.NFKCQuickCheck_ (GHC.Maybe.Maybe GHC.Types.Bool)
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.NFKDQuickCheck_ (GHC.Maybe.Maybe GHC.Types.Bool)
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.NumericType_ (GHC.Maybe.Maybe Data.Text.ICU.Char.NumericType)
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.SentenceBreak_ (GHC.Maybe.Maybe Data.Text.ICU.Char.SentenceBreak)
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.TrailingCanonicalCombiningClass_ GHC.Types.Int
+ Data.Text.ICU.Char: instance Data.Text.ICU.Char.Property Data.Text.ICU.Char.WordBreak_ (GHC.Maybe.Maybe Data.Text.ICU.Char.WordBreak)
+ Data.Text.ICU.Char: instance GHC.Classes.Eq Data.Text.ICU.Char.BidiPairedBracketType
+ Data.Text.ICU.Char: instance GHC.Classes.Eq Data.Text.ICU.Char.BlockCode
+ Data.Text.ICU.Char: instance GHC.Classes.Eq Data.Text.ICU.Char.Bool_
+ Data.Text.ICU.Char: instance GHC.Classes.Eq Data.Text.ICU.Char.Decomposition
+ Data.Text.ICU.Char: instance GHC.Classes.Eq Data.Text.ICU.Char.Direction
+ Data.Text.ICU.Char: instance GHC.Classes.Eq Data.Text.ICU.Char.EastAsianWidth
+ Data.Text.ICU.Char: instance GHC.Classes.Eq Data.Text.ICU.Char.GeneralCategory
+ Data.Text.ICU.Char: instance GHC.Classes.Eq Data.Text.ICU.Char.GraphemeClusterBreak
+ Data.Text.ICU.Char: instance GHC.Classes.Eq Data.Text.ICU.Char.HangulSyllableType
+ Data.Text.ICU.Char: instance GHC.Classes.Eq Data.Text.ICU.Char.JoiningGroup
+ Data.Text.ICU.Char: instance GHC.Classes.Eq Data.Text.ICU.Char.JoiningType
+ Data.Text.ICU.Char: instance GHC.Classes.Eq Data.Text.ICU.Char.LineBreak
+ Data.Text.ICU.Char: instance GHC.Classes.Eq Data.Text.ICU.Char.NumericType
+ Data.Text.ICU.Char: instance GHC.Classes.Eq Data.Text.ICU.Char.SentenceBreak
+ Data.Text.ICU.Char: instance GHC.Classes.Eq Data.Text.ICU.Char.WordBreak
+ Data.Text.ICU.Char: instance GHC.Enum.Bounded Data.Text.ICU.Char.BlockCode
+ Data.Text.ICU.Char: instance GHC.Enum.Enum Data.Text.ICU.Char.BidiPairedBracketType
+ Data.Text.ICU.Char: instance GHC.Enum.Enum Data.Text.ICU.Char.BlockCode
+ Data.Text.ICU.Char: instance GHC.Enum.Enum Data.Text.ICU.Char.Bool_
+ Data.Text.ICU.Char: instance GHC.Enum.Enum Data.Text.ICU.Char.Decomposition
+ Data.Text.ICU.Char: instance GHC.Enum.Enum Data.Text.ICU.Char.Direction
+ Data.Text.ICU.Char: instance GHC.Enum.Enum Data.Text.ICU.Char.EastAsianWidth
+ Data.Text.ICU.Char: instance GHC.Enum.Enum Data.Text.ICU.Char.GeneralCategory
+ Data.Text.ICU.Char: instance GHC.Enum.Enum Data.Text.ICU.Char.GraphemeClusterBreak
+ Data.Text.ICU.Char: instance GHC.Enum.Enum Data.Text.ICU.Char.HangulSyllableType
+ Data.Text.ICU.Char: instance GHC.Enum.Enum Data.Text.ICU.Char.JoiningGroup
+ Data.Text.ICU.Char: instance GHC.Enum.Enum Data.Text.ICU.Char.JoiningType
+ Data.Text.ICU.Char: instance GHC.Enum.Enum Data.Text.ICU.Char.LineBreak
+ Data.Text.ICU.Char: instance GHC.Enum.Enum Data.Text.ICU.Char.NumericType
+ Data.Text.ICU.Char: instance GHC.Enum.Enum Data.Text.ICU.Char.SentenceBreak
+ Data.Text.ICU.Char: instance GHC.Enum.Enum Data.Text.ICU.Char.WordBreak
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.BidiClass_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.BidiPairedBracketType
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.BidiPairedBracketType_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.BlockCode
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.Bool_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.CanonicalCombiningClass_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.Decomposition
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.Decomposition_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.Direction
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.EastAsianWidth
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.EastAsianWidth_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.GeneralCategory
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.GeneralCategory_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.GraphemeClusterBreak
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.GraphemeClusterBreak_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.HangulSyllableType
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.HangulSyllableType_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.JoiningGroup
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.JoiningGroup_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.JoiningType
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.JoiningType_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.LeadCanonicalCombiningClass_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.LineBreak
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.LineBreak_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.NFCQuickCheck_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.NFDQuickCheck_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.NFKCQuickCheck_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.NFKDQuickCheck_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.NumericType
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.NumericType_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.SentenceBreak
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.SentenceBreak_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.TrailingCanonicalCombiningClass_
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.WordBreak
+ Data.Text.ICU.Char: instance GHC.Show.Show Data.Text.ICU.Char.WordBreak_
+ Data.Text.ICU.Collate: instance Control.DeepSeq.NFData Data.Text.ICU.Collate.AlternateHandling
+ Data.Text.ICU.Collate: instance Control.DeepSeq.NFData Data.Text.ICU.Collate.Attribute
+ Data.Text.ICU.Collate: instance Control.DeepSeq.NFData Data.Text.ICU.Collate.CaseFirst
+ Data.Text.ICU.Collate: instance Control.DeepSeq.NFData Data.Text.ICU.Collate.Strength
+ Data.Text.ICU.Collate: instance GHC.Classes.Eq Data.Text.ICU.Collate.AlternateHandling
+ Data.Text.ICU.Collate: instance GHC.Classes.Eq Data.Text.ICU.Collate.Attribute
+ Data.Text.ICU.Collate: instance GHC.Classes.Eq Data.Text.ICU.Collate.CaseFirst
+ Data.Text.ICU.Collate: instance GHC.Classes.Eq Data.Text.ICU.Collate.Strength
+ Data.Text.ICU.Collate: instance GHC.Enum.Bounded Data.Text.ICU.Collate.AlternateHandling
+ Data.Text.ICU.Collate: instance GHC.Enum.Bounded Data.Text.ICU.Collate.CaseFirst
+ Data.Text.ICU.Collate: instance GHC.Enum.Bounded Data.Text.ICU.Collate.Strength
+ Data.Text.ICU.Collate: instance GHC.Enum.Enum Data.Text.ICU.Collate.AlternateHandling
+ Data.Text.ICU.Collate: instance GHC.Enum.Enum Data.Text.ICU.Collate.CaseFirst
+ Data.Text.ICU.Collate: instance GHC.Enum.Enum Data.Text.ICU.Collate.Strength
+ Data.Text.ICU.Collate: instance GHC.Show.Show Data.Text.ICU.Collate.AlternateHandling
+ Data.Text.ICU.Collate: instance GHC.Show.Show Data.Text.ICU.Collate.Attribute
+ Data.Text.ICU.Collate: instance GHC.Show.Show Data.Text.ICU.Collate.CaseFirst
+ Data.Text.ICU.Collate: instance GHC.Show.Show Data.Text.ICU.Collate.Strength
+ Data.Text.ICU.Normalize: instance GHC.Classes.Eq Data.Text.ICU.Normalize.CompareOption
+ Data.Text.ICU.Normalize: instance GHC.Classes.Eq Data.Text.ICU.Normalize.NormalizationMode
+ Data.Text.ICU.Normalize: instance GHC.Enum.Enum Data.Text.ICU.Normalize.CompareOption
+ Data.Text.ICU.Normalize: instance GHC.Enum.Enum Data.Text.ICU.Normalize.NormalizationMode
+ Data.Text.ICU.Normalize: instance GHC.Show.Show Data.Text.ICU.Normalize.CompareOption
+ Data.Text.ICU.Normalize: instance GHC.Show.Show Data.Text.ICU.Normalize.NormalizationMode
+ Data.Text.ICU.Regex: instance GHC.Show.Show Data.Text.ICU.Regex.Internal.Regex
+ Data.Text.ICU.Spoof: ASCII :: RestrictionLevel
+ Data.Text.ICU.Spoof: AllChecks :: SpoofCheck
+ Data.Text.ICU.Spoof: AnyCase :: SpoofCheck
+ Data.Text.ICU.Spoof: AuxInfo :: SpoofCheck
+ Data.Text.ICU.Spoof: CharLimit :: SpoofCheck
+ Data.Text.ICU.Spoof: CheckFailed :: [SpoofCheck] -> SpoofCheckResult
+ Data.Text.ICU.Spoof: CheckFailedWithRestrictionLevel :: [SpoofCheck] -> RestrictionLevel -> SpoofCheckResult
+ Data.Text.ICU.Spoof: CheckOK :: SpoofCheckResult
+ Data.Text.ICU.Spoof: HighlyRestrictive :: RestrictionLevel
+ Data.Text.ICU.Spoof: Invisible :: SpoofCheck
+ Data.Text.ICU.Spoof: MinimallyRestrictive :: RestrictionLevel
+ Data.Text.ICU.Spoof: MixedNumbers :: SpoofCheck
+ Data.Text.ICU.Spoof: MixedScriptConfusable :: SpoofCheck
+ Data.Text.ICU.Spoof: ModeratelyRestrictive :: RestrictionLevel
+ Data.Text.ICU.Spoof: OpenFromSourceParseError :: OpenFromSourceParseErrorFile -> ParseError -> OpenFromSourceParseError
+ Data.Text.ICU.Spoof: RestrictionLevel :: SpoofCheck
+ Data.Text.ICU.Spoof: SingleScriptConfusable :: SpoofCheck
+ Data.Text.ICU.Spoof: SingleScriptRestrictive :: RestrictionLevel
+ Data.Text.ICU.Spoof: SkeletonAnyCase :: SkeletonTypeOverride
+ Data.Text.ICU.Spoof: SkeletonSingleScript :: SkeletonTypeOverride
+ Data.Text.ICU.Spoof: Unrestrictive :: RestrictionLevel
+ Data.Text.ICU.Spoof: WholeScriptConfusable :: SpoofCheck
+ Data.Text.ICU.Spoof: [errFile] :: OpenFromSourceParseError -> OpenFromSourceParseErrorFile
+ Data.Text.ICU.Spoof: [failedChecks] :: SpoofCheckResult -> [SpoofCheck]
+ Data.Text.ICU.Spoof: [failedLevel] :: SpoofCheckResult -> RestrictionLevel
+ Data.Text.ICU.Spoof: [parseError] :: OpenFromSourceParseError -> ParseError
+ Data.Text.ICU.Spoof: areConfusable :: MSpoof -> Text -> Text -> IO SpoofCheckResult
+ Data.Text.ICU.Spoof: data MSpoof
+ Data.Text.ICU.Spoof: data OpenFromSourceParseError
+ Data.Text.ICU.Spoof: data RestrictionLevel
+ Data.Text.ICU.Spoof: data SkeletonTypeOverride
+ Data.Text.ICU.Spoof: data SpoofCheck
+ Data.Text.ICU.Spoof: data SpoofCheckResult
+ Data.Text.ICU.Spoof: getAllowedLocales :: MSpoof -> IO [String]
+ Data.Text.ICU.Spoof: getChecks :: MSpoof -> IO [SpoofCheck]
+ Data.Text.ICU.Spoof: getRestrictionLevel :: MSpoof -> IO (Maybe RestrictionLevel)
+ Data.Text.ICU.Spoof: getSkeleton :: MSpoof -> Maybe SkeletonTypeOverride -> Text -> IO Text
+ Data.Text.ICU.Spoof: instance Control.DeepSeq.NFData Data.Text.ICU.Spoof.OpenFromSourceParseError
+ Data.Text.ICU.Spoof: instance Control.DeepSeq.NFData Data.Text.ICU.Spoof.OpenFromSourceParseErrorFile
+ Data.Text.ICU.Spoof: instance Data.Text.ICU.BitMask.ToBitMask Data.Text.ICU.Spoof.RestrictionLevel
+ Data.Text.ICU.Spoof: instance Data.Text.ICU.BitMask.ToBitMask Data.Text.ICU.Spoof.SkeletonTypeOverride
+ Data.Text.ICU.Spoof: instance Data.Text.ICU.BitMask.ToBitMask Data.Text.ICU.Spoof.SpoofCheck
+ Data.Text.ICU.Spoof: instance GHC.Classes.Eq Data.Text.ICU.Spoof.OpenFromSourceParseErrorFile
+ Data.Text.ICU.Spoof: instance GHC.Classes.Eq Data.Text.ICU.Spoof.RestrictionLevel
+ Data.Text.ICU.Spoof: instance GHC.Classes.Eq Data.Text.ICU.Spoof.SkeletonTypeOverride
+ Data.Text.ICU.Spoof: instance GHC.Classes.Eq Data.Text.ICU.Spoof.SpoofCheck
+ Data.Text.ICU.Spoof: instance GHC.Classes.Eq Data.Text.ICU.Spoof.SpoofCheckResult
+ Data.Text.ICU.Spoof: instance GHC.Enum.Bounded Data.Text.ICU.Spoof.RestrictionLevel
+ Data.Text.ICU.Spoof: instance GHC.Enum.Bounded Data.Text.ICU.Spoof.SkeletonTypeOverride
+ Data.Text.ICU.Spoof: instance GHC.Enum.Bounded Data.Text.ICU.Spoof.SpoofCheck
+ Data.Text.ICU.Spoof: instance GHC.Enum.Enum Data.Text.ICU.Spoof.RestrictionLevel
+ Data.Text.ICU.Spoof: instance GHC.Enum.Enum Data.Text.ICU.Spoof.SkeletonTypeOverride
+ Data.Text.ICU.Spoof: instance GHC.Enum.Enum Data.Text.ICU.Spoof.SpoofCheck
+ Data.Text.ICU.Spoof: instance GHC.Exception.Type.Exception Data.Text.ICU.Spoof.OpenFromSourceParseError
+ Data.Text.ICU.Spoof: instance GHC.Show.Show Data.Text.ICU.Spoof.OpenFromSourceParseError
+ Data.Text.ICU.Spoof: instance GHC.Show.Show Data.Text.ICU.Spoof.OpenFromSourceParseErrorFile
+ Data.Text.ICU.Spoof: instance GHC.Show.Show Data.Text.ICU.Spoof.RestrictionLevel
+ Data.Text.ICU.Spoof: instance GHC.Show.Show Data.Text.ICU.Spoof.SkeletonTypeOverride
+ Data.Text.ICU.Spoof: instance GHC.Show.Show Data.Text.ICU.Spoof.SpoofCheck
+ Data.Text.ICU.Spoof: instance GHC.Show.Show Data.Text.ICU.Spoof.SpoofCheckResult
+ Data.Text.ICU.Spoof: open :: IO MSpoof
+ Data.Text.ICU.Spoof: openFromSerialized :: ByteString -> IO MSpoof
+ Data.Text.ICU.Spoof: openFromSource :: (ByteString, ByteString) -> IO MSpoof
+ Data.Text.ICU.Spoof: serialize :: MSpoof -> IO ByteString
+ Data.Text.ICU.Spoof: setAllowedLocales :: MSpoof -> [String] -> IO ()
+ Data.Text.ICU.Spoof: setChecks :: MSpoof -> [SpoofCheck] -> IO ()
+ Data.Text.ICU.Spoof: setRestrictionLevel :: MSpoof -> RestrictionLevel -> IO ()
+ Data.Text.ICU.Spoof: spoofCheck :: MSpoof -> Text -> IO SpoofCheckResult
- Data.Text.ICU: class Regular r where regFp = reRe . regRe
+ Data.Text.ICU: class Regular r
- Data.Text.ICU.Collate: CaseFirst :: (Maybe CaseFirst) -> Attribute
+ Data.Text.ICU.Collate: CaseFirst :: Maybe CaseFirst -> Attribute

Files

Data/Text/ICU.hs view
@@ -85,6 +85,28 @@     , group     , prefix     , suffix+    -- * Spoof checking+    -- $spoof+    , Spoof+    , SpoofParams(..)+    , S.SpoofCheck(..)+    , S.RestrictionLevel(..)+    , S.SpoofCheckResult(..)+    -- ** Construction+    , spoof+    , spoofWithParams+    , spoofFromSource+    , spoofFromSerialized+    -- ** String checking+    , areConfusable+    , spoofCheck+    , getSkeleton+    -- ** Configuration+    , getChecks+    , getAllowedLocales+    , getRestrictionLevel+    -- ** Persistence+    , serialize     ) where  import Data.Text.ICU.Break.Pure@@ -93,6 +115,8 @@ import Data.Text.ICU.Iterator import Data.Text.ICU.Normalize import Data.Text.ICU.Regex.Pure+import qualified Data.Text.ICU.Spoof as S+import Data.Text.ICU.Spoof.Pure import Data.Text.ICU.Text #if defined(__HADDOCK__) import Data.Text.Foreign@@ -159,3 +183,14 @@ -- Capturing groups are numbered starting from zero.  Group zero is -- always the entire matching text.  Groups greater than zero contain -- the text matching each capturing group in a regular expression.++-- $spoof+--+-- The 'Spoof' type performs security checks on visually confusable+-- (spoof) strings.  For the impure spoof checking API (which is+-- richer, but less easy to use than the pure API), see the+-- "Data.Text.ICU.Spoof" module.+--+-- See <http://unicode.org/reports/tr36/ UTR #36> and+-- <http://unicode.org/reports/tr39/ UTS #39> for detailed information+-- about the underlying algorithms and databases used by these functions.
+ Data/Text/ICU/BitMask.hs view
@@ -0,0 +1,34 @@+{-# LANGUAGE DefaultSignatures, ScopedTypeVariables #-}++-- From http://stackoverflow.com/a/15911213++module Data.Text.ICU.BitMask+       (+    -- * Bit mask twiddling API+    -- $api+    -- * Types+      ToBitMask(..)+    -- * Functions+    , fromBitMask+    , highestValueInBitMask+    ) where++import Data.Bits ((.&.), (.|.))+import Data.Maybe (listToMaybe)++-- $api+-- Conversion to and from enumerated types representable as+-- a compact bitmask.++class ToBitMask a where+  toBitMask :: a -> Int++instance (ToBitMask a) => ToBitMask [a] where+  toBitMask = foldr ((.|.) . toBitMask) 0++fromBitMask :: (Enum a, Bounded a, ToBitMask a) => Int -> [a]+fromBitMask bm = filter inBitMask $ enumFrom minBound+  where inBitMask val = (bm .&. toBitMask val) == toBitMask val++highestValueInBitMask :: (Enum a, Bounded a, ToBitMask a) => Int -> Maybe a+highestValueInBitMask = listToMaybe . reverse . fromBitMask
Data/Text/ICU/Char.hsc view
@@ -51,6 +51,7 @@     , LineBreak_(..)     , SentenceBreak_(..)     , WordBreak_(..)+    , BidiPairedBracketType_(..)     -- * Property value types     , BlockCode(..)     , Direction(..)@@ -66,6 +67,7 @@     , LineBreak(..)     , SentenceBreak(..)     , WordBreak(..)+    , BidiPairedBracketType(..)     -- * Functions     , blockCode     , charFullName@@ -357,6 +359,48 @@   | SoraSompeng   | SundaneseSupplement   | Takri+  | BassaVah+  | CaucasianAlbanian+  | CopticEpactNumbers+  | CombiningDiacriticalMarksExtended+  | Duployan+  | Elbasan+  | GeometricShapesExtended+  | Grantha+  | Khojki+  | Khudawadi+  | LatinExtendedE+  | LinearA+  | Mahajani+  | Manichaean+  | MendeKikakui+  | Modi+  | Mro+  | MyanmarExtendedB+  | Nabataean+  | OldNorthArabian+  | OldPermic+  | OrnamentalDingbats+  | PahawhHmong+  | Palmyrene+  | PauCinHau+  | PsalterPahlavi+  | ShorthandFormatControls+  | Siddham+  | SinhalaArchaicNumbers+  | SupplementalArrowsC+  | Tirhuta+  | WarangCiti+  | Ahom+  | AnatolianHieroglyphs+  | CherokeeSupplement+  | CJKUnifiedIdeographsExtensionE+  | EarlyDynasticCuneiform+  | Hatran+  | Multani+  | OldHungarian+  | SupplementalSymbolsAndPictographs+  | SuttonSignwriting   deriving (Eq, Enum, Bounded, Show, Typeable)  instance NFData BlockCode where@@ -475,6 +519,16 @@   -- ^ Printable character class.   | POSIXXDigit   -- ^ Hex digit character class.+  | Cased+  -- ^ Cased character class. For lowercase, uppercase and titlecase characters.+  | CaseIgnorable+  -- ^ Used in context-sensitive case mappings.+  | ChangesWhenLowercased+  | ChangesWhenUppercased+  | ChangesWhenTitlecased+  | ChangesWhenCasefolded+  | ChangesWhenCasemapped+  | ChangesWhenNFKCCasefolded     deriving (Eq, Enum, Show, Typeable)  instance NFData Bool_ where@@ -678,6 +732,37 @@   | Khaph   | Zhain   | BurushaskiYehBarree+  | FarsiYeh+  | Nya+  | RohingyaYeh+  | ManichaeanAleph+  | ManichaeanAyin+  | ManichaeanBeth+  | ManichaeanDaleth+  | ManichaeanDhamedh+  | ManichaeanFive+  | ManichaeanGimel+  | ManichaeanHeth+  | ManichaeanHundred+  | ManichaeanKaph+  | ManichaeanLamedh+  | ManichaeanMem+  | ManichaeanNun+  | ManichaeanOne+  | ManichaeanPe+  | ManichaeanQoph+  | ManichaeanResh+  | ManichaeanSadhe+  | ManichaeanSamekh+  | ManichaeanTaw+  | ManichaeanTen+  | ManichaeanTeth+  | ManichaeanThamedh+  | ManichaeanTwenty+  | ManichaeanWaw+  | ManichaeanYodh+  | ManichaeanZayin+  | StraightWaw     deriving (Eq, Enum, Show, Typeable)  instance NFData JoiningGroup where@@ -748,6 +833,10 @@   | JL   | JT   | JV+  | CloseParenthesis+  | ConditionalJapaneseStarter+  | LBHebrewLetter+  | LBRegionalIndicator     deriving (Eq, Enum, Show, Typeable)  instance NFData LineBreak where@@ -918,6 +1007,10 @@   | WBLF   | WBMidNumLet   | WBNewline+  | RegionalIndicator+  | HebrewLetter+  | SingleQuote+  | DoubleQuote     deriving (Eq, Enum, Show, Typeable)  instance NFData WordBreak where@@ -926,6 +1019,24 @@ instance Property WordBreak_ (Maybe WordBreak) where     fromNative  _ = maybeEnum     toUProperty _ = (#const UCHAR_WORD_BREAK)++data BidiPairedBracketType_ = BidiPairedBracketType deriving (Show, Typeable)++instance NFData BidiPairedBracketType_ where+    rnf !_ = ()++data BidiPairedBracketType =+    BPTNone+  | BPTOpen+  | BPTClose+    deriving (Eq, Enum, Show, Typeable)++instance NFData BidiPairedBracketType where+    rnf !_ = ()++instance Property BidiPairedBracketType_ (Maybe BidiPairedBracketType) where+    fromNative  _ = maybeEnum+    toUProperty _ = (#const UCHAR_BIDI_PAIRED_BRACKET_TYPE)  property :: Property p v => p -> Char -> v property p c = fromNative p . u_getIntPropertyValue (fromIntegral (ord c)) .
Data/Text/ICU/Collate/Internal.hs view
@@ -33,8 +33,7 @@ data MCollator = MCollator {-# UNPACK #-} !(ForeignPtr UCollator)                  deriving (Typeable) --- | String collator type.  'Collator's are considered equal if they--- will sort strings identically.+-- | String collator type. newtype Collator = C MCollator     deriving (Typeable) 
+ Data/Text/ICU/Spoof.hsc view
@@ -0,0 +1,468 @@+{-# LANGUAGE BangPatterns, CPP, DeriveDataTypeable, ForeignFunctionInterface,+    OverloadedStrings, RecordWildCards, ScopedTypeVariables #-}+-- |+-- Module      : Data.Text.ICU.Spoof+-- Copyright   : (c) 2015 Ben Hamilton+--+-- License     : BSD-style+-- Maintainer  : bgertzfield@gmail.com+-- Stability   : experimental+-- Portability : GHC+--+-- String spoofing (confusability) checks for Unicode, implemented as+-- bindings to the International Components for Unicode (ICU) uspoof+-- library.+--+-- See <http://unicode.org/reports/tr36/ UTR #36> and+-- <http://unicode.org/reports/tr39/ UTS #39> for detailed information+-- about the underlying algorithms and databases used by this module.++module Data.Text.ICU.Spoof+    (+    -- * Unicode spoof checking API+    -- $api+    -- * Types+      MSpoof+    , OpenFromSourceParseError(..)+    , SpoofCheck(..)+    , SpoofCheckResult(..)+    , RestrictionLevel(..)+    , SkeletonTypeOverride(..)+    -- * Functions+    , open+    , openFromSerialized+    , openFromSource+    , getSkeleton+    , getChecks+    , setChecks+    , getRestrictionLevel+    , setRestrictionLevel+    , getAllowedLocales+    , setAllowedLocales+    , areConfusable+    , spoofCheck+    , serialize+    ) where++#include <unicode/parseerr.h>+#include <unicode/uspoof.h>+#include <unicode/utypes.h>++import Control.Applicative+import Control.DeepSeq (NFData(..))+import Control.Exception (Exception, throwIO, catchJust)+import Data.Bits ((.&.))+import Data.ByteString (ByteString)+import Data.ByteString.Internal (create, memcpy, toForeignPtr)+import Data.ByteString.Unsafe (unsafeUseAsCStringLen)+import Data.Int (Int32)+import Data.List (intercalate)+import Data.Text (Text, pack, splitOn, strip, unpack)+import Data.Text.Foreign (fromPtr, useAsPtr)+import Data.Text.ICU.BitMask (ToBitMask, fromBitMask, highestValueInBitMask,+                              toBitMask)+import Data.Text.ICU.Spoof.Internal (MSpoof, USpoof, withSpoof, wrap,+                                     wrapWithSerialized)+import Data.Text.ICU.Error (u_PARSE_ERROR)+import Data.Text.ICU.Error.Internal (UErrorCode, UParseError,+                                     ParseError(..), handleError,+                                     handleOverflowError, handleParseError)+import Data.Text.ICU.Internal (UChar)+import Data.Typeable (Typeable)+import Data.Word (Word8)+import Foreign.C.String (CString, peekCString, withCString)+import Foreign.Marshal.Utils (with)+import Foreign.Ptr (Ptr, castPtr, nullPtr, plusPtr)+import Foreign.Storable (peek)+import Foreign.ForeignPtr (withForeignPtr)++-- $api+--+-- The 'spoofCheck', 'areConfusable', and 'getSkeleton' functions analyze+-- Unicode text for visually confusable (or \"spoof\") characters.+--+-- For example, Latin, Cyrillic, and Greek all contain unique Unicode+-- values which appear nearly identical on-screen:+--+-- @+--      A    0041    LATIN CAPITAL LETTER A+--      &#x0391;    0391    GREEK CAPITAL LETTER ALPHA+--      &#x0410;    0410    CYRILLIC CAPITAL LETTER A+--      &#x13AA;    13AA    CHEROKEE LETTER GO+--      &#x1D00;    1D00    LATIN LETTER SMALL CAPITAL A+--      &#x15C5;    15C5    CANADIAN SYLLABICS CARRIER GHO+--      &#xFF21;    FF21    FULLWIDTH LATIN CAPITAL LETTER A+--      &#x102A0;    102A0   CARIAN LETTER A+--      &#x1D400;    1D400   MATHEMATICAL BOLD CAPITAL A+-- @+--+-- and so on. To check a string for visually confusable characters:+--+--   1. 'open' an 'MSpoof'+--   2. optionally configure it with 'setChecks', 'setRestrictionLevel',+-- and/or 'setAllowedLocales', then+--   3. 'spoofCheck' a single string, use 'areConfusable' to check if two+-- strings could be confused for each other, or use 'getSkeleton' to precompute+-- a \"skeleton\" string (similar to a hash code) which can be cached+-- and re-used to quickly check (using Unicode string comparison) if+-- two strings are confusable.+--+-- By default, these methods will use ICU's bundled copy of+-- <http://unicode.org/Public/security/latest/confusables.txt confusables.txt>+-- and <http://unicode.org/Public/security/latest/confusablesWholeScript.txt confusablesWholeScript.txt>,+-- which could be out of date. To provide your own confusables databases, use+-- 'openFromSource'. (To avoid repeatedly parsing these databases, you+-- can then 'serialize' your configured 'MSpoof' and later+-- 'openFromSerialized' to load the pre-parsed databases.)++data SpoofCheck+  -- | Makes 'areConfusable' report if both identifiers are both from the+  -- same script and are visually confusable. Does not affect 'spoofCheck'.+  = SingleScriptConfusable++  -- | Makes 'areConfusable' report if both identifiers are visually+  -- confusable and at least one identifier contains characters from more+  -- than one script.+  --+  -- Makes 'spoofCheck' report if the identifier contains multiple scripts,+  -- and is confusable with some other identifier in a single script.+  | MixedScriptConfusable++  -- | Makes 'areConfusable' report if each identifier is of a different+  -- single script, and the identifiers are visually confusable.+  | WholeScriptConfusable++  -- | By default, spoof checks assume the strings have been processed+  -- through 'toCaseFold' and only check lower-case identifiers. If+  -- this is set, spoof checks will check both upper and lower case+  -- identifiers.+  | AnyCase++  -- | Checks that identifiers are no looser than the specified+  -- level passed to 'setRestrictionLevel'.+  | RestrictionLevel++  -- | Checks the 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.+  | Invisible++  -- | Checks whether the identifier contains only characters from a+  -- specified set (for example, via 'setAllowedLocales').+  | CharLimit++  -- | Checks that the identifier contains numbers from only a+  -- single script.+  | MixedNumbers++  -- | Enables all checks.+  | AllChecks++  -- | Enables returning a 'RestrictionLevel' in the 'SpoofCheckResult'.+  | AuxInfo+  deriving (Bounded, Enum, Eq, Show)++instance ToBitMask SpoofCheck where+  toBitMask SingleScriptConfusable = #const USPOOF_SINGLE_SCRIPT_CONFUSABLE+  toBitMask MixedScriptConfusable  = #const USPOOF_MIXED_SCRIPT_CONFUSABLE+  toBitMask WholeScriptConfusable  = #const USPOOF_WHOLE_SCRIPT_CONFUSABLE+  toBitMask AnyCase                = #const USPOOF_ANY_CASE+  toBitMask RestrictionLevel       = #const USPOOF_RESTRICTION_LEVEL+  toBitMask Invisible              = #const USPOOF_INVISIBLE+  toBitMask CharLimit              = #const USPOOF_CHAR_LIMIT+  toBitMask MixedNumbers           = #const USPOOF_MIXED_NUMBERS+  toBitMask AllChecks              = #const USPOOF_ALL_CHECKS+  toBitMask AuxInfo                = #const USPOOF_AUX_INFO++type USpoofCheck = Int32++data RestrictionLevel+  -- | Checks that the string contains only Unicode values in the range+  -- #0000#&#2013;#007F# inclusive.+  = ASCII+  -- | Checks that the string contains only characters from a single script.+  | SingleScriptRestrictive+  -- | Checks that the string contains only characters from a single script,+  -- or from the combinations (Latin + Han + Hiragana + Katakana),+  -- (Latin + Han + Bopomofo), or (Latin + Han + Hangul).+  | HighlyRestrictive+  -- | Checks that the string contains only characters from the combinations+  -- (Latin + Cyrillic + Greek + Cherokee), (Latin + Han + Hiragana + Katakana),+  -- (Latin + Han + Bopomofo), or (Latin + Han + Hangul).+  | ModeratelyRestrictive+  -- | Allows arbitrary mixtures of scripts.+  | MinimallyRestrictive+  -- | Allows any valid identifiers, including characters outside of the+  -- Identifier Profile.+  | Unrestrictive+  deriving (Bounded, Enum, Eq, Show)++instance ToBitMask RestrictionLevel where+  toBitMask ASCII                   = #const USPOOF_ASCII+  toBitMask SingleScriptRestrictive = #const USPOOF_SINGLE_SCRIPT_RESTRICTIVE+  toBitMask HighlyRestrictive       = #const USPOOF_HIGHLY_RESTRICTIVE+  toBitMask ModeratelyRestrictive   = #const USPOOF_MODERATELY_RESTRICTIVE+  toBitMask MinimallyRestrictive    = #const USPOOF_MINIMALLY_RESTRICTIVE+  toBitMask Unrestrictive           = #const USPOOF_UNRESTRICTIVE++type URestrictionLevel = Int32++data SpoofCheckResult+  -- | The string passed all configured spoof checks.+  = CheckOK+  -- | The string failed one or more spoof checks.+  | CheckFailed [SpoofCheck]+  -- | The string failed one or more spoof checks, and+  -- failed to pass the configured restriction level.+  | CheckFailedWithRestrictionLevel {+    -- | The spoof checks which the string failed.+    failedChecks :: [SpoofCheck]+    -- | The restriction level which the string failed to pass.+    , failedLevel :: RestrictionLevel+    }+  deriving (Eq, Show)++data SkeletonTypeOverride+  -- | By default, 'getSkeleton' builds skeletons which catch+  -- visually confusable characters across multiple scripts.+  -- Pass this flag to override that behavior and build skeletons+  -- which catch visually confusable characters across single scripts.+  = SkeletonSingleScript+  -- | By default, 'getSkeleton' assumes the input string has already+  -- been passed through 'toCaseFold' and is lower-case. Pass this+  -- flag to override that behavior and allow upper and lower-case strings.+  | SkeletonAnyCase+  deriving (Bounded, Enum, Eq, Show)++instance ToBitMask SkeletonTypeOverride where+  toBitMask SkeletonSingleScript = #const USPOOF_SINGLE_SCRIPT_CONFUSABLE+  toBitMask SkeletonAnyCase      = #const USPOOF_ANY_CASE++type USkeletonTypeOverride = Int32++makeSpoofCheckResult :: USpoofCheck -> SpoofCheckResult+makeSpoofCheckResult c =+  case c of+    0 -> CheckOK+    _ ->+      case restrictionLevel of+        Nothing -> CheckFailed spoofChecks+        Just l -> CheckFailedWithRestrictionLevel spoofChecks l+      where spoofChecks = fromBitMask $ fromIntegral $+                          c .&. #const USPOOF_ALL_CHECKS+            restrictionValue = c .&. #const USPOOF_RESTRICTION_LEVEL_MASK+            restrictionLevel = highestValueInBitMask $ fromIntegral $+                               restrictionValue++-- | Indicates which input file to 'openFromSource' failed to parse upon error.+data OpenFromSourceParseErrorFile =+  ConfusablesTxtError | ConfusablesWholeScriptTxtError+  deriving (Eq, Show)++instance NFData OpenFromSourceParseErrorFile where+  rnf !_ = ()++-- | Exception thrown with 'openFromSource' fails to parse one of the input files.+data OpenFromSourceParseError = OpenFromSourceParseError {+    -- | The file which could not be parsed.+      errFile :: OpenFromSourceParseErrorFile+    -- | Parse error encountered opening a spoof checker from source.+    , parseError :: ParseError+    } deriving (Show, Typeable)++instance NFData OpenFromSourceParseError where+    rnf OpenFromSourceParseError{..} = rnf parseError `seq` rnf errFile++instance Exception OpenFromSourceParseError++-- | Open a spoof checker for checking Unicode strings for lookalike+-- security issues with default options (all 'SpoofCheck's except+-- 'CharLimit').+open :: IO MSpoof+open = wrap =<< handleError uspoof_open++isParseError :: ParseError -> Maybe ParseError+isParseError = Just++-- | Open a spoof checker with custom rules given the UTF-8 encoded+-- contents of the @confusables.txt@ and @confusablesWholeScript.txt@+-- files as described in <http://unicode.org/reports/tr39/ Unicode UAX #39>.+openFromSource :: (ByteString, ByteString) -> IO MSpoof+openFromSource (confusables, confusablesWholeScript) =+  unsafeUseAsCStringLen confusables $ \(cptr, clen) ->+    unsafeUseAsCStringLen confusablesWholeScript $ \(wptr, wlen) ->+      with 0 $ \errTypePtr ->+        catchJust+          isParseError+          (wrap =<< (handleParseError+            (== u_PARSE_ERROR)+            (uspoof_openFromSource cptr (fromIntegral clen) wptr+              (fromIntegral wlen) errTypePtr)))+          (throwOpenFromSourceParseError errTypePtr)++throwOpenFromSourceParseError :: Ptr Int32 -> ParseError -> IO a+throwOpenFromSourceParseError errTypePtr parseErr = do+  errType <- peek errTypePtr+  let errFile =+        if errType == #{const USPOOF_SINGLE_SCRIPT_CONFUSABLE}+        then ConfusablesTxtError+        -- N.B.: ICU as of 55.1 actually leaves errFile set to 0 in this case.+        else ConfusablesWholeScriptTxtError+  throwIO $! OpenFromSourceParseError errFile parseErr++-- | Open a spoof checker previously serialized to bytes using 'serialize'.+-- The returned 'MSpoof' will retain a reference to the 'ForeignPtr' inside+-- the ByteString, so ensure its contents do not change for the lifetime+-- of the lifetime of the returned value.+openFromSerialized :: ByteString -> IO MSpoof+openFromSerialized b =+  case toForeignPtr b of+    (ptr, off, len) -> withForeignPtr ptr $ \p ->+      wrapWithSerialized ptr =<< handleError+      (uspoof_openFromSerialized (p `plusPtr` off) (fromIntegral len) nullPtr)++-- | Get the checks performed by a spoof checker.+getChecks :: MSpoof -> IO [SpoofCheck]+getChecks s = withSpoof s $ \sptr ->+  (fromBitMask . fromIntegral . (.&.) #{const USPOOF_ALL_CHECKS}) <$>+  handleError (uspoof_getChecks sptr)++-- | Configure the checks performed by a spoof checker.+setChecks :: MSpoof -> [SpoofCheck] -> IO ()+setChecks s c = withSpoof s $ \sptr ->+  handleError $ uspoof_setChecks sptr . fromIntegral $ toBitMask c++-- | Get the restriction level of a spoof checker.+getRestrictionLevel :: MSpoof -> IO (Maybe RestrictionLevel)+getRestrictionLevel s = withSpoof s $ \sptr ->+  (highestValueInBitMask . fromIntegral) <$> uspoof_getRestrictionLevel sptr++-- | Configure the restriction level of a spoof checker.+setRestrictionLevel :: MSpoof -> RestrictionLevel -> IO ()+setRestrictionLevel s l = withSpoof s $ \sptr ->+    uspoof_setRestrictionLevel sptr . fromIntegral $ toBitMask l++-- | Get the list of locale names allowed to be used with a spoof checker.+-- (We don't use 'LocaleName' since the root and default locales have no+-- meaning here.)+getAllowedLocales :: MSpoof -> IO [String]+getAllowedLocales s = withSpoof s $ \sptr ->+  splitLocales <$> (peekCString =<< handleError (uspoof_getAllowedLocales sptr))+  where splitLocales = fmap (unpack . strip) . splitOn "," . pack++-- | Get the list of locale names allowed to be used with a spoof checker.+-- (We don't use 'LocaleName' since the root and default locales have no+-- meaning here.)+setAllowedLocales :: MSpoof -> [String] -> IO ()+setAllowedLocales s locs = withSpoof s $ \sptr ->+  withCString (intercalate "," locs) $ \lptr ->+    handleError (uspoof_setAllowedLocales sptr lptr)++-- | Check if two strings could be confused with each other.+areConfusable :: MSpoof -> Text -> Text -> IO SpoofCheckResult+areConfusable s t1 t2 = withSpoof s $ \sptr ->+  useAsPtr t1 $ \t1ptr t1len ->+    useAsPtr t2 $ \t2ptr t2len ->+      makeSpoofCheckResult <$>+      handleError (uspoof_areConfusable sptr+                   t1ptr (fromIntegral t1len)+                   t2ptr (fromIntegral t2len))++-- | Generates re-usable "skeleton" strings which can be used (via+-- Unicode equality) to check if an identifier is confusable+-- with some large set of existing identifiers.+--+-- If you cache the returned strings in storage, you /must/ invalidate+-- your cache any time the underlying confusables database changes+-- (i.e., on ICU upgrade).+--+-- By default, assumes all input strings have been passed through+-- 'toCaseFold' and are lower-case. To change this, pass+-- 'SkeletonAnyCase'.+--+-- By default, builds skeletons which catch visually confusable+-- characters across multiple scripts.  Pass 'SkeletonSingleScript' to+-- override that behavior and build skeletons which catch visually+-- confusable characters across single scripts.+getSkeleton :: MSpoof -> Maybe SkeletonTypeOverride -> Text -> IO Text+getSkeleton s o t = withSpoof s $ \sptr ->+  useAsPtr t $ \tptr tlen ->+    handleOverflowError (fromIntegral tlen)+      (\dptr dlen -> uspoof_getSkeleton sptr oflags tptr+                     (fromIntegral tlen) dptr (fromIntegral dlen))+      (\dptr dlen -> fromPtr (castPtr dptr) (fromIntegral dlen))+    where oflags = maybe 0 (fromIntegral . toBitMask) o++-- | Checks if a string could be confused with any other.+spoofCheck :: MSpoof -> Text -> IO SpoofCheckResult+spoofCheck s t = withSpoof s $ \sptr ->+  useAsPtr t $ \tptr tlen ->+    makeSpoofCheckResult <$> handleError+      (uspoof_check sptr tptr (fromIntegral tlen) nullPtr)++-- | Serializes the rules in this spoof checker to a byte array,+-- suitable for re-use by 'openFromSerialized'.+--+-- Only includes any data provided to 'openFromSource'. Does not+-- include any other state or configuration.+serialize :: MSpoof -> IO ByteString+serialize s = withSpoof s $ \sptr ->+  handleOverflowError 0+    (\dptr dlen -> (uspoof_serialize sptr dptr (fromIntegral dlen)))+    (\dptr dlen -> create (fromIntegral dlen) $ \bptr ->+      memcpy dptr bptr (fromIntegral dlen))++foreign import ccall unsafe "hs_text_icu.h __hs_uspoof_open" uspoof_open+    :: Ptr UErrorCode -> IO (Ptr USpoof)++foreign import ccall unsafe "hs_text_icu.h __hs_uspoof_openFromSerialized"+  uspoof_openFromSerialized+    :: Ptr Word8 -> Int32 -> Ptr Int32 -> Ptr UErrorCode -> IO (Ptr USpoof)++foreign import ccall unsafe "hs_text_icu.h __hs_uspoof_openFromSource"+  uspoof_openFromSource+    :: CString -> Int32 -> CString -> Int32 -> Ptr Int32 -> Ptr UParseError ->+       Ptr UErrorCode -> IO (Ptr USpoof)++foreign import ccall unsafe "hs_text_icu.h __hs_uspoof_getChecks"+  uspoof_getChecks+    :: Ptr USpoof -> Ptr UErrorCode -> IO USpoofCheck++foreign import ccall unsafe "hs_text_icu.h __hs_uspoof_setChecks"+  uspoof_setChecks+    :: Ptr USpoof -> USpoofCheck -> Ptr UErrorCode -> IO ()++foreign import ccall unsafe "hs_text_icu.h __hs_uspoof_getRestrictionLevel"+  uspoof_getRestrictionLevel+    :: Ptr USpoof -> IO URestrictionLevel++foreign import ccall unsafe "hs_text_icu.h __hs_uspoof_setRestrictionLevel"+  uspoof_setRestrictionLevel+    :: Ptr USpoof -> URestrictionLevel -> IO ()++foreign import ccall unsafe "hs_text_icu.h __hs_uspoof_getAllowedLocales"+  uspoof_getAllowedLocales+    :: Ptr USpoof -> Ptr UErrorCode -> IO CString++foreign import ccall unsafe "hs_text_icu.h __hs_uspoof_setAllowedLocales"+  uspoof_setAllowedLocales+    :: Ptr USpoof -> CString -> Ptr UErrorCode -> IO ()++foreign import ccall unsafe "hs_text_icu.h __hs_uspoof_areConfusable"+  uspoof_areConfusable+    :: Ptr USpoof -> Ptr UChar -> Int32 -> Ptr UChar -> Int32 -> Ptr UErrorCode+       -> IO USpoofCheck++foreign import ccall unsafe "hs_text_icu.h __hs_uspoof_check" uspoof_check+    :: Ptr USpoof -> Ptr UChar -> Int32 -> Ptr Int32 -> Ptr UErrorCode+       -> IO USpoofCheck++foreign import ccall unsafe "hs_text_icu.h __hs_uspoof_getSkeleton"+  uspoof_getSkeleton+    :: Ptr USpoof -> USkeletonTypeOverride -> Ptr UChar -> Int32 -> Ptr UChar ->+       Int32 -> Ptr UErrorCode -> IO Int32++foreign import ccall unsafe "hs_text_icu.h __hs_uspoof_serialize"+  uspoof_serialize+    :: Ptr USpoof -> Ptr Word8 -> Int32 -> Ptr UErrorCode -> IO Int32
+ Data/Text/ICU/Spoof/Internal.hs view
@@ -0,0 +1,69 @@+{-# LANGUAGE DeriveDataTypeable, EmptyDataDecls, ForeignFunctionInterface #-}+-- |+-- Module      : Data.Text.ICU.Spoof.Internal+-- Copyright   : (c) 2015 Ben Hamilton+--+-- License     : BSD-style+-- Maintainer  : bgertzfield@gmail.com+-- Stability   : experimental+-- Portability : GHC+--+-- Internals of the spoofability check infrastructure.++module Data.Text.ICU.Spoof.Internal+    (+    -- * Unicode spoof checking API+    -- $api+    -- * Types+      MSpoof(..)+    , Spoof(..)+    , USpoof+    -- * Functions+    , withSpoof+    , wrap+    , wrapWithSerialized+    ) where++import Data.Typeable (Typeable)+import Data.Word (Word8)+import Foreign.ForeignPtr (ForeignPtr, newForeignPtr, withForeignPtr)+import Foreign.Ptr (FunPtr, Ptr)++-- $api+-- Low-level operations on spoof checkers.++-- | Opaque handle to a configurable spoof checker.+data USpoof++-- | Configurable spoof checker wrapping an opaque handle+-- and optionally wrapping a previously serialized instance.+data MSpoof = MSpoof {+    serializedBuf :: Maybe (ForeignPtr Word8)+  , spoofPtr :: {-# UNPACK #-} !(ForeignPtr USpoof)+} deriving (Typeable)++-- | Spoof checker type.+newtype Spoof = S MSpoof+    deriving (Typeable)++-- | Temporarily unwraps an 'MSpoof' to perform operations on its raw 'USpoof'+-- handle.+withSpoof :: MSpoof -> (Ptr USpoof -> IO a) -> IO a+withSpoof (MSpoof _ spoof) = withForeignPtr spoof+{-# INLINE withSpoof #-}++-- | Wraps a raw 'USpoof' handle in an 'MSpoof', closing the handle when+-- the last reference to the object is dropped.+wrap :: Ptr USpoof -> IO MSpoof+wrap = fmap (MSpoof Nothing) . newForeignPtr uspoof_close+{-# INLINE wrap #-}++-- | Wraps a previously serialized spoof checker and raw 'USpoof' handle+-- in an 'MSpoof', closing the handle and releasing the 'ForeignPtr' when+-- the last reference to the object is dropped.+wrapWithSerialized :: ForeignPtr Word8 -> Ptr USpoof -> IO MSpoof+wrapWithSerialized s = fmap (MSpoof $ Just s) . newForeignPtr uspoof_close+{-# INLINE wrapWithSerialized #-}++foreign import ccall unsafe "hs_text_icu.h &__hs_uspoof_close" uspoof_close+    :: FunPtr (Ptr USpoof -> IO ())
+ Data/Text/ICU/Spoof/Pure.hs view
@@ -0,0 +1,146 @@+-- |+-- Module      : Data.Text.ICU.Spoof.Pure+-- Copyright   : (c) 2015 Ben Hamilton+--+-- License     : BSD-style+-- Maintainer  : bgertzfield@gmail.com+-- Stability   : experimental+-- Portability : GHC+--+-- Pure string spoof checking functions for Unicode, implemented as+-- bindings to the International Components for Unicode (ICU)+-- libraries.+--+-- For the impure spoof checking API (which is richer, but less easy to+-- use), see the "Data.Text.ICU.Spoof" module.++module Data.Text.ICU.Spoof.Pure+    (+    -- * Types+      Spoof+    , SpoofParams(..)+    , spoof+    , spoofWithParams+    , spoofFromSource+    , spoofFromSerialized+    -- * String spoof checks+    , areConfusable+    , getSkeleton+    , spoofCheck+    -- * Configuration+    , getAllowedLocales+    , getChecks+    , getRestrictionLevel+    -- * Persistence+    , serialize+    ) where++import Data.ByteString (ByteString)+import Data.Foldable (forM_)+import Data.Text (Text)+import Data.Text.ICU.Spoof.Internal (Spoof(..))+import System.IO.Unsafe (unsafePerformIO)+import qualified Data.Text.ICU.Spoof as S++data SpoofParams+  -- | Used to configure a 'Spoof' checker via 'spoofWithParams'.+  = SpoofParams {+    -- | Optional 'S.SpoofCheck's to perform on a string. By default, performs+    -- all checks except 'CharLimit'.+    spoofChecks :: Maybe [S.SpoofCheck]+    -- | Optional 'S.RestrictionLevel' to which characters in the string will+    -- be limited. By default, uses 'HighlyRestrictive'.+  , level :: Maybe S.RestrictionLevel+    -- | Optional locale(s) whose scripts will be used to limit the+    -- set of allowed characters in a string. If set, automatically+    -- enables the 'CharLimit' spoof check.+  , locales :: Maybe [String]+} deriving (Show, Eq)++applySpoofParams :: SpoofParams -> S.MSpoof -> S.MSpoof+applySpoofParams (SpoofParams c lev loc) s = unsafePerformIO $ do+  forM_ c (S.setChecks s)+  forM_ lev (S.setRestrictionLevel s)+  forM_ loc (S.setAllowedLocales s)+  return s++-- | Open an immutable 'Spoof' checker with default options (all+-- 'S.SpoofCheck's except 'CharLimit').+spoof :: Spoof+spoof = unsafePerformIO $ S `fmap` S.open++-- | Open an immutable 'Spoof' checker with specific 'SpoofParams'+-- to control its behavior.+spoofWithParams :: SpoofParams -> Spoof+spoofWithParams p = unsafePerformIO $ do+  s <- S.open+  return (S $ applySpoofParams p s)++-- | Open a immutable 'Spoof' checker with specific 'SpoofParams'+-- to control its behavior and custom rules given the UTF-8 encoded+-- contents of the @confusables.txt@ and @confusablesWholeScript.txt@+-- files as described in <http://unicode.org/reports/tr39/ Unicode UAX #39>.+spoofFromSource :: (ByteString, ByteString) -> SpoofParams -> Spoof+spoofFromSource (confusables, confusablesWholeScript) p = unsafePerformIO $ do+  s <- S.openFromSource (confusables, confusablesWholeScript)+  return (S $ applySpoofParams p s)++-- | Create an immutable spoof checker with specific 'SpoofParams'+-- to control its behavior and custom rules previously returned+-- by 'serialize'.+spoofFromSerialized :: ByteString -> SpoofParams -> Spoof+spoofFromSerialized b p = unsafePerformIO $ do+  s <- S.openFromSerialized b+  return (S $ applySpoofParams p s)++-- | Check two strings for confusability.+areConfusable :: Spoof -> Text -> Text -> S.SpoofCheckResult+areConfusable (S s) t1 t2 = unsafePerformIO $ S.areConfusable s t1 t2++-- | Check a string for spoofing issues.+spoofCheck :: Spoof -> Text -> S.SpoofCheckResult+spoofCheck (S s) t = unsafePerformIO $ S.spoofCheck s t++-- | Generates re-usable \"skeleton\" strings which can be used (via+-- Unicode equality) to check if an identifier is confusable+-- with some large set of existing identifiers.+--+-- If you cache the returned strings in storage, you /must/ invalidate+-- your cache any time the underlying confusables database changes+-- (i.e., on ICU upgrade).+--+-- By default, assumes all input strings have been passed through+-- 'toCaseFold' and are lower-case. To change this, pass+-- 'SkeletonAnyCase'.+--+-- By default, builds skeletons which catch visually confusable+-- characters across multiple scripts.  Pass 'SkeletonSingleScript' to+-- override that behavior and build skeletons which catch visually+-- confusable characters across single scripts.+getSkeleton :: Spoof -> Maybe S.SkeletonTypeOverride -> Text -> Text+getSkeleton (S s) o t = unsafePerformIO $ S.getSkeleton s o t++-- | Gets the restriction level currently configured in the spoof+-- checker, if present.+getRestrictionLevel :: Spoof -> Maybe S.RestrictionLevel+getRestrictionLevel (S s) = unsafePerformIO $ S.getRestrictionLevel s++-- | Gets the checks currently configured in the spoof checker.+getChecks :: Spoof -> [S.SpoofCheck]+getChecks (S s) = unsafePerformIO $ S.getChecks s++-- | Gets the locales whose scripts are currently allowed by the spoof+-- checker.  (We don't use 'LocaleName' since the root and default+-- locales have no meaning here.)+getAllowedLocales :: Spoof -> [String]+getAllowedLocales (S s) = unsafePerformIO $ S.getAllowedLocales s++-- | Serializes the rules in this spoof checker to a byte array,+-- suitable for re-use by 'spoofFromSerialized'.+--+-- Only includes any data provided to 'openFromSource'. Does not+-- include any other state or configuration.+serialize :: Spoof -> ByteString+serialize (S s) = unsafePerformIO $ S.serialize s++{-# INLINE spoofCheck #-}
README.markdown view
@@ -12,14 +12,21 @@ # Prerequisites  This library is implemented as bindings to the well-respected [ICU-library](http://www.icu-project.org/), which is not included.  The versions-of ICU currently supported are 4.0 and newer.+library](http://www.icu-project.org/) (which is not bundled, and must+be installed separately).  +# Compatibility++Upstream ICU occasionally introduces backwards-incompatible API+breaks.  This package tries to stay up to date with upstream, and is+currently more or less in sync with ICU 55.++ # Get involved!  Please report bugs via the-[bitbucket issue tracker](http://bitbucket.org/bos/text-icu/issues).+[github issue tracker](http://github.com/bos/text-icu/issues).  Master [Mercurial repository](http://bitbucket.org/bos/text-icu): 
cbits/text_icu.c view
@@ -1,4 +1,5 @@ #include "hs_text_icu.h"+#include "stdbool.h"  UBreakIterator* __hs_ubrk_open(UBreakIteratorType type, const char *locale, 			       const UChar *text, int32_t textLength,@@ -25,7 +26,7 @@     return ubrk_safeClone(bi, stackBuffer, pBufferSize, status); } -int32_t __hs_ubrk_current(UBreakIterator *bi)+int32_t __hs_ubrk_current(const UBreakIterator *bi) {     return ubrk_current(bi); }@@ -305,7 +306,7 @@  int32_t __hs_u_strCompareIter(UCharIterator *iter1, UCharIterator *iter2) {-    return u_strCompareIter(iter1, iter2, TRUE);+    return u_strCompareIter(iter1, iter2, true); }  UBlockCode __hs_ublock_getCode(UChar32 c)@@ -385,8 +386,8 @@     return uregex_close(regexp); } -URegularExpression *__hs_uregex_clone(URegularExpression *regexp,-				      UErrorCode *pErrorCode)+URegularExpression * __hs_uregex_clone(const URegularExpression *regexp,+				       UErrorCode *pErrorCode) {     return uregex_clone(regexp, pErrorCode); }@@ -448,4 +449,99 @@ 			  UErrorCode *status) {     return uregex_group(regexp, groupNum, dest, destCapacity, status);+}++USpoofChecker *__hs_uspoof_open(UErrorCode *status)+{+    return uspoof_open(status);+}++USpoofChecker *__hs_uspoof_openFromSerialized(const void *data, int32_t length,+                                              int32_t *pActualLength,+                                              UErrorCode *status)+{+    return uspoof_openFromSerialized(data, length, pActualLength, status);+}++USpoofChecker *__hs_uspoof_openFromSource(const char *confusables,+                                          int32_t confusablesLen,+                                          const char *confusablesWholeScript,+                                          int32_t confusablesWholeScriptLen,+                                          int32_t *errType,+                                          UParseError *parseError,+                                          UErrorCode *status)+{+    // Work around missing call to umtx_initOnce() in uspoof_openFromSource()+    // causing crash when gNfdNormalizer is accessed+    uspoof_getInclusionSet(status);+    return uspoof_openFromSource(confusables, confusablesLen,+                                 confusablesWholeScript,+                                 confusablesWholeScriptLen,+                                 errType, parseError, status);+}++void __hs_uspoof_setChecks(USpoofChecker *sc, int32_t checks,+                           UErrorCode *status)+{+    uspoof_setChecks(sc, checks, status);+}++int32_t __hs_uspoof_getChecks(const USpoofChecker *sc, UErrorCode *status)+{+    return uspoof_getChecks(sc, status);+}++void __hs_uspoof_setRestrictionLevel(USpoofChecker *sc, URestrictionLevel level)+{+    uspoof_setRestrictionLevel(sc, level);+}++URestrictionLevel __hs_uspoof_getRestrictionLevel(const USpoofChecker *sc)+{+    return uspoof_getRestrictionLevel(sc);+}++void __hs_uspoof_setAllowedLocales(USpoofChecker *sc, const char *localesList,+                                   UErrorCode *status)+{+    uspoof_setAllowedLocales(sc, localesList, status);+}++const char *__hs_uspoof_getAllowedLocales(USpoofChecker *sc, UErrorCode *status)+{+    return uspoof_getAllowedLocales(sc, status);+}++int32_t __hs_uspoof_check(USpoofChecker *sc, const UChar *id,+                          int32_t length, int32_t *position,+                          UErrorCode *status)+{+    return uspoof_check(sc, id, length, position, status);+}++int32_t __hs_uspoof_areConfusable(USpoofChecker *sc,+                                  const UChar *id1, int32_t length1,+                                  const UChar *id2, int32_t length2,+                                  UErrorCode *status)+{+    return uspoof_areConfusable(sc, id1, length1, id2, length2, status);+}++int32_t __hs_uspoof_getSkeleton(USpoofChecker *sc,+                                int32_t type, const UChar *id, int32_t length,+                                UChar *dest, int32_t destCapacity,+                                UErrorCode *status)+{+    return uspoof_getSkeleton(sc, type, id, length, dest, destCapacity, status);+}++int32_t __hs_uspoof_serialize(USpoofChecker *sc, void *data, int32_t capacity,+                              UErrorCode *status)+{+    return uspoof_serialize(sc, data, capacity, status);+}++void __hs_uspoof_close(USpoofChecker *sc)+{+    uspoof_close(sc); }
changelog.md view
@@ -1,3 +1,10 @@+0.7.1.0++* Add fix for undefined TRUE value in cbits (#52)+* Improve CI and documentation (#20)++Thanks to everyone who contributed!+ 0.7.0.0  * Built and tested against ICU 53.
include/hs_text_icu.h view
@@ -11,6 +11,7 @@ #include "unicode/uiter.h" #include "unicode/unorm.h" #include "unicode/uregex.h"+#include "unicode/uspoof.h" #include "unicode/ustring.h"  #include <stdint.h>@@ -26,7 +27,7 @@ UBreakIterator * __hs_ubrk_safeClone(const UBreakIterator *bi, 				     void *stackBuffer, int32_t *pBufferSize, 				     UErrorCode *status);-int32_t __hs_ubrk_current(UBreakIterator *bi);+int32_t __hs_ubrk_current(const UBreakIterator *bi); int32_t __hs_ubrk_first(UBreakIterator *bi); int32_t __hs_ubrk_last(UBreakIterator *bi); int32_t __hs_ubrk_next(UBreakIterator *bi);@@ -80,7 +81,6 @@ int32_t __hs_ucol_getSortKey(const UCollator *coll, 			     const UChar *source, int32_t sourceLength, 			     uint8_t *result, int32_t resultLength);-UBool __hs_ucol_equals(const UCollator *source, const UCollator *target);  /* ucnv.h */ @@ -142,8 +142,8 @@ void __hs_uregex_setStackLimit(URegularExpression *regexp, 			       int32_t limit, UErrorCode *status); void __hs_uregex_close(URegularExpression *regexp);-URegularExpression *__hs_uregex_clone(URegularExpression *regexp,-				      UErrorCode *pErrorCode);+URegularExpression * __hs_uregex_clone(const URegularExpression *regexp,+				       UErrorCode *pErrorCode); const UChar *__hs_uregex_pattern(const URegularExpression *regexp, 				 int32_t *patLength, UErrorCode *status); int32_t __hs_uregex_flags(const URegularExpression *regexp,@@ -176,3 +176,45 @@ 			  const UChar *src, int32_t srcLength, 			  const char *locale, UErrorCode *pErrorCode); int32_t __hs_u_strCompareIter(UCharIterator *iter1, UCharIterator *iter2);++/* uspoof.h */++USpoofChecker *__hs_uspoof_open(UErrorCode *status);+USpoofChecker *__hs_uspoof_openFromSerialized(const void *data, int32_t length,+                                              int32_t *pActualLength,+                                              UErrorCode *status);+USpoofChecker *__hs_uspoof_openFromSource(const char *confusables,+                                          int32_t confusablesLen,+                                          const char *confusablesWholeScript,+                                          int32_t confusablesWholeScriptLen,+                                          int32_t *errType,+                                          UParseError *parseError,+                                          UErrorCode *status);+void __hs_uspoof_setChecks(USpoofChecker *sc, int32_t checks,+                           UErrorCode *status);+int32_t __hs_uspoof_getChecks(const USpoofChecker *sc, UErrorCode *status);++// Yes, these really don't take UErrorCode *..+void __hs_uspoof_setRestrictionLevel(USpoofChecker *sc,+                                     URestrictionLevel restrictionLevel);+URestrictionLevel __hs_uspoof_getRestrictionLevel(const USpoofChecker *sc);++void __hs_uspoof_setAllowedLocales(USpoofChecker *sc, const char *localesList,+                                   UErrorCode *status);+const char *__hs_uspoof_getAllowedLocales(USpoofChecker *sc,+                                          UErrorCode *status);++int32_t __hs_uspoof_check(USpoofChecker *sc, const UChar *id,+                          int32_t length, int32_t *position,+                          UErrorCode *status);+int32_t __hs_uspoof_areConfusable(USpoofChecker *sc,+                                  const UChar *id1, int32_t length1,+                                  const UChar *id2, int32_t length2,+                                  UErrorCode *status);+int32_t __hs_uspoof_getSkeleton(USpoofChecker *sc, int32_t checks,+                                const UChar *id, int32_t length,+                                UChar *dest, int32_t destCapacity,+                                UErrorCode *status);+int32_t __hs_uspoof_serialize(USpoofChecker *sc, void *data, int32_t capacity,+                              UErrorCode *status);+void __hs_uspoof_close(USpoofChecker *sc);
tests/Properties.hs view
@@ -13,7 +13,8 @@ import Data.Maybe (fromMaybe) import Data.Text (Text) import Data.Text.ICU (NormalizationMode(..))-import QuickCheckUtils ()+import QuickCheckUtils (NonEmptyText(..), LatinSpoofableText(..),+                        NonSpoofableText(..)) import Test.Framework (Test, testGroup) import Test.Framework.Providers.QuickCheck2 (testProperty) import qualified Data.Text as T@@ -78,7 +79,14 @@ t_digitToInt = t_rnf $ I.digitToInt t_numericValue = t_rnf $ I.numericValue +-- Spoofing +t_nonspoofable (NonSpoofableText t) = I.spoofCheck I.spoof t == I.CheckOK+t_spoofable (LatinSpoofableText t) = I.spoofCheck I.spoof t ==+                                     I.CheckFailed [I.WholeScriptConfusable]+t_confusable (NonEmptyText t) = I.areConfusable I.spoof t t ==+                                I.CheckFailed [I.SingleScriptConfusable]+ tests :: Test tests =   testGroup "Properties" [@@ -101,4 +109,7 @@   , testProperty "t_mirror" t_mirror   , testProperty "t_digitToInt" t_digitToInt   , testProperty "t_numericValue" t_numericValue+  , testProperty "t_spoofable" t_spoofable+  , testProperty "t_nonspoofable" t_nonspoofable+  , testProperty "t_confusable" t_confusable   ]
tests/QuickCheckUtils.hs view
@@ -1,13 +1,14 @@ {-# LANGUAGE BangPatterns #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -module QuickCheckUtils () where+module QuickCheckUtils (NonEmptyText(..), LatinSpoofableText(..),+                        NonSpoofableText(..)) where  import Control.Applicative ((<$>)) import Control.DeepSeq (NFData(..)) import Data.Text.ICU (Collator, LocaleName(..), NormalizationMode(..)) import Data.Text.ICU.Break (available)-import Test.QuickCheck (Arbitrary(..), elements)+import Test.QuickCheck (Arbitrary(..), Gen, elements, listOf1) import qualified Data.Text as T import qualified Data.Text.ICU as I @@ -26,3 +27,34 @@  instance Arbitrary Collator where     arbitrary = I.collator <$> arbitrary++newtype NonEmptyText = NonEmptyText { nonEmptyText :: T.Text } deriving Show+instance Arbitrary NonEmptyText where+  arbitrary = NonEmptyText <$> T.pack <$> listOf1 arbitrary++newtype LatinSpoofableText = LatinSpoofableText { latinSpoofableText :: T.Text }+                           deriving Show+instance Arbitrary LatinSpoofableText where+    arbitrary = LatinSpoofableText <$> T.pack <$>+                listOf1 genCyrillicLatinSpoofableChar++genCyrillicLatinSpoofableChar :: Gen Char+genCyrillicLatinSpoofableChar = elements (+  "\x043A\x043E\x0433\x0435\x043A\x043C" +++  ['\x043E'..'\x0443'] +++  ['\x0445'..'\x0446'] +++  "\x044A" +++  ['\x0454'..'\x0456'] +++  "\x0458\x045B\x048D\x0491\x0493\x049B\x049F\x04AB\x04AD\x04AF\x04B1\x04BB\+  \\x04BD\x04BF" +++  ['\x04CE'..'\x04CF'] +++  "\x04D5\x04D9\x04E9\x0501\x0511\x051B\x051D")++newtype NonSpoofableText = NonSpoofableText { nonSpoofableText :: T.Text }+                         deriving Show++instance Arbitrary NonSpoofableText where+    arbitrary = NonSpoofableText <$> T.pack <$> listOf1 genNonSpoofableChar++genNonSpoofableChar :: Gen Char+genNonSpoofableChar = elements "QDFRz"
text-icu.cabal view
@@ -1,5 +1,5 @@ name:           text-icu-version:        0.7.0.1+version:        0.7.1.0 synopsis:       Bindings to the ICU library homepage:       https://github.com/bos/text-icu bug-reports:    https://github.com/bos/text-icu/issues@@ -29,8 +29,10 @@     unique binary representation.)   .   * Regular expression search and replace.+  .+  * Security checks for visually confusable (spoofable) strings. maintainer:     Bryan O'Sullivan <bos@serpentine.com>-copyright:      2009-2014 Bryan O'Sullivan+copyright:      2009-2015 Bryan O'Sullivan category:       Data, Text license:        BSD3 license-file:   LICENSE@@ -59,8 +61,10 @@       Data.Text.ICU.Error       Data.Text.ICU.Normalize       Data.Text.ICU.Regex+      Data.Text.ICU.Spoof       Data.Text.ICU.Types   other-modules:+      Data.Text.ICU.BitMask       Data.Text.ICU.Break.Pure       Data.Text.ICU.Break.Types       Data.Text.ICU.Collate.Internal@@ -72,9 +76,14 @@       Data.Text.ICU.Normalize.Internal       Data.Text.ICU.Regex.Internal       Data.Text.ICU.Regex.Pure+      Data.Text.ICU.Spoof.Internal+      Data.Text.ICU.Spoof.Pure       Data.Text.ICU.Text   c-sources: cbits/text_icu.c   include-dirs: include+  if os(darwin)+    extra-lib-dirs: /usr/local/opt/icu4c/lib+    include-dirs: /usr/local/opt/icu4c/include   extra-libraries: icuuc   if os(mingw32)     extra-libraries: icuin icudt