From 3296c2f6578001f6a40de1b1e1f79b25c987d3af Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 30 Apr 2010 18:56:00 -0400 Subject: [PATCH] Add mode parsing to the CommandLine module. Separate the parse_errors, parse_options, and parse_mode functions. Add a second mode of operation, Reduce (currently echoes its input). --- src/CommandLine.hs | 59 ++++++++++++++++++++++++++++++++++++++-------- src/Main.hs | 17 ++++++++++--- 2 files changed, 63 insertions(+), 13 deletions(-) diff --git a/src/CommandLine.hs b/src/CommandLine.hs index eba70db..51f2028 100644 --- a/src/CommandLine.hs +++ b/src/CommandLine.hs @@ -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) diff --git a/src/Main.hs b/src/Main.hs index 3dfa546..7686ae3 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -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 -- 2.44.2