123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- {-# LANGUAGE DeriveDataTypeable #-}
- module Main where
- import Browse
- import CabalDev (modifyOptions)
- import Check
- import Control.Applicative
- import Control.Exception
- import Data.Typeable
- import Data.Version
- import Info
- import Lang
- import Flag
- import Lint
- import List
- import Paths_ghc_mod
- import Prelude
- import System.Console.GetOpt
- import System.Directory
- import System.Environment (getArgs)
- import System.IO (hPutStr, hPutStrLn, stderr)
- import Types
- ----------------------------------------------------------------
- ghcOptHelp :: String
- ghcOptHelp = " [-g GHC_opt1 -g GHC_opt2 ...] "
- usage :: String
- usage = "ghc-mod version " ++ showVersion version ++ "\n"
- ++ "Usage:\n"
- ++ "\t ghc-mod list" ++ ghcOptHelp ++ "[-l]\n"
- ++ "\t ghc-mod lang [-l]\n"
- ++ "\t ghc-mod flag [-l]\n"
- ++ "\t ghc-mod browse" ++ ghcOptHelp ++ "[-l] [-o] <module> [<module> ...]\n"
- ++ "\t ghc-mod check" ++ ghcOptHelp ++ "<HaskellFile>\n"
- ++ "\t ghc-mod expand" ++ ghcOptHelp ++ "<HaskellFile>\n"
- ++ "\t ghc-mod info" ++ ghcOptHelp ++ "<HaskellFile> <module> <expression>\n"
- ++ "\t ghc-mod type" ++ ghcOptHelp ++ "<HaskellFile> <module> <line-no> <column-no>\n"
- ++ "\t ghc-mod lint [-h opt] <HaskellFile>\n"
- ++ "\t ghc-mod boot\n"
- ++ "\t ghc-mod help\n"
- ----------------------------------------------------------------
- argspec :: [OptDescr (Options -> Options)]
- argspec = [ Option "l" ["tolisp"]
- (NoArg (\opts -> opts { outputStyle = LispStyle }))
- "print as a list of Lisp"
- , Option "h" ["hlintOpt"]
- (ReqArg (\h opts -> opts { hlintOpts = h : hlintOpts opts }) "hlintOpt")
- "hlint options"
- , Option "g" ["ghcOpt"]
- (ReqArg (\g opts -> opts { ghcOpts = g : ghcOpts opts }) "ghcOpt")
- "GHC options"
- , Option "o" ["operators"]
- (NoArg (\opts -> opts { operators = True }))
- "print operators, too"
- , Option "s" ["sandbox"]
- (ReqArg (\s opts -> opts { sandbox = Just s }) "path")
- "specify cabal-dev sandbox (default 'cabal-dev`)"
- ]
- parseArgs :: [OptDescr (Options -> Options)] -> [String] -> (Options, [String])
- parseArgs spec argv
- = case getOpt Permute spec argv of
- (o,n,[] ) -> (foldr id defaultOptions o, n)
- (_,_,errs) -> throw (CmdArg errs)
- ----------------------------------------------------------------
- data GHCModError = SafeList
- | NoSuchCommand String
- | CmdArg [String]
- | FileNotExist String deriving (Show, Typeable)
- instance Exception GHCModError
- ----------------------------------------------------------------
- main :: IO ()
- main = flip catches handlers $ do
- args <- getArgs
- let (opt',cmdArg) = parseArgs argspec args
- res <- modifyOptions opt' >>= \opt -> case safelist cmdArg 0 of
- "browse" -> concat <$> mapM (browseModule opt) (tail cmdArg)
- "list" -> listModules opt
- "check" -> withFile (checkSyntax opt) (safelist cmdArg 1)
- "expand" -> withFile (checkSyntax opt { expandSplice = True })
- (safelist cmdArg 1)
- "type" -> withFile (typeExpr opt (safelist cmdArg 2) (read $ safelist cmdArg 3) (read $ safelist cmdArg 4)) (safelist cmdArg 1)
- "info" -> withFile (infoExpr opt (safelist cmdArg 2) (safelist cmdArg 3)) (safelist cmdArg 1)
- "lint" -> withFile (lintSyntax opt) (safelist cmdArg 1)
- "lang" -> listLanguages opt
- "flag" -> listFlags opt
- "boot" -> do
- mods <- listModules opt
- langs <- listLanguages opt
- flags <- listFlags opt
- pre <- concat <$> mapM (browseModule opt) preBrowsedModules
- return $ mods ++ langs ++ flags ++ pre
- cmd -> throw (NoSuchCommand cmd)
- putStr res
- where
- handlers = [Handler handler1, Handler handler2]
- handler1 :: ErrorCall -> IO ()
- handler1 = print -- for debug
- handler2 :: GHCModError -> IO ()
- handler2 SafeList = printUsage
- handler2 (NoSuchCommand cmd) = do
- hPutStrLn stderr $ "\"" ++ cmd ++ "\" not supported"
- printUsage
- handler2 (CmdArg errs) = do
- mapM_ (hPutStr stderr) errs
- printUsage
- handler2 (FileNotExist file) = do
- hPutStrLn stderr $ "\"" ++ file ++ "\" not found"
- printUsage
- printUsage = hPutStrLn stderr $ '\n' : usageInfo usage argspec
- withFile cmd file = do
- exist <- doesFileExist file
- if exist
- then cmd file
- else throw (FileNotExist file)
- safelist xs idx
- | length xs <= idx = throw SafeList
- | otherwise = xs !! idx
- ----------------------------------------------------------------
- preBrowsedModules :: [String]
- preBrowsedModules = [
- "Prelude"
- , "Control.Applicative"
- , "Control.Monad"
- , "Control.Exception"
- , "Data.Char"
- , "Data.List"
- , "Data.Maybe"
- , "System.IO"
- ]
|