---------------------------------------------------------------------------- -- | -- Module : Main -- Copyright : (c) Fontaine 2010 -- License : BSD -- -- Maintainer : Fontaine@cs.uni-duesseldorf.de -- Stability : experimental -- Portability : GHC-only -- -- Comand line interface for the CSPM tools. ---------------------------------------------------------------------------- {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE RecordWildCards #-} module Main where import CSPM.Interpreter import CSPM.Interpreter.Test.CLI (evalEnv) import CSPM.FiringRules.Trace (trace) import CSPM.FiringRules.HelperClasses import CSPM.LTS.MkLtsPar (mkLtsPar) import CSPM.LTS.ToCsp (ltsToCsp) import CSPM.LTS.ToDot (mkDotFile) import Language.CSPM.Frontend (LexError(..),ParseError(..),RenameError(..)) import Language.CSPM.Token (pprintAlexPosn, Token(..)) import System.Console.CmdArgs import Control.Exception import System.Exit (exitSuccess, exitFailure) instance EqOrd INT instance CSP1 INT instance CSP2 INT instance FShow INT -- | main-funtion for the command line. main :: IO () main = do arguments <- cmdArgsRun argParser handleException $ execCommand arguments exitSuccess -- definition of the command line parser argParser :: Mode (CmdArgs Args) argParser = cmdArgsMode $ modes [evalMode, traceMode, fdrMode, dotMode ] &= program "cspm" &= summary "cspm command line utility V0.4.0.0" data Args = Eval { evalContext :: Maybe FilePath ,evalExpr :: String } |Trace { src :: FilePath ,entry :: String } |FDR { src :: FilePath ,entry :: String ,out :: Maybe FilePath } |Dot { src :: FilePath ,entry :: String ,out :: Maybe FilePath } deriving (Data,Typeable,Show,Eq) evalMode :: Args evalMode = Eval { evalContext = def &= help "optional: CSPM specification to load into context" &= typFile &= explicit &= name "s" &= name "src" ,evalExpr = def &= help "the expression to evaluate" &= typ "EXPR" &= argPos 0 } &= program "evaluate an expression" traceMode :: Args traceMode = Trace { src = def &= help "CSPM specification" &= typFile &= argPos 0 ,entry = "MAIN" &= help "optional: the main process" &= typ "PROCESS" &= explicit &= name "main" &= name "m" } &= program "trace a process" fdrMode :: Args fdrMode = FDR { src = def &= help "CSPM specification" &= typFile &= argPos 0 ,entry = "MAIN" &= help "optional: the main process" &= typ "PROCESS" &= explicit &= name "main" &= name "m" ,out = def &= help "optional: name of the generated fdr file" &= typFile &= explicit &= name "out" &= name "o" } &= program "compute the LTS and dump it as fdr script" dotMode :: Args dotMode = Dot { src = def &= help "CSPM specification" &= typFile &= argPos 0 ,entry = "MAIN" &= help "optional: the main process" &= typ "PROCESS" &= explicit &= name "main" &= name "m" ,out = def &= help "optional: name of the generated dot file" &= typFile &= explicit &= name "out" &= name "o" } &= program "compute the LTS and dump it as dot graph" -- execute the command according to command line arguments execCommand :: Args -> IO () execCommand Eval {..} = do isVerbose <- isLoud (val,_) <- evalEnv isVerbose evalContext evalExpr print val execCommand Trace {..} = do (proc,sigma) <- mkProcess src entry trace sigma proc execCommand FDR {..} = do (proc,sigma) <- mkProcess src entry let lts = mkLtsPar sigma proc outFile = case out of Just f -> f Nothing -> src ++ ".fdr" ltsToCsp proc lts outFile return () execCommand Dot {..} = do (proc,sigma) <- mkProcess src entry let lts = mkLtsPar sigma proc outFile = case out of Just f -> f Nothing -> src ++ ".dot" mkDotFile outFile lts return () mkProcess :: FilePath -> String -> IO (Process, ClosureSet) mkProcess file expr = do isVerbose <- isLoud (proc, env) <- evalEnv isVerbose (Just file) expr case proc of VProcess p -> return (p, getAllEvents env) _ -> error "type-error : entry-point is not a process" -- example exception handler handleException :: IO () -> IO () handleException x = x `catches` allHandler where allHandler = [ Handler lexError, Handler parseError, Handler renameError ,Handler errCall ,Handler async -- pressing CTRL c ,Handler ioExc -- file not found etc ,Handler someExc ] lexError :: LexError -> IO () lexError LexError {..} = do putStrLn "lexError" putStrLn $ pprintAlexPosn lexEPos putStrLn $ lexEMsg exitFailure parseError :: ParseError -> IO () parseError ParseError {..} = do putStrLn "parseError" putStrLn $ parseErrorMsg putStrLn $ pprintAlexPosn parseErrorPos putStrLn $ "at token : " ++ (show $ tokenString parseErrorToken) exitFailure renameError :: RenameError -> IO () renameError RenameError {..} = do putStrLn "renameError" putStrLn $ renameErrorMsg putStrLn $ show renameErrorLoc exitFailure ioExc :: IOException -> IO () ioExc err = do putStrLn $ show err exitFailure errCall :: ErrorCall -> IO () errCall err = flip catches allHandler $ do putStrLn "unexpected error call" putStrLn $ show err exitFailure async :: AsyncException -> IO () async err = do putStrLn "AsyncException (Pressing CRTL C ?)" putStrLn $ show err exitFailure someExc :: SomeException -> IO () someExc err = do putStrLn $ show err exitFailure