{- 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 v
v [(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 k
_ []   = []
delEntry k
k (x :: (k, v)
x@(k
k1,v
_) : [(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