module Distribution.Simple.Program.Builtin (
builtinPrograms,
ghcProgram,
ghcPkgProgram,
ghcjsProgram,
ghcjsPkgProgram,
lhcProgram,
lhcPkgProgram,
hmakeProgram,
jhcProgram,
haskellSuiteProgram,
haskellSuitePkgProgram,
uhcProgram,
gccProgram,
arProgram,
stripProgram,
happyProgram,
alexProgram,
hsc2hsProgram,
c2hsProgram,
cpphsProgram,
hscolourProgram,
haddockProgram,
greencardProgram,
ldProgram,
tarProgram,
cppProgram,
pkgConfigProgram,
hpcProgram,
) where
import Distribution.Simple.Program.Find
( findProgramOnSearchPath )
import Distribution.Simple.Program.Run
( getProgramInvocationOutput, programInvocation )
import Distribution.Simple.Program.Types
( Program(..), ConfiguredProgram(..), simpleProgram )
import Distribution.Simple.Utils
( findProgramVersion )
import Distribution.Compat.Exception
( catchIO )
import Distribution.Verbosity
( lessVerbose )
import Distribution.Version
( Version(..), withinRange, earlierVersion, laterVersion
, intersectVersionRanges )
import Data.Char
( isDigit )
import Data.List
( isInfixOf )
import qualified Data.Map as Map
builtinPrograms :: [Program]
builtinPrograms =
[
ghcProgram
, ghcPkgProgram
, ghcjsProgram
, ghcjsPkgProgram
, haskellSuiteProgram
, haskellSuitePkgProgram
, hmakeProgram
, jhcProgram
, lhcProgram
, lhcPkgProgram
, uhcProgram
, hpcProgram
, hscolourProgram
, haddockProgram
, happyProgram
, alexProgram
, hsc2hsProgram
, c2hsProgram
, cpphsProgram
, greencardProgram
, gccProgram
, arProgram
, stripProgram
, ldProgram
, tarProgram
, pkgConfigProgram
]
ghcProgram :: Program
ghcProgram = (simpleProgram "ghc") {
programFindVersion = findProgramVersion "--numeric-version" id,
programPostConf = \_verbosity ghcProg ->
do let ghcProg' = ghcProg {
programOverrideEnv = ("LANGUAGE", Just "en")
: programOverrideEnv ghcProg
}
affectedVersionRange = intersectVersionRanges
(laterVersion $ Version [7,8,0] [])
(earlierVersion $ Version [7,8,4] [])
return $ maybe ghcProg
(\v -> if withinRange v affectedVersionRange
then ghcProg' else ghcProg)
(programVersion ghcProg)
}
ghcPkgProgram :: Program
ghcPkgProgram = (simpleProgram "ghc-pkg") {
programFindVersion = findProgramVersion "--version" $ \str ->
case words str of
(_:_:_:_:ver:_) -> ver
_ -> ""
}
ghcjsProgram :: Program
ghcjsProgram = (simpleProgram "ghcjs") {
programFindVersion = findProgramVersion "--numeric-ghcjs-version" id
}
ghcjsPkgProgram :: Program
ghcjsPkgProgram = (simpleProgram "ghcjs-pkg") {
programFindVersion = findProgramVersion "--version" $ \str ->
case words str of
(_:_:_:_:ver:_) -> ver
_ -> ""
}
lhcProgram :: Program
lhcProgram = (simpleProgram "lhc") {
programFindVersion = findProgramVersion "--numeric-version" id
}
lhcPkgProgram :: Program
lhcPkgProgram = (simpleProgram "lhc-pkg") {
programFindVersion = findProgramVersion "--version" $ \str ->
case words str of
(_:_:_:_:ver:_) -> ver
_ -> ""
}
hmakeProgram :: Program
hmakeProgram = (simpleProgram "hmake") {
programFindVersion = findProgramVersion "--version" $ \str ->
case words str of
(_:ver:_) -> ver
_ -> ""
}
jhcProgram :: Program
jhcProgram = (simpleProgram "jhc") {
programFindVersion = findProgramVersion "--version" $ \str ->
case words str of
(_:ver:_) -> ver
_ -> ""
}
uhcProgram :: Program
uhcProgram = (simpleProgram "uhc") {
programFindVersion = findProgramVersion "--version-dotted" id
}
hpcProgram :: Program
hpcProgram = (simpleProgram "hpc")
{
programFindVersion = findProgramVersion "version" $ \str ->
case words str of
(_ : _ : _ : ver : _) -> ver
_ -> ""
}
haskellSuiteProgram :: Program
haskellSuiteProgram = (simpleProgram "haskell-suite") {
programFindLocation =
\_verbosity _searchPath -> return $ Just "haskell-suite-dummy-location"
}
haskellSuitePkgProgram :: Program
haskellSuitePkgProgram = (simpleProgram "haskell-suite-pkg") {
programFindLocation =
\_verbosity _searchPath -> return $ Just "haskell-suite-pkg-dummy-location"
}
happyProgram :: Program
happyProgram = (simpleProgram "happy") {
programFindVersion = findProgramVersion "--version" $ \str ->
case words str of
(_:_:ver:_) -> ver
_ -> ""
}
alexProgram :: Program
alexProgram = (simpleProgram "alex") {
programFindVersion = findProgramVersion "--version" $ \str ->
case words str of
(_:_:ver:_) -> takeWhile (\x -> isDigit x || x == '.') ver
_ -> ""
}
gccProgram :: Program
gccProgram = (simpleProgram "gcc") {
programFindVersion = findProgramVersion "-dumpversion" id
}
arProgram :: Program
arProgram = simpleProgram "ar"
stripProgram :: Program
stripProgram = (simpleProgram "strip") {
programFindVersion = \verbosity ->
findProgramVersion "--version" selectVersion (lessVerbose verbosity)
}
where
selectVersion str =
let numeric "" = False
numeric (x:_) = isDigit x
in case dropWhile (not . numeric) (words str) of
(ver:_) ->
let isDot = (== '.')
(major, rest) = break isDot ver
minor = takeWhile (not . isDot) (dropWhile isDot rest)
in major ++ "." ++ minor
_ -> ""
hsc2hsProgram :: Program
hsc2hsProgram = (simpleProgram "hsc2hs") {
programFindVersion =
findProgramVersion "--version" $ \str ->
case words str of
(_:_:ver:_) -> ver
_ -> ""
}
c2hsProgram :: Program
c2hsProgram = (simpleProgram "c2hs") {
programFindVersion = findProgramVersion "--numeric-version" id
}
cpphsProgram :: Program
cpphsProgram = (simpleProgram "cpphs") {
programFindVersion = findProgramVersion "--version" $ \str ->
case words str of
(_:ver:_) -> ver
_ -> ""
}
hscolourProgram :: Program
hscolourProgram = (simpleProgram "hscolour") {
programFindLocation = \v p -> findProgramOnSearchPath v p "HsColour",
programFindVersion = findProgramVersion "-version" $ \str ->
case words str of
(_:ver:_) -> ver
_ -> ""
}
haddockProgram :: Program
haddockProgram = (simpleProgram "haddock") {
programFindVersion = findProgramVersion "--version" $ \str ->
case words str of
(_:_:ver:_) -> takeWhile (`elem` ('.':['0'..'9'])) ver
_ -> ""
}
greencardProgram :: Program
greencardProgram = simpleProgram "greencard"
ldProgram :: Program
ldProgram = simpleProgram "ld"
tarProgram :: Program
tarProgram = (simpleProgram "tar") {
programPostConf = \verbosity tarProg -> do
tarHelpOutput <- getProgramInvocationOutput
verbosity (programInvocation tarProg ["--help"])
`catchIO` (\_ -> return "")
let k = "Supports --format"
v = if ("--format" `isInfixOf` tarHelpOutput) then "YES" else "NO"
m = Map.insert k v (programProperties tarProg)
return $ tarProg { programProperties = m }
}
cppProgram :: Program
cppProgram = simpleProgram "cpp"
pkgConfigProgram :: Program
pkgConfigProgram = (simpleProgram "pkg-config") {
programFindVersion = findProgramVersion "--version" id
}