-- 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.2.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.
--   
--   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
--   #if (defined(mingw32_HOST_OS) || defined(mingw32_TARGET_OS) || defined(__MINGW32__))
--   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.
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
isBlockDevice :: FileStatusCompat -> Bool
isSocket :: FileStatusCompat -> Bool
isSymbolicLink :: FileStatusCompat -> Bool
isDirectory :: FileStatusCompat -> Bool
isRegularFile :: FileStatusCompat -> Bool
isNamedPipe :: FileStatusCompat -> Bool
isCharacterDevice :: 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.
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, Num 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 GZipError
instance [overlap ok] Show GZipError
instance [overlap ok] Eq Header
instance [overlap ok] Show Header
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
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
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 InetServerOptions
instance [overlap ok] Show InetServerOptions
instance [overlap ok] Eq SocketServer
instance [overlap ok] Show SocketServer

-- | 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:
--   
--   
--   
- %% a % character.
--   
- %a locale's abbreviated weekday name (Sun ... Sat)
--   
- %A locale's full weekday name (Sunday .. Saturday)
--   
- %b locale's abbreviated month name (Jan..Dec)
--   
- %B locale's full month name (January..December)
--   
- %c locale's date and time format (Thu Mar 25 17:47:03 CET
--   2004)
--   
- %C century [00-99]
--   
- %d day of month, zero padded (01..31)
--   
- %D date (%m/%d/%y)
--   
- %e day of month, space padded ( 1..31)
--   
- %h same as %b
--   
- %H hour, 24-hour clock, zero padded (00..23)
--   
- %I hour, 12-hour clock, zero padded (01..12)
--   
- %j day of the year, zero padded (001..366)
--   
- %k hour, 24-hour clock, space padded ( 0..23)
--   
- %l hour, 12-hour clock, space padded ( 1..12)
--   
- %m month, zero padded (01..12)
--   
- %M minute, zero padded (00..59)
--   
- %n a newline character
--   
- %p locale's AM or PM indicator
--   
- %r locale's 12-hour time format (hh:mm:ss AM/PM)
--   
- %R hours and minutes, 24-hour clock (hh:mm)
--   
- %s * seconds since '00:00:00 1970-01-01 UTC'
--   
- %S seconds, zero padded (00..59)
--   
- %t a horizontal tab character
--   
- %T time, 24-hour clock (hh:mm:ss)
--   
- %u numeric day of the week (1=Monday, 7=Sunday)
--   
- %U * week number, weeks starting on Sunday, zero padded
--   (01-53)
--   
- %V * week number (as per ISO-8601), week 1 is the first
--   week with a Thursday, zero padded, (01-53)
--   
- %w numeric day of the week, (0=Sunday, 6=Monday)
--   
- %W * week number, weeks starting on Monday, zero padded
--   (01-53)
--   
- %x locale's preferred way of printing dates (%m/%d/%y)
--   
- %X locale's preferred way of printing time. (%H:%M:%S)
--   
- %y year, within century, zero padded (00..99)
--   
- %Y year, including century. Not padded (this is probably a
--   bug, but formatCalendarTime does it this way). (0-9999)
--   
- %Z time zone abbreviation (e.g. CET) or RFC-822 style
--   numeric timezone (-0500)
--   
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]

-- | Parses a String, possibly generated by renderNum. Parses the
--   suffix and applies it to the number, which is read via the Read class.
--   
--   Returns Left error message on error, or Right number on
--   successful parse.
--   
--   If you want an Integral result, the convenience function
--   parseNumInt is for you.
parseNum :: (Read a, Fractional a) => SizeOpts -> Bool -> String -> Either String a

-- | Parse a number as with parseNum, but return the result as an
--   Integral. Any type such as Integer, Int, etc. can be used for
--   the result type.
--   
--   This function simply calls round on the result of
--   parseNum. A Double is used internally for the parsing of
--   the numeric component.
--   
--   By using this function, a user can still say something like 1.5M and
--   get an integral result.
parseNumInt :: (Read a, Integral a) => SizeOpts -> Bool -> String -> Either String a

-- | 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)

-- | Tools for packing into bins
--   
--   Written by John Goerzen, jgoerzen@complete.org
--   
--   This module is designed to solve this type of problem: Given a bunch
--   of objects of varying sizes, what is the best possible way to pack
--   them into fixed-size bins? This can be used, for instance, by the
--   datapacker program to pack files onto CDs or DVDs; by manufacturing
--   environments to pack physical items into physicl bins; etc.
--   
--   A description of bin packing algorithms can be found at
--   http://en.wikipedia.org/wiki/Bin_packing_problem.
module Data.BinPacking

-- | The primary type for bin-packing functions.
--   
--   These functions take a list of size of bins. If every bin is the same
--   size, you can pass repeat binSize to pass an infinite list of
--   bins if the same size. Any surplus bins will simply be ignored.
--   
--   
--   [size] is the sizes of bins
--   [(size, obj)] is the sizes and objects
--   result is Either error or results
--   
type BinPacker = (Num size, Ord size, Show size, Show obj) => [size] -> [(size, obj)] -> Either (BinPackerError size obj) [[(size, obj)]]

-- | Potential errors returned as Left values by BinPacker
--   functions. Calling show on this value will produce a nice error
--   message suitable for display.
data (Num size, Ord size, Show size, Show obj) => BinPackerError size obj

-- | Ran out of bins; attached value is the list of objects that do not fit
BPTooFewBins :: [(size, obj)] -> BinPackerError size obj

-- | Bin size1 exceeded by at least the given object and size
BPSizeTooLarge :: size -> (size, obj) -> BinPackerError size obj

-- | Other error
BPOther :: String -> BinPackerError size obj

-- | Pack objects into bins, preserving order. Objects will be taken from
--   the input list one by one, and added to each bin until the bin is
--   full. Work will then proceed on the next bin. No attempt is made to
--   optimize allocations to bins. This is the simplest and most naive
--   bin-packing algorithm, but may not make very good use of bin space.
packByOrder :: BinPacker

-- | Pack objects into bins. For each bin, start with the largest objects,
--   and keep packing the largest object from the remainder until no object
--   can be found to put in the bin. This is substantially more efficient
--   than packByOrder, but requires sorting the input.
packLargeFirst :: BinPacker
instance [overlap ok] (Eq obj, Num size, Ord size, Show size, Show obj) => Eq (BinPackerError size obj)
instance [overlap ok] (Num size, Ord size, Read size, Read obj, Show size, Show obj) => Read (BinPackerError size obj)
instance [overlap ok] (Num size, Ord size, Show size, Show obj) => Error (BinPackerError size obj)
instance [overlap ok] (Num size, Ord size, Show size, Show obj) => Show (BinPackerError size obj)

-- | 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.
--   Zombies 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.
--   Zombies 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.
--   Zombies 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 where listIDs mb = listMessageFlags mb >>= return . map fst listMessageFlags mb = getAll mb >>= return . map (\ (i, f, _) -> (i, f)) getMessages mb list = do { messages <- getAll mb; return $ filter (\ (id, f, m) -> id `elem` list) messages }
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

-- | 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
--   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:
--   
--   
--   
- The PID of the running process will change
--   
- stdin, stdout, and stderr will not work (they'll be set to
--   /dev/null)
--   
- CWD will be changed to /
--   
--   
--   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:
--   
--   
--   
- The ability to use a single set of functions on various different
--   types of objects, including standard Handles, in-memory buffers,
--   compressed files, network data streams, etc.
--   
- The ability to transparently add filters to the I/O process. These
--   filters could include things such as character set conversions,
--   compression or decompression of a data stream, and more.
--   
- The ability to define new objects that have the properties of I/O
--   objects and can be used interchangably with them.
--   
- Specification compatibility with, and complete support for,
--   existing I/O on Handles.
--   
- Provide easier unit testing capabilities for I/O actions
--   
--   
--   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:
--   
--   
--   
- The new method can still accept a Handle in exactly the same way
--   as the old method. Changing your functions to use HVIO will require no
--   changes from functions that call them with Handles.
--   
- Most "h" functions have equivolent "v" functions that operate on
--   HVIO classes instead of the more specific Handle. The "v" functions
--   behave identically to the "h" functions whenever possible.
--   
- There is no equivolent of "openFile" in any HVIO class. You must
--   create your Handle (or other HVIO object) using normal means. This is
--   because the creation is so different that it cannot be
--   standardized.
--   
--   
--   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 where vSetBuffering _ _ = return () vGetBuffering _ = return NoBuffering vShow x = return (show x) vMkIOError _ et desc mfp = mkIOError et desc Nothing mfp vGetFP _ = return Nothing vThrow h et = do { fp <- vGetFP h; ioError (vMkIOError h et "" fp) } vTestEOF h = do { e <- vIsEOF h; if e then vThrow h eofErrorType else return () } vIsOpen h = vIsClosed h >>= return . not vIsClosed h = vIsOpen h >>= return . not vTestOpen h = do { e <- vIsClosed h; if e then vThrow h illegalOperationErrorType else return () } vIsReadable _ = return False vGetLine h = let loop accum = let func = do { c <- vGetChar h; case c of { '\n' -> return accum x -> accum `seq` loop (accum ++ [x]) } } handler e = if isEOFError e then return accum else ioError e in catch func handler in do { firstchar <- vGetChar h; case firstchar of { '\n' -> return [] x -> loop [x] } } vGetContents h = let loop = let func = do { c <- vGetChar h; next <- loop; c `seq` return (c : next) } handler e = if isEOFError e then return [] else ioError e in catch func handler in do { loop } vReady h = do { vTestEOF h; return True } vIsWritable _ = return False vPutStr _ [] = return () vPutStr h (x : xs) = do { vPutChar h x; vPutStr h xs } vPutStrLn h s = vPutStr h (s ++ "") vPrint h s = vPutStrLn h (show s) vFlush = vTestOpen vIsSeekable _ = return False vRewind h = vSeek h AbsoluteSeek 0 vPutChar h _ = vThrow h illegalOperationErrorType vSeek h _ _ = vThrow h illegalOperationErrorType vTell h = vThrow h illegalOperationErrorType vGetChar h = vThrow h illegalOperationErrorType vPutBuf h buf len = do { str <- peekCStringLen (castPtr buf, len); vPutStr h str } vGetBuf h b l = worker b l 0 where worker _ 0 accum = return accum worker buf len accum = do { iseof <- vIsEOF h; if iseof then return accum else do { c <- vGetChar h; let cc = castCharToCChar c; poke (castPtr buf) cc; let newptr = plusPtr buf 1; worker newptr (len - 1) (accum + 1) } }
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:
--   
--   
--   
- vGetModificationTime -- implemented in terms of
--   vGetFileStatus
--   
- vRaiseError
--   
- vDoesFileExist -- implemented in terms of
--   vGetFileStatus
--   
- vDoesDirectoryExist -- implemented in terms of
--   vGetFileStatus
--   
- vDoesExist -- implemented in terms of
--   vGetSymbolicLinkStatus
--   
- vGetSymbolicLinkStatus -- set to call
--   vGetFileStatus.
--   
--   
--   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 where vGetModificationTime fs fp = do { s <- vGetFileStatus fs fp; return $ epochToClockTime (withStat s vModificationTime) } vRaiseError _ et desc mfp = ioError $ mkIOError et desc Nothing mfp vGetCurrentDirectory fs = eh fs "vGetCurrentDirectory" vSetCurrentDirectory fs _ = eh fs "vSetCurrentDirectory" vGetDirectoryContents fs _ = eh fs "vGetDirectoryContents" vDoesFileExist fs fp = catch (do { s <- vGetFileStatus fs fp; return $ withStat s vIsRegularFile }) (\ (_ :: IOException) -> return False) vDoesDirectoryExist fs fp = catch (do { s <- vGetFileStatus fs fp; return $ withStat s vIsDirectory }) (\ (_ :: IOException) -> return False) vDoesExist fs fp = catch (do { s <- vGetSymbolicLinkStatus fs fp; return True }) (\ (_ :: IOException) -> return False) vCreateDirectory fs _ = eh fs "vCreateDirectory" vRemoveDirectory fs _ = eh fs "vRemoveDirectory" vRemoveFile fs _ = eh fs "vRemoveFile" vRenameFile fs _ _ = eh fs "vRenameFile" vRenameDirectory fs _ _ = eh fs "vRenameDirectory" vCreateSymbolicLink fs _ _ = eh fs "vCreateSymbolicLink" vReadSymbolicLink fs _ = eh fs "vReadSymbolicLink" vCreateLink fs _ _ = eh fs "vCreateLink" vGetSymbolicLinkStatus = vGetFileStatus
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 where vDeviceID _ = 0 vFileID _ = 0 vFileMode x = if vIsDirectory x then 1877 else 420 vLinkCount _ = 1 vFileOwner _ = 0 vFileGroup _ = 0 vSpecialDeviceID _ = 0 vFileSize _ = 0 vAccessTime _ = 0 vModificationTime _ = 0 vStatusChangeTime _ = 0 vIsBlockDevice _ = False vIsCharacterDevice _ = False vIsNamedPipe _ = False vIsSymbolicLink _ = False vIsSocket _ = False
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 where vReadFile h fp = do { oe <- vOpen h fp ReadMode; withOpen oe (\ fh -> vGetContents fh) } vWriteFile h fp s = do { oe <- vOpen h fp WriteMode; withOpen oe (\ fh -> do { vPutStr fh s; vClose fh }) } vOpenBinaryFile = vOpen
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

-- | See openFile
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:
--   
--   
--   
- GHC 6.2 and above: yes
--   
- GHC 6.x, earlier versions: unknown
--   
- GHC 5.x: no
--   
- nhc98: no
--   
- Hugs: partial (maybe complete; needs more testing)
--   
--   
--   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.

-- | Deprecated: Use Data.List.isInfixOf, will be removed in MissingH
--   1.1.0 
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:
--   
--   
--   
- Can consume a varying number of elements from the input list
--   during each iteration
--   
- Can arbitrarily decide when to stop processing data
--   
- Can return a varying number of elements to insert into the output
--   list
--   
- Can actually switch processing functions mid-stream
--   
- Is not even restricted to processing the input list intact
--   
--   
--   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.
--   
--   This is presently an alias for Data.List.nub
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.
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 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] Show SimpleStat
instance [overlap ok] Eq SimpleStat
instance [overlap ok] Eq MemoryEntry
instance [overlap ok] Show MemoryEntry
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 (HVFSReadOnly a)
instance [overlap ok] HVFS a => Show (HVFSReadOnly a)
instance [overlap ok] (Eq a, HVFS a) => Eq (HVFSChroot a)
instance [overlap ok] HVFS a => Show (HVFSChroot 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:
--   
--   
--   
- If multiple whitespace characters are present all in a row, they
--   are all removed;
--   
- 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

-- | Attempts to parse a value from the front of the string.
maybeRead :: Read a => String -> Maybe a

-- | 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:
--   
--   
--   
- The given tracker
--   
- Width 80
--   
- Data.Quantity.renderNums binaryOpts 1
--   
- Unit inticator B
--   
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:
--   
--   
--   
- Neither the path separator (the slash or backslash) nor the period
--   carry any special meaning for the functions in this module. That is,
--   * will match / in a filename. If this is not the
--   behavior you want, you probably want System.Path.Glob instead
--   of this module.
--   
- Unlike the Unix shell, filenames that begin with a period are not
--   ignored by this module. That is, *.txt will match
--   .test.txt.
--   
- This module does not current permit escaping of special
--   characters.
--   
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])
