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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
-- | This provides a compatiblity wrapper to the @System.Console.GetOpt@ module in @base@.
-- That module is essentially a Haskell port of the GNU @getopt@ library.
--
-- /Changes:/ The changes from @GetOpt@ are listed in the documentation for each function.
module System.Console.CmdArgs.GetOpt(
convert, getOpt, getOpt', usageInfo,
ArgOrder(..), OptDescr(..), ArgDescr(..)
) where
import System.Console.CmdArgs.Explicit
-- | What to do with options following non-options.
--
-- /Changes:/ Only 'Permute' is allowed, both @RequireOrder@ and @ReturnInOrder@
-- have been removed.
data ArgOrder a = Permute
-- | Each 'OptDescr' describes a single option/flag.
--
-- The arguments to 'Option' are:
--
-- * list of short option characters
--
-- * list of long option strings (without @\"--\"@, may not be 1 character long)
--
-- * argument descriptor
--
-- * explanation of option for userdata
data OptDescr a = Option
[Char]
[String]
(ArgDescr a)
String
-- | Describes whether an option takes an argument or not, and if so
-- how the argument is injected into a value of type @a@.
data ArgDescr a
= NoArg a -- ^ no argument expected
| ReqArg (String -> a) String -- ^ option requires argument
| OptArg (Maybe String -> a) String -- ^ optional argument
-- | Return a string describing the usage of a command, derived from
-- the header (first argument) and the options described by the
-- second argument.
usageInfo :: String -> [OptDescr a] -> String
usageInfo desc flags = unlines $ desc : drop 2 (lines $ show $ convert "" flags)
-- | Process the command-line, and return the list of values that matched
-- (and those that didn\'t). The arguments are:
--
-- * The order requirements (see 'ArgOrder')
--
-- * The option descriptions (see 'OptDescr')
--
-- * The actual command line arguments (presumably got from
-- 'System.Environment.getArgs').
--
-- 'getOpt' returns a triple consisting of the option arguments, a list
-- of non-options, and a list of error messages.
--
-- /Changes:/ The list of errors will contain at most one entry, and if an
-- error is present then the other two lists will be empty.
getOpt :: ArgOrder a -> [OptDescr a] -> [String] -> ([a], [String], [String])
getOpt _ flags args =
case process (convert "" flags) args of
Left x -> ([],[],[x])
Right (a,b) -> (a,b,[])
-- | /Changes:/ This is exactly the same as 'getOpt', but the 3rd element of the
-- tuple (second last) will be an empty list.
getOpt' :: ArgOrder a -> [OptDescr a] -> [String] -> ([a], [String], [String], [String])
getOpt' x y z = (a,b,[],c)
where (a,b,c) = getOpt x y z
-- | Given a help text and a list of option descriptions, generate a 'Mode'.
convert :: String -> [OptDescr a] -> Mode ([a],[String])
convert help flags = mode "program" ([],[]) help args (map f flags)
where
args = flagArg (\x (a,b) -> Right (a,b++[x])) "ARG"
f (Option short long x help) = case x of
NoArg x -> flagNone names (\(a,b) -> (a++[x],b)) help
ReqArg op x -> flagReq names (\x (a,b) -> Right (a++[op x],b)) x help
OptArg op x -> flagOpt "" names (\x (a,b) -> Right (a++[op $ if null x then Nothing else Just x],b)) x help
where names = map return short ++ long
|