summaryrefslogtreecommitdiff
path: root/ghc/docs/libraries/GetOpt.sgml
blob: 2aed0d895789e94d61ee6306a575062aeaf3c4f1 (plain)
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
94
95
96
<sect> <idx/GetOpt/
<label id="sec:GetOpt">
<p>

The <tt/GetOpt/ library contains Sven Panne's Haskell implementation
of <tt/getopt/, providing features nigh-on identical to GNU <tt/getopt/:

<tscreen><verb>
module GetOpt where

-- representing a single option:
data OptDescr a
 = Option [Char]         --    list of short option characters
          [String]       --    list of long option strings (without "--")
          (ArgDescr a)   --    argument descriptor
          String         --    explanation of option for user

-- argument option:
data ArgDescr a
   = NoArg                   a         --    no argument expected
   | ReqArg (String       -> a) String --    option requires argument
   | OptArg (Maybe String -> a) String --    optional argument

usageInfo :: String          -- header
          -> [OptDescr a]    -- options recognised 
          -> String          -- nicely formatted decription of options

getOpt :: ArgOrder a    -- non-option handling
       -> [OptDescr a]  -- options recognised
       -> [String]      -- the command-line
       -> ( [a]         -- options
          , [String]    -- non-options
	  ,[String]     -- error messages
	  )

data ArgOrder a
  = RequireOrder
  | Permute
  | ReturnInOrder (String -> a)

</verb></tscreen>

<itemize>
<item> The command-line options recognised is described by a list of
<tt/OptDescr/ values. The <tt/OptDescr/ describes the long and short
strings that recognise the option, together with a help string and
info on whether the option takes extra arguments, if any.
<item>
From a list of option values, <tt/usageInfo/ returns a nicely
formatted string that enumerates the different options supported
together with a short message about what
<item>
To decode a command-line with respect to a list of options,
<tt/getOpt/ is used. It processes the command-line, and returns
the list of values that matched (and those that didn't). The first
argument to <tt/getOpt/ controls whether the user is to give the
options in any old order or not.
</itemize>

To hopefully illuminate the role of the different <tt/GetOpt/ data
structures, here's the command-line options for a (very simple)
compiler:

<tscreen><verb>
module Opts where

import GetOpt
import Maybe ( fromMaybe )

data Flag 
 = Verbose  | Version 
 | Input String | Output String | LibDir String
   deriving Show

options :: [OptDescr Flag]
options =
 [ Option ['v']     ["verbose"] (NoArg Verbose)       "chatty output on stderr"
 , Option ['V','?'] ["version"] (NoArg Version)       "show version number"
 , Option ['o']     ["output"]  (OptArg outp "FILE")  "output FILE"
 , Option ['c']     []          (OptArg inp  "FILE")  "input FILE"
 , Option ['L']     ["libdir"]  (ReqArg LibDir "DIR") "library directory"
 ]

inp,outp :: Maybe String -> Flag
outp = Output . fromMaybe "stdout"
inp  = Input  . fromMaybe "stdout"

compilerOpts :: [String] -> IO ([Flag], [String])
compilerOpts argv = 
   case (getOpt Permute options argv) of
      (o,n,[]  ) -> return (o,n)
      (_,_,errs) -> fail (userError (concat errs ++ usageInfo header options))
  where header = "Usage: ic [OPTION...] files..."
</verb></tscreen>