-----------------------------------------------------------------------------
-- |
-- Module      :  Distribution.Simple.Program.Builtin
-- Copyright   :  Isaac Jones 2006, Duncan Coutts 2007-2009
--
-- Maintainer  :  cabal-devel@haskell.org
-- Portability :  portable
--
-- The module defines all the known built-in 'Program's.
--
-- Where possible we try to find their version numbers.
--
module Distribution.Simple.Program.Builtin (

    -- * The collection of unconfigured and configured progams
    builtinPrograms,

    -- * Programs that Cabal knows about
    ghcProgram,
    ghcPkgProgram,
    lhcProgram,
    lhcPkgProgram,
    nhcProgram,
    hmakeProgram,
    jhcProgram,
    hugsProgram,
    ffihugsProgram,
    uhcProgram,
    gccProgram,
    ranlibProgram,
    arProgram,
    stripProgram,
    happyProgram,
    alexProgram,
    hsc2hsProgram,
    c2hsProgram,
    cpphsProgram,
    hscolourProgram,
    haddockProgram,
    greencardProgram,
    ldProgram,
    tarProgram,
    cppProgram,
    pkgConfigProgram,
  ) where

import Distribution.Simple.Program.Types
         ( Program(..), simpleProgram )
import Distribution.Simple.Utils
         ( findProgramLocation, findProgramVersion )

-- ------------------------------------------------------------
-- * Known programs
-- ------------------------------------------------------------

-- | The default list of programs.
-- These programs are typically used internally to Cabal.
builtinPrograms :: [Program]
builtinPrograms =
    [
    -- compilers and related progs
      ghcProgram :: ProgramghcProgram
    , ghcPkgProgram :: ProgramghcPkgProgram
    , hugsProgram :: ProgramhugsProgram
    , ffihugsProgram :: ProgramffihugsProgram
    , nhcProgram :: ProgramnhcProgram
    , hmakeProgram :: ProgramhmakeProgram
    , jhcProgram :: ProgramjhcProgram
    , lhcProgram :: ProgramlhcProgram
    , lhcPkgProgram :: ProgramlhcPkgProgram
    , uhcProgram :: ProgramuhcProgram
    -- preprocessors
    , hscolourProgram :: ProgramhscolourProgram
    , haddockProgram :: ProgramhaddockProgram
    , happyProgram :: ProgramhappyProgram
    , alexProgram :: ProgramalexProgram
    , hsc2hsProgram :: Programhsc2hsProgram
    , c2hsProgram :: Programc2hsProgram
    , cpphsProgram :: ProgramcpphsProgram
    , greencardProgram :: ProgramgreencardProgram
    -- platform toolchain
    , gccProgram :: ProgramgccProgram
    , ranlibProgram :: ProgramranlibProgram
    , arProgram :: ProgramarProgram
    , stripProgram :: ProgramstripProgram
    , ldProgram :: ProgramldProgram
    , tarProgram :: ProgramtarProgram
    -- configuration tools
    , pkgConfigProgram :: ProgrampkgConfigProgram
    ]

ghcProgram :: Program
ghcProgram = (simpleProgram :: String -> ProgramsimpleProgram "ghc") {
    programFindVersion = findProgramVersion ::
  String
  -> (String -> String)
  -> Verbosity
  -> FilePath
  -> IO (Maybe Version)findProgramVersion "--numeric-version" id :: a -> aid
  }

ghcPkgProgram :: Program
ghcPkgProgram = (simpleProgram :: String -> ProgramsimpleProgram "ghc-pkg") {
    programFindVersion = findProgramVersion ::
  String
  -> (String -> String)
  -> Verbosity
  -> FilePath
  -> IO (Maybe Version)findProgramVersion "--version" ($) :: (a -> b) -> a -> b$ \str ->
      -- Invoking "ghc-pkg --version" gives a string like
      -- "GHC package manager version 6.4.1"
      case words :: String -> [String]words str :: Stringstr of
        (_:_:_:_:ver:_) -> ver :: Stringver
        _               -> ""
  }

lhcProgram :: Program
lhcProgram = (simpleProgram :: String -> ProgramsimpleProgram "lhc") {
    programFindVersion = findProgramVersion ::
  String
  -> (String -> String)
  -> Verbosity
  -> FilePath
  -> IO (Maybe Version)findProgramVersion "--numeric-version" id :: a -> aid
  }

lhcPkgProgram :: Program
lhcPkgProgram = (simpleProgram :: String -> ProgramsimpleProgram "lhc-pkg") {
    programFindVersion = findProgramVersion ::
  String
  -> (String -> String)
  -> Verbosity
  -> FilePath
  -> IO (Maybe Version)findProgramVersion "--version" ($) :: (a -> b) -> a -> b$ \str ->
      -- Invoking "lhc-pkg --version" gives a string like
      -- "LHC package manager version 0.7"
      case words :: String -> [String]words str :: Stringstr of
        (_:_:_:_:ver:_) -> ver :: Stringver
        _               -> ""
  }

nhcProgram :: Program
nhcProgram = (simpleProgram :: String -> ProgramsimpleProgram "nhc98") {
    programFindVersion = findProgramVersion ::
  String
  -> (String -> String)
  -> Verbosity
  -> FilePath
  -> IO (Maybe Version)findProgramVersion "--version" ($) :: (a -> b) -> a -> b$ \str ->
      -- Invoking "nhc98 --version" gives a string like
      -- "/usr/local/bin/nhc98: v1.20 (2007-11-22)"
      case words :: String -> [String]words str :: Stringstr of
        (_:('v':ver):_) -> ver :: Stringver
        _               -> ""
  }

hmakeProgram :: Program
hmakeProgram = (simpleProgram :: String -> ProgramsimpleProgram "hmake") {
    programFindVersion = findProgramVersion ::
  String
  -> (String -> String)
  -> Verbosity
  -> FilePath
  -> IO (Maybe Version)findProgramVersion "--version" ($) :: (a -> b) -> a -> b$ \str ->
    -- Invoking "hmake --version" gives a string line
    -- "/usr/local/bin/hmake: 3.13 (2006-11-01)"
      case words :: String -> [String]words str :: Stringstr of
        (_:ver:_) -> ver :: Stringver
        _         -> ""
  }

jhcProgram :: Program
jhcProgram = (simpleProgram :: String -> ProgramsimpleProgram "jhc") {
    programFindVersion = findProgramVersion ::
  String
  -> (String -> String)
  -> Verbosity
  -> FilePath
  -> IO (Maybe Version)findProgramVersion "--version" ($) :: (a -> b) -> a -> b$ \str ->
    -- invoking "jhc --version" gives a string like
    -- "jhc 0.3.20080208 (wubgipkamcep-2)
    -- compiled by ghc-6.8 on a x86_64 running linux"
      case words :: String -> [String]words str :: Stringstr of
        (_:ver:_) -> ver :: Stringver
        _         -> ""
  }

uhcProgram :: Program
uhcProgram = (simpleProgram :: String -> ProgramsimpleProgram "uhc") {
    programFindVersion = findProgramVersion ::
  String
  -> (String -> String)
  -> Verbosity
  -> FilePath
  -> IO (Maybe Version)findProgramVersion "--version-dotted" id :: a -> aid
  }


-- AArgh! Finding the version of hugs or ffihugs is almost impossible.
hugsProgram :: Program
hugsProgram = simpleProgram :: String -> ProgramsimpleProgram "hugs"

ffihugsProgram :: Program
ffihugsProgram = simpleProgram :: String -> ProgramsimpleProgram "ffihugs"

happyProgram :: Program
happyProgram = (simpleProgram :: String -> ProgramsimpleProgram "happy") {
    programFindVersion = findProgramVersion ::
  String
  -> (String -> String)
  -> Verbosity
  -> FilePath
  -> IO (Maybe Version)findProgramVersion "--version" ($) :: (a -> b) -> a -> b$ \str ->
      -- Invoking "happy --version" gives a string like
      -- "Happy Version 1.16 Copyright (c) ...."
      case words :: String -> [String]words str :: Stringstr of
        (_:_:ver:_) -> ver :: Stringver
        _           -> ""
  }

alexProgram :: Program
alexProgram = (simpleProgram :: String -> ProgramsimpleProgram "alex") {
    programFindVersion = findProgramVersion ::
  String
  -> (String -> String)
  -> Verbosity
  -> FilePath
  -> IO (Maybe Version)findProgramVersion "--version" ($) :: (a -> b) -> a -> b$ \str ->
      -- Invoking "alex --version" gives a string like
      -- "Alex version 2.1.0, (c) 2003 Chris Dornan and Simon Marlow"
      case words :: String -> [String]words str :: Stringstr of
        (_:_:ver:_) -> takeWhile :: (a -> Bool) -> [a] -> [a]takeWhile (elem :: Eq a => a -> [a] -> Bool`elem` ('.'(:) :: a -> [a] -> [a]:['0'..'9'])) ver :: Stringver
        _           -> ""
  }

gccProgram :: Program
gccProgram = (simpleProgram :: String -> ProgramsimpleProgram "gcc") {
    programFindVersion = findProgramVersion ::
  String
  -> (String -> String)
  -> Verbosity
  -> FilePath
  -> IO (Maybe Version)findProgramVersion "-dumpversion" id :: a -> aid
  }

ranlibProgram :: Program
ranlibProgram = simpleProgram :: String -> ProgramsimpleProgram "ranlib"

arProgram :: Program
arProgram = simpleProgram :: String -> ProgramsimpleProgram "ar"

stripProgram :: Program
stripProgram = simpleProgram :: String -> ProgramsimpleProgram "strip"

hsc2hsProgram :: Program
hsc2hsProgram = (simpleProgram :: String -> ProgramsimpleProgram "hsc2hs") {
    programFindVersion =
      findProgramVersion ::
  String
  -> (String -> String)
  -> Verbosity
  -> FilePath
  -> IO (Maybe Version)findProgramVersion "--version" ($) :: (a -> b) -> a -> b$ \str ->
        -- Invoking "hsc2hs --version" gives a string like "hsc2hs version 0.66"
        case words :: String -> [String]words str :: Stringstr of
          (_:_:ver:_) -> ver :: Stringver
          _           -> ""
  }

c2hsProgram :: Program
c2hsProgram = (simpleProgram :: String -> ProgramsimpleProgram "c2hs") {
    programFindVersion = findProgramVersion ::
  String
  -> (String -> String)
  -> Verbosity
  -> FilePath
  -> IO (Maybe Version)findProgramVersion "--numeric-version" id :: a -> aid
  }

cpphsProgram :: Program
cpphsProgram = (simpleProgram :: String -> ProgramsimpleProgram "cpphs") {
    programFindVersion = findProgramVersion ::
  String
  -> (String -> String)
  -> Verbosity
  -> FilePath
  -> IO (Maybe Version)findProgramVersion "--version" ($) :: (a -> b) -> a -> b$ \str ->
      -- Invoking "cpphs --version" gives a string like "cpphs 1.3"
      case words :: String -> [String]words str :: Stringstr of
        (_:ver:_) -> ver :: Stringver
        _         -> ""
  }

hscolourProgram :: Program
hscolourProgram = (simpleProgram :: String -> ProgramsimpleProgram "hscolour") {
    programFindLocation = \v -> findProgramLocation :: Verbosity -> FilePath -> IO (Maybe FilePath)findProgramLocation v :: Verbosityv "HsColour",
    programFindVersion  = findProgramVersion ::
  String
  -> (String -> String)
  -> Verbosity
  -> FilePath
  -> IO (Maybe Version)findProgramVersion "-version" ($) :: (a -> b) -> a -> b$ \str ->
      -- Invoking "HsColour -version" gives a string like "HsColour 1.7"
      case words :: String -> [String]words str :: Stringstr of
        (_:ver:_) -> ver :: Stringver
        _         -> ""
  }

haddockProgram :: Program
haddockProgram = (simpleProgram :: String -> ProgramsimpleProgram "haddock") {
    programFindVersion = findProgramVersion ::
  String
  -> (String -> String)
  -> Verbosity
  -> FilePath
  -> IO (Maybe Version)findProgramVersion "--version" ($) :: (a -> b) -> a -> b$ \str ->
      -- Invoking "haddock --version" gives a string like
      -- "Haddock version 0.8, (c) Simon Marlow 2006"
      case words :: String -> [String]words str :: Stringstr of
        (_:_:ver:_) -> takeWhile :: (a -> Bool) -> [a] -> [a]takeWhile (elem :: Eq a => a -> [a] -> Bool`elem` ('.'(:) :: a -> [a] -> [a]:['0'..'9'])) ver :: Stringver
        _           -> ""
  }

greencardProgram :: Program
greencardProgram = simpleProgram :: String -> ProgramsimpleProgram "greencard"

ldProgram :: Program
ldProgram = simpleProgram :: String -> ProgramsimpleProgram "ld"

tarProgram :: Program
tarProgram = simpleProgram :: String -> ProgramsimpleProgram "tar"

cppProgram :: Program
cppProgram = simpleProgram :: String -> ProgramsimpleProgram "cpp"

pkgConfigProgram :: Program
pkgConfigProgram = (simpleProgram :: String -> ProgramsimpleProgram "pkg-config") {
    programFindVersion = findProgramVersion ::
  String
  -> (String -> String)
  -> Verbosity
  -> FilePath
  -> IO (Maybe Version)findProgramVersion "--version" id :: a -> aid
  }