packages feed

eddie 0.1 → 0.2

raw patch · 3 files changed

+53/−30 lines, 3 files

Files

eddie.cabal view
@@ -1,5 +1,5 @@ Name:                eddie-Version:             0.1+Version:             0.2 Synopsis:	     Command line file filtering with haskell Description:	     A tool to let you use short haskell expressions to filter 		     files at the command line.
eddie.hs view
@@ -3,24 +3,32 @@ -- import Data.ByteString.Lazy (readFile) import Language.Haskell.Interpreter   (setImportsQ, interpret, runInterpreter, as, MonadInterpreter)-import Data.List (intercalate) import Data.IORef (newIORef, readIORef, writeIORef) import System.Environment (getArgs, getProgName)-import System.IO (openFile, hClose, stdin, IOMode (ReadMode), hIsEOF, hGetChar, withFile)+import System.IO (openFile, openBinaryFile, hClose, stdin, IOMode (ReadMode), +                  hIsEOF, hGetChar, Handle, hSetBinaryMode, stdout) import System.IO.Unsafe (unsafeInterleaveIO) import System.Console.CmdArgs.Implicit   (cmdArgs, (&=), Data, Typeable, help, explicit, name, args, summary, program,    details) import Control.Exception (finally, evaluate)+import Control.Monad     (when)  main = do-  myname <- getProgName-  opts <- cmdArgs (eddie &= program myname)-  let opts' = parseOpts opts-  fun <- runInterpreter $ makeFun opts'-  case fun of-    Left e -> putStrLn $ myname ++ ": Error: " ++ show e-    Right f -> withFiles  (files opts') (putStrLn . f)+  myName <- getProgName+  opts <- cmdArgs (eddie &= program myName)+  case parseOpts opts of+    Left e -> putStrLn $ "usage: " ++ myName ++ " " ++ e+    Right o -> runIt myName o+      where runIt name opts = do+              fun <- runInterpreter $ makeFun opts+              let opener = if binary opts then openBinaryFile else openFile+              let outputFunction = if binary opts then putStr else putStrLn+              when (binary opts) $+                hSetBinaryMode stdout True+              case fun of+                Left e -> putStrLn $ name ++ ": Error: " ++ show e+                Right f -> withFiles (files opts) opener (outputFunction . f)  makeFun :: MonadInterpreter m => Eddie -> m (String->String) makeFun opts = do@@ -30,13 +38,15 @@  -- an even lazier version of  withFile (courtesy of Heinrich Apfelmus) -- Tweaked by mwm so withFiles uses stdin if [FilePath] is an empty list-withFile' :: Maybe FilePath -> (String -> IO a) -> IO a-withFile' name f = do+-- Further tweaked by mwm to allow caller to specify opening function.+withFile' :: Maybe FilePath -> (FilePath -> IOMode -> IO Handle) ->+             (String -> IO a) -> IO a+withFile' name opener f = do     fin <- newIORef (return ())     let         close = readIORef fin >>= id         open  = do-          h <- maybe (return stdin) (flip openFile ReadMode) name+          h <- maybe (return stdin) (flip opener ReadMode) name           writeIORef fin (hClose h)           lazyRead h     finally (unsafeInterleaveIO open >>= f >>= evaluate) close@@ -51,33 +61,45 @@                 return (c:cs)  -withFiles :: [FilePath] -> (String -> IO a) -> IO a-withFiles []     f = withFile' Nothing f-withFiles [x]    f = withFile' (Just x) f-withFiles (x:xs) f = withFile' (Just x) $ \s ->-    let f' t = f (s ++ t) in withFiles xs f'+withFiles :: [FilePath] -> (FilePath -> IOMode -> IO Handle) -> +             (String -> IO a) -> IO a+withFiles []     o f = withFile' Nothing o f+withFiles [x]    o f = withFile' (Just x) o f+withFiles (x:xs) o f = withFile' (Just x) o $ \s ->+    let f' t = f (s ++ t) in withFiles xs o f'   -- argument processing data Eddie = Eddie { line :: Bool,+                     binary :: Bool,                      expr :: [String],                      files :: [String],                      modules :: [String],                      asModules :: [(String, Maybe String)]                    } deriving (Show, Data, Typeable) -parseOpts :: Eddie -> Eddie-parseOpts opts = opts {expr = [e], asModules = mods, files = fs' }-  where es = expr opts-        fs = files opts-        e:fs' = if null es then fs else intercalate "\n" es:fs-        mods = zip (modules opts) (repeat Nothing) ++ asModules opts+parseOpts :: Eddie -> Either String Eddie+parseOpts opts = +  let es = expr opts+      fs = files opts+      e:fs' = case (es, fs) of+        ([], []) -> [""]+        ([], _) -> fs+        (_, _) -> unlines es:fs+      mods = zip (modules opts) (repeat Nothing) ++ asModules opts+  in+   if e == "" then Left $ unlines ["[options] (-e expr | expr) [files ...]",+                                   "--help for options"]+   else Right $ opts {expr = [e], asModules = mods, files = fs' }+    -eddie = Eddie {line = False &= help "Process line at a time.",-               expr = [] &= help "Line of expression to evaluate.",+eddie = Eddie {line = False &= help "Process one line at a time",+               binary = False &= help "Process a binary file",+               expr = [] &= help "Line of expression to evaluate",                modules = ["Prelude", "Data.List", "Data.Char"]-                         &= help "Modules to import for expr.",-               asModules = [] &= help "Modules to import qualified." &= explicit+                         &= help "Modules to import for expr",+               asModules = [] &= help "Modules to import qualified" &= explicit                            &= name "M" &= name "Modules",                files = [] &= args} -        &= summary "eddie 0.1" &= details ["Haskell for shell scripts."]+        &= summary "eddie 0.2" &= details ["Haskell for shell scripts."]+ 
test.sh view
@@ -22,12 +22,13 @@ }         FAILED="no"+test "" "echo 'usage: eddie.hs [options] (-e expr | expr) [files ...]'; echo '--help for options'" "No arguments test" test "show.length" "wc -c | xargs echo" "simple char count" test "show.length.lines" "wc -l | xargs echo" "line count" test "show.length.words" "wc -w | xargs echo " "word count" test "-e show.length" "wc -c | xargs echo" "test -e option" test "-e 'let taker = take 10 in' -e unlines.taker.lines" head "double -e option test"-test "-l reverse /etc/motd" "rev eddie.hs" "test -l option" X+test "-l reverse" "rev eddie.hs" "test -l option" X test "-m Text.Printf 'unlines . (zipWith (printf \"%6d\t%s\") [(1::Int) ..]) . lines'" 'cat -n' 'test -m option' X test "-M Text.Printf,P 'unlines . (zipWith (P.printf \"%6d\t%s\") [(1::Int) ..]) . lines'" 'cat -n' 'test -M option' X echo -e