{-# LANGUAGE CPP #-}
{-# LANGUAGE ScopedTypeVariables #-}
module SysTools.BaseDir
( expandTopDir, expandToolDir
, findTopDir, findToolDir
, tryFindTopDir
) where
#include "HsVersions.h"
import GhcPrelude
import GHC.BaseDir
import Panic
import System.Environment (lookupEnv)
import System.FilePath
#if defined(mingw32_HOST_OS)
import System.Directory (doesDirectoryExist)
#endif
#if defined(mingw32_HOST_OS)
# if defined(i386_HOST_ARCH)
# define WINDOWS_CCONV stdcall
# elif defined(x86_64_HOST_ARCH)
# define WINDOWS_CCONV ccall
# else
# error Unknown mingw32 arch
# endif
#endif
expandToolDir :: Maybe FilePath -> String -> String
#if defined(mingw32_HOST_OS)
expandToolDir (Just tool_dir) s = expandPathVar "tooldir" tool_dir s
expandToolDir Nothing _ = panic "Could not determine $tooldir"
#else
expandToolDir :: Maybe FilePath -> FilePath -> FilePath
expandToolDir Maybe FilePath
_ FilePath
s = FilePath
s
#endif
findTopDir :: Maybe String
-> IO String
findTopDir :: Maybe FilePath -> IO FilePath
findTopDir Maybe FilePath
m_minusb = do
Maybe FilePath
maybe_exec_dir <- Maybe FilePath -> IO (Maybe FilePath)
tryFindTopDir Maybe FilePath
m_minusb
case Maybe FilePath
maybe_exec_dir of
Maybe FilePath
Nothing -> GhcException -> IO FilePath
forall a. GhcException -> IO a
throwGhcExceptionIO (GhcException -> IO FilePath) -> GhcException -> IO FilePath
forall a b. (a -> b) -> a -> b
$
FilePath -> GhcException
InstallationError FilePath
"missing -B<dir> option"
Just FilePath
dir -> FilePath -> IO FilePath
forall (m :: * -> *) a. Monad m => a -> m a
return FilePath
dir
tryFindTopDir
:: Maybe String
-> IO (Maybe String)
tryFindTopDir :: Maybe FilePath -> IO (Maybe FilePath)
tryFindTopDir (Just FilePath
minusb) = Maybe FilePath -> IO (Maybe FilePath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe FilePath -> IO (Maybe FilePath))
-> Maybe FilePath -> IO (Maybe FilePath)
forall a b. (a -> b) -> a -> b
$ FilePath -> Maybe FilePath
forall a. a -> Maybe a
Just (FilePath -> Maybe FilePath) -> FilePath -> Maybe FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath
normalise FilePath
minusb
tryFindTopDir Maybe FilePath
Nothing
= do
Maybe FilePath
maybe_env_top_dir <- FilePath -> IO (Maybe FilePath)
lookupEnv FilePath
"_GHC_TOP_DIR"
case Maybe FilePath
maybe_env_top_dir of
Just FilePath
env_top_dir -> Maybe FilePath -> IO (Maybe FilePath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe FilePath -> IO (Maybe FilePath))
-> Maybe FilePath -> IO (Maybe FilePath)
forall a b. (a -> b) -> a -> b
$ FilePath -> Maybe FilePath
forall a. a -> Maybe a
Just FilePath
env_top_dir
Maybe FilePath
Nothing -> IO (Maybe FilePath)
getBaseDir
findToolDir
:: FilePath
-> IO (Maybe FilePath)
#if defined(mingw32_HOST_OS)
findToolDir top_dir = go 0 (top_dir </> "..")
where maxDepth = 3
go :: Int -> FilePath -> IO (Maybe FilePath)
go k path
| k == maxDepth = throwGhcExceptionIO $
InstallationError "could not detect mingw toolchain"
| otherwise = do
oneLevel <- doesDirectoryExist (path </> "mingw")
if oneLevel
then return (Just path)
else go (k+1) (path </> "..")
#else
findToolDir :: FilePath -> IO (Maybe FilePath)
findToolDir FilePath
_ = Maybe FilePath -> IO (Maybe FilePath)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe FilePath
forall a. Maybe a
Nothing
#endif