    {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}

    -- ----------------------------------------------------------------------------
    --
    --  (c) The University of Glasgow 2006
    --
    -- Fingerprints for recompilation checking and ABI versioning.
    --
    -- https://gitlab.haskell.org/ghc/ghc/wikis/commentary/compiler/recompilation-avoidance
    --
    -- ----------------------------------------------------------------------------

    module GHC.Utils.Fingerprint (
            readHexFingerprint,
            fingerprintByteString,
            -- * Re-exported from GHC.Fingerprint
            Fingerprint(..), fingerprint0,
            fingerprintFingerprints,
            fingerprintData,
            fingerprintString,
            fingerprintStrings,
            getFileHash
       ) where

    import GHC.Prelude.Basic

    import Foreign
    import GHC.IO
    import Numeric          ( readHex )

    import qualified Data.ByteString as BS
    import qualified Data.ByteString.Unsafe as BS

    import GHC.Fingerprint

    -- useful for parsing the output of 'md5sum', should we want to do that.
    readHexFingerprint :: String -> Fingerprint
    readHexFingerprint :: String -> Fingerprint
    readHexFingerprint String
    s = Word64 -> Word64 -> Fingerprint
    Fingerprint Word64
    w1 Word64
    w2
     where (String
    s1,String
    s2) = Int -> String -> (String, String)
    forall a. Int -> [a] -> ([a], [a])
    splitAt Int
    16 String
    s
           [(Word64
    w1,String
    "")] = ReadS Word64
    forall a. (Eq a, Num a) => ReadS a
    readHex String
    s1
           [(Word64
    w2,String
    "")] = ReadS Word64
    forall a. (Eq a, Num a) => ReadS a
    readHex (Int -> String -> String
    forall a. Int -> [a] -> [a]
    take Int
    16 String
    s2)

    fingerprintByteString :: BS.ByteString -> Fingerprint
    fingerprintByteString :: ByteString -> Fingerprint
    fingerprintByteString ByteString
    bs = IO Fingerprint -> Fingerprint
    forall a. IO a -> a
    unsafeDupablePerformIO (IO Fingerprint -> Fingerprint) -> IO Fingerprint -> Fingerprint
    forall a b. (a -> b) -> a -> b
    $
      ByteString -> (CStringLen -> IO Fingerprint) -> IO Fingerprint
    forall a. ByteString -> (CStringLen -> IO a) -> IO a
    BS.unsafeUseAsCStringLen ByteString
    bs ((CStringLen -> IO Fingerprint) -> IO Fingerprint)
    -> (CStringLen -> IO Fingerprint) -> IO Fingerprint
    forall a b. (a -> b) -> a -> b
    $ \(Ptr CChar
    ptr, Int
    len) -> Ptr Word8 -> Int -> IO Fingerprint
    fingerprintData (Ptr CChar -> Ptr Word8
    forall a b. Ptr a -> Ptr b
    castPtr Ptr CChar
    ptr) Int
    len

    -- See Note [Repeated -optP hashing]
    fingerprintStrings :: [String] -> Fingerprint
    fingerprintStrings :: [String] -> Fingerprint
    fingerprintStrings [String]
    ss = [Fingerprint] -> Fingerprint
    fingerprintFingerprints ([Fingerprint] -> Fingerprint) -> [Fingerprint] -> Fingerprint
    forall a b. (a -> b) -> a -> b
    $ (String -> Fingerprint) -> [String] -> [Fingerprint]
    forall a b. (a -> b) -> [a] -> [b]
    map String -> Fingerprint
    fingerprintString [String]
    ss