{- There is some configuration needed before one can run a model. This script works for Windows. See comments below. -} {-# LANGUAGE CPP #-} module Interfaces.Auxiliary( Configuration(..), parseConfig, spaceFix, makePath ) where import System.Process #ifdef unix import System.FilePath.Posix #else import System.FilePath.Windows #endif import Data.List import Text.Parsec.String (Parser) import qualified Text.Parsec as P import qualified Text.Parsec.Char as C import qualified Text.Parsec.Combinator as C1 data Configuration = Config { minizinc :: FilePath , chocosolver :: FilePath , chocoparser :: FilePath , antlr_path :: FilePath } deriving Show instance Monoid Configuration where mempty = Config { minizinc = "" , chocosolver = "" , chocoparser = "" , antlr_path = "" } mappend a b = Config { minizinc = dropEmpty (minizinc a) (minizinc b) , chocosolver = dropEmpty (chocosolver a) (chocosolver b) , chocoparser = dropEmpty (chocoparser a) (chocoparser b) , antlr_path = dropEmpty (antlr_path a) (antlr_path b) } dropEmpty :: String -> String -> String dropEmpty "" "" = "" dropEmpty a "" = a dropEmpty "" b = b makeConf :: Either (P.ParseError) (String, String) -> Configuration makeConf (Right (name, path)) | name == conf_mz = Config { minizinc = path , chocosolver = "" , chocoparser = "" , antlr_path = "" } | name == conf_cs = Config { minizinc = "" , chocosolver = path , chocoparser = "" , antlr_path = "" } | name == conf_cp = Config { minizinc = "" , chocosolver = "" , chocoparser = path , antlr_path = "" } | name == conf_an = Config { minizinc = "" , chocosolver = "" , chocoparser = "" , antlr_path = path } makeConf (Right (_,_)) = mempty makeConf (Left err) = mempty -- Definitions choco = "CHOCO_" conf_mz = "MINIZINC_DIR" conf_cs = "SOLVER" conf_cp = "PARSER" conf_an = "ANTLR" parser_choco = string choco parser_mz = string conf_mz parser_cs = (parser_choco) >> (string "SOLVER") parser_cp = (parser_choco) >> (string "PARSER") parser_an = string conf_an emptyConf = Config { minizinc = "" , chocosolver = "" , chocoparser = "" , antlr_path = "" } confFile = makePath ["HZconf", "conf.txt"] -- /Definitions parseConfig = do contents <- readFile confFile return $ configure (lines contents) parserLine :: Parser (String, String) parserLine = do left <- try parser_mz <|> (try parser_cs <|> parser_cp) <|> parser_an C.spaces char '=' C.spaces right <- parserr return (left,right) parserr :: Parser String parserr = manyTill anyChar eof --tryAll = try $ (parserLine conf_mz) <|> (try ((parserLine conf_cs) <|> (parserLine conf_cp))) <|> (parserLine conf_an) configure ls = mconcat (map (makeConf . (runParser parserLine)) ls) -- Function only needed for filepaths in Windows spaceFix :: String -> String #ifdef unix spaceFix = id #else spaceFix str = if elem ' ' str then "\"" ++ str ++ "\" " else str #endif makePath :: [String] -> String makePath = intercalate [pathSeparator] runParser :: Parser a -> String -> Either P.ParseError a runParser p = P.parse (p <* eof) "" parseWithLeftOver :: Parser a -> String -> Either P.ParseError (a,String) parseWithLeftOver p = P.parse ((,) <$> p <*> leftOver) "" where leftOver = manyTill anyToken eof -- Needed definitions manyTill = C1.manyTill try = P.try anyToken = C1.anyToken anyChar :: Parser Char anyChar = C.anyChar endOfLine :: Parser Char endOfLine = C.endOfLine char = C.char eof = C1.eof (<|>) = (P.<|>) string :: String -> Parser String string = C.string