    {-# LANGUAGE CPP #-}
    {-# 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 Control.Applicative (Applicative (..))
    import Distribution.Compat.Prelude hiding (Applicative (..))
    import Prelude ()

    #if !MIN_VERSION_base(4,10,0)
    import Control.Applicative (liftA2)
    #endif

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

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

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

    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"]
    archAliases ClassificationStrictness
    _ Arch
    PPC64LE = [String
    "powerpc64le"]
    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
    $c== :: Platform -> Platform -> Bool
    == :: Platform -> Platform -> Bool
    $c/= :: Platform -> Platform -> Bool
    /= :: 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
    $cfrom :: forall x. Platform -> Rep Platform x
    from :: forall x. Platform -> Rep Platform x
    $cto :: forall x. Rep Platform x -> Platform
    to :: forall x. Rep Platform x -> Platform
    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
    $ccompare :: Platform -> Platform -> Ordering
    compare :: Platform -> Platform -> Ordering
    $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
    >= :: Platform -> Platform -> Bool
    $cmax :: Platform -> Platform -> Platform
    max :: Platform -> Platform -> Platform
    $cmin :: Platform -> Platform -> Platform
    min :: Platform -> Platform -> Platform
    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
    $cshowsPrec :: Int -> Platform -> ShowS
    showsPrec :: Int -> Platform -> ShowS
    $cshow :: Platform -> String
    show :: Platform -> String
    $cshowList :: [Platform] -> ShowS
    showList :: [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
    $creadsPrec :: Int -> ReadS Platform
    readsPrec :: Int -> ReadS Platform
    $creadList :: ReadS [Platform]
    readList :: ReadS [Platform]
    $creadPrec :: ReadPrec Platform
    readPrec :: ReadPrec Platform
    $creadListPrec :: ReadPrec [Platform]
    readListPrec :: ReadPrec [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 -> Constr
    Platform -> DataType
    (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)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Platform -> c Platform
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Platform -> c Platform
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Platform
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Platform
    $ctoConstr :: Platform -> Constr
    toConstr :: Platform -> Constr
    $cdataTypeOf :: Platform -> DataType
    dataTypeOf :: Platform -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Platform)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Platform)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Platform)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Platform)
    $cgmapT :: (forall b. Data b => b -> b) -> Platform -> Platform
    gmapT :: (forall b. Data b => b -> b) -> Platform -> Platform
    $cgmapQl :: 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
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Platform -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Platform -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Platform -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Platform -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Platform -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Platform -> u
    $cgmapM :: forall (m :: * -> *).
    Monad 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
    $cgmapMp :: 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
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Platform -> m Platform
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Platform -> m 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 ambiguous 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 <- m Arch
    parsecDashlessArch
        _ <- P.char '-'
        os <- parsec
        return (Platform arch 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 a b c. (a -> b -> c) -> m a -> m b -> m c
    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 a b. m (a -> b) -> m a -> m b
    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 <- (String -> Arch) -> ParsecParser String -> ParsecParser Arch
    forall a b. (a -> b) -> ParsecParser a -> ParsecParser b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (ClassificationStrictness -> String -> Arch
    classifyArch ClassificationStrictness
    Permissive) ParsecParser String
    parseWord
          _ <- P.char '-'
          _ <- parseWord -- Skip vendor
          _ <- P.char '-'
          os <- fmap (classifyOS Permissive) parsecIdent -- OS may have hyphens, like
          -- 'nto-qnx'
          return $ Platform arch os