{-# LANGUAGE DeriveGeneric #-}
module Distribution.Simple.InstallDirs.Internal
  ( PathComponent(..)
  , PathTemplateVariable(..)
  ) where

import Prelude ()
import Distribution.Compat.Prelude

data PathComponent =
       Ordinary FilePath
     | Variable PathTemplateVariable
     deriving (PathComponent -> PathComponent -> Bool
(PathComponent -> PathComponent -> Bool)
-> (PathComponent -> PathComponent -> Bool) -> Eq PathComponent
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PathComponent -> PathComponent -> Bool
$c/= :: PathComponent -> PathComponent -> Bool
== :: PathComponent -> PathComponent -> Bool
$c== :: PathComponent -> PathComponent -> Bool
Eq, Eq PathComponent
Eq PathComponent =>
(PathComponent -> PathComponent -> Ordering)
-> (PathComponent -> PathComponent -> Bool)
-> (PathComponent -> PathComponent -> Bool)
-> (PathComponent -> PathComponent -> Bool)
-> (PathComponent -> PathComponent -> Bool)
-> (PathComponent -> PathComponent -> PathComponent)
-> (PathComponent -> PathComponent -> PathComponent)
-> Ord PathComponent
PathComponent -> PathComponent -> Bool
PathComponent -> PathComponent -> Ordering
PathComponent -> PathComponent -> PathComponent
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 :: PathComponent -> PathComponent -> PathComponent
$cmin :: PathComponent -> PathComponent -> PathComponent
max :: PathComponent -> PathComponent -> PathComponent
$cmax :: PathComponent -> PathComponent -> PathComponent
>= :: PathComponent -> PathComponent -> Bool
$c>= :: PathComponent -> PathComponent -> Bool
> :: PathComponent -> PathComponent -> Bool
$c> :: PathComponent -> PathComponent -> Bool
<= :: PathComponent -> PathComponent -> Bool
$c<= :: PathComponent -> PathComponent -> Bool
< :: PathComponent -> PathComponent -> Bool
$c< :: PathComponent -> PathComponent -> Bool
compare :: PathComponent -> PathComponent -> Ordering
$ccompare :: PathComponent -> PathComponent -> Ordering
$cp1Ord :: Eq PathComponent
Ord, (forall x. PathComponent -> Rep PathComponent x)
-> (forall x. Rep PathComponent x -> PathComponent)
-> Generic PathComponent
forall x. Rep PathComponent x -> PathComponent
forall x. PathComponent -> Rep PathComponent x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PathComponent x -> PathComponent
$cfrom :: forall x. PathComponent -> Rep PathComponent x
Generic)

instance Binary PathComponent

data PathTemplateVariable =
       PrefixVar     -- ^ The @$prefix@ path variable
     | BindirVar     -- ^ The @$bindir@ path variable
     | LibdirVar     -- ^ The @$libdir@ path variable
     | LibsubdirVar  -- ^ The @$libsubdir@ path variable
     | DynlibdirVar  -- ^ The @$dynlibdir@ path variable
     | DatadirVar    -- ^ The @$datadir@ path variable
     | DatasubdirVar -- ^ The @$datasubdir@ path variable
     | DocdirVar     -- ^ The @$docdir@ path variable
     | HtmldirVar    -- ^ The @$htmldir@ path variable
     | PkgNameVar    -- ^ The @$pkg@ package name path variable
     | PkgVerVar     -- ^ The @$version@ package version path variable
     | PkgIdVar      -- ^ The @$pkgid@ package Id path variable, eg @foo-1.0@
     | LibNameVar    -- ^ The @$libname@ path variable
     | CompilerVar   -- ^ The compiler name and version, eg @ghc-6.6.1@
     | OSVar         -- ^ The operating system name, eg @windows@ or @linux@
     | ArchVar       -- ^ The CPU architecture name, eg @i386@ or @x86_64@
     | AbiVar        -- ^ The compiler's ABI identifier,
                     ---  $arch-$os-$compiler-$abitag
     | AbiTagVar     -- ^ The optional ABI tag for the compiler
     | ExecutableNameVar -- ^ The executable name; used in shell wrappers
     | TestSuiteNameVar   -- ^ The name of the test suite being run
     | TestSuiteResultVar -- ^ The result of the test suite being run, eg
                          -- @pass@, @fail@, or @error@.
     | BenchmarkNameVar   -- ^ The name of the benchmark being run
  deriving (PathTemplateVariable -> PathTemplateVariable -> Bool
(PathTemplateVariable -> PathTemplateVariable -> Bool)
-> (PathTemplateVariable -> PathTemplateVariable -> Bool)
-> Eq PathTemplateVariable
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PathTemplateVariable -> PathTemplateVariable -> Bool
$c/= :: PathTemplateVariable -> PathTemplateVariable -> Bool
== :: PathTemplateVariable -> PathTemplateVariable -> Bool
$c== :: PathTemplateVariable -> PathTemplateVariable -> Bool
Eq, Eq PathTemplateVariable
Eq PathTemplateVariable =>
(PathTemplateVariable -> PathTemplateVariable -> Ordering)
-> (PathTemplateVariable -> PathTemplateVariable -> Bool)
-> (PathTemplateVariable -> PathTemplateVariable -> Bool)
-> (PathTemplateVariable -> PathTemplateVariable -> Bool)
-> (PathTemplateVariable -> PathTemplateVariable -> Bool)
-> (PathTemplateVariable
    -> PathTemplateVariable -> PathTemplateVariable)
-> (PathTemplateVariable
    -> PathTemplateVariable -> PathTemplateVariable)
-> Ord PathTemplateVariable
PathTemplateVariable -> PathTemplateVariable -> Bool
PathTemplateVariable -> PathTemplateVariable -> Ordering
PathTemplateVariable
-> PathTemplateVariable -> PathTemplateVariable
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 :: PathTemplateVariable
-> PathTemplateVariable -> PathTemplateVariable
$cmin :: PathTemplateVariable
-> PathTemplateVariable -> PathTemplateVariable
max :: PathTemplateVariable
-> PathTemplateVariable -> PathTemplateVariable
$cmax :: PathTemplateVariable
-> PathTemplateVariable -> PathTemplateVariable
>= :: PathTemplateVariable -> PathTemplateVariable -> Bool
$c>= :: PathTemplateVariable -> PathTemplateVariable -> Bool
> :: PathTemplateVariable -> PathTemplateVariable -> Bool
$c> :: PathTemplateVariable -> PathTemplateVariable -> Bool
<= :: PathTemplateVariable -> PathTemplateVariable -> Bool
$c<= :: PathTemplateVariable -> PathTemplateVariable -> Bool
< :: PathTemplateVariable -> PathTemplateVariable -> Bool
$c< :: PathTemplateVariable -> PathTemplateVariable -> Bool
compare :: PathTemplateVariable -> PathTemplateVariable -> Ordering
$ccompare :: PathTemplateVariable -> PathTemplateVariable -> Ordering
$cp1Ord :: Eq PathTemplateVariable
Ord, (forall x. PathTemplateVariable -> Rep PathTemplateVariable x)
-> (forall x. Rep PathTemplateVariable x -> PathTemplateVariable)
-> Generic PathTemplateVariable
forall x. Rep PathTemplateVariable x -> PathTemplateVariable
forall x. PathTemplateVariable -> Rep PathTemplateVariable x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PathTemplateVariable x -> PathTemplateVariable
$cfrom :: forall x. PathTemplateVariable -> Rep PathTemplateVariable x
Generic)

instance Binary PathTemplateVariable

instance Show PathTemplateVariable where
  show :: PathTemplateVariable -> String
show PrefixVar     = "prefix"
  show LibNameVar    = "libname"
  show BindirVar     = "bindir"
  show LibdirVar     = "libdir"
  show LibsubdirVar  = "libsubdir"
  show DynlibdirVar  = "dynlibdir"
  show DatadirVar    = "datadir"
  show DatasubdirVar = "datasubdir"
  show DocdirVar     = "docdir"
  show HtmldirVar    = "htmldir"
  show PkgNameVar    = "pkg"
  show PkgVerVar     = "version"
  show PkgIdVar      = "pkgid"
  show CompilerVar   = "compiler"
  show OSVar         = "os"
  show ArchVar       = "arch"
  show AbiTagVar     = "abitag"
  show AbiVar        = "abi"
  show ExecutableNameVar = "executablename"
  show TestSuiteNameVar   = "test-suite"
  show TestSuiteResultVar = "result"
  show BenchmarkNameVar   = "benchmark"

instance Read PathTemplateVariable where
  readsPrec :: Int -> ReadS PathTemplateVariable
readsPrec _ s :: String
s =
    Int
-> [(PathTemplateVariable, String)]
-> [(PathTemplateVariable, String)]
forall a. Int -> [a] -> [a]
take 1
    [ (PathTemplateVariable
var, Int -> ShowS
forall a. Int -> [a] -> [a]
drop (String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
varStr) String
s)
    | (varStr :: String
varStr, var :: PathTemplateVariable
var) <- [(String, PathTemplateVariable)]
vars
    , String
varStr String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
s ]
    -- NB: order matters! Longer strings first
    where vars :: [(String, PathTemplateVariable)]
vars = [("prefix",     PathTemplateVariable
PrefixVar)
                 ,("bindir",     PathTemplateVariable
BindirVar)
                 ,("libdir",     PathTemplateVariable
LibdirVar)
                 ,("libsubdir",  PathTemplateVariable
LibsubdirVar)
                 ,("dynlibdir",  PathTemplateVariable
DynlibdirVar)
                 ,("datadir",    PathTemplateVariable
DatadirVar)
                 ,("datasubdir", PathTemplateVariable
DatasubdirVar)
                 ,("docdir",     PathTemplateVariable
DocdirVar)
                 ,("htmldir",    PathTemplateVariable
HtmldirVar)
                 ,("pkgid",      PathTemplateVariable
PkgIdVar)
                 ,("libname",    PathTemplateVariable
LibNameVar)
                 ,("pkgkey",     PathTemplateVariable
LibNameVar) -- backwards compatibility
                 ,("pkg",        PathTemplateVariable
PkgNameVar)
                 ,("version",    PathTemplateVariable
PkgVerVar)
                 ,("compiler",   PathTemplateVariable
CompilerVar)
                 ,("os",         PathTemplateVariable
OSVar)
                 ,("arch",       PathTemplateVariable
ArchVar)
                 ,("abitag",     PathTemplateVariable
AbiTagVar)
                 ,("abi",        PathTemplateVariable
AbiVar)
                 ,("executablename", PathTemplateVariable
ExecutableNameVar)
                 ,("test-suite", PathTemplateVariable
TestSuiteNameVar)
                 ,("result", PathTemplateVariable
TestSuiteResultVar)
                 ,("benchmark", PathTemplateVariable
BenchmarkNameVar)]

instance Show PathComponent where
  show :: PathComponent -> String
show (Ordinary path :: String
path) = String
path
  show (Variable var :: PathTemplateVariable
var)  = '$'Char -> ShowS
forall a. a -> [a] -> [a]
:PathTemplateVariable -> String
forall a. Show a => a -> String
show PathTemplateVariable
var
  showList :: [PathComponent] -> ShowS
showList = (PathComponent -> ShowS -> ShowS)
-> ShowS -> [PathComponent] -> ShowS
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\x :: PathComponent
x -> (PathComponent -> ShowS
forall a. Show a => a -> ShowS
shows PathComponent
x ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.)) ShowS
forall a. a -> a
id

instance Read PathComponent where
  -- for some reason we collapse multiple $ symbols here
  readsPrec :: Int -> ReadS PathComponent
readsPrec _ = ReadS PathComponent
lex0
    where lex0 :: ReadS PathComponent
lex0 [] = []
          lex0 ('$':'$':s' :: String
s') = ReadS PathComponent
lex0 ('$'Char -> ShowS
forall a. a -> [a] -> [a]
:String
s')
          lex0 ('$':s' :: String
s') = case [ (PathTemplateVariable -> PathComponent
Variable PathTemplateVariable
var, String
s'')
                               | (var :: PathTemplateVariable
var, s'' :: String
s'') <- ReadS PathTemplateVariable
forall a. Read a => ReadS a
reads String
s' ] of
                            [] -> String -> ReadS PathComponent
lex1 "$" String
s'
                            ok :: [(PathComponent, String)]
ok -> [(PathComponent, String)]
ok
          lex0 s' :: String
s' = String -> ReadS PathComponent
lex1 [] String
s'
          lex1 :: String -> ReadS PathComponent
lex1 ""  ""      = []
          lex1 acc :: String
acc ""      = [(String -> PathComponent
Ordinary (ShowS
forall a. [a] -> [a]
reverse String
acc), "")]
          lex1 acc :: String
acc ('$':'$':s :: String
s) = String -> ReadS PathComponent
lex1 String
acc ('$'Char -> ShowS
forall a. a -> [a] -> [a]
:String
s)
          lex1 acc :: String
acc ('$':s :: String
s) = [(String -> PathComponent
Ordinary (ShowS
forall a. [a] -> [a]
reverse String
acc), '$'Char -> ShowS
forall a. a -> [a] -> [a]
:String
s)]
          lex1 acc :: String
acc (c :: Char
c:s :: String
s)   = String -> ReadS PathComponent
lex1 (Char
cChar -> ShowS
forall a. a -> [a] -> [a]
:String
acc) String
s
  readList :: ReadS [PathComponent]
readList [] = [([],"")]
  readList s :: String
s  = [ (PathComponent
componentPathComponent -> [PathComponent] -> [PathComponent]
forall a. a -> [a] -> [a]
:[PathComponent]
components, String
s'')
                | (component :: PathComponent
component, s' :: String
s') <- ReadS PathComponent
forall a. Read a => ReadS a
reads String
s
                , (components :: [PathComponent]
components, s'' :: String
s'') <- ReadS [PathComponent]
forall a. Read a => ReadS [a]
readList String
s' ]