From 2404313e648301064041c12fdab8d2f976c26a64 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 18 Apr 2017 11:50:01 -0400 Subject: [PATCH] Add a --sort flag to hath and document/test why it was needed after all. --- doc/man1/hath.1 | 23 ++++++++++++++++++++++- src/CommandLine.hs | 26 +++++++++++++++++--------- src/Main.hs | 6 ++++-- test/shell/manpage-sort.test | 23 +++++++++++++++++++---- 4 files changed, 62 insertions(+), 16 deletions(-) diff --git a/doc/man1/hath.1 b/doc/man1/hath.1 index 488cebb..69b362f 100644 --- a/doc/man1/hath.1 +++ b/doc/man1/hath.1 @@ -133,7 +133,6 @@ address: .I $ echo x127.0.0.1x | grep -Po $(echo 127.0.0.1/32 | hath -b) x127.0.0.1x .fi - .IP \fB\-\-normalize\fR,\ \fB\-n\fR (reduced mode only) @@ -148,6 +147,28 @@ see CIDRs that you did not input in the first place being removed. .I $ echo 127.0.0.1/8 | hath reduced --normalize 127.0.0.0/8 .fi +.IP \fB\-\-sort\fR,\ \fB\-s\fR +(reduced mode only) + +Sort the output CIDRs numerically by octet. The \(dqsort\(dq utility +doesn't understand IP addresses, so the default pipe-to-sort approach +fails in some cases: + +.nf +.I $ echo \(dq10.0.121.32/28 10.0.93.248/29\(dq | hath reduced | sort +10.0.121.32/28 +10.0.93.248/29 +.I $ echo \(dq10.0.121.32/28 10.0.93.248/29\(dq | hath reduced | sort -n +10.0.121.32/28 +10.0.93.248/29 +.fi + +That failure justifies adding the additional option to hath: + +.nf +.I $ echo \(dq10.0.121.32/28 10.0.93.248/29\(dq | hath reduced --sort +10.0.93.248/29 +10.0.121.32/28 .SH BUGS Send bugs to michael@orlitzky.com. diff --git a/src/CommandLine.hs b/src/CommandLine.hs index 9d409ac..8e6b49c 100644 --- a/src/CommandLine.hs +++ b/src/CommandLine.hs @@ -51,10 +51,15 @@ barriers_help = normalize_help :: String normalize_help = - "(reduced mode) normalize the output CIDRS, replacing any " ++ + "(reduced mode) normalize the output CIDRs, replacing any " ++ "masked bits by zeros; e.g. '127.0.0.1/8' -> '127.0.0.0/8'" +sort_help :: String +sort_help = + "(reduced mode) sort the output CIDRs by their octets" + + -- | The Args type represents the possible command-line options. The -- duplication here seems necessary; CmdArgs' magic requires us to -- define some things explicitly. @@ -64,11 +69,11 @@ normalize_help = -- same options and arguments. -- data Args = - Regexed { barriers :: Bool, normalize :: Bool } | - Reduced { barriers :: Bool, normalize :: Bool } | - Duped { barriers :: Bool, normalize :: Bool } | - Diffed { barriers :: Bool, normalize :: Bool } | - Listed { barriers :: Bool, normalize :: Bool } + Regexed { barriers :: Bool, normalize :: Bool, sort :: Bool } | + Reduced { barriers :: Bool, normalize :: Bool, sort :: Bool } | + Duped { barriers :: Bool, normalize :: Bool, sort :: Bool } | + Diffed { barriers :: Bool, normalize :: Bool, sort :: Bool } | + Listed { barriers :: Bool, normalize :: Bool, sort :: Bool } deriving (Data, Show) -- | Description of the 'Regexed' mode. @@ -113,15 +118,18 @@ arg_spec = name "v", groupname "Common flags"] where - make_mode :: (Bool -> Bool -> Args) -> String -> (Annotate Ann) + make_mode :: (Bool -> Bool -> Bool -> Args) -> String -> (Annotate Ann) make_mode ctor desc = - record (ctor def def) + record (ctor def def def) [ barriers := def += groupname "Common flags" += help barriers_help, normalize := def += groupname "Common flags" - += help normalize_help ] + += help normalize_help, + sort := def + += groupname "Common flags" + += help sort_help ] += details [" " ++ desc] regexed = make_mode Regexed regexed_description diff --git a/src/Main.hs b/src/Main.hs index 0ebfafa..4774c87 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -3,6 +3,7 @@ where import Control.Monad (when) import Data.List ((\\), intercalate) +import qualified Data.List as List (sort) import Data.Maybe (catMaybes, isNothing) import System.Exit (ExitCode( ExitFailure ), exitWith) import System.IO (stderr, hPutStrLn) @@ -22,7 +23,7 @@ import Cidr ( min_octet4 ) import qualified Cidr ( normalize ) import CommandLine( - Args( Regexed, Reduced, Duped, Diffed, Listed, barriers, normalize ), + Args( Regexed, Reduced, Duped, Diffed, Listed, barriers, normalize, sort ), get_args ) import ExitCodes ( exit_invalid_cidr ) import Octet () @@ -130,7 +131,8 @@ main = do Reduced{} -> do -- Pre-normalize all CIDRs if the user asked for it. let nrml_func = if (normalize args) then Cidr.normalize else id - mapM_ print (combine_all (map nrml_func valid_cidrs)) + let sort_func = if (sort args) then List.sort else id :: [Cidr] -> [Cidr] + mapM_ (print . nrml_func) (sort_func $ combine_all valid_cidrs) Duped{} -> mapM_ print dupes where diff --git a/test/shell/manpage-sort.test b/test/shell/manpage-sort.test index 56dd025..845aaed 100644 --- a/test/shell/manpage-sort.test +++ b/test/shell/manpage-sort.test @@ -1,7 +1,22 @@ -# Test the pipe-to-sort example from the man page. +# Test --sort example from the man page. -echo "192.168.0.100/24 192.167.1.200/24" | dist/build/hath/hath reduced | sort +# The default pipe-to-sort doesn't work. +echo "10.0.121.32/28 10.0.93.248/29" | dist/build/hath/hath reduced | sort >>> -192.167.1.200/24 -192.168.0.100/24 +10.0.121.32/28 +10.0.93.248/29 +>>>= 0 + +# Neither does a numeric sort. +echo "10.0.121.32/28 10.0.93.248/29" | dist/build/hath/hath reduced | sort -n +>>> +10.0.121.32/28 +10.0.93.248/29 +>>>= 0 + +# But the CIDR sort order does. +echo "10.0.121.32/28 10.0.93.248/29" | dist/build/hath/hath reduced --sort +>>> +10.0.93.248/29 +10.0.121.32/28 >>>= 0 -- 2.43.2