-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Large utility library -- -- MissingH is a library of all sorts of utility functions for Haskell -- programmers. It is written in pure Haskell and thus should be -- extremely portable and easy to use. @package MissingH @version 1.0.0 -- | Written by John Goerzen, jgoerzen@complete.org -- -- Utilities for command-line parsing, including wrappers around the -- standard System.Console.GetOpt module. module System.Console.GetOpt.Utils -- | Simple command line parser -- a basic wrapper around the system's -- default getOpt. See the System.Console.GetOpt manual for a description -- of the first two parameters. -- -- The third parameter is a usage information header. -- -- The return value consists of the list of parsed flags and a list of -- non-option arguments. parseCmdLine :: ArgOrder a -> [OptDescr a] -> String -> IO ([a], [String]) -- | Similar to parseCmdLine, but takes an additional function that -- validates the post-parse command-line arguments. This is useful, for -- example, in situations where there are two arguments that are -- mutually-exclusive and only one may legitimately be given at a time. -- -- The return value of the function indicates whether or not it detected -- an error condition. If it returns Nothing, there is no error. If it -- returns Just String, there was an error, described by the String. validateCmdLine :: ArgOrder a -> [OptDescr a] -> String -> (([a], [String]) -> Maybe String) -> IO ([a], [String]) -- | A type to standardize some common uses of GetOpt. -- -- The first component of the tuple is the long name of the option. -- -- The second component is empty if there is no arg, or has the arg -- otherwise. type StdOption = (String, String) -- | Handle a required argument. stdRequired :: String -> String -> StdOption -- | Handle an optional argument. stdOptional :: String -> Maybe String -> StdOption -- | This module provides various helpful utilities for dealing with Debian -- files and programs. -- -- Written by John Goerzen, jgoerzen@complete.org module System.Debian -- | The type representing the contents of a Debian control file, or any -- control-like file (such as the output from apt-cache show, etc.) type ControlFile = [(String, String)] -- | The type representing a Debian version number. This type is an -- instance of Ord, but you can also use compareDebVersion -- if you prefer. data DebVersion -- | Compare the versions of two packages. compareDebVersion :: String -> String -> IO Ordering checkDebVersion :: String -> String -> String -> IO Bool instance [overlap ok] Eq DebVersion instance [overlap ok] Ord DebVersion -- | Provides some types and related items on Windows to be compatible with -- the System.Posix.* libraries -- -- See also System.IO.StatCompat, which this module re-exports. -- -- Copyright (c) 2005 John Goerzen, jgoerzen@complete.org -- -- On non-Windows platforms, this module does nothing. -- -- On Windows, it re-exports System.IO.StatCompat. It also -- provides various file type information modes that are otherwise in -- System.Posix.Types or System.Posix.Files. It also -- provides a rudimentary implemention of getFileStatus that emulates the -- Posix call to stat(2). -- -- Common usage might be like this: -- --
--   import System.Posix.Types
--   #ifdef mingw32_HOST_OS
--   import System.IO.WindowsCompat
--   #else
--   import System.Posix.Files
--   #endif
--   
-- -- Or, to avoid having to use CPP and make things even easier, just -- import System.IO.PlafCompat, which essentially does the above. module System.IO.WindowsCompat -- | Exports some POSIX constants and functions that are not exported in -- fptools by default. module System.Posix.Consts blockSpecialMode :: FileMode characterSpecialMode :: FileMode namedPipeMode :: FileMode regularFileMode :: FileMode directoryMode :: FileMode fileTypeModes :: FileMode socketMode :: FileMode symbolicLinkMode :: FileMode -- | Provide a stat-like structure for use in MissingH. Especially useful -- with HVFS and on Windows. See also System.IO.WindowsCompat. -- -- Copyright (c) 2005-2006 John Goerzen, jgoerzen@complete.org module System.IO.StatCompat data FileStatusCompat FileStatusCompat :: DeviceID -> FileID -> FileMode -> LinkCount -> UserID -> GroupID -> DeviceID -> FileOffset -> EpochTime -> EpochTime -> EpochTime -> FileStatusCompat deviceID :: FileStatusCompat -> DeviceID fileID :: FileStatusCompat -> FileID fileMode :: FileStatusCompat -> FileMode linkCount :: FileStatusCompat -> LinkCount fileOwner :: FileStatusCompat -> UserID fileGroup :: FileStatusCompat -> GroupID specialDeviceID :: FileStatusCompat -> DeviceID fileSize :: FileStatusCompat -> FileOffset accessTime :: FileStatusCompat -> EpochTime modificationTime :: FileStatusCompat -> EpochTime statusChangeTime :: FileStatusCompat -> EpochTime sc_helper :: FileMode -> FileStatusCompat -> Bool isCharacterDevice :: FileStatusCompat -> Bool isNamedPipe :: FileStatusCompat -> Bool isRegularFile :: FileStatusCompat -> Bool isDirectory :: FileStatusCompat -> Bool isSymbolicLink :: FileStatusCompat -> Bool isSocket :: FileStatusCompat -> Bool isBlockDevice :: FileStatusCompat -> Bool -- | On Unix, exports System.Posix.Types and System.Posix.Files. -- -- On Windows, exports System.Posix.Types and -- System.IO.WindowsCompat. -- -- The result should be roughly the same set of defined variables and -- types. module System.IO.PlafCompat -- | The name of the null device. NUL: on Windows, /dev/null everywhere -- else. nullFileName :: String -- | Maintainer : igloo@earth.li Stability : provisional -- Portability: portable -- -- Inflate algorithm implementation -- -- Copyright (C) 2004 Ian Lynagh module Data.Compression.Inflate inflate_string :: String -> String -- | Returns (Data, Remainder) inflate_string_remainder :: String -> (String, String) inflate :: [Int] -> (Output, [Bit]) type Output = [Word32] data Bit bits_to_word32 :: [Bit] -> Word32 instance [overlap ok] Eq Bit instance [overlap ok] Monad InfM instance [overlap ok] Show Bit module Data.Hash.MD5.Zord64_HARD data Zord64 instance [overlap ok] Eq Zord64 instance [overlap ok] Ord Zord64 instance [overlap ok] Bounded Zord64 instance [overlap ok] Enum Zord64 instance [overlap ok] Real Zord64 instance [overlap ok] Integral Zord64 instance [overlap ok] Bits Zord64 instance [overlap ok] Num Zord64 instance [overlap ok] Read Zord64 instance [overlap ok] Show Zord64 -- | Generation of MD5sums -- -- Written by Ian Lynagh, igloo@earth.li module Data.Hash.MD5 -- | The simplest function, gives you the MD5 of a string as 4-tuple of -- 32bit words. md5 :: (MD5 a) => a -> ABCD -- | Returns a hex number ala the md5sum program. md5s :: (MD5 a) => a -> String -- | Returns an integer equivalent to hex number from md5s. md5i :: (MD5 a) => a -> Integer -- | Anything we want to work out the MD5 of must be an instance of class -- MD5 class MD5 a get_next :: (MD5 a) => a -> ([Word32], Int, a) len_pad :: (MD5 a) => Zord64 -> a -> a finished :: (MD5 a) => a -> Bool newtype ABCD ABCD :: (Word32, Word32, Word32, Word32) -> ABCD type Zord64 = Word64 newtype Str Str :: String -> Str newtype BoolList BoolList :: [Bool] -> BoolList newtype WordList WordList :: ([Word32], Zord64) -> WordList instance [overlap ok] Eq ABCD instance [overlap ok] Show ABCD instance [overlap ok] Num ABCD instance [overlap ok] MD5 WordList instance [overlap ok] MD5 Str instance [overlap ok] MD5 BoolList -- | CRC32 checksumming using the GZIP/PKZIP algorithm as used in both ISO -- 3309 and section 8.1.1.6.2 of ITU-T V.42 and referenced in RFC1952. -- -- Copyright (c) 2004 John Goerzen, jgoerzen@complete.org module Data.Hash.CRC32.GZip update_crc :: Word32 -> Char -> Word32 update_crc_list :: Word32 -> [Char] -> Word32 calc_crc32 :: [Char] -> Word32 gzipcrctab :: Array Int Word32 -- | CRC32 checksumming using POSIX 1003.2-1992 algorithm for the -- polynomial { 32 26 23 22 16 12 11 10 8 7 5 4 2 1 }, also defined in -- ISO 8802-3: 1989. -- -- Copyright (c) 2002 HardCore SoftWare, Doug Hoyte module Data.Hash.CRC32.Posix iter_crc32 :: Word32 -> Char -> Word32 calc_crc32 :: [Char] -> Word32 -> Word32 -> Word32 crc32 :: [Char] -> Word32 crctab :: Array Int Word32 -- | Bit-related utilities -- -- Written by John Goerzen, jgoerzen@complete.org module Data.Bits.Utils -- | Returns a list representing the bytes that comprise a data type. -- -- Example: -- --
--   getBytes (0x12345678::Int) -> [0x12, 0x34, 0x56, 0x78]
--   
getBytes :: (Integral a, Bounded a, Bits a) => a -> [a] -- | The opposite of getBytes, this function builds a number based -- on its component bytes. -- -- Results are undefined if any components of the input list are > -- 0xff! fromBytes :: (Bits a) => [a] -> a -- | Converts a Char to a Word8. c2w8 :: Char -> Word8 -- | Converts a String to a [Word8]. s2w8 :: String -> [Word8] -- | Converts a Word8 to a Char. w82c :: Word8 -> Char -- | Converts a [Word8] to a String. w82s :: [Word8] -> String -- | GZip file decompression -- -- Copyright (c) 2004 John Goerzen, jgoerzen@complete.org -- -- The GZip format is described in RFC1952. module System.FileArchive.GZip -- | The data structure representing the GZip header. This occurs at the -- beginning of each Section on disk. data Header Header :: Int -> Int -> Maybe String -> Maybe String -> Maybe String -> Word32 -> Int -> Int -> Header -- | Compression method. Only 8 is defined at present. method :: Header -> Int flags :: Header -> Int extra :: Header -> Maybe String filename :: Header -> Maybe String comment :: Header -> Maybe String -- | Modification time of the original file mtime :: Header -> Word32 -- | Extra flags xfl :: Header -> Int -- | Creating operating system os :: Header -> Int -- | A section represents a compressed component in a GZip file. Every GZip -- file has at least one. type Section = (Header, String, Footer) data GZipError -- | CRC-32 check failed CRCError :: GZipError -- | Couldn't find a GZip header NotGZIPFile :: GZipError -- | Compressed with something other than method 8 (deflate) UnknownMethod :: GZipError -- | Other problem arose UnknownError :: String -> GZipError -- | Stored on-disk at the end of each section. data Footer Footer :: Word32 -> Word32 -> Bool -> Footer -- | The size of the original, decompressed data size :: Footer -> Word32 -- | The stored GZip CRC-32 of the original, decompressed data crc32 :: Footer -> Word32 -- | Whether or not the stored CRC-32 matches the calculated CRC-32 of the -- data crc32valid :: Footer -> Bool -- | Read a GZip file, decompressing all sections that are found. -- -- Returns a decompresed data stream and Nothing, or an unreliable string -- and Just (error). If you get anything other than Nothing, the String -- returned should be discarded. decompress :: String -> (String, Maybe GZipError) -- | Read a GZip file, decompressing all sections found. -- -- Writes the decompressed data stream to the given output handle. -- -- Returns Nothing if the action was successful, or Just GZipError if -- there was a problem. If there was a problem, the data written to the -- output handle should be discarded. hDecompress :: Handle -> Handle -> IO (Maybe GZipError) -- | Read all sections. read_sections :: String -> Either GZipError [Section] -- | Read the GZip header. Return (Header, Remainder). read_header :: String -> Either GZipError (Header, String) -- | Read one section, returning (ThisSection, Remainder) read_section :: String -> Either GZipError (Section, String) instance [overlap ok] Eq Header instance [overlap ok] Show Header instance [overlap ok] Eq GZipError instance [overlap ok] Show GZipError instance [overlap ok] Error GZipError -- | This module provides various helpful utilities for dealing with lists. -- -- Written by Neil Mitchell, http://www.cs.york.ac.uk/~ndm/ module Data.Tuple.Utils -- | Take the first item out of a 3 element tuple fst3 :: (a, b, c) -> a -- | Take the second item out of a 3 element tuple snd3 :: (a, b, c) -> b -- | Take the third item out of a 3 element tuple thd3 :: (a, b, c) -> c -- | Utilities for working with the Either data type -- -- Copyright (c) 2004 John Goerzen, jgoerzen@complete.org module Data.Maybe.Utils -- | Pulls a Just value out of a Maybe value. If the Maybe value is -- Nothing, raises an exception with error. forceMaybe :: Maybe a -> a -- | Like forceMaybe, but lets you customize the error message -- raised if Nothing is supplied. forceMaybeMsg :: String -> Maybe a -> a -- | Utilities for working with the Either data type -- -- Copyright (c) 2004 John Goerzen, jgoerzen@complete.org module Data.Either.Utils -- | Converts a Maybe value to an Either value, using the supplied -- parameter as the Left value if the Maybe is Nothing. -- -- This function can be interpreted as: -- --
--   maybeToEither :: e -> Maybe a -> Either e a
--   
-- -- Its definition is given as it is so that it can be used in the Error -- and related monads. maybeToEither :: (MonadError e m) => e -> Maybe a -> m a -- | Pulls a Right value out of an Either value. If the Either value -- is Left, raises an exception with error. forceEither :: (Show e) => Either e a -> a -- | Like forceEither, but can raise a specific message with the -- error. forceEitherMsg :: (Show e) => String -> Either e a -> a -- | Takes an either and transforms it into something of the more generic -- MonadError class. eitherToMonadError :: (MonadError e m) => Either e a -> m a -- | Take a Left to a value, crashes on a Right fromLeft :: Either a b -> a -- | Take a Right to a value, crashes on a Left fromRight :: Either a b -> b -- | Take an Either, and return the value inside it fromEither :: Either a a -> a -- | This module provides various helpful utilities for dealing with -- networking -- -- Written by John Goerzen, jgoerzen@complete.org module Network.Utils -- | Sets up the system for networking. Similar to the built-in -- withSocketsDo (and actually, calls it), but also sets the SIGPIPE -- handler so that signal is ignored. -- -- Example: -- --
--   main = niceSocketsDo $ do { ... }
--   
niceSocketsDo :: IO a -> IO a connectTCP :: HostName -> PortNumber -> IO Socket connectTCPAddr :: SockAddr -> IO Socket listenTCPAddr :: SockAddr -> Int -> IO Socket showSockAddr :: SockAddr -> IO String -- | This module provides an infrastructure to simplify server design. -- -- Written by John Goerzen, jgoerzen@complete.org -- -- Please note: this module is designed to work with TCP, UDP, and Unix -- domain sockets, but only TCP sockets have been tested to date. -- -- This module is presently under-documented. For an example of usage, -- please see the description of Network.FTP.Server. module Network.SocketServer -- | Options for your server. data InetServerOptions InetServerOptions :: Int -> PortNumber -> HostAddress -> Bool -> Family -> SocketType -> String -> InetServerOptions listenQueueSize :: InetServerOptions -> Int portNumber :: InetServerOptions -> PortNumber interface :: InetServerOptions -> HostAddress reuse :: InetServerOptions -> Bool family :: InetServerOptions -> Family sockType :: InetServerOptions -> SocketType protoStr :: InetServerOptions -> String -- | Get Default options. You can always modify it later. simpleTCPOptions :: Int -> InetServerOptions data SocketServer SocketServer :: InetServerOptions -> Socket -> SocketServer optionsSS :: SocketServer -> InetServerOptions sockSS :: SocketServer -> Socket -- | The main handler type. -- -- The first parameter is the socket itself. -- -- The second is the address of the remote endpoint. -- -- The third is the address of the local endpoint. type HandlerT = Socket -> SockAddr -> SockAddr -> IO () -- | Convenience function to completely set up a TCP SocketServer -- and handle all incoming requests. -- -- This function is literally this: -- --
--   serveTCPforever options func =
--       do sockserv <- setupSocketServer options
--          serveForever sockserv func
--   
serveTCPforever :: InetServerOptions -> HandlerT -> IO () -- | Takes some options and sets up the SocketServer. I will bind -- and begin listening, but will not accept any connections itself. setupSocketServer :: InetServerOptions -> IO SocketServer -- | Handle one incoming request from the given SocketServer. handleOne :: SocketServer -> HandlerT -> IO () -- | Handle all incoming requests from the given SocketServer. serveForever :: SocketServer -> HandlerT -> IO () -- | Close the socket server. Does not terminate active handlers, if any. closeSocketServer :: SocketServer -> IO () -- | Log each incoming connection using the interface in -- System.Log.Logger. -- -- Log when the incoming connection disconnects. -- -- Also, log any failures that may occur in the child handler. loggingHandler :: String -> Priority -> HandlerT -> HandlerT -- | Handle each incoming connection in its own thread to make the server -- multi-tasking. threadedHandler :: HandlerT -> HandlerT -- | Give your handler function a Handle instead of a Socket. -- -- The Handle will be opened with ReadWriteMode (you use one handle for -- both directions of the Socket). Also, it will be initialized with -- LineBuffering. -- -- Unlike other handlers, the handle will be closed when the function -- returns. Therefore, if you are doing threading, you should to it -- before you call this handler. handleHandler :: (Handle -> SockAddr -> SockAddr -> IO ()) -> HandlerT instance [overlap ok] Eq SocketServer instance [overlap ok] Show SocketServer instance [overlap ok] Eq InetServerOptions instance [overlap ok] Show InetServerOptions -- | Utility for parsing dates. module System.Time.ParseDate -- | Parse a date string as formatted by formatCalendarTime. -- -- The resulting CalendarTime will only have those fields set that -- are represented by a format specifier in the format string, and those -- fields will be set to the values given in the date string. If the same -- field is specified multiple times, the rightmost occurence takes -- precedence. -- -- The resulting date is not neccessarily a valid date. For example, if -- there is no day of the week specifier in the format string, the value -- of ctWDay will most likely be invalid. -- -- Format specifiers are % followed by some character. All other -- characters are treated literally. Whitespace in the format string -- matches zero or more arbitrary whitespace characters. -- -- Format specifiers marked with * are matched, but do not set any field -- in the output. -- -- Some of the format specifiers are marked as space-padded or -- zero-padded. Regardless of this, space-padded, zero-padded or unpadded -- inputs are accepted. Note that strings using unpadded fields without -- separating the fields may cause strange parsing. -- -- Supported format specfiers: -- -- parseCalendarTime :: TimeLocale -> String -> String -> Maybe CalendarTime -- | Low-level path name manipulations. -- -- Written by Volker Wysk module System.Path.NameManip -- | Split a path in components. Repeated "/" characters don't -- lead to empty components. "." path components are removed. If -- the path is absolute, the first component will start with -- "/". ".." components are left intact. They can't be -- simply removed, because the preceding component might be a symlink. In -- this case, realpath is probably what you need. -- -- The case that the path is empty, is probably an error. However, it is -- treated like ".", yielding an empty path components list. -- -- Examples: -- --
--   slice_path "/"        = ["/"]
--   slice_path "/foo/bar" = ["/foo","bar"]
--   slice_path "..//./"   = [".."]
--   slice_path "."        = []
--   
-- -- See unslice_path, realpath, realpath_s. slice_path :: String -> [String] -- | Form a path from path components. This isn't the inverse of -- slice_path, since unslice_path . -- slice_path normalises the path. -- -- See slice_path. unslice_path :: [String] -> String -- | Normalise a path. This is done by reducing repeated / -- characters to one, and removing . path components. -- .. path components are left intact, because of possible -- symlinks. -- --
--   normalise_path = unslice_path . slice_path
--   
normalise_path :: String -> String -- | Split a file name in components. This are the base file name and the -- suffixes, which are separated by dots. If the name starts with a dot, -- it is regarded as part of the base name. The result is a list of file -- name components. The filename may be a path. In this case, everything -- up to the last path component will be returned as part of the base -- file name. The path gets normalised thereby. -- -- No empty suffixes are returned. If the file name contains several -- consecutive dots, they are regared as part of the preceding file name -- component. -- -- Concateneting the name components and adding dots, reproduces the -- original name, with a normalised path: concat . intersperse "." . -- slice_filename == normalise. -- -- Note that the last path component might be "..". Then it is -- not possible to deduce the refered directory's name from the path. An -- IO action for getting the real path is then necessary. -- -- Examples: -- --
--   slice_filename "a.b//./.foo.tar.gz" == ["a.b/.foo","tar","gz"]
--   slice_filename ".x..y."             == [".x.", "y."]
--   
-- -- See unslice_filename, slice_filename'. slice_filename :: String -> [String] -- | This is a variant of slice_filename. It is like -- slice_filename, except for being more efficient, and the -- filename must not contain any preceding path, since this case isn't -- considered. -- -- See slice_filename, unslice_filename. slice_filename' :: String -> [String] -- | Form file name from file name components, interspersing dots. This is -- the inverse of slice_filename, except for normalisation of any -- path. -- --
--   unslice_filename = concat . intersperse "."
--   
-- -- See slice_filename. unslice_filename :: [String] -> String -- | Split a path in directory and file name. Only in the case that the -- supplied path is empty, both parts are empty strings. Otherwise, -- "." is filled in for the corresponding part, if necessary. -- Unless the path is empty, concatenating the returned path and file -- name components with a slash in between, makes a valid path to the -- file. -- -- split_path splits off the last path component. This isn't the -- same as the text after the last /. -- -- Note that the last path component might be "..". Then it is -- not possible to deduce the refered directory's name from the path. -- Then an IO action for getting the real path is necessary. -- -- Examples: -- --
--   split_path "/a/b/c"      == ("/a/b", "c")
--   split_path "foo"         == (".", "foo")
--   split_path "foo/bar"     == ("foo", "bar")
--   split_path "foo/.."      == ("foo", "..")
--   split_path "."           == (".", ".")
--   split_path ""            == ("", "")
--   split_path "/foo"        == ("/", "foo")
--   split_path "foo/"        == (".", "foo")
--   split_path "foo/."       == (".", "foo")
--   split_path "foo///./bar" == ("foo", "bar")
--   
-- -- See slice_path. split_path :: String -> (String, String) -- | Get the directory part of a path. -- --
--   dir_part = fst . split_path
--   
-- -- See split_path. dir_part :: String -> String -- | Get the last path component of a path. -- --
--   filename_part = snd . split_path
--   
-- -- Examples: -- --
--   filename_part "foo/bar" == "bar"
--   filename_part "."       == "."
--   
-- -- See split_path. filename_part :: String -> String -- | Inverse of split_path, except for normalisation. -- -- This concatenates two paths, and takes care of "." and empty -- paths. When the two components are the result of split_path, -- then unsplit_path creates a normalised path. It is best -- documented by its definition: -- --
--   unsplit_path (".", "") = "."
--   unsplit_path ("", ".") = "."
--   unsplit_path (".", q)  = q
--   unsplit_path ("", q)   = q
--   unsplit_path (p, "")   = p
--   unsplit_path (p, ".")  = p
--   unsplit_path (p, q)    = p ++ "/" ++ q
--   
-- -- Examples: -- --
--   unsplit_path ("", "")     == ""
--   unsplit_path (".", "")    == "."
--   unsplit_path (".", ".")   == "."
--   unsplit_path ("foo", ".") == "foo"
--   
-- -- See split_path. unsplit_path :: (String, String) -> String -- | Split a file name in prefix and suffix. If there isn't any suffix in -- the file name, then return an empty suffix. A dot at the beginning or -- at the end is not regarded as introducing a suffix. -- -- The last path component is what is being split. This isn't the same as -- splitting the string at the last dot. For instance, if the file name -- doesn't contain any dot, dots in previous path component's aren't -- mistaken as introducing suffixes. -- -- The path part is returned in normalised form. This means, "." -- components are removed, and multiple "/"s are reduced to one. -- -- Note that there isn't any plausibility check performed on the suffix. -- If the file name doesn't have a suffix, but happens to contain a dot, -- then this dot is mistaken as introducing a suffix. -- -- Examples: -- --
--   split_filename "path/to/foo.bar"                             = ("path/to/foo","bar")
--   split_filename "path/to/foo"                                 = ("path/to/foo","")
--   split_filename "/path.to/foo"                                = ("/path.to/foo","")
--   split_filename "a///./x"                                     = ("a/x","")
--   split_filename "dir.suffix/./"                               = ("dir","suffix")
--   split_filename "Photographie, Das 20. Jahrhundert (300 dpi)" = ("Photographie, Das 20", " Jahrhundert (300 dpi)")
--   
-- -- See slice_path, 'split_filename\'' split_filename :: String -> (String, String) -- | Variant of split_filename. This is a more efficient version of -- split_filename, for the case that you know the string is is a -- pure file name without any slashes. -- -- See split_filename. split_filename' :: String -> (String, String) -- | Inverse of split_filename. Concatenate prefix and suffix, -- adding a dot in between, iff the suffix is not empty. The path part of -- the prefix is normalised. -- -- See split_filename. unsplit_filename :: (String, String) -> String -- | Split a path in directory, base file name and suffix. split3 :: String -> (String, String, String) -- | Form path from directory, base file name and suffix parts. unsplit3 :: (String, String, String) -> String -- | Test a path for a specific suffix and split it off. -- -- If the path ends with the suffix, then the result is Just -- prefix, where prefix is the normalised path without the -- suffix. Otherwise it's Nothing. test_suffix :: String -> String -> Maybe String -- | Make a path absolute, using the current working directory. -- -- This makes a relative path absolute with respect to the current -- working directory. An absolute path is returned unmodified. -- -- The current working directory is determined with -- getCurrentDirectory which means that symbolic links in it are -- expanded and the path is normalised. This is different from -- pwd. absolute_path :: String -> IO String -- | Make a path absolute. -- -- This makes a relative path absolute with respect to a specified -- directory. An absolute path is returned unmodified. absolute_path_by :: String -> String -> String -- | Make a path absolute. -- -- This makes a relative path absolute with respect to a specified -- directory. An absolute path is returned unmodified. -- -- The order of the arguments can be confusing. You should rather use -- absolute_path_by. absolute_path' is included for -- backwards compatibility. absolute_path' :: String -> String -> String -- | Guess the ".."-component free form of a path, specified as a -- list of path components, by syntactically removing them, along with -- the preceding path components. This will produce erroneous results -- when the path contains symlinks. If the path contains leading -- ".." components, or more ".." components than -- preceeding normal components, then the ".." components can't -- be normalised away. In this case, the result is Nothing. guess_dotdot_comps :: [String] -> Maybe [String] -- | Guess the ".."-component free, normalised form of a path. The -- transformation is purely syntactic. ".." path components will -- be removed, along with their preceding path components. This will -- produce erroneous results when the path contains symlinks. If the path -- contains leading ".." components, or more ".." -- components than preceeding normal components, then the ".." -- components can't be normalised away. In this case, the result is -- Nothing. -- --
--   guess_dotdot = fmap unslice_path . guess_dotdot_comps . slice_path
--   
guess_dotdot :: String -> Maybe String -- | Tools for rendering sizes -- -- Written by John Goerzen, jgoerzen@complete.org module Data.Quantity -- | Render a number into a string, based on the given quantities. This is -- useful for displaying quantities in terms of bytes or in SI units. -- Give this function the SizeOpts for the desired output, and a -- precision (number of digits to the right of the decimal point), and -- you get a string output. -- -- Here are some examples: -- --
--   Data.Quantity> renderNum binaryOpts 0 1048576
--   "1M"
--   Data.Quantity> renderNum binaryOpts 2 10485760
--   "10.00M"
--   Data.Quantity> renderNum binaryOpts 3 1048576
--   "1.000M"
--   Data.Quantity> renderNum binaryOpts 3 1500000
--   "1.431M"
--   Data.Quantity> renderNum binaryOpts 2 (1500 ** 3)
--   "3.14G"
--   
-- --
--   Data.Quantity> renderNum siOpts 2 1024
--   "1.02k"
--   Data.Quantity> renderNum siOpts 2 1048576
--   "1.05M"
--   Data.Quantity> renderNum siOpts 2 0.001
--   "1.00m"
--   Data.Quantity> renderNum siOpts 2 0.0001
--   "100.00u"
--   
-- -- If you want more control over the output, see quantifyNum. renderNum :: (Ord a, Real a) => SizeOpts -> Int -> a -> String -- | Like renderNum, but operates on a list of numbers. The first -- number in the list will be evaluated for the suffix. The same suffix -- and scale will be used for the remaining items in the list. See -- renderNum for more examples. -- -- Also, unlike renderNum, the %f instead of %g printf format is -- used so that "scientific" notation is avoided in the output. -- -- Examples: -- --
--   *Data.Quantity> renderNums binaryOpts 3 [1500000, 10240, 104857600]
--   ["1.431M","0.010M","100.000M"]
--   *Data.Quantity> renderNums binaryOpts 3 [1500, 10240, 104857600]
--   ["1.465K","10.000K","102400.000K"]
--   
renderNums :: (Ord a, Real a) => SizeOpts -> Int -> [a] -> [String] -- | Takes a number and returns a new (quantity, suffix) combination. The -- space character is used as the suffix for items around 0. quantifyNum :: (Ord a, Real a, Floating b, Ord b) => SizeOpts -> a -> (b, Char) -- | Like quantifyNum, but takes a list of numbers. The first number -- in the list will be evaluated for the suffix. The same suffix and -- scale will be used for the remaining items in the list. Please see -- renderNums for an example of how this works. -- -- It is invalid to use this function on an empty list. quantifyNums :: (Ord a, Real a, Floating b, Ord b) => SizeOpts -> [a] -> ([b], Char) -- | The options for quantifyNum and renderNum data SizeOpts SizeOpts :: Int -> Int -> Int -> String -> SizeOpts -- | The base from which calculations are made base :: SizeOpts -> Int -- | The increment to the power for each new suffix powerIncr :: SizeOpts -> Int -- | The first power for which suffixes are given firstPower :: SizeOpts -> Int -- | The suffixes themselves suffixes :: SizeOpts -> String -- | Predefined definitions for byte measurement in groups of 1024, from 0 -- to 2**80 binaryOpts :: SizeOpts -- | Predefined definitions for SI measurement, from 10**-24 to 10**24. siOpts :: SizeOpts -- | This module provides various Haskell utilities for dealing with times -- and dates. -- -- Written by John Goerzen, jgoerzen@complete.org module System.Time.Utils -- | Converts the specified CalendarTime (see System.Time) to -- seconds-since-epoch format. -- -- The input CalendarTime is assumed to be the time as given in your -- local timezone. All timezone and DST fields in the object are ignored. -- -- This behavior is equivolent to the timelocal() and mktime() functions -- that C programmers are accustomed to. -- -- Please note that the behavior for this function during the hour -- immediately before or after a DST switchover may produce a result with -- a different hour than you expect. timelocal :: CalendarTime -> IO Integer -- | Converts the specified CalendarTime (see System.Time) to -- seconds-since-epoch time. -- -- This conversion does respect the timezone specified on the input -- object. If you want a conversion from UTC, specify ctTZ = 0 and -- ctIsDST = False. -- -- When called like that, the behavior is equivolent to the GNU C -- function timegm(). Unlike the C library, Haskell's CalendarTime -- supports timezone information, so if such information is specified, it -- will impact the result. timegm :: CalendarTime -> Integer -- | Converts the given timeDiff to the number of seconds it represents. -- -- Uses the same algorithm as normalizeTimeDiff in GHC. timeDiffToSecs :: TimeDiff -> Integer -- | January 1, 1970, midnight, UTC, represented as a CalendarTime. epoch :: CalendarTime -- | Converts an Epoch time represented with an arbitrary Real to a -- ClockTime. This input could be a CTime from Foreign.C.Types or an -- EpochTime from System.Posix.Types. epochToClockTime :: (Real a) => a -> ClockTime -- | Converts a ClockTime to something represented with an arbitrary Real. -- The result could be treated as a CTime from Foreign.C.Types or -- EpochTime from System.Posix.Types. The inverse of -- epochToClockTime. -- -- Fractions of a second are not preserved by this function. clockTimeToEpoch :: (Num a) => ClockTime -> a -- | Render a number of seconds as a human-readable amount. Shows the two -- most significant places. For instance: -- --
--   renderSecs 121 = "2m1s"
--   
-- -- See also renderTD for a function that works on a TimeDiff. renderSecs :: Integer -> String -- | Like renderSecs, but takes a TimeDiff instead of an integer -- second count. renderTD :: TimeDiff -> String -- | Tools for tracking the status of a long operation. -- -- Written by John Goerzen, jgoerzen@complete.org -- -- See also Data.Progress.Meter module Data.Progress.Tracker -- | Create a new Progress object with the given name and number of -- total units initialized as given. The start time will be initialized -- with the current time at the present moment according to the system -- clock. The units completed will be set to 0, the time source will be -- set to the system clock, and the parents and callbacks will be empty. -- -- If you need more control, see 'newProgress\''. -- -- Example: -- --
--   prog <- newProgress "mytracker" 1024
--   
newProgress :: String -> Integer -> IO Progress -- | Create a new Progress object initialized with the given status -- and callbacks. No adjustment to the startTime will be made. If -- you want to use the system clock, you can initialize startTime -- with the return value of defaultTimeSource and also pass -- defaultTimeSource as the timing source. newProgress' :: ProgressStatus -> [ProgressCallback] -> IO Progress -- | Adds an new callback to an existing Progress. The callback will -- be called whenever the object's status is updated, except by the call -- to finishP. -- -- Please note that the Progress object will be locked while the callback -- is running, so the callback will not be able to make any modifications -- to it. addCallback :: Progress -> ProgressCallback -> IO () -- | Adds a new parent to an existing Progress. The parent will -- automatically have its completed and total counters incremented by the -- value of those counters in the existing Progress. addParent :: Progress -> Progress -> IO () -- | Increment the completed unit count in the Progress object by -- the amount given. If the value as given exceeds the total, then the -- total will also be raised to match this value so that the completed -- count never exceeds the total. -- -- You can decrease the completed unit count by supplying a negative -- number here. incrP :: Progress -> Integer -> IO () -- | Like incrP, but never modify the total. incrP' :: Progress -> Integer -> IO () -- | Set the completed unit count in the Progress object to the -- specified value. Unlike incrP, this function sets the count to -- a specific value, rather than adding to the existing value. If this -- value exceeds the total, then the total will also be raised to match -- this value so that the completed count never exceeds teh total. setP :: Progress -> Integer -> IO () -- | Like setP, but never modify the total. setP' :: Progress -> Integer -> IO () -- | Increment the total unit count in the Progress object by the -- amount given. This would rarely be needed, but could be needed in some -- special cases when the total number of units is not known in advance. incrTotal :: Progress -> Integer -> IO () -- | Set the total unit count in the Progress object to the -- specified value. Like incrTotal, this would rarely be needed. setTotal :: Progress -> Integer -> IO () -- | Call this when you are finished with the object. It is especially -- important to do this when parent objects are involved. -- -- This will simply set the totalUnits to the current completedUnits -- count, but will not call the callbacks. It will additionally propogate -- any adjustment in totalUnits to the parents, whose callbacks -- will be called. -- -- This ensures that the total expected counts on the parent are always -- correct. Without doing this, if, say, a transfer ended earlier than -- expected, ETA values on the parent would be off since it would be -- expecting more data than actually arrived. finishP :: Progress -> IO () -- | Returns the speed in units processed per time unit. (If you are using -- the default time source, this would be units processed per second). -- This obtains the current speed solely from analyzing the -- Progress object. -- -- If no time has elapsed yet, returns 0. -- -- You can use this against either a Progress object or a -- ProgressStatus object. This is in the IO monad because the -- speed is based on the current time. -- -- Example: -- --
--   getSpeed progressobj >>= print
--   
-- -- Don't let the type of this function confuse you. It is a fancy way of -- saying that it can take either a Progress or a -- ProgressStatus object, and returns a number that is valid as -- any Fractional type, such as a Double, Float, or Rational. getSpeed :: (ProgressStatuses a (IO b), Fractional b) => a -> IO b -- | Returns the estimated time remaining, in standard time units. -- -- Returns 0 whenever getSpeed would return 0. -- -- See the comments under getSpeed for information about this -- function's type and result. getETR :: (ProgressStatuses a (IO Integer), ProgressStatuses a (IO Rational)) => a -> IO Integer -- | Returns the estimated system clock time of completion, in standard -- time units. Returns the current time whenever getETR would -- return 0. -- -- See the comments under getSpeed for information about this -- function's type and result. getETA :: (ProgressStatuses a (IO Integer), ProgressStatuses a (IO Rational)) => a -> IO Integer -- | The main progress status record. data ProgressStatus ProgressStatus :: Integer -> Integer -> Integer -> String -> ProgressTimeSource -> ProgressStatus completedUnits :: ProgressStatus -> Integer totalUnits :: ProgressStatus -> Integer startTime :: ProgressStatus -> Integer -- | An identifying string trackerName :: ProgressStatus -> String timeSource :: ProgressStatus -> ProgressTimeSource -- | The main Progress object. data Progress -- | A function that, when called, yields the current time. The default is -- defaultTimeSource. type ProgressTimeSource = IO Integer -- | The type for a callback function for the progress tracker. When given -- at creation time to 'newProgress\'' or when added via -- addCallback, these functions get called every time the status -- of the tracker changes. -- -- This function is passed two ProgressStatus records: the first -- reflects the status prior to the update, and the second reflects the -- status after the update. -- -- Please note that the owning Progress object will be locked -- while the callback is running, so the callback will not be able to -- make changes to it. type ProgressCallback = ProgressStatus -> ProgressStatus -> IO () class ProgressStatuses a b withStatus :: (ProgressStatuses a b) => a -> (ProgressStatus -> b) -> b -- | The default time source for the system. This is defined as: -- --
--   getClockTime >>= (return . clockTimeToEpoch)
--   
defaultTimeSource :: ProgressTimeSource instance [overlap ok] ProgressStatuses ProgressStatus b instance [overlap ok] ProgressRecords Progress (IO b) instance [overlap ok] ProgressStatuses Progress (IO b) -- | Haskell Parsec parsers for comma-separated value (CSV) files. -- -- Written by John Goerzen, jgoerzen@complete.org module Data.CSV -- | Parse a Comma-Separated Value (CSV) file. The return value is a list -- of lines; each line is a list of cells; and each cell is a String. -- -- Please note that CSV files may have a different number of cells on -- each line. Also, it is impossible to distinguish a CSV line that has a -- call with no data from a CSV line that has no cells. -- -- Here are some examples: -- --
--   Input (literal strings)          Parses As (Haskell String syntax)
--   -------------------------------- ---------------------------------
--   1,2,3                            [["1", "2", "3"]]
--   
--   l1                               [["l1"], ["l2"]]
--   l2
--   
--    (empty line)                    [[""]]
--   
--   NQ,"Quoted"                      [["NQ", "Quoted"]]
--   
--   NQ,"Embedded""Quote"             [["NQ", "Embedded\"Quote"]]
--   
-- -- To parse a String, you might use: -- --
--   import Text.ParserCombinators.Parsec
--   import Data.String.CSV
--   ....
--   parse csvFile "" mystring
--   
-- -- To parse a file, you might instead use: -- --
--   do result <- parseFromFile csvFile "/path/to/file"
--   
-- -- Please note that the result of parsing will be of type (Either -- ParseError [[String]]). A Left result indicates an error. For more -- details, see the Parsec information. csvFile :: CharParser st [[String]] -- | Generate CSV data for a file. The resulting string can be written out -- to disk directly. genCsvFile :: [[String]] -> String -- | Command invocation utilities. -- -- Written by John Goerzen, jgoerzen@complete.org -- -- Please note: Most of this module is not compatible with Hugs. -- -- Command lines executed will be logged using System.Log.Logger -- at the DEBUG level. Failure messages will be logged at the WARNING -- level in addition to being raised as an exception. Both are logged -- under "System.Cmd.Utils.funcname" -- for instance, -- "System.Cmd.Utils.safeSystem". If you wish to suppress these messages -- globally, you can simply run: -- --
--   updateGlobalLogger "System.Cmd.Utils.safeSystem"
--                       (setLevel CRITICAL)
--   
-- -- See also: updateGlobalLogger, System.Log.Logger. -- -- It is possible to set up pipelines with these utilities. Example: -- --
--   (pid1, x1) <- pipeFrom "ls" ["/etc"]
--   (pid2, x2) <- pipeBoth "grep" ["x"] x1
--   putStr x2
--   ... the grep output is displayed ...
--   forceSuccess pid2
--   forceSuccess pid1
--   
-- -- Remember, when you use the functions that return a String, you must -- not call forceSuccess until after all data from the String has -- been consumed. Failure to wait will cause your program to appear to -- hang. -- -- Here is an example of the wrong way to do it: -- --
--   (pid, x) <- pipeFrom "ls" ["/etc"]
--   forceSuccess pid         -- Hangs; the called program hasn't terminated yet
--   processTheData x
--   
-- -- You must instead process the data before calling forceSuccess. -- -- When using the hPipe family of functions, this is probably more -- obvious. -- -- Most of this module will be incompatible with Windows. module System.Cmd.Utils -- | Return value from pipeFrom, pipeLinesFrom, -- pipeTo, or pipeBoth. Contains both a ProcessID and the -- original command that was executed. If you prefer not to use -- forceSuccess on the result of one of these pipe calls, you can -- use (processID ph), assuming ph is your PipeHandle, as a -- parameter to getProcessStatus. data PipeHandle PipeHandle :: ProcessID -> FilePath -> [String] -> String -> PipeHandle processID :: PipeHandle -> ProcessID phCommand :: PipeHandle -> FilePath phArgs :: PipeHandle -> [String] -- | Function that created it phCreator :: PipeHandle -> String -- | Invokes the specified command in a subprocess, waiting for the result. -- If the command terminated successfully, return normally. Otherwise, -- raises a userError with the problem. -- -- Implemented in terms of posixRawSystem where supported, and -- System.Posix.rawSystem otherwise. safeSystem :: FilePath -> [String] -> IO () -- | Uses getProcessStatus to obtain the exit status of the given -- process ID. If the process terminated normally, does nothing. -- Otherwise, raises an exception with an appropriate error message. -- -- This call will block waiting for the given pid to terminate. -- -- Not available on Windows. forceSuccess :: PipeHandle -> IO () -- | Invokes the specified command in a subprocess, waiting for the result. -- Return the result status. Never raises an exception. Only available on -- POSIX platforms. -- -- Like system(3), this command ignores SIGINT and SIGQUIT and blocks -- SIGCHLD during its execution. -- -- Logs as System.Cmd.Utils.posixRawSystem posixRawSystem :: FilePath -> [String] -> IO ProcessStatus -- | Invokes the specified command in a subprocess, without waiting for the -- result. Returns the PID of the subprocess -- it is YOUR responsibility -- to use getProcessStatus or getAnyProcessStatus on that at some point. -- Failure to do so will lead to resource leakage (zombie processes). -- -- This function does nothing with signals. That too is up to you. -- -- Logs as System.Cmd.Utils.forkRawSystem forkRawSystem :: FilePath -> [String] -> IO ProcessID -- | Read data from a pipe. Returns a lazy string and a PipeHandle. -- -- ONLY AFTER the string has been read completely, You must call either -- getProcessStatus or forceSuccess on the -- PipeHandle. Zombies will result otherwise. -- -- Not available on Windows. pipeFrom :: FilePath -> [String] -> IO (PipeHandle, String) -- | Like pipeFrom, but returns data in lines instead of just a -- String. Shortcut for calling lines on the result from pipeFrom. -- -- Note: this function logs as pipeFrom. -- -- Not available on Windows. pipeLinesFrom :: FilePath -> [String] -> IO (PipeHandle, [String]) -- | Write data to a pipe. Returns a ProcessID. -- -- You must call either getProcessStatus or forceSuccess on -- the ProcessID. Zombies will result otherwise. -- -- Not available on Windows. pipeTo :: FilePath -> [String] -> String -> IO PipeHandle -- | Like a combination of pipeTo and pipeFrom; forks an IO -- thread to send data to the piped program, and simultaneously returns -- its output stream. -- -- The same note about checking the return status applies here as with -- pipeFrom. -- -- Not available on Windows. pipeBoth :: FilePath -> [String] -> String -> IO (PipeHandle, String) -- | Read data from a pipe. Returns a Handle and a PipeHandle. -- -- When done, you must hClose the handle, and then use either -- forceSuccess or getProcessStatus on the PipeHandle. -- Zomeibes will result otherwise. -- -- This function logs as pipeFrom. -- -- Not available on Windows or with Hugs. hPipeFrom :: FilePath -> [String] -> IO (PipeHandle, Handle) -- | Write data to a pipe. Returns a PipeHandle and a new Handle to -- write to. -- -- When done, you must hClose the handle, and then use either -- forceSuccess or getProcessStatus on the PipeHandle. -- Zomeibes will result otherwise. -- -- This function logs as pipeTo. -- -- Not available on Windows. hPipeTo :: FilePath -> [String] -> IO (PipeHandle, Handle) -- | Like a combination of hPipeTo and hPipeFrom; returns a -- 3-tuple of (PipeHandle, Data From Pipe, Data To Pipe). -- -- When done, you must hClose both handles, and then use either -- forceSuccess or getProcessStatus on the PipeHandle. -- Zomeibes will result otherwise. -- -- Hint: you will usually need to ForkIO a thread to handle one of the -- Handles; otherwise, deadlock can result. -- -- This function logs as pipeBoth. -- -- Not available on Windows. hPipeBoth :: FilePath -> [String] -> IO (PipeHandle, Handle, Handle) data PipeMode ReadFromPipe :: PipeMode WriteToPipe :: PipeMode -- | Open a pipe to the specified command. -- -- Passes the handle on to the specified function. -- -- The PipeMode specifies what you will be doing. That is, -- specifing ReadFromPipe sets up a pipe from stdin, and -- WriteToPipe sets up a pipe from stdout. -- -- Not available on Windows. pOpen :: PipeMode -> FilePath -> [String] -> (Handle -> IO a) -> IO a -- | Runs a command, redirecting things to pipes. -- -- Not available on Windows. -- -- Note that you may not use the same fd on more than one item. If you -- want to redirect stdout and stderr, dup it first. pOpen3 :: Maybe Fd -> Maybe Fd -> Maybe Fd -> FilePath -> [String] -> (ProcessID -> IO a) -> IO () -> IO a -- | Runs a command, redirecting things to pipes. -- -- Not available on Windows. -- -- Returns immediately with the PID of the child. Using waitProcess on it -- is YOUR responsibility! -- -- Note that you may not use the same fd on more than one item. If you -- want to redirect stdout and stderr, dup it first. pOpen3Raw :: Maybe Fd -> Maybe Fd -> Maybe Fd -> FilePath -> [String] -> IO () -> IO ProcessID instance [overlap ok] Eq PipeHandle instance [overlap ok] Show PipeHandle -- | This Haskell module provides an interface to transmitting a mail -- message. -- -- This is not compatible with Windows at this time. -- -- Written by John Goerzen, jgoerzen@complete.org module Network.Email.Sendmail -- | Transmits an e-mail message using the system's mail transport agent. -- -- This function takes a message, a list of recipients, and an optional -- sender, and transmits it using the system's MTA, sendmail. -- -- If sendmail is on the PATH, it will be used; -- otherwise, a list of system default locations will be searched. -- -- A failure will be logged, since this function uses safeSystem -- internally. -- -- This function will first try sendmail. If it does not exist, -- an error is logged under System.Cmd.Utils.pOpen3 and various -- default sendmail locations are tried. If that still fails, an -- error is logged and an exception raised. sendmail :: Maybe String -> [String] -> String -> IO () -- | This module provides various helpful utilities for dealing with -- threads. -- -- Written by John Goerzen, jgoerzen@complete.org module Control.Concurrent.Thread.Utils -- | Takes a IO action and a function. The IO action will be called in a -- separate thread. When it is completed, the specified function is -- called with its result. This is a simple way of doing callbacks. runInThread :: IO a -> (a -> IO b) -> IO ThreadId -- | General support for e-mail mailboxes -- -- Written by John Goerzen, jgoerzen@complete.org module Network.Email.Mailbox -- | The flags which may be assigned to a message. data Flag SEEN :: Flag ANSWERED :: Flag FLAGGED :: Flag DELETED :: Flag DRAFT :: Flag FORWARDED :: Flag OTHERFLAG :: String -> Flag -- | Convenience shortcut type Flags = [Flag] -- | A Message is represented as a simple String. type Message = String -- | Main class for readable mailboxes. -- -- The mailbox object a represents zero or more Messages. -- Each message has a unique identifier b in a format specific to -- each given mailbox. This identifier may or may not be persistent. -- -- Functions which return a list are encouraged -- but not guaranteed -- -- to do so lazily. -- -- Implementing classes must provide, at minimum, getAll. class (Show a, Show b, Eq b) => MailboxReader a b listIDs :: (MailboxReader a b) => a -> IO [b] listMessageFlags :: (MailboxReader a b) => a -> IO [(b, Flags)] getAll :: (MailboxReader a b) => a -> IO [(b, Flags, Message)] getMessages :: (MailboxReader a b) => a -> [b] -> IO [(b, Flags, Message)] class (MailboxReader a b) => MailboxWriter a b appendMessages :: (MailboxWriter a b) => a -> [(Flags, Message)] -> IO [b] deleteMessages :: (MailboxWriter a b) => a -> [b] -> IO () addFlags :: (MailboxWriter a b) => a -> [b] -> Flags -> IO () removeFlags :: (MailboxWriter a b) => a -> [b] -> Flags -> IO () setFlags :: (MailboxWriter a b) => a -> [b] -> Flags -> IO () instance [overlap ok] Eq Flag instance [overlap ok] Show Flag -- | Utilities for HUnit unit testing. -- -- Written by John Goerzen, jgoerzen@complete.org module Test.HUnit.Utils -- | Asserts that a specific exception is raised by a given action. assertRaises :: (Show a) => String -> Exception -> IO a -> IO () mapassertEqual :: (Show b, Eq b) => String -> (a -> b) -> [(a, b)] -> [Test] -- | qccheck turns the quickcheck test into an hunit test qccheck :: (Testable a) => Config -> String -> a -> Test -- | qctest is equivalent to 'qccheck defaultConfig' qctest :: (Testable a) => String -> a -> Test -- | Written by John Goerzen, jgoerzen@complete.org module Text.ParserCombinators.Parsec.Utils type GeneralizedToken a = (SourcePos, a) type GeneralizedTokenParser a st b = GenParser (GeneralizedToken a) st b -- | Generate (return) a GeneralizedToken. togtok :: a -> GenParser b st (GeneralizedToken a) -- | Retrieve the next token from a GeneralizedToken stream. The -- given function should return the value to use, or Nothing to cause an -- error. tokeng :: (Show a) => (a -> Maybe b) -> GeneralizedTokenParser a st b -- | A shortcut to tokeng; the test here is just a function that -- returns a Bool. If the result is true; return that value -- otherwise, -- an error. satisfyg :: (Show a) => (a -> Bool) -> GeneralizedTokenParser a st a -- | Matches one item in a list and returns it. oneOfg :: (Eq a, Show a) => [a] -> GeneralizedTokenParser a st a -- | Matches one item not in a list and returns it. noneOfg :: (Eq a, Show a) => [a] -> GeneralizedTokenParser a st a -- | Matches one specific token and returns it. specificg :: (Eq a, Show a) => a -> GeneralizedTokenParser a st a -- | Matches all items and returns them allg :: (Show a) => GeneralizedTokenParser a st [a] -- | Running notMatching p msg will try to apply parser p. If it -- fails, returns (). If it succeds, cause a failure and raise the given -- error message. It will not consume input in either case. notMatching :: GenParser a b c -> String -> GenParser a b () -- | Tools for writing daemons/server processes -- -- Written by John Goerzen, jgoerzen@complete.org -- -- Please note: Most of this module is not compatible with Hugs. -- -- Messages from this module are logged under System.Daemon. See -- System.Log.Logger for details. -- -- Based on background from -- http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 and -- http://www.haskell.org/hawiki/HaskellUnixDaemon. -- -- This module is not available on Windows. module System.Daemon -- | Detach the process from a controlling terminal and run it in the -- background, handling it with standard Unix deamon semantics. -- -- After running this, please note the following side-effects: -- -- -- -- I highly suggest running this function before starting any -- threads. -- -- Note that this is not intended for a daemon invoked from inetd(1). detachDaemon :: IO () -- | Haskell Virtual I/O -- a system to increase the flexibility of input -- and output in Haskell -- -- Copyright (c) 2004-2005 John Goerzen, jgoerzen@complete.org -- -- HVIO provides the following general features: -- -- -- -- HVIO defines several basic type classes that you can use. You will -- mostly be interested in HVIO. -- -- It's trivial to adapt old code to work with HVIO. For instance, -- consider this example of old and new code: -- --
--   printMsg :: Handle -> String -> IO ()
--   printMsg h msg = hPutStr h ("msg: " ++ msg)
--   
-- -- And now, the new way: -- --
--   printMsg :: HVIO h => h -> String -> IO ()
--   printMsg h msg = vPutStr h ("msg: " ++ msg)
--   
-- -- There are several points to note about this conversion: -- -- -- -- In addition to Handle, there are several pre-defined classes for your -- use. StreamReader is a particularly interesting one. At -- creation time, you pass it a String. Its contents are read lazily -- whenever a read call is made. It can be used, therefore, to implement -- filters (simply initialize it with the result from, say, a map over -- hGetContents from another HVIO object), codecs, and simple I/O -- testing. Because it is lazy, it need not hold the entire string in -- memory. You can create a StreamReader with a call to -- newStreamReader. -- -- MemoryBuffer is a similar class, but with a different purpose. -- It provides a full interface like Handle (it implements HVIOReader, -- HVIOWriter, and HVIOSeeker). However, it maintains an in-memory buffer -- with the contents of the file, rather than an actual on-disk file. You -- can access the entire contents of this buffer at any time. This can be -- quite useful for testing I/O code, or for cases where existing APIs -- use I/O, but you prefer a String representation. You can create a -- MemoryBuffer with a call to newMemoryBuffer. -- -- Finally, there are pipes. These pipes are analogous to the Unix pipes -- that are available from System.Posix, but don't require Unix and work -- only in Haskell. When you create a pipe, you actually get two HVIO -- objects: a PipeReader and a PipeWriter. You must use the -- PipeWriter in one thread and the PipeReader in another -- thread. Data that's written to the PipeWriter will then be -- available for reading with the PipeReader. The pipes are -- implemented completely with existing Haskell threading primitives, and -- require no special operating system support. Unlike Unix pipes, these -- pipes cannot be used across a fork(). Also unlike Unix pipes, these -- pipes are portable and interact well with Haskell threads. A new pipe -- can be created with a call to newHVIOPipe. -- -- Together with System.IO.HVFS, this module is part of a complete -- virtual filesystem solution. module System.IO.HVIO -- | This is the generic I/O support class. All objects that are to be used -- in the HVIO system must provide an instance of HVIO. -- -- Functions in this class provide an interface with the same -- specification as the similar functions in System.IO. Please refer to -- that documentation for a more complete specification than is provided -- here. -- -- Instances of HVIO must provide vClose, vIsEOF, -- and either vIsOpen or vIsClosed. -- -- Implementators of readable objects must provide at least -- vGetChar and vIsReadable. An implementation of -- vGetContents is also highly suggested, since the default cannot -- implement proper partial closing semantics. -- -- Implementators of writable objects must provide at least -- vPutChar and vIsWritable. -- -- Implementators of seekable objects must provide at least -- vIsSeekable, vTell, and vSeek. class (Show a) => HVIO a vClose :: (HVIO a) => a -> IO () vIsOpen :: (HVIO a) => a -> IO Bool vIsClosed :: (HVIO a) => a -> IO Bool vTestOpen :: (HVIO a) => a -> IO () vIsEOF :: (HVIO a) => a -> IO Bool vShow :: (HVIO a) => a -> IO String vMkIOError :: (HVIO a) => a -> IOErrorType -> String -> Maybe FilePath -> IOError vThrow :: (HVIO a) => a -> IOErrorType -> IO b vGetFP :: (HVIO a) => a -> IO (Maybe FilePath) vTestEOF :: (HVIO a) => a -> IO () vGetChar :: (HVIO a) => a -> IO Char vGetLine :: (HVIO a) => a -> IO String vGetContents :: (HVIO a) => a -> IO String vReady :: (HVIO a) => a -> IO Bool vIsReadable :: (HVIO a) => a -> IO Bool vPutChar :: (HVIO a) => a -> Char -> IO () vPutStr :: (HVIO a) => a -> String -> IO () vPutStrLn :: (HVIO a) => a -> String -> IO () vPrint :: (HVIO a, Show b) => a -> b -> IO () vFlush :: (HVIO a) => a -> IO () vIsWritable :: (HVIO a) => a -> IO Bool vSeek :: (HVIO a) => a -> SeekMode -> Integer -> IO () vTell :: (HVIO a) => a -> IO Integer vRewind :: (HVIO a) => a -> IO () vIsSeekable :: (HVIO a) => a -> IO Bool vSetBuffering :: (HVIO a) => a -> BufferMode -> IO () vGetBuffering :: (HVIO a) => a -> IO BufferMode vPutBuf :: (HVIO a) => a -> Ptr b -> Int -> IO () vGetBuf :: (HVIO a) => a -> Ptr b -> Int -> IO Int -- | Simulate I/O based on a string buffer. -- -- When a StreamReader is created, it is initialized based on the -- contents of a String. Its contents are read lazily whenever a -- request is made to read something from the StreamReader. It can -- be used, therefore, to implement filters (simply initialize it with -- the result from, say, a map over hGetContents from another HVIO -- object), codecs, and simple I/O testing. Because it is lazy, it need -- not hold the entire string in memory. You can create a -- StreamReader with a call to newStreamReader. data StreamReader -- | Create a new StreamReader object. newStreamReader :: String -> IO StreamReader -- | A MemoryBuffer simulates true I/O, but uses an in-memory buffer -- instead of on-disk storage. -- -- It provides a full interface like Handle (it implements HVIOReader, -- HVIOWriter, and HVIOSeeker). However, it maintains an in-memory buffer -- with the contents of the file, rather than an actual on-disk file. You -- can access the entire contents of this buffer at any time. This can be -- quite useful for testing I/O code, or for cases where existing APIs -- use I/O, but you prefer a String representation. You can create a -- MemoryBuffer with a call to newMemoryBuffer. -- -- The present MemoryBuffer implementation is rather inefficient, -- particularly when reading towards the end of large files. It's best -- used for smallish data storage. This problem will be fixed eventually. data MemoryBuffer -- | Create a new MemoryBuffer instance. The buffer is initialized -- to the value passed, and the pointer is placed at the beginning of the -- file. -- -- You can put things in it by using the normal vPutStr calls, and -- reset to the beginning by using the normal vRewind call. -- -- The function is called when vClose is called, and is passed the -- contents of the buffer at close time. You can use -- mbDefaultCloseFunc if you don't want to do anything. -- -- To create an empty buffer, pass the initial value "". newMemoryBuffer :: String -> (String -> IO ()) -> IO MemoryBuffer -- | Default (no-op) memory buf close function. mbDefaultCloseFunc :: String -> IO () -- | Grab the entire contents of the buffer as a string. Unlike -- vGetContents, this has no effect on the open status of the -- item, the EOF status, or the current position of the file pointer. getMemoryBuffer :: MemoryBuffer -> IO String -- | The reading side of a Haskell pipe. Please see newHVIOPipe for -- more details. data PipeReader -- | The writing side of a Haskell pipe. Please see newHVIOPipe for -- more details. data PipeWriter -- | Create a Haskell pipe. -- -- These pipes are analogous to the Unix pipes that are available from -- System.Posix, but don't require Unix and work only in Haskell. When -- you create a pipe, you actually get two HVIO objects: a -- PipeReader and a PipeWriter. You must use the -- PipeWriter in one thread and the PipeReader in another -- thread. Data that's written to the PipeWriter will then be -- available for reading with the PipeReader. The pipes are -- implemented completely with existing Haskell threading primitives, and -- require no special operating system support. Unlike Unix pipes, these -- pipes cannot be used across a fork(). Also unlike Unix pipes, these -- pipes are portable and interact well with Haskell threads. newHVIOPipe :: IO (PipeReader, PipeWriter) instance [overlap ok] Eq PipeBit instance [overlap ok] Show PipeBit instance [overlap ok] HVIO PipeWriter instance [overlap ok] Show PipeWriter instance [overlap ok] HVIO PipeReader instance [overlap ok] Show PipeReader instance [overlap ok] HVIO MemoryBuffer instance [overlap ok] Show MemoryBuffer instance [overlap ok] HVIO StreamReader instance [overlap ok] Show StreamReader instance [overlap ok] HVIO Handle -- | Haskell Virtual FS -- generic support for real or virtual filesystem -- in Haskell -- -- Copyright (c) 2004-2005 John Goerzen, jgoerzen@complete.org -- -- The idea of this module is to provide virtualization of filesystem -- calls. In addition to the "real" system filesystem, you can also -- provide access to other, virtual, filesystems using the same set of -- calls. Examples of such virtual filesystems might include a remote FTP -- server, WebDAV server, a local Hashtable, a ConfigParser object, or -- any other data structure you can represent as a tree of named nodes -- containing strings. -- -- Each HVFS function takes a HVFS "handle" (HVFS -- instance) as its first parameter. If you wish to operate on the -- standard system filesystem, you can just use SystemFS. -- -- The MissingH.HVFS.IO.InstanceHelpers module contains some code -- to help you make your own HVFS instances. -- -- The HVFSOpenable class works together with the -- System.IO.HVIO module to provide a complete virtual filesystem -- and I/O model that allows you to open up virtual filesystem files and -- act upon them in a manner similar to standard Handles. module System.IO.HVFS -- | The main HVFS class. -- -- Default implementations of these functions are provided: -- -- -- -- Default implementations of all other functions will generate an -- isIllegalOperation error, since they are assumed to be un-implemented. -- -- You should always provide at least a vGetFileStatus call, and -- almost certainly several of the others. -- -- Most of these functions correspond to functions in System.Directory or -- System.Posix.Files. Please see detailed documentation on them there. class (Show a) => HVFS a vGetCurrentDirectory :: (HVFS a) => a -> IO FilePath vSetCurrentDirectory :: (HVFS a) => a -> FilePath -> IO () vGetDirectoryContents :: (HVFS a) => a -> FilePath -> IO [FilePath] vDoesFileExist :: (HVFS a) => a -> FilePath -> IO Bool vDoesDirectoryExist :: (HVFS a) => a -> FilePath -> IO Bool vDoesExist :: (HVFS a) => a -> FilePath -> IO Bool vCreateDirectory :: (HVFS a) => a -> FilePath -> IO () vRemoveDirectory :: (HVFS a) => a -> FilePath -> IO () vRenameDirectory :: (HVFS a) => a -> FilePath -> FilePath -> IO () vRemoveFile :: (HVFS a) => a -> FilePath -> IO () vRenameFile :: (HVFS a) => a -> FilePath -> FilePath -> IO () vGetFileStatus :: (HVFS a) => a -> FilePath -> IO HVFSStatEncap vGetSymbolicLinkStatus :: (HVFS a) => a -> FilePath -> IO HVFSStatEncap vGetModificationTime :: (HVFS a) => a -> FilePath -> IO ClockTime vRaiseError :: (HVFS a) => a -> IOErrorType -> String -> Maybe FilePath -> IO c vCreateSymbolicLink :: (HVFS a) => a -> FilePath -> FilePath -> IO () vReadSymbolicLink :: (HVFS a) => a -> FilePath -> IO FilePath vCreateLink :: (HVFS a) => a -> FilePath -> FilePath -> IO () -- | Evaluating types of files and information about them. -- -- This corresponds to the System.Posix.Types.FileStatus type, and -- indeed, that is one instance of this class. -- -- Inplementators must, at minimum, implement vIsDirectory and -- vIsRegularFile. -- -- Default implementations of everything else are provided, returning -- reasonable values. -- -- A default implementation of this is not currently present on Windows. class (Show a) => HVFSStat a vDeviceID :: (HVFSStat a) => a -> DeviceID vFileID :: (HVFSStat a) => a -> FileID vFileMode :: (HVFSStat a) => a -> FileMode vLinkCount :: (HVFSStat a) => a -> LinkCount vFileOwner :: (HVFSStat a) => a -> UserID vFileGroup :: (HVFSStat a) => a -> GroupID vSpecialDeviceID :: (HVFSStat a) => a -> DeviceID vFileSize :: (HVFSStat a) => a -> FileOffset vAccessTime :: (HVFSStat a) => a -> EpochTime vModificationTime :: (HVFSStat a) => a -> EpochTime vStatusChangeTime :: (HVFSStat a) => a -> EpochTime vIsBlockDevice :: (HVFSStat a) => a -> Bool vIsCharacterDevice :: (HVFSStat a) => a -> Bool vIsNamedPipe :: (HVFSStat a) => a -> Bool vIsRegularFile :: (HVFSStat a) => a -> Bool vIsDirectory :: (HVFSStat a) => a -> Bool vIsSymbolicLink :: (HVFSStat a) => a -> Bool vIsSocket :: (HVFSStat a) => a -> Bool -- | Types that can open a HVIO object should be instances of this class. -- You need only implement vOpen. class (HVFS a) => HVFSOpenable a vOpen :: (HVFSOpenable a) => a -> FilePath -> IOMode -> IO HVFSOpenEncap vReadFile :: (HVFSOpenable a) => a -> FilePath -> IO String vWriteFile :: (HVFSOpenable a) => a -> FilePath -> String -> IO () vOpenBinaryFile :: (HVFSOpenable a) => a -> FilePath -> IOMode -> IO HVFSOpenEncap -- | Similar to HVFSStatEncap, but for vOpen result. data HVFSOpenEncap HVFSOpenEncap :: a -> HVFSOpenEncap -- | Encapsulate a HVFSStat result. This is required due to Haskell -- typing restrictions. You can get at it with: -- --
--   case encap of
--      HVFSStatEncap x -> -- now use x
--   
data HVFSStatEncap HVFSStatEncap :: a -> HVFSStatEncap -- | Convenience function for working with stat -- takes a stat result and -- a function that uses it, and returns the result. -- -- Here is an example from the HVFS source: -- --
--   vGetModificationTime fs fp = 
--      do s <- vGetFileStatus fs fp
--         return $ epochToClockTime (withStat s vModificationTime)
--   
-- -- See epochToClockTime for more information. withStat :: HVFSStatEncap -> (forall a. (HVFSStat a) => a -> b) -> b -- | Similar to withStat, but for the vOpen result. withOpen :: HVFSOpenEncap -> (forall a. (HVIO a) => a -> b) -> b data SystemFS SystemFS :: SystemFS -- | File and directory names are values of type String, whose -- precise meaning is operating system dependent. Files can be opened, -- yielding a handle which can then be used to operate on the contents of -- that file. type FilePath = String type DeviceID = CDev type FileID = CIno type FileMode = CMode type LinkCount = CNlink type UserID = CUid type GroupID = CGid type FileOffset = COff type EpochTime = CTime data IOMode :: * instance [overlap ok] Eq SystemFS instance [overlap ok] Show SystemFS instance [overlap ok] HVFSOpenable SystemFS instance [overlap ok] HVFS SystemFS instance [overlap ok] HVFSStat FileStatus instance [overlap ok] Show FileStatus -- | This module provides various helpful utilities for dealing with binary -- input and output. -- -- You can use this module to deal with binary blocks of data as either -- Strings or lists of Word8. The BinaryConvertible class provides this -- abstraction. -- -- Wherever you see HVIO, you can transparently substite a regular -- Handle. This module can work with any HVIO object, however. See -- System.IO.HVIO for more details. -- -- Versions of MissingH prior 0.11.6 lacked the BinaryConvertible -- class and worked only with Strings and Handles. -- -- Important note: /binary functions are not supported in all Haskell -- implementations/. Do not import or use this module unless you know you -- are using an implementation that supports them. At this time, here is -- the support status: -- -- -- -- Non-binary functions may be found in System.IO. -- -- See also: System.IO.BlockIO -- -- Written by John Goerzen, jgoerzen@complete.org module System.IO.Binary -- | Provides support for handling binary blocks with convenient types. -- -- This module provides implementations for Strings and for [Word8] -- (lists of Word8s). class (Eq a, Show a) => BinaryConvertible a toBuf :: (BinaryConvertible a) => [a] -> (Ptr CChar -> IO c) -> IO c fromBuf :: (BinaryConvertible a) => Int -> (Ptr CChar -> IO Int) -> IO [a] -- | Copies everything from the input handle to the output handle using -- binary blocks of the given size. This was once the following beautiful -- implementation: -- --
--   hBlockCopy bs hin hout = hBlockInteract bs hin hout id
--   
-- -- (id is the built-in Haskell function that just returns whatever -- is given to it) -- -- In more recent versions of MissingH, it uses a more optimized routine -- that avoids ever having to convert the binary buffer at all. hBlockCopy :: (HVIO a, HVIO b) => Int -> a -> b -> IO () -- | Copies from stdin to stdout using binary blocks of the -- given size. An alias for hBlockCopy over stdin and -- stdout blockCopy :: Int -> IO () -- | Copies one filename to another in binary mode. -- -- Please note that the Unix permission bits on the output file cannot be -- set due to a limitation of the Haskell openBinaryFile function. -- Therefore, you may need to adjust those bits after the copy yourself. -- -- This function is implemented using hBlockCopy internally. copyFileBlocksToFile :: Int -> FilePath -> FilePath -> IO () -- | As a wrapper around the standard function hPutBuf, this -- function takes a standard Haskell String instead of the far -- less convenient Ptr a. The entire contents of the string will -- be written as a binary buffer using hPutBuf. The length of the -- output will be the length of the passed String or list. -- -- If it helps, you can thing of this function as being of type -- Handle -> String -> IO () hPutBufStr :: (HVIO a, BinaryConvertible b) => a -> [b] -> IO () -- | An alias for hPutBufStr stdout putBufStr :: (BinaryConvertible b) => [b] -> IO () -- | Acts a wrapper around the standard function hGetBuf, this -- function returns a standard Haskell String (or [Word8]) instead of -- modifying a 'Ptr a' buffer. The length is the maximum length to read -- and the semantice are the same as with hGetBuf; namely, the -- empty string is returned with EOF is reached, and any given read may -- read fewer bytes than the given length. -- -- (Actually, it's a wrapper around vGetBuf) hGetBufStr :: (HVIO a, BinaryConvertible b) => a -> Int -> IO [b] -- | An alias for hGetBufStr stdin getBufStr :: (BinaryConvertible b) => Int -> IO [b] -- | Like hGetBufStr, but guarantees that it will only return fewer -- than the requested number of bytes when EOF is encountered. hFullGetBufStr :: (HVIO a, BinaryConvertible b) => a -> Int -> IO [b] -- | An alias for hFullGetBufStr stdin fullGetBufStr :: (BinaryConvertible b) => Int -> IO [b] -- | An alias for hPutBlocks stdout putBlocks :: -- (BinaryConvertible b) => [[b]] -> IO () putBlocks = hPutBlocks -- stdout -- -- Returns a lazily-evaluated list of all blocks in the input file, as -- read by hGetBufStr. There will be no 0-length block in this -- list. The list simply ends at EOF. hGetBlocks :: (HVIO a, BinaryConvertible b) => a -> Int -> IO [[b]] -- | An alias for hGetBlocks stdin getBlocks :: (BinaryConvertible b) => Int -> IO [[b]] -- | Same as hGetBlocks, but using hFullGetBufStr underneath. hFullGetBlocks :: (HVIO a, BinaryConvertible b) => a -> Int -> IO [[b]] -- | An alias for hFullGetBlocks stdin fullGetBlocks :: (BinaryConvertible b) => Int -> IO [[b]] -- | Like the built-in readFile, but opens the file in binary -- instead of text mode. readBinaryFile :: FilePath -> IO String -- | Like the built-in writeFile, but opens the file in binary -- instead of text mode. writeBinaryFile :: FilePath -> String -> IO () -- | Binary block-based interaction. This is useful for scenarios that take -- binary blocks, manipulate them in some way, and then write them out. -- Take a look at hBlockCopy for an example. The integer argument -- is the size of input binary blocks. This function uses -- hGetBlocks internally. hBlockInteract :: (HVIO a, HVIO d, BinaryConvertible b, BinaryConvertible c) => Int -> a -> d -> ([[b]] -> [[c]]) -> IO () -- | An alias for hBlockInteract over stdin and stdout blockInteract :: (BinaryConvertible b, BinaryConvertible c) => Int -> ([[b]] -> [[c]]) -> IO () -- | Same as hBlockInteract, but uses hFullGetBlocks instead -- of hGetBlocks internally. hFullBlockInteract :: (HVIO a, HVIO d, BinaryConvertible b, BinaryConvertible c) => Int -> a -> d -> ([[b]] -> [[c]]) -> IO () -- | An alias for hFullBlockInteract over stdin and -- stdout fullBlockInteract :: (BinaryConvertible b, BinaryConvertible c) => Int -> ([[b]] -> [[c]]) -> IO () instance [overlap ok] BinaryConvertible Word8 instance [overlap ok] BinaryConvertible Char -- | This module provides various helpful utilities for dealing -- filesystems. -- -- Written by John Goerzen, jgoerzen@complete.org -- -- To operate on your system's main filesystem, just pass SystemFS as the -- first parameter to these functions. module System.IO.HVFS.Utils -- | Obtain a recursive listing of all files/directories beneath the -- specified directory. The traversal is depth-first and the original -- item is always present in the returned list. -- -- If the passed value is not a directory, the return value be only that -- value. -- -- The "." and ".." entries are removed from the data returned. recurseDir :: (HVFS a) => a -> FilePath -> IO [FilePath] -- | Like recurseDir, but return the stat() -- (System.Posix.Files.FileStatus) information with them. This is an -- optimization if you will be statting files yourself later. -- -- The items are returned lazily. -- -- WARNING: do not change your current working directory until you have -- consumed all the items. Doing so could cause strange effects. -- -- Alternatively, you may wish to pass an absolute path to this function. recurseDirStat :: (HVFS a) => a -> FilePath -> IO [(FilePath, HVFSStatEncap)] -- | Removes a file or a directory. If a directory, also removes all its -- child files/directories. recursiveRemove :: (HVFS a) => a -> FilePath -> IO () -- | Provide a result similar to the command ls -l over a directory. -- -- Known bug: setuid bit semantics are inexact compared with standard ls. lsl :: (HVFS a) => a -> FilePath -> IO String data SystemFS SystemFS :: SystemFS module System.IO.Utils -- | Copies from one handle to another in raw mode (using hGetContents). hCopy :: (HVIO a, HVIO b) => a -> b -> IO () -- | Copies from one handle to another in raw mode (using hGetContents). -- Takes a function to provide progress updates to the user. hCopyProgress :: (HVIO b, HVIO c, Integral a) => b -> c -> (Maybe a -> Integer -> Bool -> IO ()) -> Int -> Maybe a -> IO Integer -- | Copies from one handle to another in text mode (with lines). Like -- hBlockCopy, this implementation is nice: -- --
--   hLineCopy hin hout = hLineInteract hin hout id
--   
hLineCopy :: (HVIO a, HVIO b) => a -> b -> IO () -- | Copies from stdin to stdout using lines. An alias for -- hLineCopy over stdin and stdout. lineCopy :: IO () -- | Copies one filename to another in text mode. -- -- Please note that the Unix permission bits are set at a default; you -- may need to adjust them after the copy yourself. -- -- This function is implemented using hLineCopy internally. copyFileLinesToFile :: FilePath -> FilePath -> IO () -- | Given a list of strings, output a line containing each item, adding -- newlines as appropriate. The list is not expected to have newlines -- already. hPutStrLns :: (HVIO a) => a -> [String] -> IO () -- | Given a handle, returns a list of all the lines in that handle. Thanks -- to lazy evaluation, this list does not have to be read all at once. -- -- Combined with hPutStrLns, this can make a powerful way to -- develop filters. See the lineInteract function for more on that -- concept. -- -- Example: -- --
--   main = do
--          l <- hGetLines stdin
--          hPutStrLns stdout $ filter (startswith "1") l
--   
hGetLines :: (HVIO a) => a -> IO [String] -- | This is similar to the built-in interact, but works on any -- handle, not just stdin and stdout. -- -- In other words: -- --
--   interact = hInteract stdin stdout
--   
hInteract :: (HVIO a, HVIO b) => a -> b -> (String -> String) -> IO () -- | Line-based interaction over arbitrary handles. This is similar to -- wrapping hInteract with lines and unlines. -- -- One could view this function like this: -- --
--   hLineInteract finput foutput func =
--       let newf = unlines . func . lines in
--           hInteract finput foutput newf
--   
-- -- Though the actual implementation is this for efficiency: -- --
--   hLineInteract finput foutput func =
--       do
--       lines <- hGetLines finput
--       hPutStrLns foutput (func lines)
--   
hLineInteract :: (HVIO a, HVIO b) => a -> b -> ([String] -> [String]) -> IO () -- | Line-based interaction. This is similar to wrapping your interact -- functions with lines and unlines. This equality holds: -- --
--   lineInteract = hLineInteract stdin stdout
--   
-- -- Here's an example: -- --
--   main = lineInteract (filter (startswith "1"))
--   
-- -- This will act as a simple version of grep -- all lines that start with -- 1 will be displayed; all others will be ignored. lineInteract :: ([String] -> [String]) -> IO () -- | Applies a given function to every item in a list, and returns the new -- list. Unlike the system's mapM, items are evaluated lazily. lazyMapM :: (a -> IO b) -> [a] -> IO [b] -- | Sets stdin and stdout to be block-buffered. This can save a huge -- amount of system resources since far fewer syscalls are made, and can -- make programs run much faster. optimizeForBatch :: IO () -- | Sets stdin and stdout to be line-buffered. This saves resources on -- stdout, but not many on stdin, since it it still looking for newlines. optimizeForInteraction :: IO () -- | This module provides various helpful utilities for dealing with lists. -- -- Written by John Goerzen, jgoerzen@complete.org module Data.List.Utils -- | Merge two sorted lists into a single, sorted whole. -- -- Example: -- --
--   merge [1,3,5] [1,2,4,6] -> [1,1,2,3,4,5,6]
--   
-- -- QuickCheck test property: -- -- prop_merge xs ys = merge (sort xs) (sort ys) == sort (xs ++ ys) where -- types = xs :: [Int] merge :: (Ord a) => [a] -> [a] -> [a] -- | Merge two sorted lists using into a single, sorted whole, allowing the -- programmer to specify the comparison function. -- -- QuickCheck test property: -- -- prop_mergeBy xs ys = mergeBy cmp (sortBy cmp xs) (sortBy cmp ys) == -- sortBy cmp (xs ++ ys) where types = xs :: [ (Int, Int) ] cmp (x1,_) -- (x2,_) = compare x1 x2 mergeBy :: (a -> a -> Ordering) -> [a] -> [a] -> [a] -- | Returns true if the given list starts with the specified elements; -- false otherwise. (This is an alias for Data.List.isPrefixOf.) -- -- Example: -- --
--   startswith "He" "Hello" -> True
--   
startswith :: (Eq a) => [a] -> [a] -> Bool -- | Returns true if the given list ends with the specified elements; false -- otherwise. (This is an alias for Data.List.isSuffixOf.) -- -- Example: -- --
--   endswith "lo" "Hello" -> True
--   
endswith :: (Eq a) => [a] -> [a] -> Bool -- | Returns true if the given parameter is a sublist of the given list; -- false otherwise. -- -- Example: -- --
--   contains "Haskell" "I really like Haskell." -> True
--   contains "Haskell" "OCaml is great." -> False
--   
-- -- This function was submitted to GHC and was applied as -- isInfixOf. This function therefore is deprecated and will be -- removed in future versions. contains :: (Eq a) => [a] -> [a] -> Bool -- | Returns true if the given list contains any of the elements in the -- search list. hasAny :: (Eq a) => [a] -> [a] -> Bool -- | Adds the specified (key, value) pair to the given list, removing any -- existing pair with the same key already present. addToAL :: (Eq key) => [(key, elt)] -> key -> elt -> [(key, elt)] -- | Removes all (key, value) pairs from the given list where the key -- matches the given one. delFromAL :: (Eq key) => [(key, a)] -> key -> [(key, a)] -- | Flips an association list. Converts (key1, val), (key2, val) pairs to -- (val, [key1, key2]). flipAL :: (Eq key, Eq val) => [(key, val)] -> [(val, [key])] -- | Returns the keys that comprise the (key, value) pairs of the given AL. -- -- Same as: -- --
--   map fst
--   
keysAL :: [(key, a)] -> [key] -- | Returns the values the comprise the (key, value) pairs of the given -- AL. -- -- Same as: -- --
--   map snd
--   
valuesAL :: [(a, value)] -> [value] -- | Indicates whether or not the given key is in the AL. hasKeyAL :: (Eq a) => a -> [(a, b)] -> Bool -- | Converts an association list to a string. The string will have one -- pair per line, with the key and value both represented as a Haskell -- string. -- -- This function is designed to work with [(String, String)] association -- lists, but may work with other types as well. strFromAL :: (Show a, Show b) => [(a, b)] -> String -- | The inverse of strFromAL, this function reads a string and -- outputs the appropriate association list. -- -- Like strFromAL, this is designed to work with [(String, -- String)] association lists but may also work with other objects with -- simple representations. strToAL :: (Read a, Read b) => String -> [(a, b)] -- | Given a delimiter and a list (or string), split into components. -- -- Example: -- --
--   split "," "foo,bar,,baz," -> ["foo", "bar", "", "baz", ""]
--   
-- --
--   split "ba" ",foo,bar,,baz," -> [",foo,","r,,","z,"]
--   
split :: (Eq a) => [a] -> [a] -> [[a]] -- | Given a delimiter and a list of items (or strings), join the items by -- using the delimiter. -- -- Example: -- --
--   join "|" ["foo", "bar", "baz"] -> "foo|bar|baz"
--   
join :: [a] -> [[a]] -> [a] -- | Given a list and a replacement list, replaces each occurance of the -- search list with the replacement list in the operation list. -- -- Example: -- --
--   replace "," "." "127,0,0,1" -> "127.0.0.1"
--   
-- -- This could logically be thought of as: -- --
--   replace old new l = join new . split old $ l
--   
replace :: (Eq a) => [a] -> [a] -> [a] -> [a] -- | Like join, but works with a list of anything showable, -- converting it to a String. -- -- Examples: -- --
--   genericJoin ", " [1, 2, 3, 4] -> "1, 2, 3, 4"
--   genericJoin "|" ["foo", "bar", "baz"] -> "\"foo\"|\"bar\"|\"baz\""
--   
genericJoin :: (Show a) => String -> [a] -> String -- | Similar to Data.List.takeWhile, takes elements while the func is true. -- The function is given the remainder of the list to examine. takeWhileList :: ([a] -> Bool) -> [a] -> [a] -- | Similar to Data.List.dropWhile, drops elements while the func is true. -- The function is given the remainder of the list to examine. dropWhileList :: ([a] -> Bool) -> [a] -> [a] -- | Similar to Data.List.span, but performs the test on the entire -- remaining list instead of just one element. -- -- spanList p xs is the same as (takeWhileList p xs, -- dropWhileList p xs) spanList :: ([a] -> Bool) -> [a] -> ([a], [a]) -- | Similar to Data.List.break, but performs the test on the entire -- remaining list instead of just one element. breakList :: ([a] -> Bool) -> [a] -> ([a], [a]) -- | The type used for functions for wholeMap. See wholeMap -- for details. newtype WholeFunc a b WholeFunc :: ([a] -> (WholeFunc a b, [a], [b])) -> WholeFunc a b -- | This is an enhanced version of the concatMap or map functions in -- Data.List. -- -- Unlike those functions, this one: -- -- -- -- The function used by wholeMap, of type WholeFunc, is repeatedly -- called with the input list. The function returns three things: the -- function to call for the next iteration (if any), what remains of the -- input list, and the list of output elements generated during this -- iteration. The return value of wholeMap is the concatenation of -- the output element lists from all iterations. -- -- Processing stops when the remaining input list is empty. An example of -- a WholeFunc is fixedWidth. wholeMap :: WholeFunc a b -> [a] -> [b] -- | A parser designed to process fixed-width input fields. Use it with -- wholeMap. -- -- The Int list passed to this function is the list of the field widths -- desired from the input. The result is a list of those widths, if -- possible. If any of the input remains after processing this list, it -- is added on as the final element in the result list. If the input is -- less than the sum of the requested widths, then the result list will -- be short the appropriate number of elements, and its final element may -- be shorter than requested. -- -- Examples: -- --
--   wholeMap (fixedWidth [1, 2, 3]) "1234567890"
--    --> ["1","23","456","7890"]
--   wholeMap (fixedWidth (repeat 2)) "123456789"
--    --> ["12","34","56","78","9"]
--   wholeMap (fixedWidth []) "123456789"
--    --> ["123456789"]
--   wholeMap (fixedWidth [5, 3, 6, 1]) "Hello, This is a test."
--    --> ["Hello",", T","his is"," ","a test."]
--   
fixedWidth :: [Int] -> WholeFunc a [a] -- | Helps you pick out fixed-width components from a list. -- -- Example: -- --
--   conv :: String -> (String,String)
--   conv = runState $
--           do f3 <- grab 3
--              n2 <- grab 2
--              return $ f3 ++ "," ++ n2
--   
--   main = print $ conv "TestIng"
--   
-- -- Prints: -- --
--   ("Tes,tI","ng")
--   
grab :: Int -> State [a] [a] -- | Returns a count of the number of times the given element occured in -- the given list. countElem :: (Eq a) => a -> [a] -> Int -- | Returns the rightmost index of the given element in the given list. elemRIndex :: (Eq a) => a -> [a] -> Maybe Int -- | Like elemRIndex, but returns -1 if there is nothing found. alwaysElemRIndex :: (Eq a) => a -> [a] -> Int -- | Forces the evaluation of the entire list. seqList :: [a] -> [a] -- | Similar to Data.List.elemIndex. Instead of looking for one element in -- a list, this function looks for the first occurance of a sublist in -- the list, and returns the index of the first element of that -- occurance. If there is no such list, returns Nothing. -- -- If the list to look for is the empty list, will return Just 0 -- regardless of the content of the list to search. -- -- Examples: -- --
--   subIndex "foo" "asdfoobar" -> Just 3
--   subIndex "foo" [] -> Nothing
--   subIndex "" [] -> Just 0
--   subIndex "" "asdf" -> Just 0
--   subIndex "test" "asdftestbartest" -> Just 4
--   subIndex [(1::Int), 2] [0, 5, 3, 2, 1, 2, 4] -> Just 4
--   
subIndex :: (Eq a) => [a] -> [a] -> Maybe Int -- | Given a list, returns a new list with all duplicate elements removed. -- For example: -- --
--   uniq "Mississippi" -> "Misp"
--   
-- -- You should not rely on this function necessarily preserving order, -- though the current implementation happens to. -- -- This function is not compatible with infinite lists. uniq :: (Eq a) => [a] -> [a] -- | This module provides various helpful utilities for dealing with -- Data.Maps. -- -- Written by John Goerzen, jgoerzen@complete.org module Data.Map.Utils -- | Flips a Map. See flipAL for more on the similar function for -- lists. flipM :: (Ord key, Ord val) => Map key val -> Map val [key] -- | Returns a list of all keys in the Map whose value matches the -- parameter. If the value does not occur in the Map, the empty list is -- returned. flippedLookupM :: (Ord val, Ord key) => val -> Map key val -> [key] -- | Performs a lookup, and raises an exception (with an error message -- prepended with the given string) if the key could not be found. forceLookupM :: (Show key, Ord key) => String -> key -> Map key elt -> elt -- | Converts a String into a String, String Map. See strToAL for -- more on the similar function for association lists. -- -- This implementation is simple: -- --
--   strToM = Data.Map.fromList . strToAL
--   
-- -- This function is designed to work with Map String String objects, but -- may work with other key/value combinations if they have simple -- representations. strToM :: (Read a, Read b, Ord a) => String -> Map a b -- | Converts a String, String Map into a string representation. See -- strFromAL for more on the similar function for association -- lists. This implementation is simple: -- --
--   strFromM = strFromAL . Data.Map.toList
--   
-- -- This function is designed to work with Map String String objects, but -- may also work with other objects with simple representations. strFromM :: (Show a, Show b, Ord a) => Map a b -> String -- | This module provides various helpful utilities for dealing with path -- and file names, directories, and related support. -- -- Written by John Goerzen, jgoerzen@complete.org module System.Path -- | Splits a pathname into a tuple representing the root of the name and -- the extension. The extension is considered to be all characters from -- the last dot after the last slash to the end. Either returned string -- may be empty. splitExt :: String -> (String, String) -- | Make an absolute, normalized version of a path with all double -- slashes, dot, and dotdot entries removed. -- -- The first parameter is the base for the absolut calculation; in many -- cases, it would correspond to the current working directory. -- -- The second parameter is the pathname to transform. If it is already -- absolute, the first parameter is ignored. -- -- Nothing may be returned if there's an error; for instance, too many -- .. entries for the given path. absNormPath :: String -> String -> Maybe String -- | Like absNormPath, but returns Nothing if the generated result is not -- the passed base path or a subdirectory thereof. secureAbsNormPath :: String -> String -> Maybe String -- | Obtain a recursive listing of all files/directories beneath the -- specified directory. The traversal is depth-first and the original -- item is always present in the returned list. -- -- If the passed value is not a directory, the return value be only that -- value. -- -- The "." and ".." entries are removed from the data returned. recurseDir :: (HVFS a) => a -> FilePath -> IO [FilePath] -- | Like recurseDir, but return the stat() -- (System.Posix.Files.FileStatus) information with them. This is an -- optimization if you will be statting files yourself later. -- -- The items are returned lazily. -- -- WARNING: do not change your current working directory until you have -- consumed all the items. Doing so could cause strange effects. -- -- Alternatively, you may wish to pass an absolute path to this function. recurseDirStat :: (HVFS a) => a -> FilePath -> IO [(FilePath, HVFSStatEncap)] -- | Removes a file or a directory. If a directory, also removes all its -- child files/directories. recursiveRemove :: (HVFS a) => a -> FilePath -> IO () -- | Changes the current working directory to the given path, executes the -- given I/O action, then changes back to the original directory, even if -- the I/O action raised an exception. bracketCWD :: FilePath -> IO a -> IO a -- | Creates a temporary directory for your use. -- -- The passed string should be a template suitable for mkstemp; that is, -- end with "XXXXXX". -- -- Your string should probably start with the value returned from -- System.Directory.getTemporaryDirectory. -- -- The name of the directory created will be returned. mktmpdir :: String -> IO String -- | Creates a temporary directory for your use via mktmpdir, runs -- the specified action (passing in the directory name), then removes the -- directory and all its contents when the action completes (or raises an -- exception. brackettmpdir :: String -> (String -> IO a) -> IO a -- | Runs the given I/O action with the CWD set to the given tmp dir, -- removing the tmp dir and changing CWD back afterwards, even if there -- was an exception. brackettmpdirCWD :: String -> IO a -> IO a -- | Utilities for creating instances of the items defined in -- System.IO.HVFS. -- -- Copyright (c) 2004 John Goerzen, jgoerzen@complete.org module System.IO.HVFS.InstanceHelpers -- | A simple System.IO.HVFS.HVFSStat class that assumes that -- everything is either a file or a directory. data SimpleStat SimpleStat :: Bool -> FileOffset -> SimpleStat -- | True if file, False if directory isFile :: SimpleStat -> Bool -- | Set to 0 if unknown or a directory fileSize :: SimpleStat -> FileOffset -- | An in-memory read/write filesystem. Think of it as a dynamically -- resizable ramdisk written in Haskell. data MemoryVFS -- | Create a new MemoryVFS object from an existing tree. An empty -- filesystem may be created by using [] for the parameter. newMemoryVFS :: [MemoryNode] -> IO MemoryVFS -- | Create a new MemoryVFS object using an IORef to an existing -- tree. newMemoryVFSRef :: IORef [MemoryNode] -> IO MemoryVFS -- | The basic node of a MemoryVFS. The String corresponds to the -- filename, and the entry to the contents. type MemoryNode = (String, MemoryEntry) -- | The content of a file or directory in a MemoryVFS. data MemoryEntry MemoryDirectory :: [MemoryNode] -> MemoryEntry MemoryFile :: String -> MemoryEntry -- | Similar to System.Path.NameManip but the first element won't be -- /. -- --
--   nice_slice "/" -> []
--   nice_slice "/foo/bar" -> ["foo", "bar"]
--   
nice_slice :: String -> [String] -- | Gets a full path, after investigating the cwd. getFullPath :: (HVFS a) => a -> String -> IO String -- | Gets the full path via getFullPath, then splits it via -- nice_slice. getFullSlice :: (HVFS a) => a -> String -> IO [String] instance [overlap ok] Eq MemoryEntry instance [overlap ok] Show MemoryEntry instance [overlap ok] Show SimpleStat instance [overlap ok] Eq SimpleStat instance [overlap ok] HVFSOpenable MemoryVFS instance [overlap ok] HVFS MemoryVFS instance [overlap ok] Show MemoryVFS instance [overlap ok] HVFSStat SimpleStat -- | Support for combining different HVFS modules together -- -- Copyright (c) 2004-2005 John Goerzen, jgoerzen@complete.org module System.IO.HVFS.Combinators -- | Restrict access to the underlying filesystem to be strictly read-only. -- Any write-type operations will cause an error. -- -- No constructor is required; just say HVFSReadOnly fs to make -- a new read-only wrapper around the HVFS instance fs. data (HVFS a) => HVFSReadOnly a HVFSReadOnly :: a -> HVFSReadOnly a -- | Access a subdirectory of a real filesystem as if it was the root of -- that filesystem. data (HVFS a) => HVFSChroot a -- | Create a new HVFSChroot object. newHVFSChroot :: (HVFS a) => a -> FilePath -> IO (HVFSChroot a) instance [overlap ok] (Eq a, HVFS a) => Eq (HVFSChroot a) instance [overlap ok] (HVFS a) => Show (HVFSChroot a) instance [overlap ok] (Eq a, HVFS a) => Eq (HVFSReadOnly a) instance [overlap ok] (HVFS a) => Show (HVFSReadOnly a) instance [overlap ok] (HVFSOpenable a) => HVFSOpenable (HVFSChroot a) instance [overlap ok] (HVFS a) => HVFS (HVFSChroot a) instance [overlap ok] (HVFSOpenable a) => HVFSOpenable (HVFSReadOnly a) instance [overlap ok] (HVFS a) => HVFS (HVFSReadOnly a) -- | Utilities for guessing MIME types of files. -- -- Written by John Goerzen, jgoerzen@complete.org module Data.MIME.Types -- | Default MIME type data to use defaultmtd :: MIMETypeData -- | Read the given mime.types file and add it to an existing object. -- Returns new object. readMIMETypes :: MIMETypeData -> Bool -> FilePath -> IO MIMETypeData -- | Load a mime.types file from an already-open handle. hReadMIMETypes :: MIMETypeData -> Bool -> Handle -> IO MIMETypeData -- | Read the system's default mime.types files, and add the data contained -- therein to the passed object, then return the new one. readSystemMIMETypes :: MIMETypeData -> IO MIMETypeData -- | Return value from guessing a file's type. -- -- The first element of the tuple gives the MIME type. It is Nothing if -- no suitable type could be found. -- -- The second element gives the encoding. It is Nothing if there was no -- particular encoding for the file, or if no encoding could be found. type MIMEResults = (Maybe String, Maybe String) data MIMETypeData MIMETypeData :: Map String String -> Map String String -> Map String String -> Map String String -> MIMETypeData -- | A mapping used to expand common suffixes into equivolent, -- better-parsed versions. For instance, .tgz would expand into -- .tar.gz. suffixMap :: MIMETypeData -> Map String String -- | A mapping used to determine the encoding of a file. This is used, for -- instance, to map .gz to gzip. encodingsMap :: MIMETypeData -> Map String String -- | A mapping used to map extensions to MIME types. typesMap :: MIMETypeData -> Map String String -- | A mapping used to augment the typesMap when non-strict lookups -- are used. commonTypesMap :: MIMETypeData -> Map String String -- | Guess the type of a file given a filename or URL. The file is not -- opened; only the name is considered. guessType :: MIMETypeData -> Bool -> String -> MIMEResults -- | Guess the extension of a file based on its MIME type. The return value -- includes the leading dot. -- -- Returns Nothing if no extension could be found. -- -- In the event that multiple possible extensions are available, one of -- them will be picked and returned. The logic to select one of these -- should be considered undefined. guessExtension :: MIMETypeData -> Bool -> String -> Maybe String -- | Similar to guessExtension, but returns a list of all possible -- matching extensions, or the empty list if there are no matches. guessAllExtensions :: MIMETypeData -> Bool -> String -> [String] -- | This module provides various helpful utilities for dealing with -- strings. -- -- Written by John Goerzen, jgoerzen@complete.org module Data.String.Utils -- | Removes any whitespace characters that are present at the start or end -- of a string. Does not alter the internal contents of a string. If no -- whitespace characters are present at the start or end of a string, -- returns the original string unmodified. Safe to use on any string. -- -- Note that this may differ from some other similar functions from other -- authors in that: -- -- 1. If multiple whitespace characters are present all in a row, they -- are all removed; -- -- 2. If no whitespace characters are present, nothing is done. strip :: String -> String -- | Same as strip, but applies only to the left side of the string. lstrip :: String -> String -- | Same as strip, but applies only to the right side of the -- string. rstrip :: String -> String -- | Returns true if the given list starts with the specified elements; -- false otherwise. (This is an alias for Data.List.isPrefixOf.) -- -- Example: -- --
--   startswith "He" "Hello" -> True
--   
startswith :: (Eq a) => [a] -> [a] -> Bool -- | Returns true if the given list ends with the specified elements; false -- otherwise. (This is an alias for Data.List.isSuffixOf.) -- -- Example: -- --
--   endswith "lo" "Hello" -> True
--   
endswith :: (Eq a) => [a] -> [a] -> Bool -- | Given a delimiter and a list of items (or strings), join the items by -- using the delimiter. -- -- Example: -- --
--   join "|" ["foo", "bar", "baz"] -> "foo|bar|baz"
--   
join :: [a] -> [[a]] -> [a] -- | Given a delimiter and a list (or string), split into components. -- -- Example: -- --
--   split "," "foo,bar,,baz," -> ["foo", "bar", "", "baz", ""]
--   
-- --
--   split "ba" ",foo,bar,,baz," -> [",foo,","r,,","z,"]
--   
split :: (Eq a) => [a] -> [a] -> [[a]] -- | Splits a string around whitespace. Empty elements in the result list -- are automatically removed. splitWs :: String -> [String] -- | Given a list and a replacement list, replaces each occurance of the -- search list with the replacement list in the operation list. -- -- Example: -- --
--   replace "," "." "127,0,0,1" -> "127.0.0.1"
--   
-- -- This could logically be thought of as: -- --
--   replace old new l = join new . split old $ l
--   
replace :: (Eq a) => [a] -> [a] -> [a] -> [a] -- | Escape all characters in the input pattern that are not alphanumeric. -- -- Does not make special allowances for NULL, which isn't valid in a -- Haskell regular expression pattern. escapeRe :: String -> String -- | Tool for maintaining a status bar, supporting multiple simultaneous -- tasks, as a layer atop Data.Progress.Tracker. -- -- Written by John Goerzen, jgoerzen@complete.org module Data.Progress.Meter type ProgressMeter = MVar ProgressMeterR -- | Set up a new status bar using defaults: -- -- simpleNewMeter :: Progress -> IO ProgressMeter -- | Set up a new status bar. newMeter :: Progress -> String -> Int -> ([Integer] -> [String]) -> IO ProgressMeter -- | Adjust the list of components of this ProgressMeter. setComponents :: ProgressMeter -> [Progress] -> IO () -- | Add a new component to the list of components. addComponent :: ProgressMeter -> Progress -> IO () -- | Remove a component by name. removeComponent :: ProgressMeter -> String -> IO () -- | Adjusts the width of this ProgressMeter. setWidth :: ProgressMeter -> Int -> IO () -- | Render the current status. renderMeter :: ProgressMeter -> IO String -- | Like renderMeter, but prints it to the screen instead of returning it. -- -- This function will output CR, then the meter. -- -- Pass stdout as the handle for regular display to the screen. displayMeter :: Handle -> ProgressMeter -> IO () -- | Clears the meter -- outputs CR, spaces equal to the width - 1, then -- another CR. -- -- Pass stdout as the handle for regular display to the screen. clearMeter :: Handle -> ProgressMeter -> IO () -- | Clears the meter, writes the given string, then restores the meter. -- The string is assumed to contain a trailing newline. -- -- Pass stdout as the handle for regular display to the screen. writeMeterString :: Handle -> ProgressMeter -> String -> IO () -- | Starts a thread that updates the meter every n seconds by calling the -- specified function. Note: displayMeter stdout is an ideal -- function here. -- -- Save this threadID and use it later to call stopAutoDisplayMeter. autoDisplayMeter :: ProgressMeter -> Int -> (ProgressMeter -> IO ()) -> IO ThreadId -- | Stops the specified meter from displaying. -- -- You should probably call clearMeter after a call to this. killAutoDisplayMeter :: ProgressMeter -> ThreadId -> IO () -- | Matching filenames with wildcards. See also System.Path.Glob -- for support for generating lists of files based on wildcards. -- -- Inspired by fnmatch.py, part of the Python standard library. -- -- Written by John Goerzen, jgoerzen@complete.org -- -- The input wildcard for functions in this module is expected to be in -- the standard style of Posix shells. -- -- That is: -- --
--   ? matches exactly one character
--   \* matches zero or more characters
--   [list] matches any character in list
--   [!list] matches any character not in the list
--   
-- -- The returned regular expression will always end in $ but never begins -- with ^, making it suitable for appending to the end of paths. If you -- want to match a given filename directly, you should prepend the ^ -- character to the returned value from this function. -- -- Please note: -- -- module System.Path.WildMatch -- | Check the given name against the given pattern, being case-sensitive. -- -- The given pattern is forced to match the given name starting at the -- beginning. wildCheckCase :: String -> String -> Bool -- | Convert a wildcard to an (uncompiled) regular expression. wildToRegex :: String -> String -- | Functions for expanding wildcards, filenames, and pathnames. -- -- For information on the metacharacters recognized, please see the notes -- in System.Path.WildMatch. module System.Path.Glob -- | Takes a pattern. Returns a list of names that match that pattern. The -- pattern is evaluated by System.Path.WildMatch. This function -- does not perform tilde or environment variable expansion. -- -- Filenames that begin with a dot are not included in the result set -- unless that component of the pattern also begins with a dot. -- -- In MissingH, this function is defined as: -- --
--   glob = vGlob SystemFS
--   
glob :: FilePath -> IO [FilePath] -- | Like glob, but works on both the system (real) and HVFS -- virtual filesystems. vGlob :: (HVFS a) => a -> FilePath -> IO [FilePath] -- | This module provides various helpful utilities for dealing with Debian -- files and programs. -- -- Written by John Goerzen, jgoerzen@complete.org module System.Debian.ControlParser -- | Main parser for the control file control :: CharParser a [(String, String)] -- | Dependency parser. -- -- Returns (package name, Maybe version, arch list) -- -- version is (operator, operand) depPart :: CharParser a (String, Maybe (String, String), [String])