module Agda.Utils.Environment ( expandEnvironmentVariables ) where
import Data.Char
import Data.Maybe
import System.Environment
import System.Directory ( getHomeDirectory )
expandEnvironmentVariables :: String -> IO String
expandEnvironmentVariables :: String -> IO String
expandEnvironmentVariables s :: String
s = do
[(String, String)]
env <- IO [(String, String)]
getEnvironment
String
home <- IO String
getHomeDirectory
String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String) -> String -> IO String
forall a b. (a -> b) -> a -> b
$ String -> [(String, String)] -> String -> String
expandVars String
home [(String, String)]
env String
s
expandVars :: String -> [(String, String)] -> String -> String
expandVars :: String -> [(String, String)] -> String -> String
expandVars home :: String
home env :: [(String, String)]
env s :: String
s = (Token -> String) -> [Token] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Token -> String
repl ([Token] -> String) -> [Token] -> String
forall a b. (a -> b) -> a -> b
$ String -> [Token]
tokens String
s
where
repl :: Token -> String
repl Home = String
home String -> String -> String
forall a. [a] -> [a] -> [a]
++ "/"
repl (Var x :: String
x) = String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe "" (Maybe String -> String) -> Maybe String -> String
forall a b. (a -> b) -> a -> b
$ String -> [(String, String)] -> Maybe String
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
x [(String, String)]
env
repl (Str s :: String
s) = String
s
data Token = Home | Var String | Str String
deriving (Token -> Token -> Bool
(Token -> Token -> Bool) -> (Token -> Token -> Bool) -> Eq Token
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Token -> Token -> Bool
$c/= :: Token -> Token -> Bool
== :: Token -> Token -> Bool
$c== :: Token -> Token -> Bool
Eq, Int -> Token -> String -> String
[Token] -> String -> String
Token -> String
(Int -> Token -> String -> String)
-> (Token -> String) -> ([Token] -> String -> String) -> Show Token
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [Token] -> String -> String
$cshowList :: [Token] -> String -> String
show :: Token -> String
$cshow :: Token -> String
showsPrec :: Int -> Token -> String -> String
$cshowsPrec :: Int -> Token -> String -> String
Show)
tokens :: String -> [Token]
tokens :: String -> [Token]
tokens s :: String
s = case String
s of
'~' : '/' : s :: String
s -> Token
Home Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: String -> [Token]
tokens' String
s
'\\' : '~' : s :: String
s -> Char -> [Token] -> [Token]
cons '~' ([Token] -> [Token]) -> [Token] -> [Token]
forall a b. (a -> b) -> a -> b
$ String -> [Token]
tokens' String
s
_ -> String -> [Token]
tokens' String
s
where
tokens' :: String -> [Token]
tokens' :: String -> [Token]
tokens' s :: String
s =
case String
s of
'$' : '$' : s :: String
s -> Char -> [Token] -> [Token]
cons '$' ([Token] -> [Token]) -> [Token] -> [Token]
forall a b. (a -> b) -> a -> b
$ String -> [Token]
tokens' String
s
'$' : s :: String
s@(c :: Char
c : _) | Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '_' Bool -> Bool -> Bool
|| Char -> Bool
isAlpha Char
c -> String -> Token
Var String
x Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: String -> [Token]
tokens' String
s'
where (x :: String
x, s' :: String
s') = (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
span (\ c :: Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '_' Bool -> Bool -> Bool
|| Char -> Bool
isAlphaNum Char
c) String
s
'$' : '{' : s :: String
s ->
case (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '}') String
s of
(x :: String
x, '}' : s :: String
s) -> String -> Token
Var String
x Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: String -> [Token]
tokens' String
s
_ -> [String -> Token
Str (String -> Token) -> String -> Token
forall a b. (a -> b) -> a -> b
$ "${" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s]
c :: Char
c : s :: String
s -> Char -> [Token] -> [Token]
cons Char
c ([Token] -> [Token]) -> [Token] -> [Token]
forall a b. (a -> b) -> a -> b
$ String -> [Token]
tokens' String
s
"" -> []
cons :: Char -> [Token] -> [Token]
cons c :: Char
c (Str s :: String
s : ts :: [Token]
ts) = String -> Token
Str (Char
c Char -> String -> String
forall a. a -> [a] -> [a]
: String
s) Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: [Token]
ts
cons c :: Char
c ts :: [Token]
ts = String -> Token
Str [Char
c] Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: [Token]
ts