module Lvm.Path
( searchPath, searchPathMaybe,
explodePath, slashify, splitFilePath, getLvmPath
) where
import qualified Control.Exception as CE (catch, IOException)
import Data.List
import System.FilePath
import System.Directory
import System.Environment
import System.Exit
slash :: Char
slash = pathSeparator
slashify :: String -> String
slashify xs = if last xs == slash then xs else xs ++ [slash]
splitFilePath :: String -> (String, String, String)
splitFilePath filePath =
let slashes = [slash]
(revFileName, revPath) = span (`notElem` slashes) (reverse filePath)
(baseName, ext) = span (/= '.') (reverse revFileName)
in (reverse revPath, baseName, dropWhile (== '.') ext)
searchPath :: [String] -> String -> String -> IO String
searchPath path ext name = do
ms <- searchPathMaybe path ext name
case ms of
Just s -> return s
Nothing -> do
putStrLn ("Error: could not find " ++ show nameext)
putStrLn (" with search path " ++ show path)
exitFailure
where
nameext
| ext `isSuffixOf` name = name
| otherwise = name ++ ext
searchPathMaybe :: [String] -> String -> String -> IO (Maybe String)
searchPathMaybe path ext name
= walk (map makeFName path)
where
walk [] = return Nothing
walk (fname:xs) = do{ exist <- doesFileExist fname
; if exist
then return (Just fname)
else walk xs
}
makeFName dir = slashify dir ++ nameext
nameext
| ext `isSuffixOf` name = name
| otherwise = name ++ ext
getLvmPath :: IO [String]
getLvmPath
= do{ xs <- getEnv "LVMPATH"
; return (explodePath xs)
}
`CE.catch` handler
where
handler :: CE.IOException -> IO [String]
handler _ = return []
explodePath :: String -> [String]
explodePath = walk [] ""
where
walk ps p xs
= case xs of
[] -> if null p
then reverse ps
else reverse (reverse p:ps)
(';':cs) -> walk (reverse p:ps) "" cs
(':':'\\':cs) -> walk ps ("\\:" ++ p) cs
(':':cs) -> walk (reverse p:ps) "" cs
(c:cs) -> walk ps (c:p) cs