ContentsIndex
HsUnixArgs
Contents
Argument Properties
Evaluating the Command Line
Extracting the Argument Values
Placing additional Constraints on the Arguments
Argument Error Reporting
Description

This module provides a more convient way of parsing command line arguments than the GHC GetOpt package. It makes use of GetOpt, but hides it from the user.

For each command line argument, a description is to be created with argdesc. Then the command line arguments are evaluated with one of the getargs... functions. In case of an error, this will cause a dynamic exception, which provides an expressive error message to be printed. Then the arg... functions are used to extract the values contained in the arguments, with the right type. The typical use of HsUnixArgs looks something like this:

import HsUnix

main =
   do let a_onevalue = argdesc [ desc_at_most_once, ... ]
          a_values   = argdesc [ desc_direct, ... ]
          a_switch   = argdesc [ ... ]
          ...
          header = "mclapep - My Command Line Argument Parser Example Program, version 1.0.0"

      args <- getargs header [a_onevalue, a_values, a_switch, ...]

      val  <- optarg_req a_onevalue args        -- val  :: Maybe String
      vals <- args_req   a_values args          -- vals :: [String]
      doit <- arg_switch a_switch args          -- doit :: Bool
      ...
   `catchDyn` 
      (\argerror -> do
          hPutStrLn stderr $ (argerror_message argerror) ++ "\n\n" ++ (argerror_usageinfo argerror)
          exitFailure
      )

Errors in the argument descriptions are regarded as bugs, and handled by aborting the program with a message which is meaningful to the programmer. It is assumed that the argument description is a constant for a given program.

Errors in the arguments are reported using HsUnix's error handling scheme. See the HsUnixErrors module. An error description value is generated, and either returned via an Either value, or thrown as an exception.

Synopsis
data HsUnixArgumentProperty
data HsUnixArgumentDescription
type Argtester = String -> Maybe (HsUnixArgumentDescription -> String)
argdesc :: [HsUnixArgumentProperty] -> HsUnixArgumentDescription
desc_short :: Char -> HsUnixArgumentProperty
desc_long :: String -> HsUnixArgumentProperty
desc_direct :: HsUnixArgumentProperty
desc_value_required :: HsUnixArgumentProperty
desc_value_optional :: HsUnixArgumentProperty
desc_times :: Int -> Int -> HsUnixArgumentProperty
desc_once :: HsUnixArgumentProperty
desc_at_least_once :: HsUnixArgumentProperty
desc_at_most_once :: HsUnixArgumentProperty
desc_any_times :: HsUnixArgumentProperty
desc_at_least :: Int -> HsUnixArgumentProperty
desc_at_most :: Int -> HsUnixArgumentProperty
desc_argname :: String -> HsUnixArgumentProperty
desc_description :: String -> HsUnixArgumentProperty
desc_tester :: Argtester -> HsUnixArgumentProperty
desc_integer :: HsUnixArgumentProperty
desc_nonneg_integer :: HsUnixArgumentProperty
readtester :: ReadS a -> String -> Argtester
data HsUnixArguments
getargs :: String -> [HsUnixArgumentDescription] -> IO HsUnixArguments
getargs_ordered :: String -> [HsUnixArgumentDescription] -> IO HsUnixArguments
getargs' :: String -> [String] -> [HsUnixArgumentDescription] -> Either ArgError HsUnixArguments
getargs_ordered' :: String -> [String] -> [HsUnixArgumentDescription] -> Either ArgError HsUnixArguments
unsafe_getargs :: String -> [HsUnixArgumentDescription] -> HsUnixArguments
unsafe_getargs_ordered :: String -> [HsUnixArgumentDescription] -> HsUnixArguments
arg_switch :: HsUnixArguments -> HsUnixArgumentDescription -> Bool
arg_times :: HsUnixArguments -> HsUnixArgumentDescription -> Int
args_opt :: HsUnixArguments -> HsUnixArgumentDescription -> [Maybe String]
args_req :: HsUnixArguments -> HsUnixArgumentDescription -> [String]
reqarg_opt :: HsUnixArguments -> HsUnixArgumentDescription -> Maybe String
reqarg_req :: HsUnixArguments -> HsUnixArgumentDescription -> String
optarg_opt :: HsUnixArguments -> HsUnixArgumentDescription -> Maybe (Maybe String)
optarg_req :: HsUnixArguments -> HsUnixArgumentDescription -> Maybe String
args_none :: [HsUnixArgumentDescription] -> HsUnixArguments -> IO ()
args_all :: [HsUnixArgumentDescription] -> HsUnixArguments -> IO ()
args_one :: [HsUnixArgumentDescription] -> HsUnixArguments -> IO ()
args_at_most_one :: [HsUnixArgumentDescription] -> HsUnixArguments -> IO ()
args_at_least_one :: [HsUnixArgumentDescription] -> HsUnixArguments -> IO ()
data ArgError = ArgError {
argerror_message :: String
argerror_usageinfo :: String
}
usage_info :: HsUnixArguments -> String
argname :: HsUnixArgumentDescription -> String
argname_a :: HsUnixArgumentDescription -> String
Argument Properties
data HsUnixArgumentProperty
A property of a command line argument. These are generated by the desc_... functions, and condensed to argument descriptions of type HsUnixArgumentDescription by argdesc. This type is abstract.
data HsUnixArgumentDescription
Description of one command line argument. These are generated by argdesc from a list of argument properties, and subsequently used by one of the getargs... functions. This type is abstract.
Instances
Eq HsUnixArgumentDescription
type Argtester = String -> Maybe (HsUnixArgumentDescription -> String)

Command line argument value tester function. This tests the format of an argument's value for errors. The tester function is specified by desc_tester or such, as part of the argument description.

The tester is passed the argument value. If the format is correct, then it returns Nothing. If there is an error, then it returns Just msgf, with msgf being an error message generation function. This function gets passed the argument description, and produces the error message. The argument description typically is used to extract a descriptive name of the argument (using argname or argname_a) to be included in the error message.

argdesc
:: [HsUnixArgumentProperty] List of properties, which describe the command line argument.
-> HsUnixArgumentDescription The corresponding argument description.
Make an argument description from a list of argument properties. This condenses the list to an argument description, which can be uses by the getargs... functions and the argument value extraction functions.
desc_short
:: Char The character to name the argument.
-> HsUnixArgumentProperty The corresponding argument property.
Short name of the argument. This specifies a character for a one letter style argument, like -x. There can be specified several for the same argument. Each argument needs at least either a short or a long name.
desc_long
:: String The long name of the argument.
-> HsUnixArgumentProperty The corresponding argument property.
Long name of the argument. This specifies a GNU style long name for the argument, like --arg or --arg=.... There can be specified several names for the same argument. Each argument needs at least either a short or a long name.
desc_direct :: HsUnixArgumentProperty
Signal that this is the description of direct arguments. Direct arguments are the ones not introduced by any short or long argument names (like -x or --arg), or which occur after the special argument --. The presence of desc_direct in the argument properties list signals argdesc that this is the description of the direct arguments. There may be at most one such description.
desc_value_required :: HsUnixArgumentProperty
Signal that the argument requires a value.
desc_value_optional :: HsUnixArgumentProperty
Signal that the argument optionally has a value. The user may or may not specify a value to this argument.
desc_times
:: Int Lower bound of the allowed number of times.
-> Int Upper bound of the allowed number of times.
-> HsUnixArgumentProperty The corresponding argument property.
Specify lower and upper bound on the number of times an argument may occur.
desc_once
:: HsUnixArgumentProperty The corresponding argument property.
Signal that the argument must be present exactly once. This is meaningful only for arguments which can take a value.
desc_at_least_once
:: HsUnixArgumentProperty The corresponding argument property.
Signal that the argument must occur at least one time.
desc_at_most_once
:: HsUnixArgumentProperty The corresponding argument property.
Signal that the argument must occur at most one time.
desc_any_times
:: HsUnixArgumentProperty The corresponding argument property.
Signal that the argument may occur any number of times.
desc_at_least
:: Int Number of times.
-> HsUnixArgumentProperty The corresponding argument property.
Signal that the argument must have at least the specified number of occurences, and has no upper limit of occurences.
desc_at_most
:: Int Number of times.
-> HsUnixArgumentProperty The corresponding argument property.
Signal that the argument does not need to be present, and may occur at most the specified number of times.
desc_argname
:: String Name of the argument's value.
-> HsUnixArgumentProperty The corresponding argument property.
Specify the descriptive name for command line argument's value. Used for the generation of the usage message. The name should be very short.
desc_description
:: String Short description of the argument.
-> HsUnixArgumentProperty The corresponding argument property.
Specify a short description of what the argument does. Used for the generation of the usage message. This is to fit on one line, after the short and long argument names. It should be 40 characters long or so.
desc_tester
:: Argtester Argument tester to apply to this argument
-> HsUnixArgumentProperty The corresponding argument property.

Specify a tester for this argument. The tester is a function which tests the argument value for format errors. Typically, it tests whether the value can be parsed to some target type. If the test fails, the tester produces an error message. When parsing the command line arguments (which getargs or related), all the testers are applied to the respective argument values, and an ArgError is thrown in case of failure. By using a tester, it can be ensured that the argument values abide a specific format when extracting them, such that they can be parsed without errors, e.g. myarg = read (reqarg_req args d_myarg).

An argument tester is a function of type Argtester.

See readtester, desc_integer, desc_nonneg_integer, Argtester.

desc_integer :: HsUnixArgumentProperty

Specify that the value of this argument, if present, is a positive integer. This will cause an error when the command line is parsed, and the argument's value doesn't specify an integer.

desc_integer = desc_tester (readtester (reads :: ReadS Int) "Integer expected.")

See desc_tester.

desc_nonneg_integer :: HsUnixArgumentProperty

Specify that the value of this argument, if present, is a non-negative integer. This will cause an error when the command line is parsed, and the value doesn't specify a non-negative integer.

desc_nonneg_integer = desc_tester (readtester ((filter (\(a,_) -> a >= 0) . reads) :: ReadS Int) "Non-negative integer expected." )

See desc_tester.

readtester :: ReadS a -> String -> Argtester
Build an argument tester from a reads like function. Typically, a specialisation of the standard prelude function read is used. Example: readtester Integer expected. (reads :: ReadS Int)
Evaluating the Command Line
data HsUnixArguments

This represents the parsed contents of the command line. It is returned by the getargs... functions, and passed on to the value extraction functions by the user.

See getargs, getargs_ordered, getargs', getargs_ordered'.

getargs
:: String Header to be used in the usage info.
-> [HsUnixArgumentDescription] The argument descriptions.
-> IO HsUnixArguments The contents of the command line.

Parse command line arguments. The arguments are taken from a call to getArgs and parsed. Any error is thrown as a dynamic ArgError exception. The result is a value from which the information in the command line can be extracted by the arg..., reqarg... and optarg... functions.

Named arguments (like -x or --arg) and direct arguments may occur in any order.

getargs_ordered
:: String Header to be used in the usage info.
-> [HsUnixArgumentDescription] Descriptions of the arguments.
-> IO HsUnixArguments The contents of the command line.

Parse command line arguments. The arguments are taken from a call to getArgs and parsed. Any error is thrown as a dynamic ArgError exception. The result is a value from which the information in the command line can be extracted by the arg..., reqarg... and optarg... functions.

All arguments after the first direct argument are regarded as direct arguments. This means that argument names introduced by - or -- no longer take effect.

getargs'
:: String Header to be used in the usage info.
-> [String] Command line to be parsed.
-> [HsUnixArgumentDescription] The argument descriptions.
-> Either ArgError HsUnixArguments The contents of the command line.

Parse the specified command line. Any error is returned as Left argerror. In case of success, the result is returned as Right res. From the result, the information in the command line can be extracted by the arg..., reqarg... and optarg... functions.

Named arguments (like -x or --arg) and direct arguments may occur in any order.

getargs_ordered'
:: String Header to be used in the usage info.
-> [String] Command line to be parsed.
-> [HsUnixArgumentDescription] The argument descriptions.
-> Either ArgError HsUnixArguments The contents of the command line.

Parse the specified command line. Any error is returned as Left argerror. In case of success, the result is returned as Right res. From the result, the information in the command line can be extracted by the arg..., reqarg... and optarg... functions.

All arguments after the first direct argument are regarded as direct arguments. This means that argument names introduced by - or -- no longer take effect.

unsafe_getargs
:: String The header used in the usage information
-> [HsUnixArgumentDescription] The argument descriptions
-> HsUnixArguments The parsed command line arguments

getargs as a pure function, instead of an IO action. This allows to make evaluated command line arguments global values.

This calls getargs to parse the command line arguments. In case of an error, it prints an error message, which contains the usage info, on stderr and terminates the program with exitFailure. The parse result is returned (same as getarg's). GHC.IOBase.unsafePerformIO is used to take the result out of the IO monad.

The action is performed on demand, when the parse result is evaluated. It may result in the program being aborted. In order to avoid this happening at unexpected times, the main function should, assuming that args is the result of unsafe_getargs, start with the line seq args (return ()). This will trigger any command line argument errors at the beginning of the program, terminating it properly. See section 6.2 of the Hakell Report for the definition of seq.

A typical use of unsafe_getargs looks like this:

header = "..."
descs = [ d_myflag, ... ]

d_myflag = argdesc [ ... ]

args = unsafe_getargs header descs
myflag = arg_switch args d_myflag

main = do
   seq args (return ())
   ...

See getargs, unsafe_getargs_ordered.

unsafe_getargs_ordered
:: String The header used in the usage information
-> [HsUnixArgumentDescription] The argument descriptions
-> HsUnixArguments The parsed command line arguments

getargs_ordered as a pure function, instead of an IO action. This is exactly like unsafe_getargs, but using getargs_ordered instead of getargs.

See unsafe_getargs.

Extracting the Argument Values
arg_switch
:: HsUnixArguments Command line parse result.
-> HsUnixArgumentDescription Argument description of the switch.
-> Bool Whether the switch is present in the command line.
Query whether a certain switch is specified on the command line. A switch is an argument which is allowed zero or one time, and has no value.
arg_times
:: HsUnixArguments Command line parse result.
-> HsUnixArgumentDescription Description of the argument.
-> Int Number of times the argument occurs.
Query the number of occurences of an argument.
args_opt
:: HsUnixArguments Command line parse result.
-> HsUnixArgumentDescription Description of the argument.
-> [Maybe String] The occurences of the argument.
Query the values of an argument with optional value. This is for arguments which take an optional value, and may occur several times. The occurences with value are represented as Just value, the occurences without are represented as Nothing.
args_req
:: HsUnixArguments Command line parse result.
-> HsUnixArgumentDescription Description of the argument.
-> [String] The values of the argument.
Query the values of an argument with required value. This is for arguments which require a value, and may occur several times.
reqarg_opt
:: HsUnixArguments Command line parse result.
-> HsUnixArgumentDescription Description of the argument.
-> Maybe String The value of the argument, if it occurs.
Query the optional value of a required argument. This is for arguments which must occur once, and may have a value. If the argument is specified, its value is returned as Just value. If it isn't, the result is Nothing.
reqarg_req
:: HsUnixArguments Command line parse result.
-> HsUnixArgumentDescription Description of the argument.
-> String The value of the argument.
Query the value of a required argument. This is for arguments which must occur exactly once, and require a value.
optarg_opt
:: HsUnixArguments Command line parse result.
-> HsUnixArgumentDescription Description of the argument.
-> Maybe (Maybe String) The occurence of the argument and its value (see above).
Query the optional value of an optional argument. This is for arguments which may occur zero or one time, and which may or may not have a value. If the argument doesn't occur, the result is Nothing. If it does occur, but has no value, then the result is Just Nothing. If it does occur with value, the result is Just (Just value).
optarg_req
:: HsUnixArguments Command line parse result.
-> HsUnixArgumentDescription Description of the argument.
-> Maybe String The value of the argument, if it occurs.
Query the value of an optional argument. This is for optional arguments which require a value, and may occur at most once. The result is Just value if the argument occurs, and Nothing if it doesn't occur.
Placing additional Constraints on the Arguments
args_none
:: [HsUnixArgumentDescription] List of the arguments which must not be present.
-> HsUnixArguments Command line parse result.
-> IO ()

None of the specifed arguments may be present.

Throws an ArgError if any of the arguments are present.

args_all
:: [HsUnixArgumentDescription] List of the arguments which must be present.
-> HsUnixArguments Command line parse result.
-> IO ()

All of the specified arguments must be present.

Throws an ArgError if any is missing.

args_one
:: [HsUnixArgumentDescription] List of the arguments, of which exactly one must be present.
-> HsUnixArguments Command line parse result.
-> IO ()

Exactly one of the specified arguments must be present.

Otherwise throw an ArgError.

args_at_most_one
:: [HsUnixArgumentDescription] List of the arguments, of which at most one may be present.
-> HsUnixArguments Command line parse result.
-> IO ()

At most one of the specified arguments may be present.

Otherwise throw an ArgError.

args_at_least_one
:: [HsUnixArgumentDescription] List of the arguments, of which at least one must be present.
-> HsUnixArguments Command line parse result.
-> IO ()

At least one of the specified arguments must be present.

Otherwise throw an ArgError.

Argument Error Reporting
data ArgError
Error thrown as a dynamic exception when there is an error in the command line arguments.
Constructors
ArgError
argerror_message :: String Error message generated by HsUnixArgs.
argerror_usageinfo :: String Usage information derived from the argument descriptions.
Instances
Typeable ArgError
Show ArgError
usage_info :: HsUnixArguments -> String
Get the usage information from the parsed arguments. The usage info contains the header specified to the corresponding getargs... function, and descriptions of the command line arguments.
argname :: HsUnixArgumentDescription -> String
Generate a descriptive argument name from an argument description, suitable for use in error messages. This uses the long and short argument names (as specified by desc_short and desc_long) and generates descriptive names of the argument like "-f", "-myflag", "-f/--myflag", etc. All the argument names are included. In case of direct arguments (see desc_direct), the descriptive name is "(direct argument)".
argname_a :: HsUnixArgumentDescription -> String
Generate a descriptive argument name from an argument description, beginning with "argument". This uses the long and short argument names (as specified by desc_short and desc_long) and generates descriptive names of the argument like "argument -f", "argument -myflag", "argument -f/--myflag", etc. All the argument names are included. In case of direct arguments (see desc_direct), the descriptive name is "direct argument".
Produced by Haddock version 0.4