module General.Glob(globFile, globDir) where
import General.Code
globFile :: [FilePath] -> [String] -> FilePath -> IO [FilePath]
globFile dirs exts file = f poss
where
f [] = exitMessage $ ["Could not find file:"
, " " ++ file
,"Searched:"] ++
map (" " ++) poss
f (x:xs) = do
y <- globFileTest x
if null y then f xs else return y
exts2 = "" : if hasExtension file then [] else exts
poss = [d </> file <.> e | d <- dirs, e <- exts2]
globFileTest :: FilePath -> IO [FilePath]
globFileTest file = do
(dir,fil) <- return $ splitFileName file
if '*' `notElem` fil then do
b <- doesFileExist file
return [file | b]
else do
s <- getDirectoryContents $ dropTrailingPathSeparator dir
concatMapM (f dir fil) s
where
f dir fil x = do
let dirx = dir </> x
b <- doesFileExist dirx
return [dirx | b && globMatch fil x]
globMatch :: String -> String -> Bool
globMatch glob s | null glob = False
| otherwise =
head matches `isPrefixOf` s2 && last matches `isSuffixOf` s2 && f matches s2
where
norm = if searchPathSeparator == ';' then lower else id
s2 = norm s
matches = split '*' $ norm glob
f [] s = True
f (m:ms) [] = False
f (m:ms) s | m `isPrefixOf` s = f ms $ drop (length m) s
| otherwise = f (m:ms) (tail s)
globDir :: FilePath -> IO FilePath
globDir x = do
x <- canonicalizePath x
b <- doesDirectoryExist x
if b then return x else
exitMessage ["Could not find directory:"
, " " ++ x]