{-# LANGUAGE CPP #-}

-- ----------------------------------------------------------------------------
--
--  (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 Fingerprint (
        readHexFingerprint,
        fingerprintByteString,
        -- * Re-exported from GHC.Fingerprint
        Fingerprint(..), fingerprint0,
        fingerprintFingerprints,
        fingerprintData,
        fingerprintString,
        getFileHash
   ) where

#include "GhclibHsVersions.h"

import GhcPrelude

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 s :: String
s = Word64 -> Word64 -> Fingerprint
Fingerprint Word64
w1 Word64
w2
 where (s1 :: String
s1,s2 :: String
s2) = Int -> String -> (String, String)
forall a. Int -> [a] -> ([a], [a])
splitAt 16 String
s
       [(w1 :: Word64
w1,"")] = ReadS Word64
forall a. (Eq a, Num a) => ReadS a
readHex String
s1
       [(w2 :: Word64
w2,"")] = ReadS Word64
forall a. (Eq a, Num a) => ReadS a
readHex (Int -> String -> String
forall a. Int -> [a] -> [a]
take 16 String
s2)

fingerprintByteString :: BS.ByteString -> Fingerprint
fingerprintByteString :: ByteString -> Fingerprint
fingerprintByteString bs :: 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 :: Ptr CChar
ptr, len :: 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