]> gitweb.michael.orlitzky.com - hath.git/blob - src/CommandLine.hs
Add more Haddock comments.
[hath.git] / src / CommandLine.hs
1 -- The CommandLine module handles parsing of the command-line options.
2 -- It should more or less be a black box, providing Main with only the
3 -- information it requires.
4
5 module CommandLine
6 ( help_set,
7 help_text,
8 input_function,
9 Mode(..),
10 parse_errors,
11 parse_mode
12 ) where
13
14 import Data.Char(toLower)
15 import System.Console.GetOpt
16 import System.Environment (getArgs)
17
18
19 -- | Lowercase an entire string.
20 lowercase :: String -> String
21 lowercase = map toLower
22
23
24 -- | The application currently has four modes. The default, Regex,
25 -- will compute a regular expression matching the input
26 -- CIDRs. Reduce, on the other hand, will combine any
27 -- redundant/adjacent CIDR blocks into one. Dupe will show you what
28 -- would be removed by Reduce, and Diff will show both additions and
29 -- deletions in a diff-like format.
30 data Mode = Regex | Reduce | Dupe | Diff
31
32
33 -- | A record containing values for all available options.
34 data Options = Options { opt_help :: Bool,
35 opt_input :: IO String }
36
37
38 -- | This constructs an instance of Options, with each of its members
39 -- set to default values.
40 default_options :: Options
41 default_options = Options { opt_help = False,
42 opt_input = getContents }
43
44
45 -- | The options list that we construct associates a function with
46 -- each option. This function is responsible for updating an Options
47 -- record with the appropriate value.
48 --
49 -- For more information and an example of this idiom, see,
50 --
51 -- http://www.haskell.org/haskellwiki/High-level_option_handling_with_GetOpt
52 --
53 options :: [OptDescr (Options -> IO Options)]
54 options =
55 [ Option ['h']["help"] (NoArg set_help) "Prints this help message.",
56 Option ['i']["input"] (ReqArg set_input "FILE") "Read FILE instead of stdin." ]
57
58 -- | Takes an Options as an argument, and sets its opt_help member to
59 -- True.
60 set_help :: Options -> IO Options
61 set_help opts = do
62 return opts { opt_help = True }
63
64
65 -- | If the input file option is set, this function will update the
66 -- passed Options record with a new function for opt_input. The
67 -- default opt_input is to read from stdin, but if this option is
68 -- set, we replace that with readFile.
69 set_input :: String -> Options -> IO Options
70 set_input arg opts = do
71 return opts { opt_input = readFile arg }
72
73
74 -- | The usage header.
75 usage :: String
76 usage = "Usage: hath [regexed|reduced|duped|diffed] [-h] [-i FILE] <input>"
77
78
79 -- | The usage header, and all available flags (as generated by GetOpt).
80 help_text :: String
81 help_text = usageInfo usage options
82
83
84 -- | Return a list of options.
85 parse_options :: IO Options
86 parse_options = do
87 argv <- getArgs
88 let (actions, _, _) = getOpt Permute options argv
89
90 -- This will execute each of the functions contained in our options
91 -- list, one after another, on a default_options record. The end
92 -- result should be an Options instance with all of its members set
93 -- correctly.
94 opts <- foldl (>>=) (return default_options) actions
95
96 return opts
97
98
99 -- | Return the mode if one was given.
100 parse_mode :: IO Mode
101 parse_mode = do
102 argv <- getArgs
103 let (_, non_options, _) = getOpt Permute options argv
104 if (null non_options)
105 then do
106 -- Default
107 return Regex
108 else do
109 -- Some non-option was given, but were any of them modes?
110 case (lowercase (non_options !! 0)) of
111 "regex" -> return Regex
112 "regexed" -> return Regex
113 "reduce" -> return Reduce
114 "reduced" -> return Reduce
115 "dupe" -> return Dupe
116 "duped" -> return Dupe
117 "diff" -> return Diff
118 "diffed" -> return Diff
119 _ -> return Regex
120
121
122
123
124 -- | Return a list of errors.
125 parse_errors :: IO [String]
126 parse_errors = do
127 argv <- getArgs
128 let (_, _, errors) = getOpt Permute options argv
129 return errors
130
131
132
133 -- | Is the help option set?
134 help_set :: IO Bool
135 help_set = do
136 opts <- parse_options
137 return (opt_help opts)
138
139
140 -- | Return our input function, getContents by default, or readFile if
141 -- the input file option was set.
142 input_function :: IO (IO String)
143 input_function = do
144 opts <- parse_options
145 return (opt_input opts)