-- 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 <a>parseCmdLine</a>, 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 <a>Ord</a>, but you can also use <a>compareDebVersion</a>
--   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 <a>System.IO.StatCompat</a>, which this module re-exports.
--   
--   On non-Windows platforms, this module does nothing.
--   
--   On Windows, it re-exports <a>System.IO.StatCompat</a>. It also
--   provides various file type information modes that are otherwise in
--   <a>System.Posix.Types</a> or <a>System.Posix.Files</a>. It also
--   provides a rudimentary implemention of getFileStatus that emulates the
--   Posix call to stat(2).
--   
--   Common usage might be like this:
--   
--   <pre>
--   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
--   </pre>
--   
--   Or, to avoid having to use CPP and make things even easier, just
--   import <a>System.IO.PlafCompat</a>, 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 <a>System.IO.WindowsCompat</a>.
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
--   <a>System.IO.WindowsCompat</a>.
--   
--   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 : <a>igloo@earth.li</a> 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 <a>md5s</a>.
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:
--   
--   <pre>
--   getBytes (0x12345678::Int) -&gt; [0x12, 0x34, 0x56, 0x78]
--   </pre>
getBytes :: (Integral a, Bounded a, Bits a) => a -> [a]

-- | The opposite of <a>getBytes</a>, this function builds a number based
--   on its component bytes.
--   
--   Results are undefined if any components of the input list are &gt;
--   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 <a>Section</a> 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, <a>http://www.cs.york.ac.uk/~ndm/</a>
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 <a>forceMaybe</a>, 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:
--   
--   <pre>
--   maybeToEither :: e -&gt; Maybe a -&gt; Either e a
--   </pre>
--   
--   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 <a>Right</a> value out of an Either value. If the Either value
--   is Left, raises an exception with <a>error</a>.
forceEither :: Show e => Either e a -> a

-- | Like <a>forceEither</a>, 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:
--   
--   <pre>
--   main = niceSocketsDo $ do { ... }
--   </pre>
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 <a>Network.FTP.Server</a>.
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 <a>SocketServer</a>
--   and handle all incoming requests.
--   
--   This function is literally this:
--   
--   <pre>
--   serveTCPforever options func =
--       do sockserv &lt;- setupSocketServer options
--          serveForever sockserv func
--   </pre>
serveTCPforever :: InetServerOptions -> HandlerT -> IO ()

-- | Takes some options and sets up the <a>SocketServer</a>. I will bind
--   and begin listening, but will not accept any connections itself.
setupSocketServer :: InetServerOptions -> IO SocketServer

-- | Handle one incoming request from the given <a>SocketServer</a>.
handleOne :: SocketServer -> HandlerT -> IO ()

-- | Handle all incoming requests from the given <a>SocketServer</a>.
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
--   <a>System.Log.Logger</a>.
--   
--   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 <a>formatCalendarTime</a>.
--   
--   The resulting <a>CalendarTime</a> 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 <a>ctWDay</a> 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:
--   
--   <ul>
--   <li><i>%%</i> a % character.</li>
--   <li><i>%a</i> locale's abbreviated weekday name (Sun ... Sat)</li>
--   <li><i>%A</i> locale's full weekday name (Sunday .. Saturday)</li>
--   <li><i>%b</i> locale's abbreviated month name (Jan..Dec)</li>
--   <li><i>%B</i> locale's full month name (January..December)</li>
--   <li><i>%c</i> locale's date and time format (Thu Mar 25 17:47:03 CET
--   2004)</li>
--   <li><i>%C</i> century [00-99]</li>
--   <li><i>%d</i> day of month, zero padded (01..31)</li>
--   <li><i>%D</i> date (%m/%d/%y)</li>
--   <li><i>%e</i> day of month, space padded ( 1..31)</li>
--   <li><i>%h</i> same as %b</li>
--   <li><i>%H</i> hour, 24-hour clock, zero padded (00..23)</li>
--   <li><i>%I</i> hour, 12-hour clock, zero padded (01..12)</li>
--   <li><i>%j</i> day of the year, zero padded (001..366)</li>
--   <li><i>%k</i> hour, 24-hour clock, space padded ( 0..23)</li>
--   <li><i>%l</i> hour, 12-hour clock, space padded ( 1..12)</li>
--   <li><i>%m</i> month, zero padded (01..12)</li>
--   <li><i>%M</i> minute, zero padded (00..59)</li>
--   <li><i>%n</i> a newline character</li>
--   <li><i>%p</i> locale's AM or PM indicator</li>
--   <li><i>%r</i> locale's 12-hour time format (hh:mm:ss AM/PM)</li>
--   <li><i>%R</i> hours and minutes, 24-hour clock (hh:mm)</li>
--   <li><i>%s</i> * seconds since '00:00:00 1970-01-01 UTC'</li>
--   <li><i>%S</i> seconds, zero padded (00..59)</li>
--   <li><i>%t</i> a horizontal tab character</li>
--   <li><i>%T</i> time, 24-hour clock (hh:mm:ss)</li>
--   <li><i>%u</i> numeric day of the week (1=Monday, 7=Sunday)</li>
--   <li><i>%U</i> * week number, weeks starting on Sunday, zero padded
--   (01-53)</li>
--   <li><i>%V</i> * week number (as per ISO-8601), week 1 is the first
--   week with a Thursday, zero padded, (01-53)</li>
--   <li><i>%w</i> numeric day of the week, (0=Sunday, 6=Monday)</li>
--   <li><i>%W</i> * week number, weeks starting on Monday, zero padded
--   (01-53)</li>
--   <li><i>%x</i> locale's preferred way of printing dates (%m/%d/%y)</li>
--   <li><i>%X</i> locale's preferred way of printing time. (%H:%M:%S)</li>
--   <li><i>%y</i> year, within century, zero padded (00..99)</li>
--   <li><i>%Y</i> year, including century. Not padded (this is probably a
--   bug, but formatCalendarTime does it this way). (0-9999)</li>
--   <li><i>%Z</i> time zone abbreviation (e.g. CET) or RFC-822 style
--   numeric timezone (-0500)</li>
--   </ul>
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 "<tt>/</tt>" characters don't
--   lead to empty components. "<tt>.</tt>" path components are removed. If
--   the path is absolute, the first component will start with
--   "<tt>/</tt>". "<tt>..</tt>" components are left intact. They can't be
--   simply removed, because the preceding component might be a symlink. In
--   this case, <tt>realpath</tt> is probably what you need.
--   
--   The case that the path is empty, is probably an error. However, it is
--   treated like "<tt>.</tt>", yielding an empty path components list.
--   
--   Examples:
--   
--   <pre>
--   slice_path "/"        = ["/"]
--   slice_path "/foo/bar" = ["/foo","bar"]
--   slice_path "..//./"   = [".."]
--   slice_path "."        = []
--   </pre>
--   
--   See <a>unslice_path</a>, <tt>realpath</tt>, <tt>realpath_s</tt>.
slice_path :: String -> [String]

-- | Form a path from path components. This isn't the inverse of
--   <a>slice_path</a>, since <tt><a>unslice_path</a> .
--   <a>slice_path</a></tt> normalises the path.
--   
--   See <a>slice_path</a>.
unslice_path :: [String] -> String

-- | Normalise a path. This is done by reducing repeated <tt>/</tt>
--   characters to one, and removing <tt>.</tt> path components.
--   <tt>..</tt> path components are left intact, because of possible
--   symlinks.
--   
--   <pre>
--   <a>normalise_path</a> = <a>unslice_path</a> . <a>slice_path</a>
--   </pre>
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: <tt>concat . intersperse "." .
--   <a>slice_filename</a> == <tt>normalise</tt></tt>.
--   
--   Note that the last path component might be "<tt>..</tt>". 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:
--   
--   <pre>
--   <a>slice_filename</a> "a.b//./.foo.tar.gz" == ["a.b/.foo","tar","gz"]
--   <a>slice_filename</a> ".x..y."             == [".x.", "y."]
--   </pre>
--   
--   See <a>unslice_filename</a>, <tt>slice_filename'</tt>.
slice_filename :: String -> [String]

-- | This is a variant of <a>slice_filename</a>. It is like
--   <a>slice_filename</a>, except for being more efficient, and the
--   filename must not contain any preceding path, since this case isn't
--   considered.
--   
--   See <a>slice_filename</a>, <a>unslice_filename</a>.
slice_filename' :: String -> [String]

-- | Form file name from file name components, interspersing dots. This is
--   the inverse of <a>slice_filename</a>, except for normalisation of any
--   path.
--   
--   <pre>
--   unslice_filename = concat . intersperse "."
--   </pre>
--   
--   See <a>slice_filename</a>.
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,
--   <tt>"."</tt> 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.
--   
--   <tt>split_path</tt> splits off the last path component. This isn't the
--   same as the text after the last <tt>/</tt>.
--   
--   Note that the last path component might be <tt>".."</tt>. 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:
--   
--   <pre>
--   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")
--   </pre>
--   
--   See <a>slice_path</a>.
split_path :: String -> (String, String)

-- | Get the directory part of a path.
--   
--   <pre>
--   dir_part = fst . split_path
--   </pre>
--   
--   See <a>split_path</a>.
dir_part :: String -> String

-- | Get the last path component of a path.
--   
--   <pre>
--   filename_part = snd . split_path
--   </pre>
--   
--   Examples:
--   
--   <pre>
--   filename_part "foo/bar" == "bar"
--   filename_part "."       == "."
--   </pre>
--   
--   See <a>split_path</a>.
filename_part :: String -> String

-- | Inverse of <a>split_path</a>, except for normalisation.
--   
--   This concatenates two paths, and takes care of <tt>"."</tt> and empty
--   paths. When the two components are the result of <tt>split_path</tt>,
--   then <tt>unsplit_path</tt> creates a normalised path. It is best
--   documented by its definition:
--   
--   <pre>
--   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
--   </pre>
--   
--   Examples:
--   
--   <pre>
--   unsplit_path ("", "")     == ""
--   unsplit_path (".", "")    == "."
--   unsplit_path (".", ".")   == "."
--   unsplit_path ("foo", ".") == "foo"
--   </pre>
--   
--   See <a>split_path</a>.
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, <tt>"."</tt>
--   components are removed, and multiple "<tt>/</tt>"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:
--   
--   <pre>
--   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)")
--   </pre>
--   
--   See <a>slice_path</a>, 'split_filename\''
split_filename :: String -> (String, String)

-- | Variant of <a>split_filename</a>. This is a more efficient version of
--   <a>split_filename</a>, for the case that you know the string is is a
--   pure file name without any slashes.
--   
--   See <a>split_filename</a>.
split_filename' :: String -> (String, String)

-- | Inverse of <a>split_filename</a>. Concatenate prefix and suffix,
--   adding a dot in between, iff the suffix is not empty. The path part of
--   the prefix is normalised.
--   
--   See <a>split_filename</a>.
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 <tt>Just
--   prefix</tt>, where <tt>prefix</tt> is the normalised path without the
--   suffix. Otherwise it's <tt>Nothing</tt>.
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
--   <tt>getCurrentDirectory</tt> which means that symbolic links in it are
--   expanded and the path is normalised. This is different from
--   <tt>pwd</tt>.
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
--   <a>absolute_path_by</a>. <tt>absolute_path'</tt> is included for
--   backwards compatibility.
absolute_path' :: String -> String -> String

-- | Guess the <tt>".."</tt>-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
--   <tt>".."</tt> components, or more <tt>".."</tt> components than
--   preceeding normal components, then the <tt>".."</tt> components can't
--   be normalised away. In this case, the result is <tt>Nothing</tt>.
guess_dotdot_comps :: [String] -> Maybe [String]

-- | Guess the <tt>".."</tt>-component free, normalised form of a path. The
--   transformation is purely syntactic. <tt>".."</tt> 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 <tt>".."</tt> components, or more <tt>".."</tt>
--   components than preceeding normal components, then the <tt>".."</tt>
--   components can't be normalised away. In this case, the result is
--   <tt>Nothing</tt>.
--   
--   <pre>
--   guess_dotdot = fmap unslice_path . guess_dotdot_comps . slice_path
--   </pre>
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 <a>SizeOpts</a> 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:
--   
--   <pre>
--   Data.Quantity&gt; renderNum binaryOpts 0 1048576
--   "1M"
--   Data.Quantity&gt; renderNum binaryOpts 2 10485760
--   "10.00M"
--   Data.Quantity&gt; renderNum binaryOpts 3 1048576
--   "1.000M"
--   Data.Quantity&gt; renderNum binaryOpts 3 1500000
--   "1.431M"
--   Data.Quantity&gt; renderNum binaryOpts 2 (1500 ** 3)
--   "3.14G"
--   </pre>
--   
--   <pre>
--   Data.Quantity&gt; renderNum siOpts 2 1024
--   "1.02k"
--   Data.Quantity&gt; renderNum siOpts 2 1048576
--   "1.05M"
--   Data.Quantity&gt; renderNum siOpts 2 0.001
--   "1.00m"
--   Data.Quantity&gt; renderNum siOpts 2 0.0001
--   "100.00u"
--   </pre>
--   
--   If you want more control over the output, see <a>quantifyNum</a>.
renderNum :: (Ord a, Real a) => SizeOpts -> Int -> a -> String

-- | Like <a>renderNum</a>, 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
--   <a>renderNum</a> for more examples.
--   
--   Also, unlike <a>renderNum</a>, the %f instead of %g printf format is
--   used so that "scientific" notation is avoided in the output.
--   
--   Examples:
--   
--   <pre>
--   *Data.Quantity&gt; renderNums binaryOpts 3 [1500000, 10240, 104857600]
--   ["1.431M","0.010M","100.000M"]
--   *Data.Quantity&gt; renderNums binaryOpts 3 [1500, 10240, 104857600]
--   ["1.465K","10.000K","102400.000K"]
--   </pre>
renderNums :: (Ord a, Real a) => SizeOpts -> Int -> [a] -> [String]

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

-- | Parse a number as with <a>parseNum</a>, but return the result as an
--   <a>Integral</a>. Any type such as Integer, Int, etc. can be used for
--   the result type.
--   
--   This function simply calls <a>round</a> on the result of
--   <a>parseNum</a>. A <a>Double</a> 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 <a>quantifyNum</a>, 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
--   <a>renderNums</a> 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 <a>quantifyNum</a> and <a>renderNum</a>
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
--   <a>epochToClockTime</a>.
--   
--   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:
--   
--   <pre>
--   renderSecs 121 = "2m1s"
--   </pre>
--   
--   See also <a>renderTD</a> for a function that works on a TimeDiff.
renderSecs :: Integer -> String

-- | Like <a>renderSecs</a>, 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 <a>Data.Progress.Meter</a>
module Data.Progress.Tracker

-- | Create a new <a>Progress</a> 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:
--   
--   <pre>
--   prog &lt;- newProgress "mytracker" 1024
--   </pre>
newProgress :: String -> Integer -> IO Progress

-- | Create a new <a>Progress</a> object initialized with the given status
--   and callbacks. No adjustment to the <a>startTime</a> will be made. If
--   you want to use the system clock, you can initialize <a>startTime</a>
--   with the return value of <a>defaultTimeSource</a> and also pass
--   <a>defaultTimeSource</a> as the timing source.
newProgress' :: ProgressStatus -> [ProgressCallback] -> IO Progress

-- | Adds an new callback to an existing <a>Progress</a>. 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 <a>Progress</a>. The parent will
--   automatically have its completed and total counters incremented by the
--   value of those counters in the existing <a>Progress</a>.
addParent :: Progress -> Progress -> IO ()

-- | Increment the completed unit count in the <a>Progress</a> 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 <a>incrP</a>, but never modify the total.
incrP' :: Progress -> Integer -> IO ()

-- | Set the completed unit count in the <a>Progress</a> object to the
--   specified value. Unlike <a>incrP</a>, 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 <a>setP</a>, but never modify the total.
setP' :: Progress -> Integer -> IO ()

-- | Increment the total unit count in the <a>Progress</a> 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 <a>Progress</a> object to the
--   specified value. Like <a>incrTotal</a>, 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
--   <i>will</i> 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
--   <a>Progress</a> object.
--   
--   If no time has elapsed yet, returns 0.
--   
--   You can use this against either a <a>Progress</a> object or a
--   <a>ProgressStatus</a> object. This is in the IO monad because the
--   speed is based on the current time.
--   
--   Example:
--   
--   <pre>
--   getSpeed progressobj &gt;&gt;= print
--   </pre>
--   
--   Don't let the type of this function confuse you. It is a fancy way of
--   saying that it can take either a <a>Progress</a> or a
--   <a>ProgressStatus</a> 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 <a>getSpeed</a> would return 0.
--   
--   See the comments under <a>getSpeed</a> 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 <a>getETR</a> would
--   return 0.
--   
--   See the comments under <a>getSpeed</a> 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
--   <a>defaultTimeSource</a>.
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
--   <a>addCallback</a>, these functions get called every time the status
--   of the tracker changes.
--   
--   This function is passed two <a>ProgressStatus</a> records: the first
--   reflects the status prior to the update, and the second reflects the
--   status after the update.
--   
--   Please note that the owning <a>Progress</a> 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:
--   
--   <pre>
--   getClockTime &gt;&gt;= (return . clockTimeToEpoch)
--   </pre>
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
--   <a>http://en.wikipedia.org/wiki/Bin_packing_problem</a>.
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 <tt>repeat binSize</tt> to pass an infinite list of
--   bins if the same size. Any surplus bins will simply be ignored.
--   
--   <pre>
--   [size] is the sizes of bins
--   [(size, obj)] is the sizes and objects
--   result is Either error or results
--   </pre>
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 <a>BinPacker</a>
--   functions. Calling <a>show</a> 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 <a>packByOrder</a>, 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:
--   
--   <pre>
--   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"]]
--   </pre>
--   
--   To parse a String, you might use:
--   
--   <pre>
--   import Text.ParserCombinators.Parsec
--   import Data.String.CSV
--   ....
--   parse csvFile "" mystring
--   </pre>
--   
--   To parse a file, you might instead use:
--   
--   <pre>
--   do result &lt;- parseFromFile csvFile "/path/to/file"
--   </pre>
--   
--   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 <a>System.Log.Logger</a>
--   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:
--   
--   <pre>
--   updateGlobalLogger "System.Cmd.Utils.safeSystem"
--                       (setLevel CRITICAL)
--   </pre>
--   
--   See also: <a>updateGlobalLogger</a>, <a>System.Log.Logger</a>.
--   
--   It is possible to set up pipelines with these utilities. Example:
--   
--   <pre>
--   (pid1, x1) &lt;- pipeFrom "ls" ["/etc"]
--   (pid2, x2) &lt;- pipeBoth "grep" ["x"] x1
--   putStr x2
--   ... the grep output is displayed ...
--   forceSuccess pid2
--   forceSuccess pid1
--   </pre>
--   
--   Remember, when you use the functions that return a String, you must
--   not call <a>forceSuccess</a> 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:
--   
--   <pre>
--   (pid, x) &lt;- pipeFrom "ls" ["/etc"]
--   forceSuccess pid         -- Hangs; the called program hasn't terminated yet
--   processTheData x
--   </pre>
--   
--   You must instead process the data before calling <a>forceSuccess</a>.
--   
--   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 <a>pipeFrom</a>, <a>pipeLinesFrom</a>,
--   <a>pipeTo</a>, or <a>pipeBoth</a>. Contains both a ProcessID and the
--   original command that was executed. If you prefer not to use
--   <a>forceSuccess</a> on the result of one of these pipe calls, you can
--   use (processID ph), assuming ph is your <a>PipeHandle</a>, as a
--   parameter to <a>getProcessStatus</a>.
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 <a>posixRawSystem</a> where supported, and
--   System.Posix.rawSystem otherwise.
safeSystem :: FilePath -> [String] -> IO ()

-- | Uses <a>getProcessStatus</a> 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 <a>PipeHandle</a>.
--   
--   ONLY AFTER the string has been read completely, You must call either
--   <a>getProcessStatus</a> or <a>forceSuccess</a> on the
--   <a>PipeHandle</a>. Zombies will result otherwise.
--   
--   Not available on Windows.
pipeFrom :: FilePath -> [String] -> IO (PipeHandle, String)

-- | Like <a>pipeFrom</a>, but returns data in lines instead of just a
--   String. Shortcut for calling lines on the result from <a>pipeFrom</a>.
--   
--   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 <a>getProcessStatus</a> or <a>forceSuccess</a> on
--   the ProcessID. Zombies will result otherwise.
--   
--   Not available on Windows.
pipeTo :: FilePath -> [String] -> String -> IO PipeHandle

-- | Like a combination of <a>pipeTo</a> and <a>pipeFrom</a>; 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
--   <a>pipeFrom</a>.
--   
--   Not available on Windows.
pipeBoth :: FilePath -> [String] -> String -> IO (PipeHandle, String)

-- | Read data from a pipe. Returns a Handle and a <a>PipeHandle</a>.
--   
--   When done, you must hClose the handle, and then use either
--   <a>forceSuccess</a> or getProcessStatus on the <a>PipeHandle</a>.
--   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 <a>PipeHandle</a> and a new Handle to
--   write to.
--   
--   When done, you must hClose the handle, and then use either
--   <a>forceSuccess</a> or getProcessStatus on the <a>PipeHandle</a>.
--   Zombies will result otherwise.
--   
--   This function logs as pipeTo.
--   
--   Not available on Windows.
hPipeTo :: FilePath -> [String] -> IO (PipeHandle, Handle)

-- | Like a combination of <a>hPipeTo</a> and <a>hPipeFrom</a>; returns a
--   3-tuple of (<a>PipeHandle</a>, Data From Pipe, Data To Pipe).
--   
--   When done, you must hClose both handles, and then use either
--   <a>forceSuccess</a> or getProcessStatus on the <a>PipeHandle</a>.
--   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 <a>PipeMode</a> specifies what you will be doing. That is,
--   specifing <a>ReadFromPipe</a> sets up a pipe from stdin, and
--   <a>WriteToPipe</a> 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
--   <tt>waitProcess</tt> 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 <tt>sendmail</tt> is on the <tt>PATH</tt>, it will be used;
--   otherwise, a list of system default locations will be searched.
--   
--   A failure will be logged, since this function uses <a>safeSystem</a>
--   internally.
--   
--   This function will first try <tt>sendmail</tt>. If it does not exist,
--   an error is logged under <tt>System.Cmd.Utils.pOpen3</tt> and various
--   default <tt>sendmail</tt> 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 <i>a</i> represents zero or more <a>Message</a>s.
--   Each message has a unique identifier <i>b</i> 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, <a>getAll</a>.
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 <a>GeneralizedToken</a>.
togtok :: a -> GenParser b st (GeneralizedToken a)

-- | Retrieve the next token from a <a>GeneralizedToken</a> 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 <a>tokeng</a>; 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 <tt>notMatching p msg</tt> 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 <tt>System.Daemon</tt>. See
--   <a>Logger</a> for details.
--   
--   Based on background from
--   <a>http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16</a> and
--   <a>http://www.haskell.org/hawiki/HaskellUnixDaemon</a>.
--   
--   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:
--   
--   <ul>
--   <li>The PID of the running process will change</li>
--   <li>stdin, stdout, and stderr will not work (they'll be set to
--   /dev/null)</li>
--   <li>CWD will be changed to /</li>
--   </ul>
--   
--   I <i>highly</i> 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:
--   
--   <ul>
--   <li>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.</li>
--   <li>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.</li>
--   <li>The ability to define new objects that have the properties of I/O
--   objects and can be used interchangably with them.</li>
--   <li>Specification compatibility with, and complete support for,
--   existing I/O on Handles.</li>
--   <li>Provide easier unit testing capabilities for I/O actions</li>
--   </ul>
--   
--   HVIO defines several basic type classes that you can use. You will
--   mostly be interested in <a>HVIO</a>.
--   
--   It's trivial to adapt old code to work with HVIO. For instance,
--   consider this example of old and new code:
--   
--   <pre>
--   printMsg :: Handle -&gt; String -&gt; IO ()
--   printMsg h msg = hPutStr h ("msg: " ++ msg)
--   </pre>
--   
--   And now, the new way:
--   
--   <pre>
--   printMsg :: HVIO h =&gt; h -&gt; String -&gt; IO ()
--   printMsg h msg = vPutStr h ("msg: " ++ msg)
--   </pre>
--   
--   There are several points to note about this conversion:
--   
--   <ul>
--   <li>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.</li>
--   <li>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.</li>
--   <li>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.</li>
--   </ul>
--   
--   In addition to Handle, there are several pre-defined classes for your
--   use. <a>StreamReader</a> 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 <a>StreamReader</a> with a call to
--   <a>newStreamReader</a>.
--   
--   <a>MemoryBuffer</a> is a similar class, but with a different purpose.
--   It provides a full interface like Handle (it implements
--   <tt>HVIOReader</tt>, <tt>HVIOWriter</tt>, and <tt>HVIOSeeker</tt>).
--   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 <a>MemoryBuffer</a>
--   with a call to <a>newMemoryBuffer</a>.
--   
--   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 <a>PipeReader</a> and a <a>PipeWriter</a>. You must use the
--   <a>PipeWriter</a> in one thread and the <a>PipeReader</a> in another
--   thread. Data that's written to the <a>PipeWriter</a> will then be
--   available for reading with the <a>PipeReader</a>. 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 <a>newHVIOPipe</a>.
--   
--   Together with <a>System.IO.HVFS</a>, 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 <a>HVIO</a>.
--   
--   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 <a>HVIO</a> must provide <a>vClose</a>, <a>vIsEOF</a>,
--   and either <a>vIsOpen</a> or <a>vIsClosed</a>.
--   
--   Implementators of readable objects must provide at least
--   <a>vGetChar</a> and <a>vIsReadable</a>. An implementation of
--   <a>vGetContents</a> is also highly suggested, since the default cannot
--   implement proper partial closing semantics.
--   
--   Implementators of writable objects must provide at least
--   <a>vPutChar</a> and <a>vIsWritable</a>.
--   
--   Implementators of seekable objects must provide at least
--   <a>vIsSeekable</a>, <a>vTell</a>, and <a>vSeek</a>.
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 <a>StreamReader</a> is created, it is initialized based on the
--   contents of a <a>String</a>. Its contents are read lazily whenever a
--   request is made to read something from the <a>StreamReader</a>. 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
--   <a>StreamReader</a> with a call to <a>newStreamReader</a>.
data StreamReader

-- | Create a new <a>StreamReader</a> object.
newStreamReader :: String -> IO StreamReader

-- | A <a>MemoryBuffer</a> simulates true I/O, but uses an in-memory buffer
--   instead of on-disk storage.
--   
--   It provides a full interface like Handle (it implements
--   <tt>HVIOReader</tt>, <tt>HVIOWriter</tt>, and <tt>HVIOSeeker</tt>).
--   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 <a>MemoryBuffer</a>
--   with a call to <a>newMemoryBuffer</a>.
--   
--   The present <a>MemoryBuffer</a> 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 <a>MemoryBuffer</a> 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 <a>vPutStr</a> calls, and
--   reset to the beginning by using the normal <a>vRewind</a> call.
--   
--   The function is called when <a>vClose</a> is called, and is passed the
--   contents of the buffer at close time. You can use
--   <a>mbDefaultCloseFunc</a> if you don't want to do anything.
--   
--   To create an empty buffer, pass the initial value <tt>""</tt>.
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
--   <a>vGetContents</a>, 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 <a>newHVIOPipe</a> for
--   more details.
data PipeReader

-- | The writing side of a Haskell pipe. Please see <a>newHVIOPipe</a> 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
--   <a>PipeReader</a> and a <a>PipeWriter</a>. You must use the
--   <a>PipeWriter</a> in one thread and the <a>PipeReader</a> in another
--   thread. Data that's written to the <a>PipeWriter</a> will then be
--   available for reading with the <a>PipeReader</a>. 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 <a>HVFS</a> function takes a <a>HVFS</a> "handle" (<a>HVFS</a>
--   instance) as its first parameter. If you wish to operate on the
--   standard system filesystem, you can just use <a>SystemFS</a>.
--   
--   The <a>MissingH.HVFS.IO.InstanceHelpers</a> module contains some code
--   to help you make your own HVFS instances.
--   
--   The <a>HVFSOpenable</a> class works together with the
--   <a>System.IO.HVIO</a> 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:
--   
--   <ul>
--   <li><a>vGetModificationTime</a> -- implemented in terms of
--   <a>vGetFileStatus</a></li>
--   <li><a>vRaiseError</a></li>
--   <li><a>vDoesFileExist</a> -- implemented in terms of
--   <a>vGetFileStatus</a></li>
--   <li><a>vDoesDirectoryExist</a> -- implemented in terms of
--   <a>vGetFileStatus</a></li>
--   <li><a>vDoesExist</a> -- implemented in terms of
--   <a>vGetSymbolicLinkStatus</a></li>
--   <li><a>vGetSymbolicLinkStatus</a> -- set to call
--   <a>vGetFileStatus</a>.</li>
--   </ul>
--   
--   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 <a>vGetFileStatus</a> 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 <a>vIsDirectory</a> and
--   <a>vIsRegularFile</a>.
--   
--   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 <a>vOpen</a>.
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 <a>HVFSStatEncap</a>, but for <a>vOpen</a> result.
data HVFSOpenEncap
HVFSOpenEncap :: a -> HVFSOpenEncap

-- | Encapsulate a <a>HVFSStat</a> result. This is required due to Haskell
--   typing restrictions. You can get at it with:
--   
--   <pre>
--   case encap of
--      HVFSStatEncap x -&gt; -- now use x
--   </pre>
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:
--   
--   <pre>
--   vGetModificationTime fs fp = 
--      do s &lt;- vGetFileStatus fs fp
--         return $ epochToClockTime (withStat s vModificationTime)
--   </pre>
--   
--   See <a>epochToClockTime</a> for more information.
withStat :: HVFSStatEncap -> (forall a. HVFSStat a => a -> b) -> b

-- | Similar to <a>withStat</a>, but for the <a>vOpen</a> result.
withOpen :: HVFSOpenEncap -> (forall a. HVIO a => a -> b) -> b
data SystemFS
SystemFS :: SystemFS

-- | File and directory names are values of type <a>String</a>, 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 <a>openFile</a>
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
--   <a>System.IO.HVIO</a> for more details.
--   
--   Versions of MissingH prior 0.11.6 lacked the <a>BinaryConvertible</a>
--   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:
--   
--   <ul>
--   <li>GHC 6.2 and above: yes</li>
--   <li>GHC 6.x, earlier versions: unknown</li>
--   <li>GHC 5.x: no</li>
--   <li>nhc98: no</li>
--   <li>Hugs: partial (maybe complete; needs more testing)</li>
--   </ul>
--   
--   Non-binary functions may be found in <a>System.IO</a>.
--   
--   See also: <a>System.IO.BlockIO</a>
--   
--   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:
--   
--   <pre>
--   hBlockCopy bs hin hout = hBlockInteract bs hin hout id
--   </pre>
--   
--   (<a>id</a> 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 <a>stdin</a> to <a>stdout</a> using binary blocks of the
--   given size. An alias for <a>hBlockCopy</a> over <a>stdin</a> and
--   <a>stdout</a>
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 <a>openBinaryFile</a> function.
--   Therefore, you may need to adjust those bits after the copy yourself.
--   
--   This function is implemented using <a>hBlockCopy</a> internally.
copyFileBlocksToFile :: Int -> FilePath -> FilePath -> IO ()

-- | As a wrapper around the standard function <a>hPutBuf</a>, this
--   function takes a standard Haskell <a>String</a> instead of the far
--   less convenient <tt>Ptr a</tt>. The entire contents of the string will
--   be written as a binary buffer using <a>hPutBuf</a>. 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
--   <tt>Handle -&gt; String -&gt; IO ()</tt>
hPutBufStr :: (HVIO a, BinaryConvertible b) => a -> [b] -> IO ()

-- | An alias for <a>hPutBufStr</a> <a>stdout</a>
putBufStr :: BinaryConvertible b => [b] -> IO ()

-- | Acts a wrapper around the standard function <a>hGetBuf</a>, 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 <a>hGetBuf</a>; 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 <a>vGetBuf</a>)
hGetBufStr :: (HVIO a, BinaryConvertible b) => a -> Int -> IO [b]

-- | An alias for <a>hGetBufStr</a> <a>stdin</a>
getBufStr :: BinaryConvertible b => Int -> IO [b]

-- | Like <a>hGetBufStr</a>, 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 <a>hFullGetBufStr</a> <a>stdin</a>
fullGetBufStr :: BinaryConvertible b => Int -> IO [b]

-- | An alias for <a>hPutBlocks</a> <a>stdout</a> putBlocks ::
--   (BinaryConvertible b) =&gt; [[b]] -&gt; IO () putBlocks = hPutBlocks
--   stdout
--   
--   Returns a lazily-evaluated list of all blocks in the input file, as
--   read by <a>hGetBufStr</a>. 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 <a>hGetBlocks</a> <a>stdin</a>
getBlocks :: BinaryConvertible b => Int -> IO [[b]]

-- | Same as <a>hGetBlocks</a>, but using <a>hFullGetBufStr</a> underneath.
hFullGetBlocks :: (HVIO a, BinaryConvertible b) => a -> Int -> IO [[b]]

-- | An alias for <a>hFullGetBlocks</a> <a>stdin</a>
fullGetBlocks :: BinaryConvertible b => Int -> IO [[b]]

-- | Like the built-in <a>readFile</a>, but opens the file in binary
--   instead of text mode.
readBinaryFile :: FilePath -> IO String

-- | Like the built-in <a>writeFile</a>, 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 <a>hBlockCopy</a> for an example. The integer argument
--   is the size of input binary blocks. This function uses
--   <a>hGetBlocks</a> internally.
hBlockInteract :: (HVIO a, HVIO d, BinaryConvertible b, BinaryConvertible c) => Int -> a -> d -> ([[b]] -> [[c]]) -> IO ()

-- | An alias for <a>hBlockInteract</a> over <a>stdin</a> and <a>stdout</a>
blockInteract :: (BinaryConvertible b, BinaryConvertible c) => Int -> ([[b]] -> [[c]]) -> IO ()

-- | Same as <a>hBlockInteract</a>, but uses <a>hFullGetBlocks</a> instead
--   of <a>hGetBlocks</a> internally.
hFullBlockInteract :: (HVIO a, HVIO d, BinaryConvertible b, BinaryConvertible c) => Int -> a -> d -> ([[b]] -> [[c]]) -> IO ()

-- | An alias for <a>hFullBlockInteract</a> over <a>stdin</a> and
--   <a>stdout</a>
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 <a>recurseDir</a>, 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
--   <tt>hBlockCopy</tt>, this implementation is nice:
--   
--   <pre>
--   hLineCopy hin hout = hLineInteract hin hout id
--   </pre>
hLineCopy :: (HVIO a, HVIO b) => a -> b -> IO ()

-- | Copies from <a>stdin</a> to <a>stdout</a> using lines. An alias for
--   <a>hLineCopy</a> over <a>stdin</a> and <a>stdout</a>.
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 <a>hLineCopy</a> 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 <a>hPutStrLns</a>, this can make a powerful way to
--   develop filters. See the <a>lineInteract</a> function for more on that
--   concept.
--   
--   Example:
--   
--   <pre>
--   main = do
--          l &lt;- hGetLines stdin
--          hPutStrLns stdout $ filter (startswith "1") l
--   </pre>
hGetLines :: HVIO a => a -> IO [String]

-- | This is similar to the built-in <a>interact</a>, but works on any
--   handle, not just stdin and stdout.
--   
--   In other words:
--   
--   <pre>
--   interact = hInteract stdin stdout
--   </pre>
hInteract :: (HVIO a, HVIO b) => a -> b -> (String -> String) -> IO ()

-- | Line-based interaction over arbitrary handles. This is similar to
--   wrapping hInteract with <a>lines</a> and <a>unlines</a>.
--   
--   One could view this function like this:
--   
--   <pre>
--   hLineInteract finput foutput func =
--       let newf = unlines . func . lines in
--           hInteract finput foutput newf
--   </pre>
--   
--   Though the actual implementation is this for efficiency:
--   
--   <pre>
--   hLineInteract finput foutput func =
--       do
--       lines &lt;- hGetLines finput
--       hPutStrLns foutput (func lines)
--   </pre>
hLineInteract :: (HVIO a, HVIO b) => a -> b -> ([String] -> [String]) -> IO ()

-- | Line-based interaction. This is similar to wrapping your interact
--   functions with <a>lines</a> and <a>unlines</a>. This equality holds:
--   
--   <pre>
--   lineInteract = hLineInteract stdin stdout
--   </pre>
--   
--   Here's an example:
--   
--   <pre>
--   main = lineInteract (filter (startswith "1"))
--   </pre>
--   
--   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:
--   
--   <pre>
--   merge [1,3,5] [1,2,4,6] -&gt; [1,1,2,3,4,5,6]
--   </pre>
--   
--   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 <a>Data.List.isPrefixOf</a>.)
--   
--   Example:
--   
--   <pre>
--   startswith "He" "Hello" -&gt; True
--   </pre>
startswith :: Eq a => [a] -> [a] -> Bool

-- | Returns true if the given list ends with the specified elements; false
--   otherwise. (This is an alias for <a>Data.List.isSuffixOf</a>.)
--   
--   Example:
--   
--   <pre>
--   endswith "lo" "Hello" -&gt; True
--   </pre>
endswith :: Eq a => [a] -> [a] -> Bool

-- | Returns true if the given parameter is a sublist of the given list;
--   false otherwise.
--   
--   Example:
--   
--   <pre>
--   contains "Haskell" "I really like Haskell." -&gt; True
--   contains "Haskell" "OCaml is great." -&gt; False
--   </pre>
--   
--   This function was submitted to GHC and was applied as
--   <a>isInfixOf</a>. This function therefore is deprecated and will be
--   removed in future versions.

-- | <i>Deprecated: Use Data.List.isInfixOf, will be removed in MissingH
--   1.1.0 </i>
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:
--   
--   <pre>
--   map fst
--   </pre>
keysAL :: [(key, a)] -> [key]

-- | Returns the values the comprise the (key, value) pairs of the given
--   AL.
--   
--   Same as:
--   
--   <pre>
--   map snd
--   </pre>
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 <a>strFromAL</a>, this function reads a string and
--   outputs the appropriate association list.
--   
--   Like <a>strFromAL</a>, 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:
--   
--   <pre>
--   split "," "foo,bar,,baz," -&gt; ["foo", "bar", "", "baz", ""]
--   </pre>
--   
--   <pre>
--   split "ba" ",foo,bar,,baz," -&gt; [",foo,","r,,","z,"]
--   </pre>
split :: Eq a => [a] -> [a] -> [[a]]

-- | Given a delimiter and a list of items (or strings), join the items by
--   using the delimiter.
--   
--   Example:
--   
--   <pre>
--   join "|" ["foo", "bar", "baz"] -&gt; "foo|bar|baz"
--   </pre>
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:
--   
--   <pre>
--   replace "," "." "127,0,0,1" -&gt; "127.0.0.1"
--   </pre>
--   
--   This could logically be thought of as:
--   
--   <pre>
--   replace old new l = join new . split old $ l
--   </pre>
replace :: Eq a => [a] -> [a] -> [a] -> [a]

-- | Like <a>join</a>, but works with a list of anything showable,
--   converting it to a String.
--   
--   Examples:
--   
--   <pre>
--   genericJoin ", " [1, 2, 3, 4] -&gt; "1, 2, 3, 4"
--   genericJoin "|" ["foo", "bar", "baz"] -&gt; "\"foo\"|\"bar\"|\"baz\""
--   </pre>
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.
--   
--   <tt>spanList p xs</tt> is the same as <tt>(takeWhileList p xs,
--   dropWhileList p xs)</tt>
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 <a>wholeMap</a>. See <a>wholeMap</a>
--   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:
--   
--   <ul>
--   <li>Can consume a varying number of elements from the input list
--   during each iteration</li>
--   <li>Can arbitrarily decide when to stop processing data</li>
--   <li>Can return a varying number of elements to insert into the output
--   list</li>
--   <li>Can actually switch processing functions mid-stream</li>
--   <li>Is not even restricted to processing the input list intact</li>
--   </ul>
--   
--   The function used by wholeMap, of type <a>WholeFunc</a>, 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 <a>wholeMap</a> is the concatenation of
--   the output element lists from all iterations.
--   
--   Processing stops when the remaining input list is empty. An example of
--   a <a>WholeFunc</a> is <a>fixedWidth</a>.
wholeMap :: WholeFunc a b -> [a] -> [b]

-- | A parser designed to process fixed-width input fields. Use it with
--   <a>wholeMap</a>.
--   
--   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:
--   
--   <pre>
--   wholeMap (fixedWidth [1, 2, 3]) "1234567890"
--    --&gt; ["1","23","456","7890"]
--   wholeMap (fixedWidth (repeat 2)) "123456789"
--    --&gt; ["12","34","56","78","9"]
--   wholeMap (fixedWidth []) "123456789"
--    --&gt; ["123456789"]
--   wholeMap (fixedWidth [5, 3, 6, 1]) "Hello, This is a test."
--    --&gt; ["Hello",", T","his is"," ","a test."]
--   </pre>
fixedWidth :: [Int] -> WholeFunc a [a]

-- | Helps you pick out fixed-width components from a list.
--   
--   Example:
--   
--   <pre>
--   conv :: String -&gt; (String,String)
--   conv = runState $
--           do f3 &lt;- grab 3
--              n2 &lt;- grab 2
--              return $ f3 ++ "," ++ n2
--   
--   main = print $ conv "TestIng"
--   </pre>
--   
--   Prints:
--   
--   <pre>
--   ("Tes,tI","ng")
--   </pre>
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:
--   
--   <pre>
--   subIndex "foo" "asdfoobar" -&gt; Just 3
--   subIndex "foo" [] -&gt; Nothing
--   subIndex "" [] -&gt; Just 0
--   subIndex "" "asdf" -&gt; Just 0
--   subIndex "test" "asdftestbartest" -&gt; Just 4
--   subIndex [(1::Int), 2] [0, 5, 3, 2, 1, 2, 4] -&gt; Just 4
--   </pre>
subIndex :: Eq a => [a] -> [a] -> Maybe Int

-- | Given a list, returns a new list with all duplicate elements removed.
--   For example:
--   
--   <pre>
--   uniq "Mississippi" -&gt; "Misp"
--   </pre>
--   
--   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 <a>flipAL</a> 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 <a>strToAL</a> for
--   more on the similar function for association lists.
--   
--   This implementation is simple:
--   
--   <pre>
--   strToM = Data.Map.fromList . strToAL
--   </pre>
--   
--   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
--   <a>strFromAL</a> for more on the similar function for association
--   lists. This implementation is simple:
--   
--   <pre>
--   strFromM = strFromAL . Data.Map.toList
--   </pre>
--   
--   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
--   <tt>..</tt> 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 <a>recurseDir</a>, 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 <tt>"XXXXXX"</tt>.
--   
--   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 <a>mktmpdir</a>, 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
--   <a>System.IO.HVFS</a>.
module System.IO.HVFS.InstanceHelpers

-- | A simple <a>System.IO.HVFS.HVFSStat</a> 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 <a>MemoryVFS</a> object from an existing tree. An empty
--   filesystem may be created by using <tt>[]</tt> for the parameter.
newMemoryVFS :: [MemoryNode] -> IO MemoryVFS

-- | Create a new <a>MemoryVFS</a> object using an IORef to an existing
--   tree.
newMemoryVFSRef :: IORef [MemoryNode] -> IO MemoryVFS

-- | The basic node of a <a>MemoryVFS</a>. 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 <a>MemoryVFS</a>.
data MemoryEntry
MemoryDirectory :: [MemoryNode] -> MemoryEntry
MemoryFile :: String -> MemoryEntry

-- | Similar to <a>NameManip</a> but the first element won't be <tt>/</tt>.
--   
--   <pre>
--   nice_slice "/" -&gt; []
--   nice_slice "/foo/bar" -&gt; ["foo", "bar"]
--   </pre>
nice_slice :: String -> [String]

-- | Gets a full path, after investigating the cwd.
getFullPath :: HVFS a => a -> String -> IO String

-- | Gets the full path via <a>getFullPath</a>, then splits it via
--   <a>nice_slice</a>.
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 <tt>HVFSReadOnly fs</tt> to make
--   a new read-only wrapper around the <a>HVFS</a> instance <tt>fs</tt>.
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 <a>HVFSChroot</a> 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, <a>.tgz</a> would expand into
--   <a>.tar.gz</a>.
suffixMap :: MIMETypeData -> Map String String

-- | A mapping used to determine the encoding of a file. This is used, for
--   instance, to map <a>.gz</a> to <a>gzip</a>.
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 <a>typesMap</a> 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 <a>guessExtension</a>, 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:
--   
--   <ol>
--   <li>If multiple whitespace characters are present all in a row, they
--   are all removed;</li>
--   <li>If no whitespace characters are present, nothing is done.</li>
--   </ol>
strip :: String -> String

-- | Same as <a>strip</a>, but applies only to the left side of the string.
lstrip :: String -> String

-- | Same as <a>strip</a>, 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 <a>Data.List.isPrefixOf</a>.)
--   
--   Example:
--   
--   <pre>
--   startswith "He" "Hello" -&gt; True
--   </pre>
startswith :: Eq a => [a] -> [a] -> Bool

-- | Returns true if the given list ends with the specified elements; false
--   otherwise. (This is an alias for <a>Data.List.isSuffixOf</a>.)
--   
--   Example:
--   
--   <pre>
--   endswith "lo" "Hello" -&gt; True
--   </pre>
endswith :: Eq a => [a] -> [a] -> Bool

-- | Given a delimiter and a list of items (or strings), join the items by
--   using the delimiter.
--   
--   Example:
--   
--   <pre>
--   join "|" ["foo", "bar", "baz"] -&gt; "foo|bar|baz"
--   </pre>
join :: [a] -> [[a]] -> [a]

-- | Given a delimiter and a list (or string), split into components.
--   
--   Example:
--   
--   <pre>
--   split "," "foo,bar,,baz," -&gt; ["foo", "bar", "", "baz", ""]
--   </pre>
--   
--   <pre>
--   split "ba" ",foo,bar,,baz," -&gt; [",foo,","r,,","z,"]
--   </pre>
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:
--   
--   <pre>
--   replace "," "." "127,0,0,1" -&gt; "127.0.0.1"
--   </pre>
--   
--   This could logically be thought of as:
--   
--   <pre>
--   replace old new l = join new . split old $ l
--   </pre>
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 <a>Data.Progress.Tracker</a>.
--   
--   Written by John Goerzen, jgoerzen@complete.org
module Data.Progress.Meter
type ProgressMeter = MVar ProgressMeterR

-- | Set up a new status bar using defaults:
--   
--   <ul>
--   <li>The given tracker</li>
--   <li>Width 80</li>
--   <li>Data.Quantity.renderNums binaryOpts 1</li>
--   <li>Unit inticator <tt><a>B</a></tt></li>
--   </ul>
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 <a>ProgressMeter</a>.
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 <a>ProgressMeter</a>.
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: <tt>displayMeter stdout</tt> is an ideal
--   function here.
--   
--   Save this threadID and use it later to call
--   <tt>stopAutoDisplayMeter</tt>.
autoDisplayMeter :: ProgressMeter -> Int -> (ProgressMeter -> IO ()) -> IO ThreadId

-- | Stops the specified meter from displaying.
--   
--   You should probably call <a>clearMeter</a> after a call to this.
killAutoDisplayMeter :: ProgressMeter -> ThreadId -> IO ()


-- | Matching filenames with wildcards. See also <a>System.Path.Glob</a>
--   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:
--   
--   <pre>
--   ? matches exactly one character
--   \* matches zero or more characters
--   [list] matches any character in list
--   [!list] matches any character not in the list
--   </pre>
--   
--   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:
--   
--   <ul>
--   <li>Neither the path separator (the slash or backslash) nor the period
--   carry any special meaning for the functions in this module. That is,
--   <tt>*</tt> will match <tt>/</tt> in a filename. If this is not the
--   behavior you want, you probably want <a>System.Path.Glob</a> instead
--   of this module.</li>
--   <li>Unlike the Unix shell, filenames that begin with a period are not
--   ignored by this module. That is, <tt>*.txt</tt> will match
--   <tt>.test.txt</tt>.</li>
--   <li>This module does not current permit escaping of special
--   characters.</li>
--   </ul>
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 <a>System.Path.WildMatch</a>.
module System.Path.Glob

-- | Takes a pattern. Returns a list of names that match that pattern. The
--   pattern is evaluated by <a>System.Path.WildMatch</a>. 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:
--   
--   <pre>
--   glob = vGlob SystemFS
--   </pre>
glob :: FilePath -> IO [FilePath]

-- | Like <a>glob</a>, but works on both the system (<a>real</a>) 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])
