]> gitweb.michael.orlitzky.com - hath.git/commitdiff
Add mode parsing to the CommandLine module.
authorMichael Orlitzky <michael@orlitzky.com>
Fri, 30 Apr 2010 22:56:00 +0000 (18:56 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Fri, 30 Apr 2010 22:56:00 +0000 (18:56 -0400)
Separate the parse_errors, parse_options, and parse_mode functions.
Add a second mode of operation, Reduce (currently echoes its input).

src/CommandLine.hs
src/Main.hs

index eba70dbbe87fcbe8fb2b86e0bdaea3ce66663cc1..51f20289fe9adb1c3c28163f92b308389a0eba3d 100644 (file)
@@ -6,17 +6,33 @@ module CommandLine
 ( help_set,
   help_text,
   input_function,
-  parse_errors
+  Mode(..),
+  parse_errors,
+  parse_mode
 ) where
 
+import Data.Char(toLower)
 import System.Console.GetOpt
 import System.Environment (getArgs)
 
 
+-- Dark magic.
+lowercase :: String -> String
+lowercase = map toLower
+
+
+-- The application currently has two modes. The default, Regex, will
+-- compute a regular expression matching the input CIDRs. Reduce, on
+-- the other hand, will combine any redundant/adjacent CIDR blocks
+-- into one.
+data Mode = Regex | Reduce
+
+
 -- A record containing values for all available options.
 data Options = Options { opt_help  :: Bool,
                          opt_input :: IO String }
 
+
 -- This constructs an instance of Options, with each of its members
 -- set to default values.
 default_options :: Options
@@ -43,6 +59,7 @@ set_help :: Options -> IO Options
 set_help opts = do
   return opts { opt_help = True }
 
+
 -- If the input file option is set, this function will update the
 -- passed Options record with a new function for opt_input. The
 -- default opt_input is to read from stdin, but if this option is set,
@@ -51,6 +68,7 @@ set_input :: String -> Options -> IO Options
 set_input arg opts = do
   return opts { opt_input = readFile arg }
 
+
 -- The usage header
 usage :: String
 usage = "Usage: hath [-h] [-i FILE]"
@@ -61,11 +79,11 @@ help_text :: String
 help_text = usageInfo usage options
 
 
--- Return a tuple of options and errors.
-parse_options :: IO (Options, [String])
+-- Return a list of options.
+parse_options :: IO Options
 parse_options = do
   argv <- getArgs
-  let (actions, _, errors) = getOpt Permute options argv
+  let (actions, _, _) = getOpt Permute options argv
 
   -- This will execute each of the functions contained in our options
   -- list, one after another, on a default_options record. The end
@@ -73,20 +91,41 @@ parse_options = do
   -- correctly.
   opts <- foldl (>>=) (return default_options) actions
 
-  return (opts, errors)
+  return opts
 
 
--- Return just the errors from parse_options.
+-- Return the mode if one was given.
+parse_mode :: IO Mode
+parse_mode = do
+  argv <- getArgs
+  let (_, non_options, _) = getOpt Permute options argv
+  if (null non_options)
+    then do
+      -- Default
+      return Regex
+    else do
+      -- Some non-option was given, but were any of them modes?
+      case (lowercase (non_options !! 0)) of
+        "regex"  -> return Regex
+        "reduce" -> return Reduce
+        _        -> return Regex
+
+
+
+
+-- Return a list of errors.
 parse_errors :: IO [String]
 parse_errors = do
-    (_, errors) <- parse_options
-    return errors
+  argv <- getArgs
+  let (_, _, errors) = getOpt Permute options argv
+  return errors
+
 
 
 -- Is the help option set?
 help_set :: IO Bool
 help_set = do
-    (opts, _) <- parse_options
+    opts <- parse_options
     return (opt_help opts)
 
 
@@ -94,5 +133,5 @@ help_set = do
 -- the input file option was set.
 input_function :: IO (IO String)
 input_function = do
-    (opts, _) <- parse_options
+    opts <- parse_options
     return (opt_input opts)
index 3dfa546e374c84b6c86cd2bdce848285d5fd2ea8..7686ae30fb989e0cd3ee51d2dca2ac9e6980629b 100644 (file)
@@ -18,7 +18,9 @@ import Cidr (Cidr,
 import CommandLine (help_set,
                     help_text,
                     input_function,
-                    parse_errors)
+                    Mode(..),
+                    parse_errors,
+                    parse_mode)
 
 -- Some exit codes, used in the ExitFailure constructor.
 exit_invalid_cidr :: Int
@@ -126,8 +128,17 @@ main = do
   -- The input function we receive here should know what to read.
   inputfunc <- (CommandLine.input_function)
   input <- inputfunc
+
   let cidr_strings = lines input
   mapM validate_or_die cidr_strings
   let cidrs = map Cidr.from_string cidr_strings
-  let regexes = map cidr_to_regex cidrs
-  putStrLn $ alternate regexes
+
+  -- Get the mode of operation.
+  mode <- CommandLine.parse_mode
+
+  case mode of
+    Regex -> do
+        let regexes = map cidr_to_regex cidrs
+        putStrLn $ alternate regexes
+    Reduce -> do
+        putStr input