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