-----------------------------------------------------------------------------
-- |
-- Module : Language.Python.Colour.Options
-- Copyright : (c) 2009 Bernie Pope
-- License : BSD-style
-- Maintainer : bjpop@csse.unimelb.edu.au
-- Stability : experimental
-- Portability : ghc
--
-- Command line option processing for the Python colouring program.
-----------------------------------------------------------------------------
module Language.Python.Colour.Options
( processOptions
, programName
, Flag (..)
, PythonVersion (..)
, getPyVersion
, probeFlags
, probeFlagsFirst
, existsFlag
, defaultPyVersion
)
where
import System.Console.GetOpt
import Data.Maybe (fromMaybe)
import Data.Char (toLower, isDigit)
import Data.Maybe (catMaybes)
import IO (stderr, hPutStrLn)
import System
programName :: String
programName = "pycol"
-- This should really come from the cabal file somehow.
versionNumber :: String
versionNumber = "0.1"
versionInfo :: String
versionInfo = unwords [programName, "version", versionNumber]
processOptions :: [String] -> IO ([Flag], String)
processOptions argv =
case getOpt RequireOrder options argv of
(flags, nonOpts, [])
| existsFlag flags Help -> do
putStrLn $ usageInfo header options
exitWith ExitSuccess
| existsFlag flags Version -> do
putStrLn versionInfo
exitWith ExitSuccess
| length nonOpts /= 1 ->
raiseError ["You must specify a single input Python file.\n"]
| otherwise -> return (flags, head nonOpts)
(_, _, errs) -> raiseError errs
where
header = "Usage: " ++ programName ++ " [OPTION...] file"
failureMsg = programName ++ ": command line error.\n"
raiseError errs = do
hPutStrLn stderr $ failureMsg ++ concat errs ++ usageInfo header options
exitFailure
probeFlags :: [Flag] -> (Flag -> Maybe a) -> [a]
probeFlags flags probe = catMaybes (map probe flags)
probeFlagsFirst :: [Flag] -> (Flag -> Maybe a) -> a -> a
probeFlagsFirst flags probe defaultValue
| null probed = defaultValue
| otherwise = head probed
where
probed = probeFlags flags probe
existsFlag :: [Flag] -> Flag -> Bool
existsFlag flags f
= probeFlagsFirst flags probe False
where
probe someFlag = if f == someFlag then Just True else Nothing
data Flag
= PyVersion PythonVersion -- ^ Which version of Python to parse (2 or 3).
| Help -- ^ Print a help message and exit.
| Version -- ^ Print the version number.
deriving (Eq, Ord, Show)
getPyVersion :: Flag -> Maybe PythonVersion
getPyVersion (PyVersion v) = Just v
getPyVersion _ = Nothing
data PythonVersion
= V2
| V3
deriving (Eq, Ord, Show)
options :: [OptDescr Flag]
options =
[ Option ['p'] ["pyver"] (ReqArg mkPyVersion "VERSION") "VERSION of Python to parse: 2 or 3 (default is 2)"
, Option ['v'] ["version"] (NoArg Version) "show version number"
, Option ['h'] ["help"] (NoArg Help) "get help about using this program"
]
defaultPyVersion :: PythonVersion
defaultPyVersion = V2
mkPyVersion :: String -> Flag
mkPyVersion = normalMkVersion . map toLower
where
normalMkVersion "2" = PyVersion V2
normalMkVersion "3" = PyVersion V3
normalMkVersion other = PyVersion defaultPyVersion