{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
module Distribution.Types.ForeignLib(
ForeignLib(..),
emptyForeignLib,
foreignLibModules,
foreignLibIsShared,
foreignLibVersion,
LibVersionInfo,
mkLibVersionInfo,
libVersionInfoCRA,
libVersionNumber,
libVersionNumberShow,
libVersionMajor
) where
import Prelude ()
import Distribution.Compat.Prelude
import Distribution.ModuleName
import Distribution.Version
import Distribution.System
import Distribution.Text
import qualified Distribution.Compat.ReadP as Parse
import Distribution.Types.BuildInfo
import Distribution.Types.ForeignLibType
import Distribution.Types.ForeignLibOption
import Distribution.Types.UnqualComponentName
import qualified Text.PrettyPrint as Disp
import qualified Text.Read as Read
data ForeignLib = ForeignLib {
foreignLibName :: UnqualComponentName
, foreignLibType :: ForeignLibType
, foreignLibOptions :: [ForeignLibOption]
, foreignLibBuildInfo :: BuildInfo
, foreignLibVersionInfo :: Maybe LibVersionInfo
, foreignLibVersionLinux :: Maybe Version
, foreignLibModDefFile :: [FilePath]
}
deriving (Generic, Show, Read, Eq, Typeable, Data)
data LibVersionInfo = LibVersionInfo Int Int Int deriving (Data, Eq, Generic, Typeable)
instance Ord LibVersionInfo where
LibVersionInfo c r _ `compare` LibVersionInfo c' r' _ =
case c `compare` c' of
EQ -> r `compare` r'
e -> e
instance Show LibVersionInfo where
showsPrec d (LibVersionInfo c r a) = showParen (d > 10)
$ showString "mkLibVersionInfo "
. showsPrec 11 (c,r,a)
instance Read LibVersionInfo where
readPrec = Read.parens $ do
Read.Ident "mkLibVersionInfo" <- Read.lexP
t <- Read.step Read.readPrec
return (mkLibVersionInfo t)
instance Binary LibVersionInfo
instance Text LibVersionInfo where
disp (LibVersionInfo c r a)
= Disp.hcat $ Disp.punctuate (Disp.char ':') $ map Disp.int [c,r,a]
parse = do
c <- parseNat
(r, a) <- Parse.option (0,0) $ do
_ <- Parse.char ':'
r <- parseNat
a <- Parse.option 0 (Parse.char ':' >> parseNat)
return (r, a)
return $ mkLibVersionInfo (c,r,a)
where
parseNat = read `fmap` Parse.munch1 isDigit
mkLibVersionInfo :: (Int, Int, Int) -> LibVersionInfo
mkLibVersionInfo (c,r,a) = LibVersionInfo c r a
libVersionInfoCRA :: LibVersionInfo -> (Int, Int, Int)
libVersionInfoCRA (LibVersionInfo c r a) = (c,r,a)
libVersionNumber :: LibVersionInfo -> (Int, Int, Int)
libVersionNumber (LibVersionInfo c r a) = (c-a , a , r)
libVersionNumberShow :: LibVersionInfo -> String
libVersionNumberShow v =
let (major, minor, build) = libVersionNumber v
in show major ++ "." ++ show minor ++ "." ++ show build
libVersionMajor :: LibVersionInfo -> Int
libVersionMajor (LibVersionInfo c _ a) = c-a
instance Binary ForeignLib
instance Semigroup ForeignLib where
a <> b = ForeignLib {
foreignLibName = combine' foreignLibName
, foreignLibType = combine foreignLibType
, foreignLibOptions = combine foreignLibOptions
, foreignLibBuildInfo = combine foreignLibBuildInfo
, foreignLibVersionInfo = combine'' foreignLibVersionInfo
, foreignLibVersionLinux = combine'' foreignLibVersionLinux
, foreignLibModDefFile = combine foreignLibModDefFile
}
where combine field = field a `mappend` field b
combine' field = case ( unUnqualComponentName $ field a
, unUnqualComponentName $ field b) of
("", _) -> field b
(_, "") -> field a
(x, y) -> error $ "Ambiguous values for executable field: '"
++ x ++ "' and '" ++ y ++ "'"
combine'' field = field b
instance Monoid ForeignLib where
mempty = ForeignLib {
foreignLibName = mempty
, foreignLibType = ForeignLibTypeUnknown
, foreignLibOptions = []
, foreignLibBuildInfo = mempty
, foreignLibVersionInfo = Nothing
, foreignLibVersionLinux = Nothing
, foreignLibModDefFile = []
}
mappend = (<>)
emptyForeignLib :: ForeignLib
emptyForeignLib = mempty
foreignLibModules :: ForeignLib -> [ModuleName]
foreignLibModules = otherModules . foreignLibBuildInfo
foreignLibIsShared :: ForeignLib -> Bool
foreignLibIsShared = foreignLibTypeIsShared . foreignLibType
foreignLibVersion :: ForeignLib -> OS -> [Int]
foreignLibVersion flib Linux =
case foreignLibVersionLinux flib of
Just v -> versionNumbers v
Nothing ->
case foreignLibVersionInfo flib of
Just v' ->
let (major, minor, build) = libVersionNumber v'
in [major, minor, build]
Nothing -> []
foreignLibVersion _ _ = []