packages feed

eddie (empty) → 0.1

raw patch · 6 files changed

+280/−0 lines, 6 filesdep +basedep +cmdargsdep +hintsetup-changed

Dependencies added: base, cmdargs, hint

Files

+ LICENSE view
@@ -0,0 +1,26 @@+Copyright (c) 2011 Mike Meyer++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+   notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+   notice, this list of conditions and the following disclaimer in the+   documentation and/or other materials provided with the distribution.++THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.++The views and conclusions contained in the software and documentation are+those of the authors and should not be interpreted as representing official+policies, either expressed or implied, of Mike Meyer.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ eddie.1 view
@@ -0,0 +1,105 @@+.TH eddie 1+.SH NAME+eddie \- run haskell filters from the command line+.SH SYNOPSYS+.B eddie +[+.I options+]+[+.I expr+]+.I file ...+.SH DESCRIPTION+.B eddie+evalutes the provided+.I expression+on either the contents of the+.I file+arguments concatenated together,+or standard input if no file arguments are present.+.PP+If the+.B \-l+option is used, the +.I expression+is used to process each line instead of the entire contents.+.PP+The prelude, Data.List and Data.Char modules are available for building+expressions. Other modules may be added with the+.B \-M+and+.B \-m+options.+.SH OPTIONS+.IP \-e+The+.BI \-e\  expr+(long form+.BI \-\-expr\  expr)+option concatenates it's value to the+haskell expression being evaluated with a newline separator.+Multiple occurrences can be used to build up a+multi-line expression.+.IP ""+If no+.BI \-e\  expr+option is present, the first non-flag argument will be used for+the haskell expression.+.IP \-l+The+.B \-l+(long form+.B \-\-line+)+option causes+.B eddie+to process input line at a time. The+.I expr+will be run on each line and the results concatenated together.+.RS+.PP+The command+.RS+.PP+.B eddie \-l+.I expr file ...+.RE+.PP+is equivalent to the command+.RS+.PP+.B eddie+"unlines . map+.I expr+\&. lines"+.I file ...+.+.RE 1+.IP \-m+The+.BI \-m name+(long form+.BI \-\-module name+)+option is used to import module+.I name+into haskell before evaluating the expression.+.IP \-M+The+.BI \-M name,as+(long form+.BI \-\-Modules name,as+)+option imports the+.I name+module using a qualified import with an as clause,+with +.I as+being the value for the as clause.+.SH SEE ALSO+The wiki at <http://code.google.com/p/eddie/w/list> for examples.+.SH BUGS+See the issues list at <http://code.google.com/p/eddie/issues/list>.+.SH AUTHOR+Mike Meyer (mwm@mired.org)
+ eddie.cabal view
@@ -0,0 +1,23 @@+Name:                eddie+Version:             0.1+Synopsis:	     Command line file filtering with haskell+Description:	     A tool to let you use short haskell expressions to filter+		     files at the command line.+Category:	     CLI tool+License:             BSD3+License-file:	     LICENSE+Author:              Mike Meyer+Copyright:	     (c) 2011 Mike Meyer+Maintainer:          mwm@mired.org+Build-type:          Simple+Homepage:	     http://eddie.googlecode.com/+Cabal-version:       >=1.8+Extra-source-files:  test.sh eddie.1++Executable eddie+    Main-is:         eddie.hs+    Build-Depends:   hint >= 0.3.3.2, base >= 4.3.1 && < 5, cmdargs >= 0.7++Source-repository head+    Type: hg+    Location: http://eddie.googlecode.com/hg/
+ eddie.hs view
@@ -0,0 +1,83 @@+{-# LANGUAGE DeriveDataTypeable #-}++-- 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.Unsafe (unsafeInterleaveIO)+import System.Console.CmdArgs.Implicit+  (cmdArgs, (&=), Data, Typeable, help, explicit, name, args, summary, program,+   details)+import Control.Exception (finally, evaluate)++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)++makeFun :: MonadInterpreter m => Eddie -> m (String->String)+makeFun opts = do+  setImportsQ (asModules opts)+  fun <- interpret (head (expr opts)) (as :: String -> String)+  return $ if line opts then unlines . map fun . lines else fun++-- 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+    fin <- newIORef (return ())+    let+        close = readIORef fin >>= id+        open  = do+          h <- maybe (return stdin) (flip openFile ReadMode) name+          writeIORef fin (hClose h)+          lazyRead h+    finally (unsafeInterleaveIO open >>= f >>= evaluate) close++    where+    lazyRead h = hIsEOF h >>= \b ->+        if b+            then do hClose h; return []+            else do+                c  <- hGetChar h+                cs <- unsafeInterleaveIO $ lazyRead h+                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'+++-- argument processing+data Eddie = Eddie { line :: 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+   +eddie = Eddie {line = False &= help "Process line at a time.",+               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+                           &= name "M" &= name "Modules",+               files = [] &= args} +        &= summary "eddie 0.1" &= details ["Haskell for shell scripts."]
+ test.sh view
@@ -0,0 +1,41 @@+#!/bin/sh++# $1 is args to use with eddie.hs to process a file, $2 is a shell command to+# run the same process. Run them both on our test file.+# If the outputs differ, report failure of $3, including output unless $4+# is present.+test () {+   TEST=$(eval runghc eddie.hs $1 < eddie.hs)+   EXPECTED=$(eval "cat eddie.hs | $2")+   if [ "$EXPECTED" != "$TEST" ]+   then+       FAILED="yes"+       echo -e+       if [ -n "$4" ]+       then+	   echo $3 failed "(output supressed)"+       else+	   echo $3 failed: expected $EXPECTED, got $TEST+       fi+   fi+   echo -n .+}       ++FAILED="no"+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 "-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++if [ $FAILED = "yes" ]+then+    exit 1+else+    exit 0+fi+