Skip to content
This repository
tree: a9146a9025
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 79 lines (68 sloc) 2.989 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
module Ocram.Options
-- export {{{1
(
  Options(..), options, defaultOptions
) where

-- import {{{1
import Data.List (intercalate)
import Data.Maybe (isJust)
import Ocram.Text (new_error, OcramError)
import System.Console.GetOpt

data Options = Options { -- {{{1
    optInput :: FilePath
  , optOutput :: FilePath
  , optPreprocessor :: FilePath
  , optPalGenerator :: Maybe FilePath
  , optPalFile :: Maybe FilePath
  , optDebugFile :: Maybe FilePath
  , optHelp :: Bool
}


-- options :: String -> [String] -> Either String Options {{{1
options :: String -> [String] -> Either [OcramError] Options
options prg argv =
  let use = usage prg in
  case getOpt Permute availableOptions argv of
    (o,[],[]) ->
      let opts = foldl (flip id) defaultOptions o in
      if optHelp opts then
          Left [new_error 1 (help use) Nothing]
      else
        if checkOptions opts then
          Right opts
        else
          Left [new_error 2 (err use "missing required option(s)") Nothing]
    (_,n,[]) -> Left [new_error 3 (err use ("unknown options '" ++ unwords n ++ "'")) Nothing]
    (_,_,es) -> Left [new_error 4 (err use $ intercalate "\n" es) Nothing]

help :: String -> String
help use = "Printing usage:\n" ++ use

err :: String -> String -> String
err use msg = "Error in command line options\n" ++ msg ++ "\n" ++ use

usage :: String -> String
usage prg = usageInfo ("Usage: " ++ prg ++ " OPTIONS") availableOptions

availableOptions :: [OptDescr (Options -> Options)]
availableOptions = [
    Option "i" ["input"] (ReqArg (\x opts -> opts {optInput = x}) "input") "input tc file (required)"
  , Option "o" ["output"] (ReqArg (\x opts -> opts {optOutput = x}) "output") "output ec file (required)"
  , Option "c" ["preprocessor"] (ReqArg (\x opts -> opts {optPreprocessor = x}) "preprocessor") "external program which performs the pre-processing of the input C file (required)"
  , Option "g" ["generator"] (ReqArg (\x opts -> opts {optPalGenerator = Just x}) "generator") "external program which generates the PAL implementation (optional)"
  , Option "p" ["pal"] (ReqArg (\x opts -> opts {optPalFile = Just x}) "pal") "file path for the PAL generator program (mandatory if generator is specified)"
  , Option "d" ["debug"] (ReqArg (\x opts -> opts {optDebugFile = Just x}) "debug") "file path for the debugging information (optional)"
  , Option "h" ["help"] (NoArg (\opts -> opts {optHelp = True})) "print help and quit"
  ]

defaultOptions :: Options
defaultOptions = Options {
    optInput = ""
  , optOutput = ""
  , optPreprocessor = ""
  , optPalGenerator = Nothing
  , optPalFile = Nothing
  , optDebugFile = Nothing
  , optHelp = False
}

checkOptions :: Options -> Bool
checkOptions opts
  | optInput opts == optInput defaultOptions = False
  | optOutput opts == optOutput defaultOptions = False
  | isJust (optPalGenerator opts) && not (isJust (optPalFile opts)) = False
  | optPreprocessor opts == optPreprocessor defaultOptions = False
  | otherwise = True
Something went wrong with that request. Please try again.