    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE FlexibleContexts #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Distribution.System
    -- Copyright   :  Duncan Coutts 2007-2008
    --
    -- Maintainer  :  cabal-devel@haskell.org
    -- Portability :  portable
    --
    -- Cabal often needs to do slightly different things on specific platforms. You
    -- probably know about the 'System.Info.os' however using that is very
    -- inconvenient because it is a string and different Haskell implementations
    -- do not agree on using the same strings for the same platforms! (In
    -- particular see the controversy over \"windows\" vs \"mingw32\"). So to make it
    -- more consistent and easy to use we have an 'OS' enumeration.
    --
    module Distribution.System (
      -- * Operating System
      OS(..),
      buildOS,

      -- * Machine Architecture
      Arch(..),
      buildArch,

      -- * Platform is a pair of arch and OS
      Platform(..),
      buildPlatform,
      platformFromTriple,

      -- * Internal
      knownOSs,
      knownArches,

      -- * Classification
      ClassificationStrictness (..),
      classifyOS,
      classifyArch,
      ) where

    import Prelude ()
    import Distribution.Compat.Prelude
    import Control.Applicative (liftA2)

    import qualified System.Info (os, arch)
    import Distribution.Utils.Generic (lowercase)

    import Distribution.Parsec
    import Distribution.Pretty

    import qualified Distribution.Compat.CharParsing as P
    import qualified Text.PrettyPrint as Disp

    -- | How strict to be when classifying strings into the 'OS' and 'Arch' enums.
    --
    -- The reason we have multiple ways to do the classification is because there
    -- are two situations where we need to do it.
    --
    -- For parsing OS and arch names in .cabal files we really want everyone to be
    -- referring to the same or arch by the same name. Variety is not a virtue
    -- in this case. We don't mind about case though.
    --
    -- For the System.Info.os\/arch different Haskell implementations use different
    -- names for the same or\/arch. Also they tend to distinguish versions of an
    -- OS\/arch which we just don't care about.
    --
    -- The 'Compat' classification allows us to recognise aliases that are already
    -- in common use but it allows us to distinguish them from the canonical name
    -- which enables us to warn about such deprecated aliases.
    --
    data ClassificationStrictness = Permissive | Compat | Strict

    -- ------------------------------------------------------------
    -- * Operating System
    -- ------------------------------------------------------------

    -- | These are the known OS names: Linux, Windows, OSX
    --  ,FreeBSD, OpenBSD, NetBSD, DragonFly
    --  ,Solaris, AIX, HPUX, IRIX
    --  ,HaLVM ,Hurd ,IOS, Android,Ghcjs
    --
    -- The following aliases can also be used:,
    --    * Windows aliases: mingw32, win32, cygwin32
    --    * OSX alias: darwin
    --    * Hurd alias: gnu
    --    * FreeBSD alias: kfreebsdgnu
    --    * Solaris alias: solaris2
    --
    data OS = Linux | Windows | OSX        -- tier 1 desktop OSs
            | FreeBSD | OpenBSD | NetBSD   -- other free Unix OSs
            | DragonFly
            | Solaris | AIX | HPUX | IRIX  -- ageing Unix OSs
            | HaLVM                        -- bare metal / VMs / hypervisors
            | Hurd                         -- GNU's microkernel
            | IOS  | Android               -- mobile OSs
            | Ghcjs
            | OtherOS String
      deriving (OS -> OS -> Bool
    (OS -> OS -> Bool) -> (OS -> OS -> Bool) -> Eq OS
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: OS -> OS -> Bool
    $c/= :: OS -> OS -> Bool
    == :: OS -> OS -> Bool
    $c== :: OS -> OS -> Bool
    Eq, (forall x. OS -> Rep OS x)
    -> (forall x. Rep OS x -> OS) -> Generic OS
    forall x. Rep OS x -> OS
    forall x. OS -> Rep OS x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cto :: forall x. Rep OS x -> OS
    $cfrom :: forall x. OS -> Rep OS x
    Generic, Eq OS
    Eq OS
    -> (OS -> OS -> Ordering)
    -> (OS -> OS -> Bool)
    -> (OS -> OS -> Bool)
    -> (OS -> OS -> Bool)
    -> (OS -> OS -> Bool)
    -> (OS -> OS -> OS)
    -> (OS -> OS -> OS)
    -> Ord OS
    OS -> OS -> Bool
    OS -> OS -> Ordering
    OS -> OS -> OS
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    min :: OS -> OS -> OS
    $cmin :: OS -> OS -> OS
    max :: OS -> OS -> OS
    $cmax :: OS -> OS -> OS
    >= :: OS -> OS -> Bool
    $c>= :: OS -> OS -> Bool
    > :: OS -> OS -> Bool
    $c> :: OS -> OS -> Bool
    <= :: OS -> OS -> Bool
    $c<= :: OS -> OS -> Bool
    < :: OS -> OS -> Bool
    $c< :: OS -> OS -> Bool
    compare :: OS -> OS -> Ordering
    $ccompare :: OS -> OS -> Ordering
    Ord, Int -> OS -> ShowS
    [OS] -> ShowS
    OS -> String
    (Int -> OS -> ShowS)
    -> (OS -> String) -> ([OS] -> ShowS) -> Show OS
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [OS] -> ShowS
    $cshowList :: [OS] -> ShowS
    show :: OS -> String
    $cshow :: OS -> String
    showsPrec :: Int -> OS -> ShowS
    $cshowsPrec :: Int -> OS -> ShowS
    Show, ReadPrec [OS]
    ReadPrec OS
    Int -> ReadS OS
    ReadS [OS]
    (Int -> ReadS OS)
    -> ReadS [OS] -> ReadPrec OS -> ReadPrec [OS] -> Read OS
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [OS]
    $creadListPrec :: ReadPrec [OS]
    readPrec :: ReadPrec OS
    $creadPrec :: ReadPrec OS
    readList :: ReadS [OS]
    $creadList :: ReadS [OS]
    readsPrec :: Int -> ReadS OS
    $creadsPrec :: Int -> ReadS OS
    Read, Typeable, Typeable OS
    Typeable OS
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> OS -> c OS)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c OS)
    -> (OS -> Constr)
    -> (OS -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c OS))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c OS))
    -> ((forall b. Data b => b -> b) -> OS -> OS)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> OS -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> OS -> r)
    -> (forall u. (forall d. Data d => d -> u) -> OS -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> OS -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> OS -> m OS)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> OS -> m OS)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> OS -> m OS)
    -> Data OS
    OS -> DataType
    OS -> Constr
    (forall b. Data b => b -> b) -> OS -> OS
    forall a.
    Typeable a
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> OS -> u
    forall u. (forall d. Data d => d -> u) -> OS -> [u]
    forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> OS -> r
    forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> OS -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> OS -> m OS
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> OS -> m OS
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c OS
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> OS -> c OS
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c OS)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c OS)
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> OS -> m OS
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> OS -> m OS
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> OS -> m OS
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> OS -> m OS
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> OS -> m OS
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> OS -> m OS
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> OS -> u
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> OS -> u
    gmapQ :: forall u. (forall d. Data d => d -> u) -> OS -> [u]
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> OS -> [u]
    gmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> OS -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> OS -> r
    gmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> OS -> r
    $cgmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> OS -> r
    gmapT :: (forall b. Data b => b -> b) -> OS -> OS
    $cgmapT :: (forall b. Data b => b -> b) -> OS -> OS
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c OS)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c OS)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c OS)
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c OS)
    dataTypeOf :: OS -> DataType
    $cdataTypeOf :: OS -> DataType
    toConstr :: OS -> Constr
    $ctoConstr :: OS -> Constr
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c OS
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c OS
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> OS -> c OS
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> OS -> c OS
    Data)

    instance Binary OS
    instance Structured OS
    instance NFData OS where rnf :: OS -> ()
    rnf = OS -> ()
    forall a. (Generic a, GNFData (Rep a)) => a -> ()
    genericRnf

    knownOSs :: [OS]
    knownOSs :: [OS]
    knownOSs = [OS
    Linux, OS
    Windows, OS
    OSX
               ,OS
    FreeBSD, OS
    OpenBSD, OS
    NetBSD, OS
    DragonFly
               ,OS
    Solaris, OS
    AIX, OS
    HPUX, OS
    IRIX
               ,OS
    HaLVM
               ,OS
    Hurd
               ,OS
    IOS, OS
    Android
               ,OS
    Ghcjs]

    osAliases :: ClassificationStrictness -> OS -> [String]
    osAliases :: ClassificationStrictness -> OS -> [String]
    osAliases ClassificationStrictness
    Permissive OS
    Windows = [String
    "mingw32", String
    "win32", String
    "cygwin32"]
    osAliases ClassificationStrictness
    Compat     OS
    Windows = [String
    "mingw32", String
    "win32"]
    osAliases ClassificationStrictness
    _          OS
    OSX     = [String
    "darwin"]
    osAliases ClassificationStrictness
    _          OS
    Hurd    = [String
    "gnu"]
    osAliases ClassificationStrictness
    Permissive OS
    FreeBSD = [String
    "kfreebsdgnu"]
    osAliases ClassificationStrictness
    Compat     OS
    FreeBSD = [String
    "kfreebsdgnu"]
    osAliases ClassificationStrictness
    Permissive OS
    Solaris = [String
    "solaris2"]
    osAliases ClassificationStrictness
    Compat     OS
    Solaris = [String
    "solaris2"]
    osAliases ClassificationStrictness
    Permissive OS
    Android = [String
    "linux-android", String
    "linux-androideabi", String
    "linux-androideabihf"]
    osAliases ClassificationStrictness
    Compat     OS
    Android = [String
    "linux-android"]
    osAliases ClassificationStrictness
    _          OS
    _       = []

    instance Pretty OS where
      pretty :: OS -> Doc
    pretty (OtherOS String
    name) = String -> Doc
    Disp.text String
    name
      pretty OS
    other          = String -> Doc
    Disp.text (ShowS
    lowercase (OS -> String
    forall a. Show a => a -> String
    show OS
    other))

    instance Parsec OS where
      parsec :: forall (m :: * -> *). CabalParsing m => m OS
    parsec = ClassificationStrictness -> String -> OS
    classifyOS ClassificationStrictness
    Compat (String -> OS) -> m String -> m OS
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> m String
    forall (m :: * -> *). CabalParsing m => m String
    parsecIdent

    classifyOS :: ClassificationStrictness -> String -> OS
    classifyOS :: ClassificationStrictness -> String -> OS
    classifyOS ClassificationStrictness
    strictness String
    s =
      OS -> Maybe OS -> OS
    forall a. a -> Maybe a -> a
    fromMaybe (String -> OS
    OtherOS String
    s) (Maybe OS -> OS) -> Maybe OS -> OS
    forall a b. (a -> b) -> a -> b
    $ String -> [(String, OS)] -> Maybe OS
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup (ShowS
    lowercase String
    s) [(String, OS)]
    osMap
      where
        osMap :: [(String, OS)]
    osMap = [ (String
    name, OS
    os)
                | OS
    os <- [OS]
    knownOSs
                , String
    name <- OS -> String
    forall a. Pretty a => a -> String
    prettyShow OS
    os String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    : ClassificationStrictness -> OS -> [String]
    osAliases ClassificationStrictness
    strictness OS
    os ]

    buildOS :: OS
    buildOS :: OS
    buildOS = ClassificationStrictness -> String -> OS
    classifyOS ClassificationStrictness
    Permissive String
    System.Info.os

    -- ------------------------------------------------------------
    -- * Machine Architecture
    -- ------------------------------------------------------------

    -- | These are the known Arches: I386, X86_64, PPC, PPC64, Sparc,
    -- Arm, AArch64, Mips, SH, IA64, S39, Alpha, Hppa, Rs6000, M68k,
    -- Vax, and JavaScript.
    --
    -- The following aliases can also be used:
    --    * PPC alias: powerpc
    --    * PPC64 alias : powerpc64, powerpc64le
    --    * Sparc aliases: sparc64, sun4
    --    * Mips aliases: mipsel, mipseb
    --    * Arm aliases: armeb, armel
    --    * AArch64 aliases: arm64
    --
    data Arch = I386  | X86_64  | PPC  | PPC64 | Sparc
              | Arm   | AArch64 | Mips | SH
              | IA64  | S390
              | Alpha | Hppa    | Rs6000
              | M68k  | Vax
              | JavaScript
              | OtherArch String
      deriving (Arch -> Arch -> Bool
    (Arch -> Arch -> Bool) -> (Arch -> Arch -> Bool) -> Eq Arch
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: Arch -> Arch -> Bool
    $c/= :: Arch -> Arch -> Bool
    == :: Arch -> Arch -> Bool
    $c== :: Arch -> Arch -> Bool
    Eq, (forall x. Arch -> Rep Arch x)
    -> (forall x. Rep Arch x -> Arch) -> Generic Arch
    forall x. Rep Arch x -> Arch
    forall x. Arch -> Rep Arch x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cto :: forall x. Rep Arch x -> Arch
    $cfrom :: forall x. Arch -> Rep Arch x
    Generic, Eq Arch
    Eq Arch
    -> (Arch -> Arch -> Ordering)
    -> (Arch -> Arch -> Bool)
    -> (Arch -> Arch -> Bool)
    -> (Arch -> Arch -> Bool)
    -> (Arch -> Arch -> Bool)
    -> (Arch -> Arch -> Arch)
    -> (Arch -> Arch -> Arch)
    -> Ord Arch
    Arch -> Arch -> Bool
    Arch -> Arch -> Ordering
    Arch -> Arch -> Arch
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    min :: Arch -> Arch -> Arch
    $cmin :: Arch -> Arch -> Arch
    max :: Arch -> Arch -> Arch
    $cmax :: Arch -> Arch -> Arch
    >= :: Arch -> Arch -> Bool
    $c>= :: Arch -> Arch -> Bool
    > :: Arch -> Arch -> Bool
    $c> :: Arch -> Arch -> Bool
    <= :: Arch -> Arch -> Bool
    $c<= :: Arch -> Arch -> Bool
    < :: Arch -> Arch -> Bool
    $c< :: Arch -> Arch -> Bool
    compare :: Arch -> Arch -> Ordering
    $ccompare :: Arch -> Arch -> Ordering
    Ord, Int -> Arch -> ShowS
    [Arch] -> ShowS
    Arch -> String
    (Int -> Arch -> ShowS)
    -> (Arch -> String) -> ([Arch] -> ShowS) -> Show Arch
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Arch] -> ShowS
    $cshowList :: [Arch] -> ShowS
    show :: Arch -> String
    $cshow :: Arch -> String
    showsPrec :: Int -> Arch -> ShowS
    $cshowsPrec :: Int -> Arch -> ShowS
    Show, ReadPrec [Arch]
    ReadPrec Arch
    Int -> ReadS Arch
    ReadS [Arch]
    (Int -> ReadS Arch)
    -> ReadS [Arch] -> ReadPrec Arch -> ReadPrec [Arch] -> Read Arch
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [Arch]
    $creadListPrec :: ReadPrec [Arch]
    readPrec :: ReadPrec Arch
    $creadPrec :: ReadPrec Arch
    readList :: ReadS [Arch]
    $creadList :: ReadS [Arch]
    readsPrec :: Int -> ReadS Arch
    $creadsPrec :: Int -> ReadS Arch
    Read, Typeable, Typeable Arch
    Typeable Arch
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> Arch -> c Arch)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c Arch)
    -> (Arch -> Constr)
    -> (Arch -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c Arch))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Arch))
    -> ((forall b. Data b => b -> b) -> Arch -> Arch)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Arch -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Arch -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Arch -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> Arch -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> Arch -> m Arch)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Arch -> m Arch)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Arch -> m Arch)
    -> Data Arch
    Arch -> DataType
    Arch -> Constr
    (forall b. Data b => b -> b) -> Arch -> Arch
    forall a.
    Typeable a
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> Arch -> u
    forall u. (forall d. Data d => d -> u) -> Arch -> [u]
    forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Arch -> r
    forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Arch -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Arch -> m Arch
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Arch -> m Arch
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Arch
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Arch -> c Arch
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Arch)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Arch)
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Arch -> m Arch
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Arch -> m Arch
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Arch -> m Arch
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Arch -> m Arch
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Arch -> m Arch
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Arch -> m Arch
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Arch -> u
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Arch -> u
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Arch -> [u]
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Arch -> [u]
    gmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Arch -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Arch -> r
    gmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Arch -> r
    $cgmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Arch -> r
    gmapT :: (forall b. Data b => b -> b) -> Arch -> Arch
    $cgmapT :: (forall b. Data b => b -> b) -> Arch -> Arch
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Arch)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Arch)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Arch)
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Arch)
    dataTypeOf :: Arch -> DataType
    $cdataTypeOf :: Arch -> DataType
    toConstr :: Arch -> Constr
    $ctoConstr :: Arch -> Constr
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Arch
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Arch
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Arch -> c Arch
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Arch -> c Arch
    Data)

    instance Binary Arch
    instance Structured Arch
    instance NFData Arch where rnf :: Arch -> ()
    rnf = Arch -> ()
    forall a. (Generic a, GNFData (Rep a)) => a -> ()
    genericRnf

    knownArches :: [Arch]
    knownArches :: [Arch]
    knownArches = [Arch
    I386, Arch
    X86_64, Arch
    PPC, Arch
    PPC64, Arch
    Sparc
                  ,Arch
    Arm, Arch
    AArch64, Arch
    Mips, Arch
    SH
                  ,Arch
    IA64, Arch
    S390
                  ,Arch
    Alpha, Arch
    Hppa, Arch
    Rs6000
                  ,Arch
    M68k, Arch
    Vax
                  ,Arch
    JavaScript]

    archAliases :: ClassificationStrictness -> Arch -> [String]
    archAliases :: ClassificationStrictness -> Arch -> [String]
    archAliases ClassificationStrictness
    Strict Arch
    _       = []
    archAliases ClassificationStrictness
    Compat Arch
    _       = []
    archAliases ClassificationStrictness
    _      Arch
    PPC     = [String
    "powerpc"]
    archAliases ClassificationStrictness
    _      Arch
    PPC64   = [String
    "powerpc64", String
    "powerpc64le"]
    archAliases ClassificationStrictness
    _      Arch
    Sparc   = [String
    "sparc64", String
    "sun4"]
    archAliases ClassificationStrictness
    _      Arch
    Mips    = [String
    "mipsel", String
    "mipseb"]
    archAliases ClassificationStrictness
    _      Arch
    Arm     = [String
    "armeb", String
    "armel"]
    archAliases ClassificationStrictness
    _      Arch
    AArch64 = [String
    "arm64"]
    archAliases ClassificationStrictness
    _      Arch
    _       = []

    instance Pretty Arch where
      pretty :: Arch -> Doc
    pretty (OtherArch String
    name) = String -> Doc
    Disp.text String
    name
      pretty Arch
    other            = String -> Doc
    Disp.text (ShowS
    lowercase (Arch -> String
    forall a. Show a => a -> String
    show Arch
    other))

    instance Parsec Arch where
      parsec :: forall (m :: * -> *). CabalParsing m => m Arch
    parsec = ClassificationStrictness -> String -> Arch
    classifyArch ClassificationStrictness
    Strict (String -> Arch) -> m String -> m Arch
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> m String
    forall (m :: * -> *). CabalParsing m => m String
    parsecIdent

    classifyArch :: ClassificationStrictness -> String -> Arch
    classifyArch :: ClassificationStrictness -> String -> Arch
    classifyArch ClassificationStrictness
    strictness String
    s =
      Arch -> Maybe Arch -> Arch
    forall a. a -> Maybe a -> a
    fromMaybe (String -> Arch
    OtherArch String
    s) (Maybe Arch -> Arch) -> Maybe Arch -> Arch
    forall a b. (a -> b) -> a -> b
    $ String -> [(String, Arch)] -> Maybe Arch
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup (ShowS
    lowercase String
    s) [(String, Arch)]
    archMap
      where
        archMap :: [(String, Arch)]
    archMap = [ (String
    name, Arch
    arch)
                  | Arch
    arch <- [Arch]
    knownArches
                  , String
    name <- Arch -> String
    forall a. Pretty a => a -> String
    prettyShow Arch
    arch String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    : ClassificationStrictness -> Arch -> [String]
    archAliases ClassificationStrictness
    strictness Arch
    arch ]

    buildArch :: Arch
    buildArch :: Arch
    buildArch = ClassificationStrictness -> String -> Arch
    classifyArch ClassificationStrictness
    Permissive String
    System.Info.arch

    -- ------------------------------------------------------------
    -- * Platform
    -- ------------------------------------------------------------

    data Platform = Platform Arch OS
      deriving (Platform -> Platform -> Bool
    (Platform -> Platform -> Bool)
    -> (Platform -> Platform -> Bool) -> Eq Platform
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: Platform -> Platform -> Bool
    $c/= :: Platform -> Platform -> Bool
    == :: Platform -> Platform -> Bool
    $c== :: Platform -> Platform -> Bool
    Eq, (forall x. Platform -> Rep Platform x)
    -> (forall x. Rep Platform x -> Platform) -> Generic Platform
    forall x. Rep Platform x -> Platform
    forall x. Platform -> Rep Platform x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cto :: forall x. Rep Platform x -> Platform
    $cfrom :: forall x. Platform -> Rep Platform x
    Generic, Eq Platform
    Eq Platform
    -> (Platform -> Platform -> Ordering)
    -> (Platform -> Platform -> Bool)
    -> (Platform -> Platform -> Bool)
    -> (Platform -> Platform -> Bool)
    -> (Platform -> Platform -> Bool)
    -> (Platform -> Platform -> Platform)
    -> (Platform -> Platform -> Platform)
    -> Ord Platform
    Platform -> Platform -> Bool
    Platform -> Platform -> Ordering
    Platform -> Platform -> Platform
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    min :: Platform -> Platform -> Platform
    $cmin :: Platform -> Platform -> Platform
    max :: Platform -> Platform -> Platform
    $cmax :: Platform -> Platform -> Platform
    >= :: Platform -> Platform -> Bool
    $c>= :: Platform -> Platform -> Bool
    > :: Platform -> Platform -> Bool
    $c> :: Platform -> Platform -> Bool
    <= :: Platform -> Platform -> Bool
    $c<= :: Platform -> Platform -> Bool
    < :: Platform -> Platform -> Bool
    $c< :: Platform -> Platform -> Bool
    compare :: Platform -> Platform -> Ordering
    $ccompare :: Platform -> Platform -> Ordering
    Ord, Int -> Platform -> ShowS
    [Platform] -> ShowS
    Platform -> String
    (Int -> Platform -> ShowS)
    -> (Platform -> String) -> ([Platform] -> ShowS) -> Show Platform
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Platform] -> ShowS
    $cshowList :: [Platform] -> ShowS
    show :: Platform -> String
    $cshow :: Platform -> String
    showsPrec :: Int -> Platform -> ShowS
    $cshowsPrec :: Int -> Platform -> ShowS
    Show, ReadPrec [Platform]
    ReadPrec Platform
    Int -> ReadS Platform
    ReadS [Platform]
    (Int -> ReadS Platform)
    -> ReadS [Platform]
    -> ReadPrec Platform
    -> ReadPrec [Platform]
    -> Read Platform
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [Platform]
    $creadListPrec :: ReadPrec [Platform]
    readPrec :: ReadPrec Platform
    $creadPrec :: ReadPrec Platform
    readList :: ReadS [Platform]
    $creadList :: ReadS [Platform]
    readsPrec :: Int -> ReadS Platform
    $creadsPrec :: Int -> ReadS Platform
    Read, Typeable, Typeable Platform
    Typeable Platform
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> Platform -> c Platform)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c Platform)
    -> (Platform -> Constr)
    -> (Platform -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c Platform))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Platform))
    -> ((forall b. Data b => b -> b) -> Platform -> Platform)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> Platform -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> Platform -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Platform -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> Platform -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> Platform -> m Platform)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Platform -> m Platform)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Platform -> m Platform)
    -> Data Platform
    Platform -> DataType
    Platform -> Constr
    (forall b. Data b => b -> b) -> Platform -> Platform
    forall a.
    Typeable a
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> Platform -> u
    forall u. (forall d. Data d => d -> u) -> Platform -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Platform -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Platform -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Platform -> m Platform
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Platform -> m Platform
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Platform
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Platform -> c Platform
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Platform)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Platform)
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Platform -> m Platform
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Platform -> m Platform
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Platform -> m Platform
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Platform -> m Platform
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Platform -> m Platform
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Platform -> m Platform
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Platform -> u
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Platform -> u
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Platform -> [u]
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Platform -> [u]
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Platform -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Platform -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Platform -> r
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Platform -> r
    gmapT :: (forall b. Data b => b -> b) -> Platform -> Platform
    $cgmapT :: (forall b. Data b => b -> b) -> Platform -> Platform
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Platform)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Platform)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Platform)
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Platform)
    dataTypeOf :: Platform -> DataType
    $cdataTypeOf :: Platform -> DataType
    toConstr :: Platform -> Constr
    $ctoConstr :: Platform -> Constr
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Platform
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Platform
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Platform -> c Platform
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Platform -> c Platform
    Data)

    instance Binary Platform
    instance Structured Platform
    instance NFData Platform where rnf :: Platform -> ()
    rnf = Platform -> ()
    forall a. (Generic a, GNFData (Rep a)) => a -> ()
    genericRnf

    instance Pretty Platform where
      pretty :: Platform -> Doc
    pretty (Platform Arch
    arch OS
    os) = Arch -> Doc
    forall a. Pretty a => a -> Doc
    pretty Arch
    arch Doc -> Doc -> Doc
    <<>> Char -> Doc
    Disp.char Char
    '-' Doc -> Doc -> Doc
    <<>> OS -> Doc
    forall a. Pretty a => a -> Doc
    pretty OS
    os

    instance Parsec Platform where
        -- TODO: there are ambigious platforms like: `arch-word-os`
        -- which could be parsed as
        --   * Platform "arch-word" "os"
        --   * Platform "arch" "word-os"
        -- We could support that preferring variants 'OtherOS' or 'OtherArch'
        --
        -- For now we split into arch and os parts on the first dash.
        parsec :: forall (m :: * -> *). CabalParsing m => m Platform
    parsec = do
            Arch
    arch <- m Arch
    parsecDashlessArch
            Char
    _ <- Char -> m Char
    forall (m :: * -> *). CharParsing m => Char -> m Char
    P.char Char
    '-'
            OS
    os <- m OS
    forall a (m :: * -> *). (Parsec a, CabalParsing m) => m a
    parsec
            Platform -> m Platform
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Arch -> OS -> Platform
    Platform Arch
    arch OS
    os)
          where
            parsecDashlessArch :: m Arch
    parsecDashlessArch = ClassificationStrictness -> String -> Arch
    classifyArch ClassificationStrictness
    Strict (String -> Arch) -> m String -> m Arch
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> m String
    dashlessIdent

            dashlessIdent :: m String
    dashlessIdent = (Char -> ShowS) -> m Char -> m String -> m String
    forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2 (:) m Char
    firstChar m String
    rest
              where
                firstChar :: m Char
    firstChar = (Char -> Bool) -> m Char
    forall (m :: * -> *). CharParsing m => (Char -> Bool) -> m Char
    P.satisfy Char -> Bool
    isAlpha
                rest :: m String
    rest = (Char -> Bool) -> m String
    forall (m :: * -> *). CharParsing m => (Char -> Bool) -> m String
    P.munch (\Char
    c -> Char -> Bool
    isAlphaNum Char
    c Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '_')

    -- | The platform Cabal was compiled on. In most cases,
    -- @LocalBuildInfo.hostPlatform@ should be used instead (the platform we're
    -- targeting).
    buildPlatform :: Platform
    buildPlatform :: Platform
    buildPlatform = Arch -> OS -> Platform
    Platform Arch
    buildArch OS
    buildOS

    -- Utils:

    parsecIdent :: CabalParsing m => m String
    parsecIdent :: forall (m :: * -> *). CabalParsing m => m String
    parsecIdent = (:) (Char -> ShowS) -> m Char -> m ShowS
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> m Char
    firstChar m ShowS -> m String -> m String
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> m String
    rest
      where
        firstChar :: m Char
    firstChar = (Char -> Bool) -> m Char
    forall (m :: * -> *). CharParsing m => (Char -> Bool) -> m Char
    P.satisfy Char -> Bool
    isAlpha
        rest :: m String
    rest      = (Char -> Bool) -> m String
    forall (m :: * -> *). CharParsing m => (Char -> Bool) -> m String
    P.munch (\Char
    c -> Char -> Bool
    isAlphaNum Char
    c Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '_' Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '-')

    platformFromTriple :: String -> Maybe Platform
    platformFromTriple :: String -> Maybe Platform
    platformFromTriple String
    triple =
        (String -> Maybe Platform)
    -> (Platform -> Maybe Platform)
    -> Either String Platform
    -> Maybe Platform
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (Maybe Platform -> String -> Maybe Platform
    forall a b. a -> b -> a
    const Maybe Platform
    forall a. Maybe a
    Nothing) Platform -> Maybe Platform
    forall a. a -> Maybe a
    Just (Either String Platform -> Maybe Platform)
    -> Either String Platform -> Maybe Platform
    forall a b. (a -> b) -> a -> b
    $ ParsecParser Platform -> String -> Either String Platform
    forall a. ParsecParser a -> String -> Either String a
    explicitEitherParsec ParsecParser Platform
    parseTriple String
    triple
      where parseWord :: ParsecParser String
    parseWord = (Char -> Bool) -> ParsecParser String
    forall (m :: * -> *). CharParsing m => (Char -> Bool) -> m String
    P.munch1 (\Char
    c -> Char -> Bool
    isAlphaNum Char
    c Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '_')
            parseTriple :: ParsecParser Platform
    parseTriple = do
              Arch
    arch <- (String -> Arch) -> ParsecParser String -> ParsecParser Arch
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (ClassificationStrictness -> String -> Arch
    classifyArch ClassificationStrictness
    Permissive) ParsecParser String
    parseWord
              Char
    _ <- Char -> ParsecParser Char
    forall (m :: * -> *). CharParsing m => Char -> m Char
    P.char Char
    '-'
              String
    _ <- ParsecParser String
    parseWord -- Skip vendor
              Char
    _ <- Char -> ParsecParser Char
    forall (m :: * -> *). CharParsing m => Char -> m Char
    P.char Char
    '-'
              OS
    os <- (String -> OS) -> ParsecParser String -> ParsecParser OS
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (ClassificationStrictness -> String -> OS
    classifyOS ClassificationStrictness
    Permissive) ParsecParser String
    forall (m :: * -> *). CabalParsing m => m String
    parsecIdent -- OS may have hyphens, like
                                                   -- 'nto-qnx'
              Platform -> ParsecParser Platform
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Platform -> ParsecParser Platform)
    -> Platform -> ParsecParser Platform
    forall a b. (a -> b) -> a -> b
    $ Arch -> OS -> Platform
    Platform Arch
    arch OS
    os