packages feed

sifflet-1.1: Options.hs

module Options (Options(..), processArgs, showHelp) where

-- ?? import Control.Monad (mapM_)

-- | Options are the interpretation of sifflet command-line arguments.
-- If a function call is requested, the remaining arguments are unparsed,
-- and just saved as strings to be fed into the parser when the
-- function's argument types are known.

data Options = Options { optionsShowFunPad :: Bool
                       , optionsHelp :: Bool
                       , optionsSourceFile :: Maybe FilePath
                       , optionsShowFunction :: Maybe String
                       , optionsCallFunction :: Maybe String
                       , optionsAdditionalArgs :: [String]
                       , optionsErrorMsg :: Maybe String
                       }
             deriving (Eq, Show)

defaultOptions :: Options
defaultOptions = Options { optionsShowFunPad = True
                         , optionsHelp = False
                         , optionsSourceFile = Nothing
                         , optionsShowFunction = Nothing
                         , optionsCallFunction = Nothing
                         , optionsAdditionalArgs = []
                         , optionsErrorMsg = Nothing
                         }

processArgs :: [String] -> Options
processArgs = processArgsLoop defaultOptions 

processArgsLoop :: Options -> [String] -> Options
processArgsLoop options args =
    case args of
      [] -> options
      arg:args' ->
          case arg of
            "--help" -> options {optionsHelp = True,
                                 optionsShowFunPad = False}
            "--file" ->
                case args' of
                  [] -> options {optionsErrorMsg = 
                                     Just "--file: missing file name"}
                  file:args'' ->
                      processArgsLoop (options {optionsSourceFile = Just file,
                                                optionsShowFunPad = False})
                                      args''
            "--show" ->
                case args' of
                  [] -> options {optionsErrorMsg =
                                     Just "--show: missing function name"}
                  fname:args'' ->
                      processArgsLoop (options {optionsShowFunction = 
                                                    Just fname,
                                               optionsShowFunPad = False})
                                      args''
            "--call" ->
                case args' of
                  [] -> options {optionsErrorMsg =
                                     Just "--call: missing function name"}
                  fname:args'' ->
                      options {optionsCallFunction = Just fname,
                               optionsAdditionalArgs = args'',
                               optionsShowFunPad = False}
            _ ->
                options {optionsErrorMsg = Just ("unexpected argument: " ++
                                                  arg)}

helpText :: [String]
helpText =
    ["Usage:",
     "sifflet [--file SIFFLET-FILE] --show FUNCTION-NAME",
     "sifflet [--file SIFFLET-FILE] --call FUNCTION-NAME [ARG ...]",
     "sifflet --help",
     "sifflet",
     "where",
     "1.  If --file SIFFLET-FILE is given, then the function definition is",
     "read from that file; otherwise, it should be one of the Sifflet",
     "examples in the Function Pad.",
     "2.  If --show FUNCTION-NAME is used, the function is merely",
     "displayed, ready to be called but not actually called.",
     "3.  If --call FUNCTION-NAME [ARG ...] is used, the function",
     "is displayed and called (with the given arguments ARG ..., if any).",
     "4.  --help displays this message.",
     "Any of these options suppresses the initial appearance of",
     "the Function Pad, though (except with --help) it can still be",
     "activated by the user."]

showHelp :: IO ()
showHelp = mapM_ putStrLn helpText