    module System.Directory.Internal.Common
      ( module System.Directory.Internal.Common
      , OsPath
      , OsString
      ) where
    import Prelude ()
    import System.Directory.Internal.Prelude
    import GHC.IO.Encoding.Failure (CodingFailureMode(TransliterateCodingFailure))
    import GHC.IO.Encoding.UTF16 (mkUTF16le)
    import GHC.IO.Encoding.UTF8 (mkUTF8)
    import System.File.OsPath.Internal (openFileWithCloseOnExec)
    import System.OsPath
      ( OsPath
      , OsString
      , addTrailingPathSeparator
      , decodeUtf
      , decodeWith
      , encodeUtf
      , hasTrailingPathSeparator
      , isPathSeparator
      , isRelative
      , joinDrive
      , joinPath
      , normalise
      , pack
      , pathSeparator
      , pathSeparators
      , splitDirectories
      , splitDrive
      , toChar
      , unpack
      , unsafeFromChar
      )

    -- | A generator with side-effects.
    newtype ListT m a = ListT { forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
    unListT :: m (Maybe (a, ListT m a)) }

    emptyListT :: Applicative m => ListT m a
    emptyListT :: forall (m :: * -> *) a. Applicative m => ListT m a
    emptyListT = m (Maybe (a, ListT m a)) -> ListT m a
    forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
    ListT (Maybe (a, ListT m a) -> m (Maybe (a, ListT m a))
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Maybe (a, ListT m a)
    forall a. Maybe a
    Nothing)

    maybeToListT :: Applicative m => m (Maybe a) -> ListT m a
    maybeToListT :: forall (m :: * -> *) a. Applicative m => m (Maybe a) -> ListT m a
    maybeToListT m (Maybe a)
    m = m (Maybe (a, ListT m a)) -> ListT m a
    forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
    ListT (((\ a
    x -> (a
    x, ListT m a
    forall (m :: * -> *) a. Applicative m => ListT m a
    emptyListT)) (a -> (a, ListT m a)) -> Maybe a -> Maybe (a, ListT m a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>) (Maybe a -> Maybe (a, ListT m a))
    -> m (Maybe a) -> m (Maybe (a, ListT m a))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> m (Maybe a)
    m)

    listToListT :: Applicative m => [a] -> ListT m a
    listToListT :: forall (m :: * -> *) a. Applicative m => [a] -> ListT m a
    listToListT [] = ListT m a
    forall (m :: * -> *) a. Applicative m => ListT m a
    emptyListT
    listToListT (a
    x : [a]
    xs) = m (Maybe (a, ListT m a)) -> ListT m a
    forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
    ListT (Maybe (a, ListT m a) -> m (Maybe (a, ListT m a))
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ((a, ListT m a) -> Maybe (a, ListT m a)
    forall a. a -> Maybe a
    Just (a
    x, [a] -> ListT m a
    forall (m :: * -> *) a. Applicative m => [a] -> ListT m a
    listToListT [a]
    xs)))

    liftJoinListT :: Monad m => m (ListT m a) -> ListT m a
    liftJoinListT :: forall (m :: * -> *) a. Monad m => m (ListT m a) -> ListT m a
    liftJoinListT m (ListT m a)
    m = m (Maybe (a, ListT m a)) -> ListT m a
    forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
    ListT (m (ListT m a)
    m m (ListT m a)
    -> (ListT m a -> m (Maybe (a, ListT m a)))
    -> m (Maybe (a, ListT m a))
    forall a b. m a -> (a -> m b) -> m b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= ListT m a -> m (Maybe (a, ListT m a))
    forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
    unListT)

    listTHead :: Functor m => ListT m a -> m (Maybe a)
    listTHead :: forall (m :: * -> *) a. Functor m => ListT m a -> m (Maybe a)
    listTHead (ListT m (Maybe (a, ListT m a))
    m) = ((a, ListT m a) -> a
    forall a b. (a, b) -> a
    fst ((a, ListT m a) -> a) -> Maybe (a, ListT m a) -> Maybe a
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>) (Maybe (a, ListT m a) -> Maybe a)
    -> m (Maybe (a, ListT m a)) -> m (Maybe a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> m (Maybe (a, ListT m a))
    m

    listTToList :: Monad m => ListT m a -> m [a]
    listTToList :: forall (m :: * -> *) a. Monad m => ListT m a -> m [a]
    listTToList (ListT m (Maybe (a, ListT m a))
    m) = do
      mx <- m (Maybe (a, ListT m a))
    m
      case mx of
        Maybe (a, ListT m a)
    Nothing -> [a] -> m [a]
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []
        Just (a
    x, ListT m a
    m') -> do
          xs <- ListT m a -> m [a]
    forall (m :: * -> *) a. Monad m => ListT m a -> m [a]
    listTToList ListT m a
    m'
          return (x : xs)

    andM :: Monad m => m Bool -> m Bool -> m Bool
    andM :: forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
    andM m Bool
    mx m Bool
    my = do
      x <- m Bool
    mx
      if x
        then my
        else return x

    sequenceWithIOErrors_ :: [IO ()] -> IO ()
    sequenceWithIOErrors_ :: [IO ()] -> IO ()
    sequenceWithIOErrors_ [IO ()]
    actions = Either IOError () -> [IO ()] -> IO ()
    go (() -> Either IOError ()
    forall a b. b -> Either a b
    Right ()) [IO ()]
    actions
      where

        go :: Either IOError () -> [IO ()] -> IO ()
        go :: Either IOError () -> [IO ()] -> IO ()
    go (Left IOError
    e)   []       = IOError -> IO ()
    forall a. HasCallStack => IOError -> IO a
    ioError IOError
    e
        go (Right ()) []       = () -> IO ()
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ()
        go Either IOError ()
    s          (IO ()
    m : [IO ()]
    ms) = Either IOError ()
    s Either IOError () -> IO () -> IO ()
    forall a b. a -> b -> b
    `seq` do
          r <- IO () -> IO (Either IOError ())
    forall a. IO a -> IO (Either IOError a)
    tryIOError IO ()
    m
          go (s *> r) ms

    -- | Similar to 'try' but only catches a specify kind of 'IOError' as
    --   specified by the predicate.
    tryIOErrorType :: (IOError -> Bool) -> IO a -> IO (Either IOError a)
    tryIOErrorType :: forall a. (IOError -> Bool) -> IO a -> IO (Either IOError a)
    tryIOErrorType IOError -> Bool
    check IO a
    action = do
      result <- IO a -> IO (Either IOError a)
    forall a. IO a -> IO (Either IOError a)
    tryIOError IO a
    action
      case result of
        Left  IOError
    err -> if IOError -> Bool
    check IOError
    err then Either IOError a -> IO (Either IOError a)
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (IOError -> Either IOError a
    forall a b. a -> Either a b
    Left IOError
    err) else IOError -> IO (Either IOError a)
    forall e a. (HasCallStack, Exception e) => e -> IO a
    throwIO IOError
    err
        Right a
    val -> Either IOError a -> IO (Either IOError a)
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (a -> Either IOError a
    forall a b. b -> Either a b
    Right a
    val)

    -- | Attempt to perform the given action, silencing any IO exception thrown by
    -- it.
    ignoreIOExceptions :: IO () -> IO ()
    ignoreIOExceptions :: IO () -> IO ()
    ignoreIOExceptions IO ()
    io = IO ()
    io IO () -> (IOError -> IO ()) -> IO ()
    forall a. IO a -> (IOError -> IO a) -> IO a
    `catchIOError` (\IOError
    _ -> () -> IO ()
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ())

    specializeErrorString :: String -> (IOError -> Bool) -> IO a -> IO a
    specializeErrorString :: forall a. String -> (IOError -> Bool) -> IO a -> IO a
    specializeErrorString String
    str IOError -> Bool
    errType IO a
    action = do
      mx <- (IOError -> Bool) -> IO a -> IO (Either IOError a)
    forall a. (IOError -> Bool) -> IO a -> IO (Either IOError a)
    tryIOErrorType IOError -> Bool
    errType IO a
    action
      case mx of
        Left  IOError
    e -> IOError -> IO a
    forall e a. (HasCallStack, Exception e) => e -> IO a
    throwIO (IOError -> String -> IOError
    ioeSetErrorString IOError
    e String
    str)
        Right a
    x -> a -> IO a
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure a
    x

    ioeAddLocation :: IOError -> String -> IOError
    ioeAddLocation :: IOError -> String -> IOError
    ioeAddLocation IOError
    e String
    loc = do
      IOError -> String -> IOError
    ioeSetLocation IOError
    e String
    newLoc
      where
        newLoc :: String
    newLoc = String
    loc String -> String -> String
    forall a. Semigroup a => a -> a -> a
    <> if String -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null String
    oldLoc then String
    "" else String
    ":" String -> String -> String
    forall a. Semigroup a => a -> a -> a
    <> String
    oldLoc
        oldLoc :: String
    oldLoc = IOError -> String
    ioeGetLocation IOError
    e

    rightOrError :: Exception e => Either e a -> a
    rightOrError :: forall e a. Exception e => Either e a -> a
    rightOrError (Left e
    e)  = String -> a
    forall a. HasCallStack => String -> a
    error (e -> String
    forall e. Exception e => e -> String
    displayException e
    e)
    rightOrError (Right a
    a) = a
    a

    -- | Fallibly converts String to OsString. Only intended to be used on literals.
    os :: String -> OsString
    os :: String -> OsString
    os = Either SomeException OsString -> OsString
    forall e a. Exception e => Either e a -> a
    rightOrError (Either SomeException OsString -> OsString)
    -> (String -> Either SomeException OsString) -> String -> OsString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Either SomeException OsString
    forall (m :: * -> *). MonadThrow m => String -> m OsString
    encodeUtf

    -- | Fallibly converts OsString to String. Only intended to be used on literals.
    so :: OsString -> String
    so :: OsString -> String
    so = Either SomeException String -> String
    forall e a. Exception e => Either e a -> a
    rightOrError (Either SomeException String -> String)
    -> (OsString -> Either SomeException String) -> OsString -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . OsString -> Either SomeException String
    forall (m :: * -> *). MonadThrow m => OsString -> m String
    decodeUtf

    ioeSetOsPath :: IOError -> OsPath -> IOError
    ioeSetOsPath :: IOError -> OsString -> IOError
    ioeSetOsPath IOError
    err =
      IOError -> String -> IOError
    ioeSetFileName IOError
    err (String -> IOError) -> (OsString -> String) -> OsString -> IOError
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
      Either EncodingException String -> String
    forall e a. Exception e => Either e a -> a
    rightOrError (Either EncodingException String -> String)
    -> (OsString -> Either EncodingException String)
    -> OsString
    -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
      TextEncoding
    -> TextEncoding -> OsString -> Either EncodingException String
    decodeWith
        (CodingFailureMode -> TextEncoding
    mkUTF8 CodingFailureMode
    TransliterateCodingFailure)
        (CodingFailureMode -> TextEncoding
    mkUTF16le CodingFailureMode
    TransliterateCodingFailure)

    dropSpecialDotDirs :: [OsPath] -> [OsPath]
    dropSpecialDotDirs :: [OsString] -> [OsString]
    dropSpecialDotDirs = (OsString -> Bool) -> [OsString] -> [OsString]
    forall a. (a -> Bool) -> [a] -> [a]
    filter OsString -> Bool
    f
      where f :: OsString -> Bool
    f OsString
    filename = OsString
    filename OsString -> OsString -> Bool
    forall a. Eq a => a -> a -> Bool
    /= String -> OsString
    os String
    "." Bool -> Bool -> Bool
    && OsString
    filename OsString -> OsString -> Bool
    forall a. Eq a => a -> a -> Bool
    /= String -> OsString
    os String
    ".."

    -- | Given a list of path segments, expand @.@ and @..@.  The path segments
    -- must not contain path separators.
    expandDots :: [OsPath] -> [OsPath]
    expandDots :: [OsString] -> [OsString]
    expandDots = [OsString] -> [OsString]
    forall a. [a] -> [a]
    reverse ([OsString] -> [OsString])
    -> ([OsString] -> [OsString]) -> [OsString] -> [OsString]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [OsString] -> [OsString] -> [OsString]
    go []
      where
        go :: [OsString] -> [OsString] -> [OsString]
    go [OsString]
    ys' [OsString]
    xs' =
          case [OsString]
    xs' of
            [] -> [OsString]
    ys'
            OsString
    x : [OsString]
    xs
              | OsString
    x OsString -> OsString -> Bool
    forall a. Eq a => a -> a -> Bool
    == String -> OsString
    os String
    "." -> [OsString] -> [OsString] -> [OsString]
    go [OsString]
    ys' [OsString]
    xs
              | OsString
    x OsString -> OsString -> Bool
    forall a. Eq a => a -> a -> Bool
    == String -> OsString
    os String
    ".." ->
                  case [OsString]
    ys' of
                    [] -> [OsString] -> [OsString] -> [OsString]
    go (OsString
    x OsString -> [OsString] -> [OsString]
    forall a. a -> [a] -> [a]
    : [OsString]
    ys') [OsString]
    xs
                    OsString
    y : [OsString]
    ys
                      | OsString
    y OsString -> OsString -> Bool
    forall a. Eq a => a -> a -> Bool
    == String -> OsString
    os String
    ".." -> [OsString] -> [OsString] -> [OsString]
    go (OsString
    x OsString -> [OsString] -> [OsString]
    forall a. a -> [a] -> [a]
    : [OsString]
    ys') [OsString]
    xs
                      | Bool
    otherwise -> [OsString] -> [OsString] -> [OsString]
    go [OsString]
    ys [OsString]
    xs
              | Bool
    otherwise -> [OsString] -> [OsString] -> [OsString]
    go (OsString
    x OsString -> [OsString] -> [OsString]
    forall a. a -> [a] -> [a]
    : [OsString]
    ys') [OsString]
    xs

    -- | Convert to the right kind of slashes.
    normalisePathSeps :: OsPath -> OsPath
    normalisePathSeps :: OsString -> OsString
    normalisePathSeps OsString
    p = [OsChar] -> OsString
    pack (OsChar -> OsChar
    normaliseChar (OsChar -> OsChar) -> [OsChar] -> [OsChar]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> OsString -> [OsChar]
    unpack OsString
    p)
      where normaliseChar :: OsChar -> OsChar
    normaliseChar OsChar
    c = if OsChar -> Bool
    isPathSeparator OsChar
    c then OsChar
    pathSeparator else OsChar
    c

    -- | Remove redundant trailing slashes and pick the right kind of slash.
    normaliseTrailingSep :: OsPath -> OsPath
    normaliseTrailingSep :: OsString -> OsString
    normaliseTrailingSep OsString
    path = do
      let path' :: [OsChar]
    path' = [OsChar] -> [OsChar]
    forall a. [a] -> [a]
    reverse (OsString -> [OsChar]
    unpack OsString
    path)
      let ([OsChar]
    sep, [OsChar]
    path'') = (OsChar -> Bool) -> [OsChar] -> ([OsChar], [OsChar])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    span OsChar -> Bool
    isPathSeparator [OsChar]
    path'
      let addSep :: [OsChar] -> [OsChar]
    addSep = if [OsChar] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [OsChar]
    sep then [OsChar] -> [OsChar]
    forall a. a -> a
    id else (OsChar
    pathSeparator OsChar -> [OsChar] -> [OsChar]
    forall a. a -> [a] -> [a]
    :)
      [OsChar] -> OsString
    pack ([OsChar] -> [OsChar]
    forall a. [a] -> [a]
    reverse ([OsChar] -> [OsChar]
    addSep [OsChar]
    path''))

    -- | Convert empty paths to the current directory, otherwise leave it
    -- unchanged.
    emptyToCurDir :: OsPath -> OsPath
    emptyToCurDir :: OsString -> OsString
    emptyToCurDir OsString
    path
      | OsString
    path OsString -> OsString -> Bool
    forall a. Eq a => a -> a -> Bool
    == OsString
    forall a. Monoid a => a
    mempty = String -> OsString
    os String
    "."
      | Bool
    otherwise      = OsString
    path

    -- | Similar to 'normalise' but empty paths stay empty.
    simplifyPosix :: OsPath -> OsPath
    simplifyPosix :: OsString -> OsString
    simplifyPosix OsString
    path
      | OsString
    path OsString -> OsString -> Bool
    forall a. Eq a => a -> a -> Bool
    == OsString
    forall a. Monoid a => a
    mempty = OsString
    forall a. Monoid a => a
    mempty
      | Bool
    otherwise      = OsString -> OsString
    normalise OsString
    path

    -- | Similar to 'normalise' but:
    --
    -- * empty paths stay empty,
    -- * parent dirs (@..@) are expanded, and
    -- * paths starting with @\\\\?\\@ are preserved.
    --
    -- The goal is to preserve the meaning of paths better than 'normalise'.
    simplifyWindows :: OsPath -> OsPath
    simplifyWindows :: OsString -> OsString
    simplifyWindows OsString
    path
      | OsString
    path OsString -> OsString -> Bool
    forall a. Eq a => a -> a -> Bool
    == OsString
    forall a. Monoid a => a
    mempty         = OsString
    forall a. Monoid a => a
    mempty
      | OsString
    drive' OsString -> OsString -> Bool
    forall a. Eq a => a -> a -> Bool
    == String -> OsString
    os String
    "\\\\?\\" = OsString
    drive' OsString -> OsString -> OsString
    forall a. Semigroup a => a -> a -> a
    <> OsString
    subpath
      | Bool
    otherwise              = OsString
    simplifiedPath
      where
        simplifiedPath :: OsString
    simplifiedPath = OsString -> OsString -> OsString
    joinDrive OsString
    drive' OsString
    subpath'
        (OsString
    drive, OsString
    subpath) = OsString -> (OsString, OsString)
    splitDrive OsString
    path
        drive' :: OsString
    drive' = OsString -> OsString
    upperDrive (OsString -> OsString
    normaliseTrailingSep (OsString -> OsString
    normalisePathSeps OsString
    drive))
        subpath' :: OsString
    subpath' = OsString -> OsString
    appendSep (OsString -> OsString)
    -> (OsString -> OsString) -> OsString -> OsString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . OsString -> OsString
    avoidEmpty (OsString -> OsString)
    -> (OsString -> OsString) -> OsString -> OsString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . OsString -> OsString
    prependSep (OsString -> OsString)
    -> (OsString -> OsString) -> OsString -> OsString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [OsString] -> OsString
    joinPath ([OsString] -> OsString)
    -> (OsString -> [OsString]) -> OsString -> OsString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
                   [OsString] -> [OsString]
    stripPardirs ([OsString] -> [OsString])
    -> (OsString -> [OsString]) -> OsString -> [OsString]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [OsString] -> [OsString]
    expandDots ([OsString] -> [OsString])
    -> (OsString -> [OsString]) -> OsString -> [OsString]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [OsString] -> [OsString]
    skipSeps ([OsString] -> [OsString])
    -> (OsString -> [OsString]) -> OsString -> [OsString]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
                   OsString -> [OsString]
    splitDirectories (OsString -> OsString) -> OsString -> OsString
    forall a b. (a -> b) -> a -> b
    $ OsString
    subpath

        upperDrive :: OsString -> OsString
    upperDrive OsString
    d = case OsString -> [OsChar]
    unpack OsString
    d of
          OsChar
    c : OsChar
    k : [OsChar]
    s
            | Char -> Bool
    isAlpha (OsChar -> Char
    toChar OsChar
    c), OsChar -> Char
    toChar OsChar
    k Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    ':', (OsChar -> Bool) -> [OsChar] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all OsChar -> Bool
    isPathSeparator [OsChar]
    s ->
              -- unsafeFromChar is safe here since all characters are ASCII.
              [OsChar] -> OsString
    pack (Char -> OsChar
    unsafeFromChar (Char -> Char
    toUpper (OsChar -> Char
    toChar OsChar
    c)) OsChar -> [OsChar] -> [OsChar]
    forall a. a -> [a] -> [a]
    : Char -> OsChar
    unsafeFromChar Char
    ':' OsChar -> [OsChar] -> [OsChar]
    forall a. a -> [a] -> [a]
    : [OsChar]
    s)
          [OsChar]
    _ -> OsString
    d
        skipSeps :: [OsString] -> [OsString]
    skipSeps =
          ([OsChar] -> OsString
    pack ([OsChar] -> OsString) -> [[OsChar]] -> [OsString]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>) ([[OsChar]] -> [OsString])
    -> ([OsString] -> [[OsChar]]) -> [OsString] -> [OsString]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
          ([OsChar] -> Bool) -> [[OsChar]] -> [[OsChar]]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool) -> ([OsChar] -> Bool) -> [OsChar] -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([OsChar] -> [[OsChar]] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` (OsChar -> [OsChar]
    forall a. a -> [a]
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (OsChar -> [OsChar]) -> [OsChar] -> [[OsChar]]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [OsChar]
    pathSeparators))) ([[OsChar]] -> [[OsChar]])
    -> ([OsString] -> [[OsChar]]) -> [OsString] -> [[OsChar]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
          (OsString -> [OsChar]
    unpack (OsString -> [OsChar]) -> [OsString] -> [[OsChar]]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>)
        stripPardirs :: [OsString] -> [OsString]
    stripPardirs | Bool
    pathIsAbsolute Bool -> Bool -> Bool
    || Bool
    subpathIsAbsolute = (OsString -> Bool) -> [OsString] -> [OsString]
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile (OsString -> OsString -> Bool
    forall a. Eq a => a -> a -> Bool
    == String -> OsString
    os String
    "..")
                     | Bool
    otherwise = [OsString] -> [OsString]
    forall a. a -> a
    id
        prependSep :: OsString -> OsString
    prependSep | Bool
    subpathIsAbsolute = ([OsChar] -> OsString
    pack [OsChar
    pathSeparator] OsString -> OsString -> OsString
    forall a. Semigroup a => a -> a -> a
    <>)
                   | Bool
    otherwise = OsString -> OsString
    forall a. a -> a
    id
        avoidEmpty :: OsString -> OsString
    avoidEmpty | Bool -> Bool
    not Bool
    pathIsAbsolute
                   , OsString
    drive OsString -> OsString -> Bool
    forall a. Eq a => a -> a -> Bool
    == OsString
    forall a. Monoid a => a
    mempty Bool -> Bool -> Bool
    || Bool
    hasTrailingPathSep -- prefer "C:" over "C:."
                     = OsString -> OsString
    emptyToCurDir
                   | Bool
    otherwise = OsString -> OsString
    forall a. a -> a
    id
        appendSep :: OsString -> OsString
    appendSep OsString
    p | Bool
    hasTrailingPathSep, Bool -> Bool
    not (Bool
    pathIsAbsolute Bool -> Bool -> Bool
    && OsString
    p OsString -> OsString -> Bool
    forall a. Eq a => a -> a -> Bool
    == OsString
    forall a. Monoid a => a
    mempty)
                      = OsString -> OsString
    addTrailingPathSeparator OsString
    p
                    | Bool
    otherwise = OsString
    p
        pathIsAbsolute :: Bool
    pathIsAbsolute = Bool -> Bool
    not (OsString -> Bool
    isRelative OsString
    path)
        subpathIsAbsolute :: Bool
    subpathIsAbsolute = (OsChar -> Bool) -> [OsChar] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any OsChar -> Bool
    isPathSeparator (Int -> [OsChar] -> [OsChar]
    forall a. Int -> [a] -> [a]
    take Int
    1 (OsString -> [OsChar]
    unpack OsString
    subpath))
        hasTrailingPathSep :: Bool
    hasTrailingPathSep = OsString -> Bool
    hasTrailingPathSeparator OsString
    subpath

    data WhetherFollow = NoFollow | FollowLinks deriving (Int -> WhetherFollow -> String -> String
    [WhetherFollow] -> String -> String
    WhetherFollow -> String
    (Int -> WhetherFollow -> String -> String)
    -> (WhetherFollow -> String)
    -> ([WhetherFollow] -> String -> String)
    -> Show WhetherFollow
    forall a.
    (Int -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: Int -> WhetherFollow -> String -> String
    showsPrec :: Int -> WhetherFollow -> String -> String
    $cshow :: WhetherFollow -> String
    show :: WhetherFollow -> String
    $cshowList :: [WhetherFollow] -> String -> String
    showList :: [WhetherFollow] -> String -> String
    Show)

    isNoFollow :: WhetherFollow -> Bool
    isNoFollow :: WhetherFollow -> Bool
    isNoFollow WhetherFollow
    NoFollow    = Bool
    True
    isNoFollow WhetherFollow
    FollowLinks = Bool
    False

    data FileType = File
                  | SymbolicLink -- ^ POSIX: either file or directory link; Windows: file link
                  | Directory
                  | DirectoryLink -- ^ Windows only: directory link
                  deriving (FileType
    FileType -> FileType -> Bounded FileType
    forall a. a -> a -> Bounded a
    $cminBound :: FileType
    minBound :: FileType
    $cmaxBound :: FileType
    maxBound :: FileType
    Bounded, Int -> FileType
    FileType -> Int
    FileType -> [FileType]
    FileType -> FileType
    FileType -> FileType -> [FileType]
    FileType -> FileType -> FileType -> [FileType]
    (FileType -> FileType)
    -> (FileType -> FileType)
    -> (Int -> FileType)
    -> (FileType -> Int)
    -> (FileType -> [FileType])
    -> (FileType -> FileType -> [FileType])
    -> (FileType -> FileType -> [FileType])
    -> (FileType -> FileType -> FileType -> [FileType])
    -> Enum FileType
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: FileType -> FileType
    succ :: FileType -> FileType
    $cpred :: FileType -> FileType
    pred :: FileType -> FileType
    $ctoEnum :: Int -> FileType
    toEnum :: Int -> FileType
    $cfromEnum :: FileType -> Int
    fromEnum :: FileType -> Int
    $cenumFrom :: FileType -> [FileType]
    enumFrom :: FileType -> [FileType]
    $cenumFromThen :: FileType -> FileType -> [FileType]
    enumFromThen :: FileType -> FileType -> [FileType]
    $cenumFromTo :: FileType -> FileType -> [FileType]
    enumFromTo :: FileType -> FileType -> [FileType]
    $cenumFromThenTo :: FileType -> FileType -> FileType -> [FileType]
    enumFromThenTo :: FileType -> FileType -> FileType -> [FileType]
    Enum, FileType -> FileType -> Bool
    (FileType -> FileType -> Bool)
    -> (FileType -> FileType -> Bool) -> Eq FileType
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: FileType -> FileType -> Bool
    == :: FileType -> FileType -> Bool
    $c/= :: FileType -> FileType -> Bool
    /= :: FileType -> FileType -> Bool
    Eq, Eq FileType
    Eq FileType =>
    (FileType -> FileType -> Ordering)
    -> (FileType -> FileType -> Bool)
    -> (FileType -> FileType -> Bool)
    -> (FileType -> FileType -> Bool)
    -> (FileType -> FileType -> Bool)
    -> (FileType -> FileType -> FileType)
    -> (FileType -> FileType -> FileType)
    -> Ord FileType
    FileType -> FileType -> Bool
    FileType -> FileType -> Ordering
    FileType -> FileType -> FileType
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: FileType -> FileType -> Ordering
    compare :: FileType -> FileType -> Ordering
    $c< :: FileType -> FileType -> Bool
    < :: FileType -> FileType -> Bool
    $c<= :: FileType -> FileType -> Bool
    <= :: FileType -> FileType -> Bool
    $c> :: FileType -> FileType -> Bool
    > :: FileType -> FileType -> Bool
    $c>= :: FileType -> FileType -> Bool
    >= :: FileType -> FileType -> Bool
    $cmax :: FileType -> FileType -> FileType
    max :: FileType -> FileType -> FileType
    $cmin :: FileType -> FileType -> FileType
    min :: FileType -> FileType -> FileType
    Ord, ReadPrec [FileType]
    ReadPrec FileType
    Int -> ReadS FileType
    ReadS [FileType]
    (Int -> ReadS FileType)
    -> ReadS [FileType]
    -> ReadPrec FileType
    -> ReadPrec [FileType]
    -> Read FileType
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS FileType
    readsPrec :: Int -> ReadS FileType
    $creadList :: ReadS [FileType]
    readList :: ReadS [FileType]
    $creadPrec :: ReadPrec FileType
    readPrec :: ReadPrec FileType
    $creadListPrec :: ReadPrec [FileType]
    readListPrec :: ReadPrec [FileType]
    Read, Int -> FileType -> String -> String
    [FileType] -> String -> String
    FileType -> String
    (Int -> FileType -> String -> String)
    -> (FileType -> String)
    -> ([FileType] -> String -> String)
    -> Show FileType
    forall a.
    (Int -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: Int -> FileType -> String -> String
    showsPrec :: Int -> FileType -> String -> String
    $cshow :: FileType -> String
    show :: FileType -> String
    $cshowList :: [FileType] -> String -> String
    showList :: [FileType] -> String -> String
    Show)

    -- | Check whether the given 'FileType' is considered a directory by the
    -- operating system.  This affects the choice of certain functions
    -- e.g. 'System.Directory.removeDirectory' vs 'System.Directory.removeFile'.
    fileTypeIsDirectory :: FileType -> Bool
    fileTypeIsDirectory :: FileType -> Bool
    fileTypeIsDirectory FileType
    Directory     = Bool
    True
    fileTypeIsDirectory FileType
    DirectoryLink = Bool
    True
    fileTypeIsDirectory FileType
    _             = Bool
    False

    -- | Return whether the given 'FileType' is a link.
    fileTypeIsLink :: FileType -> Bool
    fileTypeIsLink :: FileType -> Bool
    fileTypeIsLink FileType
    SymbolicLink  = Bool
    True
    fileTypeIsLink FileType
    DirectoryLink = Bool
    True
    fileTypeIsLink FileType
    _             = Bool
    False

    data Permissions
      = Permissions
      { Permissions -> Bool
    readable :: Bool
      , Permissions -> Bool
    writable :: Bool
      , Permissions -> Bool
    executable :: Bool
      , Permissions -> Bool
    searchable :: Bool
      } deriving (Permissions -> Permissions -> Bool
    (Permissions -> Permissions -> Bool)
    -> (Permissions -> Permissions -> Bool) -> Eq Permissions
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Permissions -> Permissions -> Bool
    == :: Permissions -> Permissions -> Bool
    $c/= :: Permissions -> Permissions -> Bool
    /= :: Permissions -> Permissions -> Bool
    Eq, Eq Permissions
    Eq Permissions =>
    (Permissions -> Permissions -> Ordering)
    -> (Permissions -> Permissions -> Bool)
    -> (Permissions -> Permissions -> Bool)
    -> (Permissions -> Permissions -> Bool)
    -> (Permissions -> Permissions -> Bool)
    -> (Permissions -> Permissions -> Permissions)
    -> (Permissions -> Permissions -> Permissions)
    -> Ord Permissions
    Permissions -> Permissions -> Bool
    Permissions -> Permissions -> Ordering
    Permissions -> Permissions -> Permissions
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: Permissions -> Permissions -> Ordering
    compare :: Permissions -> Permissions -> Ordering
    $c< :: Permissions -> Permissions -> Bool
    < :: Permissions -> Permissions -> Bool
    $c<= :: Permissions -> Permissions -> Bool
    <= :: Permissions -> Permissions -> Bool
    $c> :: Permissions -> Permissions -> Bool
    > :: Permissions -> Permissions -> Bool
    $c>= :: Permissions -> Permissions -> Bool
    >= :: Permissions -> Permissions -> Bool
    $cmax :: Permissions -> Permissions -> Permissions
    max :: Permissions -> Permissions -> Permissions
    $cmin :: Permissions -> Permissions -> Permissions
    min :: Permissions -> Permissions -> Permissions
    Ord, ReadPrec [Permissions]
    ReadPrec Permissions
    Int -> ReadS Permissions
    ReadS [Permissions]
    (Int -> ReadS Permissions)
    -> ReadS [Permissions]
    -> ReadPrec Permissions
    -> ReadPrec [Permissions]
    -> Read Permissions
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS Permissions
    readsPrec :: Int -> ReadS Permissions
    $creadList :: ReadS [Permissions]
    readList :: ReadS [Permissions]
    $creadPrec :: ReadPrec Permissions
    readPrec :: ReadPrec Permissions
    $creadListPrec :: ReadPrec [Permissions]
    readListPrec :: ReadPrec [Permissions]
    Read, Int -> Permissions -> String -> String
    [Permissions] -> String -> String
    Permissions -> String
    (Int -> Permissions -> String -> String)
    -> (Permissions -> String)
    -> ([Permissions] -> String -> String)
    -> Show Permissions
    forall a.
    (Int -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: Int -> Permissions -> String -> String
    showsPrec :: Int -> Permissions -> String -> String
    $cshow :: Permissions -> String
    show :: Permissions -> String
    $cshowList :: [Permissions] -> String -> String
    showList :: [Permissions] -> String -> String
    Show)

    withBinaryFile :: OsPath -> IOMode -> (Handle -> IO r) -> IO r
    withBinaryFile :: forall r. OsString -> IOMode -> (Handle -> IO r) -> IO r
    withBinaryFile OsString
    path IOMode
    mode = IO Handle -> (Handle -> IO ()) -> (Handle -> IO r) -> IO r
    forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
    bracket (OsString -> IOMode -> IO Handle
    openFileWithCloseOnExec OsString
    path IOMode
    mode) Handle -> IO ()
    hClose

    -- | Copy data from one handle to another until end of file.
    copyHandleData :: Handle                -- ^ Source handle
                   -> Handle                -- ^ Destination handle
                   -> IO ()
    copyHandleData :: Handle -> Handle -> IO ()
    copyHandleData Handle
    hFrom Handle
    hTo =
      (IOError -> String -> IOError
    `ioeAddLocation` String
    "copyData") (IOError -> IOError) -> IO () -> IO ()
    forall a. (IOError -> IOError) -> IO a -> IO a
    `modifyIOError` do
        Int -> (Ptr (ZonkAny 0) -> IO ()) -> IO ()
    forall a b. Int -> (Ptr a -> IO b) -> IO b
    allocaBytes Int
    bufferSize Ptr (ZonkAny 0) -> IO ()
    forall {a}. Ptr a -> IO ()
    go
      where
        bufferSize :: Int
    bufferSize = Int
    131072 -- 128 KiB, as coreutils `cp` uses as of May 2014 (see ioblksize.h)
        go :: Ptr a -> IO ()
    go Ptr a
    buffer = do
          count <- Handle -> Ptr a -> Int -> IO Int
    forall a. Handle -> Ptr a -> Int -> IO Int
    hGetBuf Handle
    hFrom Ptr a
    buffer Int
    bufferSize
          when (count > 0) $ do
            hPutBuf hTo buffer count
            go buffer

    -- | Special directories for storing user-specific application data,
    -- configuration, and cache files, as specified by the
    -- <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html XDG Base Directory Specification>.
    --
    -- Note: On Windows, 'XdgData' and 'XdgConfig' usually map to the same
    -- directory.
    --
    -- @since 1.2.3.0
    data XdgDirectory
      = XdgData
        -- ^ For data files (e.g. images).
        -- It uses the @XDG_DATA_HOME@ environment variable.
        -- On non-Windows systems, the default is @~\/.local\/share@.
        -- On Windows, the default is @%APPDATA%@
        -- (e.g. @C:\/Users\//\<user\>/\/AppData\/Roaming@).
        -- Can be considered as the user-specific equivalent of @\/usr\/share@.
      | XdgConfig
        -- ^ For configuration files.
        -- It uses the @XDG_CONFIG_HOME@ environment variable.
        -- On non-Windows systems, the default is @~\/.config@.
        -- On Windows, the default is @%APPDATA%@
        -- (e.g. @C:\/Users\//\<user\>/\/AppData\/Roaming@).
        -- Can be considered as the user-specific equivalent of @\/etc@.
      | XdgCache
        -- ^ For non-essential files (e.g. cache).
        -- It uses the @XDG_CACHE_HOME@ environment variable.
        -- On non-Windows systems, the default is @~\/.cache@.
        -- On Windows, the default is @%LOCALAPPDATA%@
        -- (e.g. @C:\/Users\//\<user\>/\/AppData\/Local@).
        -- Can be considered as the user-specific equivalent of @\/var\/cache@.
      | XdgState
       -- ^ For data that should persist between (application) restarts,
       -- but that is not important or portable enough to the user that it
       -- should be stored in 'XdgData'.
       -- It uses the @XDG_STATE_HOME@ environment variable.
       -- On non-Windows sytems, the default is @~\/.local\/state@.  On
       -- Windows, the default is @%LOCALAPPDATA%@
       -- (e.g. @C:\/Users\//\<user\>/\/AppData\/Local@).
       --
       -- @since 1.3.7.0
      deriving (XdgDirectory
    XdgDirectory -> XdgDirectory -> Bounded XdgDirectory
    forall a. a -> a -> Bounded a
    $cminBound :: XdgDirectory
    minBound :: XdgDirectory
    $cmaxBound :: XdgDirectory
    maxBound :: XdgDirectory
    Bounded, Int -> XdgDirectory
    XdgDirectory -> Int
    XdgDirectory -> [XdgDirectory]
    XdgDirectory -> XdgDirectory
    XdgDirectory -> XdgDirectory -> [XdgDirectory]
    XdgDirectory -> XdgDirectory -> XdgDirectory -> [XdgDirectory]
    (XdgDirectory -> XdgDirectory)
    -> (XdgDirectory -> XdgDirectory)
    -> (Int -> XdgDirectory)
    -> (XdgDirectory -> Int)
    -> (XdgDirectory -> [XdgDirectory])
    -> (XdgDirectory -> XdgDirectory -> [XdgDirectory])
    -> (XdgDirectory -> XdgDirectory -> [XdgDirectory])
    -> (XdgDirectory -> XdgDirectory -> XdgDirectory -> [XdgDirectory])
    -> Enum XdgDirectory
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: XdgDirectory -> XdgDirectory
    succ :: XdgDirectory -> XdgDirectory
    $cpred :: XdgDirectory -> XdgDirectory
    pred :: XdgDirectory -> XdgDirectory
    $ctoEnum :: Int -> XdgDirectory
    toEnum :: Int -> XdgDirectory
    $cfromEnum :: XdgDirectory -> Int
    fromEnum :: XdgDirectory -> Int
    $cenumFrom :: XdgDirectory -> [XdgDirectory]
    enumFrom :: XdgDirectory -> [XdgDirectory]
    $cenumFromThen :: XdgDirectory -> XdgDirectory -> [XdgDirectory]
    enumFromThen :: XdgDirectory -> XdgDirectory -> [XdgDirectory]
    $cenumFromTo :: XdgDirectory -> XdgDirectory -> [XdgDirectory]
    enumFromTo :: XdgDirectory -> XdgDirectory -> [XdgDirectory]
    $cenumFromThenTo :: XdgDirectory -> XdgDirectory -> XdgDirectory -> [XdgDirectory]
    enumFromThenTo :: XdgDirectory -> XdgDirectory -> XdgDirectory -> [XdgDirectory]
    Enum, XdgDirectory -> XdgDirectory -> Bool
    (XdgDirectory -> XdgDirectory -> Bool)
    -> (XdgDirectory -> XdgDirectory -> Bool) -> Eq XdgDirectory
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: XdgDirectory -> XdgDirectory -> Bool
    == :: XdgDirectory -> XdgDirectory -> Bool
    $c/= :: XdgDirectory -> XdgDirectory -> Bool
    /= :: XdgDirectory -> XdgDirectory -> Bool
    Eq, Eq XdgDirectory
    Eq XdgDirectory =>
    (XdgDirectory -> XdgDirectory -> Ordering)
    -> (XdgDirectory -> XdgDirectory -> Bool)
    -> (XdgDirectory -> XdgDirectory -> Bool)
    -> (XdgDirectory -> XdgDirectory -> Bool)
    -> (XdgDirectory -> XdgDirectory -> Bool)
    -> (XdgDirectory -> XdgDirectory -> XdgDirectory)
    -> (XdgDirectory -> XdgDirectory -> XdgDirectory)
    -> Ord XdgDirectory
    XdgDirectory -> XdgDirectory -> Bool
    XdgDirectory -> XdgDirectory -> Ordering
    XdgDirectory -> XdgDirectory -> XdgDirectory
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: XdgDirectory -> XdgDirectory -> Ordering
    compare :: XdgDirectory -> XdgDirectory -> Ordering
    $c< :: XdgDirectory -> XdgDirectory -> Bool
    < :: XdgDirectory -> XdgDirectory -> Bool
    $c<= :: XdgDirectory -> XdgDirectory -> Bool
    <= :: XdgDirectory -> XdgDirectory -> Bool
    $c> :: XdgDirectory -> XdgDirectory -> Bool
    > :: XdgDirectory -> XdgDirectory -> Bool
    $c>= :: XdgDirectory -> XdgDirectory -> Bool
    >= :: XdgDirectory -> XdgDirectory -> Bool
    $cmax :: XdgDirectory -> XdgDirectory -> XdgDirectory
    max :: XdgDirectory -> XdgDirectory -> XdgDirectory
    $cmin :: XdgDirectory -> XdgDirectory -> XdgDirectory
    min :: XdgDirectory -> XdgDirectory -> XdgDirectory
    Ord, ReadPrec [XdgDirectory]
    ReadPrec XdgDirectory
    Int -> ReadS XdgDirectory
    ReadS [XdgDirectory]
    (Int -> ReadS XdgDirectory)
    -> ReadS [XdgDirectory]
    -> ReadPrec XdgDirectory
    -> ReadPrec [XdgDirectory]
    -> Read XdgDirectory
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS XdgDirectory
    readsPrec :: Int -> ReadS XdgDirectory
    $creadList :: ReadS [XdgDirectory]
    readList :: ReadS [XdgDirectory]
    $creadPrec :: ReadPrec XdgDirectory
    readPrec :: ReadPrec XdgDirectory
    $creadListPrec :: ReadPrec [XdgDirectory]
    readListPrec :: ReadPrec [XdgDirectory]
    Read, Int -> XdgDirectory -> String -> String
    [XdgDirectory] -> String -> String
    XdgDirectory -> String
    (Int -> XdgDirectory -> String -> String)
    -> (XdgDirectory -> String)
    -> ([XdgDirectory] -> String -> String)
    -> Show XdgDirectory
    forall a.
    (Int -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: Int -> XdgDirectory -> String -> String
    showsPrec :: Int -> XdgDirectory -> String -> String
    $cshow :: XdgDirectory -> String
    show :: XdgDirectory -> String
    $cshowList :: [XdgDirectory] -> String -> String
    showList :: [XdgDirectory] -> String -> String
    Show)

    -- | Search paths for various application data, as specified by the
    -- <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html XDG Base Directory Specification>.
    --
    -- The list of paths is split using 'System.FilePath.searchPathSeparator',
    -- which on Windows is a semicolon.
    --
    -- Note: On Windows, 'XdgDataDirs' and 'XdgConfigDirs' usually yield the same
    -- result.
    --
    -- @since 1.3.2.0
    data XdgDirectoryList
      = XdgDataDirs
        -- ^ For data files (e.g. images).
        -- It uses the @XDG_DATA_DIRS@ environment variable.
        -- On non-Windows systems, the default is @\/usr\/local\/share\/@ and
        -- @\/usr\/share\/@.
        -- On Windows, the default is @%PROGRAMDATA%@ or @%ALLUSERSPROFILE%@
        -- (e.g. @C:\/ProgramData@).
      | XdgConfigDirs
        -- ^ For configuration files.
        -- It uses the @XDG_CONFIG_DIRS@ environment variable.
        -- On non-Windows systems, the default is @\/etc\/xdg@.
        -- On Windows, the default is @%PROGRAMDATA%@ or @%ALLUSERSPROFILE%@
        -- (e.g. @C:\/ProgramData@).
      deriving (XdgDirectoryList
    XdgDirectoryList -> XdgDirectoryList -> Bounded XdgDirectoryList
    forall a. a -> a -> Bounded a
    $cminBound :: XdgDirectoryList
    minBound :: XdgDirectoryList
    $cmaxBound :: XdgDirectoryList
    maxBound :: XdgDirectoryList
    Bounded, Int -> XdgDirectoryList
    XdgDirectoryList -> Int
    XdgDirectoryList -> [XdgDirectoryList]
    XdgDirectoryList -> XdgDirectoryList
    XdgDirectoryList -> XdgDirectoryList -> [XdgDirectoryList]
    XdgDirectoryList
    -> XdgDirectoryList -> XdgDirectoryList -> [XdgDirectoryList]
    (XdgDirectoryList -> XdgDirectoryList)
    -> (XdgDirectoryList -> XdgDirectoryList)
    -> (Int -> XdgDirectoryList)
    -> (XdgDirectoryList -> Int)
    -> (XdgDirectoryList -> [XdgDirectoryList])
    -> (XdgDirectoryList -> XdgDirectoryList -> [XdgDirectoryList])
    -> (XdgDirectoryList -> XdgDirectoryList -> [XdgDirectoryList])
    -> (XdgDirectoryList
        -> XdgDirectoryList -> XdgDirectoryList -> [XdgDirectoryList])
    -> Enum XdgDirectoryList
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: XdgDirectoryList -> XdgDirectoryList
    succ :: XdgDirectoryList -> XdgDirectoryList
    $cpred :: XdgDirectoryList -> XdgDirectoryList
    pred :: XdgDirectoryList -> XdgDirectoryList
    $ctoEnum :: Int -> XdgDirectoryList
    toEnum :: Int -> XdgDirectoryList
    $cfromEnum :: XdgDirectoryList -> Int
    fromEnum :: XdgDirectoryList -> Int
    $cenumFrom :: XdgDirectoryList -> [XdgDirectoryList]
    enumFrom :: XdgDirectoryList -> [XdgDirectoryList]
    $cenumFromThen :: XdgDirectoryList -> XdgDirectoryList -> [XdgDirectoryList]
    enumFromThen :: XdgDirectoryList -> XdgDirectoryList -> [XdgDirectoryList]
    $cenumFromTo :: XdgDirectoryList -> XdgDirectoryList -> [XdgDirectoryList]
    enumFromTo :: XdgDirectoryList -> XdgDirectoryList -> [XdgDirectoryList]
    $cenumFromThenTo :: XdgDirectoryList
    -> XdgDirectoryList -> XdgDirectoryList -> [XdgDirectoryList]
    enumFromThenTo :: XdgDirectoryList
    -> XdgDirectoryList -> XdgDirectoryList -> [XdgDirectoryList]
    Enum, XdgDirectoryList -> XdgDirectoryList -> Bool
    (XdgDirectoryList -> XdgDirectoryList -> Bool)
    -> (XdgDirectoryList -> XdgDirectoryList -> Bool)
    -> Eq XdgDirectoryList
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: XdgDirectoryList -> XdgDirectoryList -> Bool
    == :: XdgDirectoryList -> XdgDirectoryList -> Bool
    $c/= :: XdgDirectoryList -> XdgDirectoryList -> Bool
    /= :: XdgDirectoryList -> XdgDirectoryList -> Bool
    Eq, Eq XdgDirectoryList
    Eq XdgDirectoryList =>
    (XdgDirectoryList -> XdgDirectoryList -> Ordering)
    -> (XdgDirectoryList -> XdgDirectoryList -> Bool)
    -> (XdgDirectoryList -> XdgDirectoryList -> Bool)
    -> (XdgDirectoryList -> XdgDirectoryList -> Bool)
    -> (XdgDirectoryList -> XdgDirectoryList -> Bool)
    -> (XdgDirectoryList -> XdgDirectoryList -> XdgDirectoryList)
    -> (XdgDirectoryList -> XdgDirectoryList -> XdgDirectoryList)
    -> Ord XdgDirectoryList
    XdgDirectoryList -> XdgDirectoryList -> Bool
    XdgDirectoryList -> XdgDirectoryList -> Ordering
    XdgDirectoryList -> XdgDirectoryList -> XdgDirectoryList
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: XdgDirectoryList -> XdgDirectoryList -> Ordering
    compare :: XdgDirectoryList -> XdgDirectoryList -> Ordering
    $c< :: XdgDirectoryList -> XdgDirectoryList -> Bool
    < :: XdgDirectoryList -> XdgDirectoryList -> Bool
    $c<= :: XdgDirectoryList -> XdgDirectoryList -> Bool
    <= :: XdgDirectoryList -> XdgDirectoryList -> Bool
    $c> :: XdgDirectoryList -> XdgDirectoryList -> Bool
    > :: XdgDirectoryList -> XdgDirectoryList -> Bool
    $c>= :: XdgDirectoryList -> XdgDirectoryList -> Bool
    >= :: XdgDirectoryList -> XdgDirectoryList -> Bool
    $cmax :: XdgDirectoryList -> XdgDirectoryList -> XdgDirectoryList
    max :: XdgDirectoryList -> XdgDirectoryList -> XdgDirectoryList
    $cmin :: XdgDirectoryList -> XdgDirectoryList -> XdgDirectoryList
    min :: XdgDirectoryList -> XdgDirectoryList -> XdgDirectoryList
    Ord, ReadPrec [XdgDirectoryList]
    ReadPrec XdgDirectoryList
    Int -> ReadS XdgDirectoryList
    ReadS [XdgDirectoryList]
    (Int -> ReadS XdgDirectoryList)
    -> ReadS [XdgDirectoryList]
    -> ReadPrec XdgDirectoryList
    -> ReadPrec [XdgDirectoryList]
    -> Read XdgDirectoryList
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS XdgDirectoryList
    readsPrec :: Int -> ReadS XdgDirectoryList
    $creadList :: ReadS [XdgDirectoryList]
    readList :: ReadS [XdgDirectoryList]
    $creadPrec :: ReadPrec XdgDirectoryList
    readPrec :: ReadPrec XdgDirectoryList
    $creadListPrec :: ReadPrec [XdgDirectoryList]
    readListPrec :: ReadPrec [XdgDirectoryList]
    Read, Int -> XdgDirectoryList -> String -> String
    [XdgDirectoryList] -> String -> String
    XdgDirectoryList -> String
    (Int -> XdgDirectoryList -> String -> String)
    -> (XdgDirectoryList -> String)
    -> ([XdgDirectoryList] -> String -> String)
    -> Show XdgDirectoryList
    forall a.
    (Int -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: Int -> XdgDirectoryList -> String -> String
    showsPrec :: Int -> XdgDirectoryList -> String -> String
    $cshow :: XdgDirectoryList -> String
    show :: XdgDirectoryList -> String
    $cshowList :: [XdgDirectoryList] -> String -> String
    showList :: [XdgDirectoryList] -> String -> String
    Show)