    {- portable environment variables
     -
     - Copyright 2013 Joey Hess <id@joeyh.name>
     -
     - License: BSD-2-clause
     -}

    {-# LANGUAGE CPP #-}
    {-# OPTIONS_GHC -fno-warn-tabs #-}

    module Utility.Env where

    #ifdef mingw32_HOST_OS
    import Utility.Exception
    import Control.Applicative
    import Data.Maybe
    import Prelude
    import qualified System.Environment as E
    #else
    import qualified System.Posix.Env as PE
    #endif

    getEnv :: String -> IO (Maybe String)
    #ifndef mingw32_HOST_OS
    getEnv :: String -> IO (Maybe String)
    getEnv = String -> IO (Maybe String)
    PE.getEnv
    #else
    getEnv = catchMaybeIO . E.getEnv
    #endif

    getEnvDefault :: String -> String -> IO String
    #ifndef mingw32_HOST_OS
    getEnvDefault :: String -> String -> IO String
    getEnvDefault = String -> String -> IO String
    PE.getEnvDefault
    #else
    getEnvDefault var fallback = fromMaybe fallback <$> getEnv var
    #endif

    getEnvironment :: IO [(String, String)]
    #ifndef mingw32_HOST_OS
    getEnvironment :: IO [(String, String)]
    getEnvironment = IO [(String, String)]
    PE.getEnvironment
    #else
    getEnvironment = E.getEnvironment
    #endif

    {- Adds the environment variable to the input environment. If already
     - present in the list, removes the old value.
     -
     - This does not really belong here, but Data.AssocList is for some reason
     - buried inside hxt.
     -}
    addEntry :: Eq k => k -> v -> [(k, v)] -> [(k, v)]
    addEntry :: k -> v -> [(k, v)] -> [(k, v)]
    addEntry k :: k
    k v :: v
    v l :: [(k, v)]
    l = ( (k
    k,v
    v) (k, v) -> [(k, v)] -> [(k, v)]
    forall a. a -> [a] -> [a]
    : ) ([(k, v)] -> [(k, v)]) -> [(k, v)] -> [(k, v)]
    forall a b. (a -> b) -> a -> b
    $! k -> [(k, v)] -> [(k, v)]
    forall k v. Eq k => k -> [(k, v)] -> [(k, v)]
    delEntry k
    k [(k, v)]
    l

    addEntries :: Eq k => [(k, v)] -> [(k, v)] -> [(k, v)]
    addEntries :: [(k, v)] -> [(k, v)] -> [(k, v)]
    addEntries = (([(k, v)] -> [(k, v)])
     -> ([(k, v)] -> [(k, v)]) -> [(k, v)] -> [(k, v)])
    -> ([(k, v)] -> [(k, v)])
    -> [[(k, v)] -> [(k, v)]]
    -> [(k, v)]
    -> [(k, v)]
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr ([(k, v)] -> [(k, v)])
    -> ([(k, v)] -> [(k, v)]) -> [(k, v)] -> [(k, v)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    (.) [(k, v)] -> [(k, v)]
    forall a. a -> a
    id ([[(k, v)] -> [(k, v)]] -> [(k, v)] -> [(k, v)])
    -> ([(k, v)] -> [[(k, v)] -> [(k, v)]])
    -> [(k, v)]
    -> [(k, v)]
    -> [(k, v)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((k, v) -> [(k, v)] -> [(k, v)])
    -> [(k, v)] -> [[(k, v)] -> [(k, v)]]
    forall a b. (a -> b) -> [a] -> [b]
    map ((k -> v -> [(k, v)] -> [(k, v)]) -> (k, v) -> [(k, v)] -> [(k, v)]
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry k -> v -> [(k, v)] -> [(k, v)]
    forall k v. Eq k => k -> v -> [(k, v)] -> [(k, v)]
    addEntry) ([(k, v)] -> [[(k, v)] -> [(k, v)]])
    -> ([(k, v)] -> [(k, v)]) -> [(k, v)] -> [[(k, v)] -> [(k, v)]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [(k, v)] -> [(k, v)]
    forall a. [a] -> [a]
    reverse

    delEntry :: Eq k => k -> [(k, v)] -> [(k, v)]
    delEntry :: k -> [(k, v)] -> [(k, v)]
    delEntry _ []   = []
    delEntry k :: k
    k (x :: (k, v)
    x@(k1 :: k
    k1,_) : rest :: [(k, v)]
    rest)
    	| k
    k k -> k -> Bool
    forall a. Eq a => a -> a -> Bool
    == k
    k1 = [(k, v)]
    rest
    	| Bool
    otherwise = ( (k, v)
    x (k, v) -> [(k, v)] -> [(k, v)]
    forall a. a -> [a] -> [a]
    : ) ([(k, v)] -> [(k, v)]) -> [(k, v)] -> [(k, v)]
    forall a b. (a -> b) -> a -> b
    $! k -> [(k, v)] -> [(k, v)]
    forall k v. Eq k => k -> [(k, v)] -> [(k, v)]
    delEntry k
    k [(k, v)]
    rest