-- | Library module module Language.Haskell.DataFilesGen where import Control.Monad import System.Directory import System.FilePath import qualified Data.Set as S import Data.List (isPrefixOf, sort) import Data.Default -- | Options for processing data Options = Options { optExcludeDirs :: S.Set String -- ^ Directory names to exclude , optExcludeExts :: S.Set String -- ^ Extensions to exclude , optIndent :: Int -- ^ Number of spaces to indent } deriving (Read,Show,Eq,Ord) -- | Default instance, excluding nothing instance Default Options where def = Options S.empty S.empty 0 -- | Generate the list of matching expressions generateList :: Options -> FilePath -> IO [String] generateList opts root = do fs <- getDirectoryContents root let vis = filter isVisible fs (exts,foldrs,files) <- foldM collect (S.empty,S.empty,S.empty) vis subs <- mapM (generateList opts) $ S.toList foldrs let fullExts = map (\x -> root ("*"++x)) $ S.toList exts return $ (S.toAscList files) ++ (sort fullExts) ++ ( sort $ concat subs) where isVisible :: FilePath -> Bool isVisible fn | fn == "." = False | fn == ".." = False | "." `isPrefixOf` fn = False | otherwise = True collect :: (S.Set String,S.Set FilePath,S.Set FilePath) -> FilePath -> IO (S.Set String,S.Set FilePath,S.Set FilePath) collect (exts,fldrs,files) fp = do let full = root fp fex <- doesFileExist full return $ if fex then let ext = takeExtensions fp in if null ext then (exts,fldrs,S.insert full files) else if ext `S.member` optExcludeExts opts then (exts,fldrs,files) else (S.insert ext exts,fldrs,files) else if fp `S.member` optExcludeDirs opts then (exts,fldrs,files) else (exts,S.insert full fldrs,files)