packages feed

HSH 2.0.0 → 2.0.1

raw patch · 3 files changed

+63/−73 lines, 3 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- HSH.ShellEquivs: catBytes :: Int -> (Maybe Integer) -> Handle -> Handle -> IO ()
+ HSH.ShellEquivs: catBytes :: (Maybe Integer) -> Channel -> IO Channel
- HSH.ShellEquivs: catBytesFrom :: Int -> Handle -> (Maybe Integer) -> Handle -> Handle -> IO ()
+ HSH.ShellEquivs: catBytesFrom :: Channel -> (Maybe Integer) -> Channel -> IO Channel
- HSH.ShellEquivs: discard :: Handle -> Handle -> IO ()
+ HSH.ShellEquivs: discard :: Channel -> IO Channel
- HSH.ShellEquivs: tee :: [FilePath] -> ByteString -> IO ByteString
+ HSH.ShellEquivs: tee :: [FilePath] -> Channel -> IO Channel
- HSH.ShellEquivs: teeFIFO :: [FilePath] -> ByteString -> IO ByteString
+ HSH.ShellEquivs: teeFIFO :: [FilePath] -> Channel -> IO Channel

Files

HSH.cabal view
@@ -1,5 +1,5 @@ Name: HSH-Version: 2.0.0+Version: 2.0.1 License: LGPL Maintainer: John Goerzen <jgoerzen@complete.org> Author: John Goerzen
HSH/Channel.hs view
@@ -28,6 +28,7 @@ import qualified Data.ByteString.Lazy as BSL import qualified Data.ByteString as BS import qualified Data.ByteString.Lazy.UTF8 as UTF8+import qualified System.IO.UTF8 as IOUTF8 import System.IO import Control.Concurrent @@ -40,7 +41,7 @@ chanAsString :: Channel -> IO String chanAsString (ChanString s) = return s chanAsString (ChanBSL s) = return . bsl2str $ s-chanAsString (ChanHandle h) = hGetContents h+chanAsString (ChanHandle h) = IOUTF8.hGetContents h  chanAsBSL :: Channel -> IO BSL.ByteString chanAsBSL (ChanString s) = return . str2bsl $ s@@ -54,7 +55,7 @@  {- | Writes the Channel to the given Handle. -} chanToHandle :: Channel -> Handle -> IO ()-chanToHandle (ChanString s) h = hPutStr h s+chanToHandle (ChanString s) h = IOUTF8.hPutStr h s chanToHandle (ChanBSL s) h = BSL.hPut h s chanToHandle (ChanHandle srchdl) desthdl = forkIO copier >> return ()     where copier = do c <- BSL.hGetContents srchdl
HSH/ShellEquivs.hs view
@@ -84,6 +84,7 @@ import Text.Printf (printf) import Control.Monad (foldM) import System.Directory hiding (createDirectory)+import Control.Exception(evaluate) -- import System.FilePath (splitPath)  #ifdef __HSH_POSIX__@@ -136,14 +137,11 @@ {- | Load the specified files and display them, one at a time.  The special file @-@ means to display the input.  If it is not given,-no input is processed (though a small amount may be read into a buffer).--Unlike the shell cat, @-@ may be given twice.  However, if it is, you-will be forcing Haskell to buffer the input.+no input is processed at all. -Note: buffering behavior here is untested. +@-@ may be given a maximum of one time. -See also 'catFromBS', 'catBytes' . -}+See also 'catBytes' . -} catFrom :: [FilePath] -> Channel -> IO Channel catFrom fplist ichan =     do r <- foldM foldfunc BSL.empty fplist@@ -155,53 +153,38 @@                     fn -> do c <- BSL.readFile fn                              return (BSL.append accum c) -{- | Copy data in chunks from stdin to stdout, optionally with a fixed-maximum size.   Uses strict ByteStrings internally.  Uses hSetBuffering-to set the buffering of the input handle to blockbuffering in chunksize-increments as well, but restores original buffering before returning.-See also 'catFrom', 'catBytesFrom' -}-catBytes :: Int                -- ^ Preferred chunk size; data will be read in chunks of this size-          -> (Maybe Integer)    -- ^ Maximum amount of data to transfer-          -> Handle             -- ^ Handle for input-          -> Handle             -- ^ Handle for output-          -> IO ()-catBytes chunksize count hr = catBytesFrom chunksize hr count hr+{- | Copy data from input to output, optionally with a fixed+maximum size, in bytes.  Processes data using ByteStrings internally,+so be aware of any possible UTF-8 conversions. -{- | Generic version of 'catBytes'; reads data from specified Handle, and-ignores stdin. -}+You may wish to use @hSetBuffering h (BlockBuffering Nothing)@ prior to calling+this function for optimal performance. -catBytesFrom :: Int             -- ^ Preferred chunk size; data will be read in chunks of this size-             -> Handle          -- ^ Handle to read from-             -> (Maybe Integer) -- ^ Maximum amount of data to transfer-             -> Handle          -- ^ Handle for input (ignored)-             -> Handle          -- ^ Handle for output-             -> IO ()-catBytesFrom chunksize hr count hignore hw =-    do buf <- hGetBuffering hr-       catBytesFrom' chunksize hr count hignore hw-       hSetBuffering hr buf+See also 'catFrom', 'catBytesFrom' -}+catBytes :: (Maybe Integer)    -- ^ Maximum amount of data to transfer+          -> Channel             -- ^ Handle for input+          -> IO Channel+catBytes count hr = catBytesFrom hr count hr -catBytesFrom' _ _ (Just 0) _ _ = return ()-catBytesFrom' chunksize hr count hignore hw =-    do hSetBuffering hr (BlockBuffering (Just readamount))-       case count of -         Just x -> if x < 1-                      then do fail $ "catBytesFrom: count < 0 not supported"-                      else return ()-         _ -> return ()-       r <- BS.hGet hr readamount-       if BS.null r-          then return ()        -- No more data to read-          else do BS.hPutStr hw r-                  catBytesFrom' chunksize hr (newCount (BS.length r)) hignore hw-    where readamount = -              case count of-                Just x -> fromIntegral $ min x (fromIntegral chunksize)-                Nothing -> (fromIntegral chunksize)-          newCount newlen = case count of-                              Nothing -> Nothing-                              Just x -> Just (x - (fromIntegral newlen))+{- | Generic version of 'catBytes'; reads data from specified Channel, and+ignores stdin.+-} +catBytesFrom :: Channel          -- ^ Handle to read from+             -> (Maybe Integer)  -- ^ Maximum amount of data to transfer+             -> Channel          -- ^ Handle for input (ignored)+             -> IO Channel+catBytesFrom (ChanHandle hr) count cignore =+    case count of+         Nothing -> return (ChanHandle hr)+         Just m -> do c <- BSL.hGet hr (fromIntegral m)+                      return (ChanBSL c)+catBytesFrom cinput count cignore =+    case count of+      Nothing -> return cinput+      Just m -> do r <- chanAsBSL cinput+                   return (ChanBSL (BSL.take (fromIntegral m) r))+ {- | Takes input, writes it to the specified file, and does not pass it on.      The return value is the empty string.  See also 'catToBS',       'catToFIFO' -}@@ -266,13 +249,11 @@ cut pos = cutR [pos]  {- | Read all input and produce no output.  Discards input completely. -}-discard :: Handle -> Handle -> IO ()-discard inh outh =-    do eof <- hIsEOF inh-       if eof-          then return ()-          else do BS.hGet inh 4096-                  discard inh outh+discard :: Channel -> IO Channel+discard inh =+    do c <- chanAsBSL inh+       evaluate (BSL.length c)+       return (ChanString "")  {- | Split a list by a given character and select ranges of the resultant lists. @@ -433,27 +414,30 @@ tac = reverse  {- | Takes input, writes it to all the specified files, and passes it on.-This function does /NOT' buffer input.+This function does /NOT/ buffer input.  See also 'catFrom'. -}-tee :: [FilePath] -> BSL.ByteString -> IO BSL.ByteString+tee :: [FilePath] -> Channel -> IO Channel tee fplist inp = teeBSGeneric (\fp -> openFile fp WriteMode) fplist inp  #ifdef __HSH_POSIX__-{- | FIFO-safe version of 'teeBS'.+{- | FIFO-safe version of 'tee'.  This call will BLOCK all threads on open until a reader connects.  This function is only available on POSIX platforms. -}-teeFIFO :: [FilePath] -> BSL.ByteString -> IO BSL.ByteString+teeFIFO :: [FilePath] -> Channel -> IO Channel teeFIFO fplist inp = teeBSGeneric fifoOpen fplist inp #endif -teeBSGeneric :: (FilePath -> IO Handle) -> [FilePath] -> BSL.ByteString -> IO BSL.ByteString-teeBSGeneric openfunc fplist inp =+teeBSGeneric :: (FilePath -> IO Handle) +             -> [FilePath] +             -> Channel -> IO Channel+teeBSGeneric openfunc fplist ichan =     do handles <- mapM openfunc fplist+       inp <- chanAsBSL ichan        resultChunks <- hProcChunks handles (BSL.toChunks inp)-       return (BSL.fromChunks resultChunks)+       return (ChanBSL $ BSL.fromChunks resultChunks)     where hProcChunks :: [Handle] -> [BS.ByteString] -> IO [BS.ByteString]           hProcChunks handles chunks = unsafeInterleaveIO $               case chunks of@@ -484,23 +468,28 @@ uniq :: String -> String uniq = unlines . nub . lines -{- | Double space a file -}-space, unspace :: [String] -> [String]+{- | Double space a file; add an empty line between each line. -}+space :: [String] -> [String] space = intersperse "" -{- | Inverse of double space; drop empty lines -}+{- | Inverse of double 'space'; drop all empty lines. -}+unspace :: [String] -> [String] unspace = filter (not . null) -{- | Convert a string to all upper or lower case -}-lower, upper :: String -> String+{- | Convert a string to all lower case -}+lower :: String -> String lower = map toLower++{- | Convert a string to all upper case -}+upper :: String -> String upper = map toUpper -{- | Count number of lines.  wc -l -}-wcL, wcW :: [String] -> [String]+{- | Count number of lines.  Like wc -l -}+wcL :: [String] -> [String] wcL inp = [show (genericLength inp :: Integer)]  {- | Count number of words in a file (like wc -w) -}+wcW :: [String] -> [String] wcW inp = [show ((genericLength $ words $ unlines inp) :: Integer)]  {- Utility function.