]> gitweb.michael.orlitzky.com - hath.git/blob - src/CommandLine.hs
Add a --sort flag to hath and document/test why it was needed after all.
[hath.git] / src / CommandLine.hs
1 {-# LANGUAGE DeriveDataTypeable #-}
2
3 -- | The CommandLine module handles parsing of the command-line
4 -- options. It should more or less be a black box, providing Main
5 -- with only the information it requires.
6 --
7 -- Which is why we're allowed all of this unsafe voodoo.
8 --
9 module CommandLine (
10 Args(..),
11 get_args
12 )
13 where
14
15 import System.Console.CmdArgs (
16 Ann,
17 Annotate( (:=) ),
18 Data,
19 (+=),
20 auto,
21 cmdArgs_,
22 def,
23 details,
24 explicit,
25 groupname,
26 help,
27 helpArg,
28 modes_,
29 name,
30 program,
31 record,
32 summary,
33 versionArg )
34
35 -- Get the version from Cabal.
36 import Paths_hath (version)
37 import Data.Version (showVersion)
38
39 -- | The name of our program.
40 program_name :: String
41 program_name = "hath"
42
43 -- | A brief summary; displays the program name and version.
44 my_summary :: String
45 my_summary = program_name ++ "-" ++ (showVersion version)
46
47 barriers_help :: String
48 barriers_help =
49 "(regexed mode) place barriers in front/back of the regex " ++
50 "to prevent e.g. '127.0.0.1' from matching '127.0.0.100'"
51
52 normalize_help :: String
53 normalize_help =
54 "(reduced mode) normalize the output CIDRs, replacing any " ++
55 "masked bits by zeros; e.g. '127.0.0.1/8' -> '127.0.0.0/8'"
56
57
58 sort_help :: String
59 sort_help =
60 "(reduced mode) sort the output CIDRs by their octets"
61
62
63 -- | The Args type represents the possible command-line options. The
64 -- duplication here seems necessary; CmdArgs' magic requires us to
65 -- define some things explicitly.
66 --
67 -- The application currently has five modes (if this number is wrong,
68 -- it means I forgot to update the comment!), all of which take the
69 -- same options and arguments.
70 --
71 data Args =
72 Regexed { barriers :: Bool, normalize :: Bool, sort :: Bool } |
73 Reduced { barriers :: Bool, normalize :: Bool, sort :: Bool } |
74 Duped { barriers :: Bool, normalize :: Bool, sort :: Bool } |
75 Diffed { barriers :: Bool, normalize :: Bool, sort :: Bool } |
76 Listed { barriers :: Bool, normalize :: Bool, sort :: Bool }
77 deriving (Data, Show)
78
79 -- | Description of the 'Regexed' mode.
80 regexed_description :: String
81 regexed_description =
82 "Compute a regular expression matching the input CIDRs."
83
84 -- | Description of the 'Reduced' mode.
85 reduced_description :: String
86 reduced_description =
87 "Combine any redundant/adjacent CIDR blocks into one."
88
89 -- | Description of the 'Duped' mode.
90 duped_description :: String
91 duped_description = "Display what would be removed by 'reduced'."
92
93 -- | Description of the 'Diffed' mode.
94 diffed_description :: String
95 diffed_description =
96 "Display both additions and deletions in a diff-like format."
97
98 -- | Description of the 'Listed' mode.
99 listed_description :: String
100 listed_description =
101 "Enumerate the IP addresses contained within the input CIDRs."
102
103 -- | We use explicit annotation here because if we use the magic
104 -- annotation, we have to duplicate the same argument definitions six
105 -- times.
106 --
107 arg_spec :: Annotate Ann
108 arg_spec =
109 modes_ [regexed += auto, reduced, duped, diffed, listed]
110 += program program_name
111 += summary my_summary
112 += helpArg [explicit,
113 name "help",
114 name "h",
115 groupname "Common flags"]
116 += versionArg [explicit,
117 name "version",
118 name "v",
119 groupname "Common flags"]
120 where
121 make_mode :: (Bool -> Bool -> Bool -> Args) -> String -> (Annotate Ann)
122 make_mode ctor desc =
123 record (ctor def def def)
124 [ barriers := def
125 += groupname "Common flags"
126 += help barriers_help,
127 normalize := def
128 += groupname "Common flags"
129 += help normalize_help,
130 sort := def
131 += groupname "Common flags"
132 += help sort_help ]
133 += details [" " ++ desc]
134
135 regexed = make_mode Regexed regexed_description
136 reduced = make_mode Reduced reduced_description
137 duped = make_mode Duped duped_description
138 diffed = make_mode Diffed diffed_description
139 listed = make_mode Listed listed_description
140
141 -- | This is the public interface; i.e. what main() should use to get
142 -- the command-line arguments.
143 get_args :: IO Args
144 get_args = cmdArgs_ arg_spec