{-# LANGUAGE UnicodeSyntax #-} -- | Module for parsing config files module Config (readConfig) where import Prelude hiding (putStrLn,readFile,getContents,print) import IO import System.Environment import System.FilePath import System.Directory (doesFileExist) import Data.Maybe import Data.Either import Text.ParserCombinators.Parsec import Unicode import Types word ∷ Parser String word = choice $ map try [quotedOption, simpleOption, quoted, simpleWord] simpleWord = many1 $ noneOf " \t\r\n=\"'" quotedOption = (try quotedLongOption) <|> quotedShortOption quotedLongOption ∷ Parser String quotedLongOption = do string "--" o ← simpleWord char '=' v ← quoted return ("--" ⧺ o ⧺ "=" ⧺ v) quotedShortOption ∷ Parser String quotedShortOption = do string "-" o ← simpleWord v ← quoted return ("-" ⧺ o ⧺ v) simpleOption = do o ← simpleWord optional $ char '=' v ← simpleWord return (o ⧺ "=" ⧺ v) quoted = quoted1 <|> quoted2 quoted1 = do char '\'' s ← many1 $ noneOf "'" char '\'' return s quoted2 = do char '"' s ← many1 $ noneOf "\"" char '"' return s pConfig ∷ Parser [String] pConfig = word `sepBy` space parseConfig ∷ String → [String] parseConfig str = case parse pConfig "config file" str of Right lst → lst Left err → error $ show err readFile' ∷ FilePath → IO [String] readFile' path = do b ← doesFileExist path if not b then return [] else do str ← readFile path return $ parseConfig (unwords $ lines str) -- | Read list of options from config files readConfig ∷ IO [String] readConfig = do home ← getEnv "HOME" let homepath = home ".config" "todos" homecfg ← readFile' homepath localcfg ← readFile' ".todos.conf" return $ homecfg ⧺ localcfg