hsshellscript-3.5.0: Haskell for Unix shell scripting tasks
Safe HaskellNone
LanguageHaskell2010

HsShellScript.Args

Description

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

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 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 HsShellScript.Args looks something like this:

import HsShellScript
import Control.Exception
import Control.Monad
import System.Environment
import System.Exit
import System.IO

header = "mclapep - My Command Line Argument Parser Example Program, version 1.0.0\n\n"
descs  = [d_onevalue, d_values, d_switch {-...-}]

d_onevalue = argdesc [ desc_short 'o', desc_at_most_once, desc_argname "a", desc_value_required {-...-}]
d_values   = argdesc [ desc_direct, desc_any_times {-...-} ]
d_switch   = argdesc [ desc_long "doit", desc_at_most_once {-...-} ] 
-- ...

args = unsafe_getargs header descs
val  = optarg_req args d_onevalue        -- val  :: Maybe String
vals = args_req   args d_values          -- vals :: [String]
doit = arg_switch args d_switch          -- doit :: Bool
-- ...

main = mainwrapper $ do
   args0 <- getArgs
   when (null args0) $ do
      -- No command line arguments - print usage information
      print_usage_info stdout header descs
      exitWith ExitSuccess
   -- trigger argument errors
   seq args (return ())

   -- Do something with the arguments

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 HsShellScript's error handling scheme. An error description value is generated, and either returned via an Either value, or thrown as an exception.

Synopsis

Argument Properties

newtype ArgumentProperty Source #

A property of a command line argument. These are generated by the desc_... functions, and condensed to argument descriptions of type ArgumentDescription by argdesc. This type is abstract.

data ArgumentDescription Source #

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.

Constructors

ArgumentDescription 

Fields

type Argtester = String -> Maybe (ArgumentDescription -> String) Source #

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 Source #

Arguments

:: [ArgumentProperty]

List of properties, which describe the command line argument.

-> ArgumentDescription

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 used by the getargs... functions and the argument value extraction functions.

desc_short Source #

Arguments

:: Char

The character to name the argument.

-> ArgumentProperty

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 Source #

Arguments

:: String

The long name of the argument.

-> ArgumentProperty

The corresponding argument property.

Long name of the argument. This specifies a GNU style long name for the argument, which is introduced by two dashes, 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. Except for direct arguments, which don't have a name.

See desc_direct

desc_direct :: ArgumentProperty Source #

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). After the special argument --, also everything is a direct argument, even when starting with - or --. 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.

The is_direct function can be used in order to determine if a specific argument is the direct argument.

See is_direct.

desc_value_required :: ArgumentProperty Source #

Signal that the argument requires a value.

desc_value_optional :: ArgumentProperty Source #

Signal that the argument optionally has a value. The user may or may not specify a value to this argument.

desc_times Source #

Arguments

:: Int

Lower bound of the allowed number of argdesc_times.

-> Int

Upper bound of the allowed number of argdesc_times.

-> ArgumentProperty

The corresponding argument property.

Specify lower and upper bound on the number of times an argument may occur.

desc_once Source #

Arguments

:: ArgumentProperty

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 Source #

Arguments

:: ArgumentProperty

The corresponding argument property.

Signal that the argument must occur at least one time.

desc_at_most_once Source #

Arguments

:: ArgumentProperty

The corresponding argument property.

Signal that the argument must occur at most one time.

desc_any_times Source #

Arguments

:: ArgumentProperty

The corresponding argument property.

Signal that the argument may occur any number of times.

desc_at_least Source #

Arguments

:: Int

Number of times.

-> ArgumentProperty

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 Source #

Arguments

:: Int

Number of times.

-> ArgumentProperty

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 Source #

Arguments

:: String

Name of the argument's value.

-> ArgumentProperty

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 Source #

Arguments

:: String

Short description of the argument.

-> ArgumentProperty

The corresponding argument property.

Specify a description of what the argument does. Used for usage message generation. This can be arbitratily long, long lines are wrapped.

desc_tester Source #

Arguments

:: Argtester

Argument tester to apply to this argument

-> ArgumentProperty

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 :: ArgumentProperty Source #

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 :: ArgumentProperty Source #

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 Source #

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)

is_direct Source #

Arguments

:: ArgumentDescription

Argument description, as returned by argdesc.

-> Bool 

Whether the specified argument is the direct argument. Direct arguments are the ones which are specified without introducing "-" or "--", in the command line, or which occur after the special argument "--".

See argdesc, desc_direct.

Evaluating the Command Line

data Arguments Source #

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 Source #

Arguments

:: String

Header to be used by the deprecated usage_info function.

-> [ArgumentDescription]

The argument descriptions.

-> IO Arguments

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 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.

The header is used only by the deprecated usage_info function. If you don't use it, you don't need to specify a header. Just pass an empty string.

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

See usage_info, make_usage_info, print_usage_info.

getargs_ordered Source #

Arguments

:: String

Header to be used by the deprecated usage_info function.

-> [ArgumentDescription]

Descriptions of the arguments.

-> IO Arguments

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 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.

The header is used only by the deprecated usage_info function. If you don't use it, you don't need to specify a header. Just pass an empty string.

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

See usage_info, make_usage_info, print_usage_info.

getargs' Source #

Arguments

:: String

Header to be used by the deprecated usage_info function.

-> [String]

Command line to be parsed.

-> [ArgumentDescription]

The argument descriptions.

-> Either ArgError Arguments

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.

The header is used only by the deprecated usage_info function. If you don't use it, you don't need to specify a header. Just pass an empty string.

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

See usage_info, make_usage_info, print_usage_info.

getargs_ordered' Source #

Arguments

:: String

Header to be used by the deprecated usage_info function.

-> [String]

Command line to be parsed.

-> [ArgumentDescription]

The argument descriptions.

-> Either ArgError Arguments

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.

The header is used only by the deprecated usage_info function. If you don't use it, you don't need to specify a header. Just pass an empty string.

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

See usage_info, make_usage_info, print_usage_info.

unsafe_getargs Source #

Arguments

:: String

Header to be used by the deprecated usage_info function.

-> [ArgumentDescription]

The argument descriptions

-> Arguments

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. GHC.IO.unsafePerformIO is used to take the result out of the IO monad.

unsafe_getargs header descs = GHC.IO.unsafePerformIO $ getargs "" descs

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

The header is used only by the deprecated usage_info function. If you don't use it, you don't need to specify a header. Just pass an empty string.

A typical use of unsafe_getargs looks like this:

descs = [ d_myflag, ... ]

d_myflag = argdesc [ ... ]

args = unsafe_getargs "" descs
myflag = arg_switch args d_myflag

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

See getargs, unsafe_getargs_ordered.

unsafe_getargs_ordered Source #

Arguments

:: String

Header to be used by the deprecated usage_info function.

-> [ArgumentDescription]

The argument descriptions

-> Arguments

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.

The header is used only by the deprecated usage_info function. If you don't use it, you don't need to specify a header. Just pass an empty string.

The definition is:

unsafe_getargs_ordered = GHC.IO.unsafePerformIO $ getargs_ordered "" descs

See unsafe_getargs, usage_info, make_usage_info, print_usage_info.

Extracting the Argument Values

arg_switch Source #

Arguments

:: Arguments

Command line parse result.

-> ArgumentDescription

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 Source #

Arguments

:: Arguments

Command line parse result.

-> ArgumentDescription

Description of the argument.

-> Int

Number of times the argument occurs.

Query the number of occurences of an argument.

args_opt Source #

Arguments

:: Arguments

Command line parse result.

-> ArgumentDescription

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 Source #

Arguments

:: Arguments

Command line parse result.

-> ArgumentDescription

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 Source #

Arguments

:: Arguments

Command line parse result.

-> ArgumentDescription

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 Source #

Arguments

:: Arguments

Command line parse result.

-> ArgumentDescription

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 Source #

Arguments

:: Arguments

Command line parse result.

-> ArgumentDescription

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 Source #

Arguments

:: Arguments

Command line parse result.

-> ArgumentDescription

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.

arg_occurs Source #

Arguments

:: Arguments

Command line parse result.

-> ArgumentDescription

Description of the respective argument.

-> Bool

Whether the specified argument occurs in the command line.

Whether the specified argument occurs in the command line.

Placing additional Constraints on the Arguments

args_none Source #

Arguments

:: [ArgumentDescription]

List of the arguments which must not be present.

-> Arguments

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 Source #

Arguments

:: [ArgumentDescription]

List of the arguments which must be present.

-> Arguments

Command line parse result.

-> IO () 

All of the specified arguments must be present.

Throws an ArgError if any is missing.

args_one Source #

Arguments

:: [ArgumentDescription]

List of the arguments, of which exactly one must be present.

-> Arguments

Command line parse result.

-> IO () 

Exactly one of the specified arguments must be present.

Otherwise throw an ArgError.

args_at_most_one Source #

Arguments

:: [ArgumentDescription]

List of the arguments, of which at most one may be present.

-> Arguments

Command line parse result.

-> IO () 

At most one of the specified arguments may be present.

Otherwise throw an ArgError.

args_at_least_one Source #

Arguments

:: [ArgumentDescription]

List of the arguments, of which at least one must be present.

-> Arguments

Command line parse result.

-> IO () 

At least one of the specified arguments must be present.

Otherwise throw an ArgError.

arg_conflicts Source #

Arguments

:: ArgumentDescription

Argument which doesn't tolerate the other arguments

-> [ArgumentDescription]

Arguments which aren't tolerated by the specified argument

-> Arguments

Command line parse result.

-> IO () 

When the specified argument is present, then none of the other arguments may be present.

Otherwise throw an ArgError.

Argument Error Reporting

data ArgError Source #

Error thrown when there is an error in the command line arguments.

The usage information is generated by the deprecated function usage_info. Better ignore this, and use the newer make_usage_info or print_usage_info.

See make_usage_info, print_usage_info, usage_info.

Constructors

ArgError 

Fields

Instances

Instances details
Show ArgError Source # 
Instance details

Defined in HsShellScript.Args

Exception ArgError Source #

Make ArgError an instance of Exception, so we can throw and catch it, using GHC-6.10's new exception library.

Instance details

Defined in HsShellScript.Args

usage_info :: Arguments -> String Source #

Deprecated. This is left here for backwards compatibility. New programs should use make_usage_info and/or print_usage_info.

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.

Descriptions can be several lines long. Lines get wrapped at column 80.

See make_usage_info, print_usage_info, wrap.

make_usage_info Source #

Arguments

:: [ArgumentDescription]

List of argument descriptions, as created by a argdesc

-> Int

The output is indented this many columns. Probably zero.

-> Int

Maximum width of the column of the short form of each argument. When this many aren't needed, less are used.

-> Int

Maximum width of the column of the long form of each argument. When this many aren't needed, less are used.

-> Int

Wrap everything at this column. Should probably be the terminal width.

-> [String]

Pretty printed usage information, in paragraphs, which contain one or several lines, which are separated by newlines.

Generate pretty-printed information about the command line arguments. This function gives you much control on how the usage information is generated. print_usage_info might be more like what you need.

The specified argument descriptions (as taken by the getargs... functions) are processed in the given order. Each one is formatted as a paragraph, detailing the argument. This is done according to the specified geometry.

The direct argument, in case there is one, is omitted. You should detail the direct command line arguments separatly, such as in some header.

The specified maximum breadths must fit in the specified width, or an error is raised. This happens, when colsleft + colsshort + 2 + colslong + 2 + 2 > width.

See print_usage_info, getargs, usage_info, ArgumentDescription, desc_description, argdesc, terminal_width, terminal_width_ioe.

print_usage_info Source #

Arguments

:: Handle

To which handle to print the usage info.

-> String

The header to print first. Can be empty.

-> [ArgumentDescription]

The argument description of the arguments, which should be documented.

-> IO () 

Print the usage information (about the command line arguments), for the specified header and arguments to the specified handle. When the handle is connected to a terminal, the terminal's width (in columns) is used to format the output, such that it fits the terminal. Both the header and the argument descriptions are adapted to the width of the terminal (by using wrap).

When the handle does not connected to a terminal, 80 columns are used. This may happen to stdout or stderr, for instance, when the program is in a pipe, or the output has been redirected to a file.

When the terminal is too narrow for useful output, then instead of the usage information, a short message ("Terminal too narrow") is printed. This applies to terminals with a width of less than 12.

You should specify one long line for each paragraph in the header and the argument descriptions, and let print_usage_info do the wrapping. When you have several paragraphs, separate them by a double \n\n. This also applies for an empty line, which should be printed after the actual header.

The arguments are printed in the order, in which they occur in the argument description list.

This function is a front end to terminal_width and make_usage_info.

See argdesc, desc_description, terminal_width, make_usage_info, usage_info, wrap.

argname Source #

Arguments

:: ArgumentDescription

Argument description, as returned by argdesc

-> String

Printable name for the argument

Generate a descriptive argument name from an argument description, suitable for use in error messages and usage information. 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)".

See argdesc.

argname_a Source #

Arguments

:: ArgumentDescription

Argument description, as returned by argdesc

-> String

Printable name for the argument

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".

See argdesc.

argname_short Source #

Arguments

:: ArgumentDescription

Argument description, as returned by argdesc

-> String

Printable name for the argument

Create a string, which lists the short forms of one command line argument. If it has an subargument, it's name is listed as well. For arguments without short form, the result is the empty string.

For the illegal command line argument, with neither short nor long forms, and not being the direct argument either, the result is "yet unnamed argument". Such argument descriptions are incomplete, and will be rejected by getargs and unsafe_getargs.

This is meant for refering to an argument, such as in error messages or usage information.

Examples:

argname_short (argdesc [ desc_short 'a'
                       , desc_short 'b'
                       , desc_value_required
                       , desc_argname "Name"
                       ])
  == "-a/-b Name"

See argdesc, desc_direct. argname_long.

argname_long Source #

Arguments

:: ArgumentDescription

Argument description, as returned by argdesc

-> String

Printable name for the argument

Create a string, which lists the long forms of one command line argument. If it has an subargument, it's name is listed as well. For arguments without long form, the result is the empty string.

For the illegal command line argument, with neither short nor long forms, and not being the direct argument either, the result is "yet unnamed argument". Such argument descriptions are incomplete, and will be rejected by getargs and unsafe_getargs.

This is meant for refering to an argument, such as in error messages or usage information.

Examples:

argname_long (argdesc [ desc_long "foo"
                      , desc_long "bar"
                      , desc_value_required
                      , desc_argname "Name"
                      ])
  == "--foo/--bar Name"

See argdesc, desc_direct. argname_long.

wrap Source #

Arguments

:: Int

Maximum width for the lines of the text, which is to be broken down

-> String

Text to break down

-> [String]

The broken down text in columns

Break down a text to lines, such that each one has the specified maximum width.

Newline characters in the input text are respected. They terminate the line, without it being filled up to the width.

The text is wrapped at space characters. Words remain intact, except when they are too long for one line.