{-# 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
$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
$cto :: 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]

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
$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
$cto :: 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
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
$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
$cto :: 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 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
forall (m :: * -> *). CabalParsing m => m OS
parsec
        Platform -> m Platform
forall a. a -> m a
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 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
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
          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 a b. (a -> b) -> ParsecParser a -> ParsecParser b
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 a. a -> ParsecParser a
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