X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=System%2FDirectory.hs;h=3301ed3d2f93268ad96871703a713afd634100c6;hb=e3a4b0478ada7409027379fdf104419a46e219a7;hp=e5e988fa88222c7f0917c1e66f91b55bec3b0e94;hpb=8588695da8e9dcbfd78e1b3674f1883bf1116c0e;p=haskell-directory.git diff --git a/System/Directory.hs b/System/Directory.hs index e5e988f..3301ed3 100644 --- a/System/Directory.hs +++ b/System/Directory.hs @@ -39,6 +39,7 @@ module System.Directory , copyFile -- :: FilePath -> FilePath -> IO () , canonicalizePath + , makeRelativeToCurrentDirectory , findExecutable -- * Existence tests @@ -65,24 +66,23 @@ module System.Directory , getModificationTime -- :: FilePath -> IO ClockTime ) where -import System.Directory.Internals import System.Environment ( getEnv ) +import System.FilePath import System.IO.Error import Control.Monad ( when, unless ) #ifdef __NHC__ import Directory -import NHC.FFI #endif /* __NHC__ */ #ifdef __HUGS__ import Hugs.Directory #endif /* __HUGS__ */ -#if defined(__GLASGOW_HASKELL__) || defined(mingw32_HOST_OS) import Foreign import Foreign.C -#endif + +{-# CFILES cbits/directory.c #-} #ifdef __GLASGOW_HASKELL__ import Prelude @@ -270,11 +270,12 @@ createDirectoryIfMissing :: Bool -- ^ Create its parents too? -> IO () createDirectoryIfMissing parents file = do b <- doesDirectoryExist file - case (b,parents, file) of + case (b,parents, file) of (_, _, "") -> return () (True, _, _) -> return () - (_, True, _) -> mapM_ (createDirectoryIfMissing False) (tail (pathParents file)) + (_, True, _) -> mapM_ (createDirectoryIfMissing False) $ mkParents file (_, False, _) -> createDirectory file + where mkParents = scanl1 () . splitDirectories . normalise #if __GLASGOW_HASKELL__ {- | @'removeDirectory' dir@ removes an existing directory /dir/. The @@ -331,7 +332,7 @@ removeDirectory path = do removeDirectoryRecursive :: FilePath -> IO () removeDirectoryRecursive startLoc = do cont <- getDirectoryContents startLoc - sequence_ [rm (startLoc `joinFileName` x) | x <- cont, x /= "." && x /= ".."] + sequence_ [rm (startLoc x) | x <- cont, x /= "." && x /= ".."] removeDirectory startLoc where rm :: FilePath -> IO () @@ -564,7 +565,6 @@ copyFile fromFPath toFPath = copyContents hFrom hTo buffer #endif -#ifdef __GLASGOW_HASKELL__ -- | Given path referring to a file or directory, returns a -- canonicalized path, with the intent that two paths referring -- to the same file\/directory will map to the same canonicalized @@ -597,11 +597,12 @@ foreign import ccall unsafe "realpath" -> CString -> IO CString #endif -#else /* !__GLASGOW_HASKELL__ */ --- dummy implementation -canonicalizePath :: FilePath -> IO FilePath -canonicalizePath fpath = return fpath -#endif /* !__GLASGOW_HASKELL__ */ + +-- | 'makeRelative' the current directory. +makeRelativeToCurrentDirectory :: FilePath -> IO FilePath +makeRelativeToCurrentDirectory x = do + cur <- getCurrentDirectory + return $ makeRelative cur x -- | Given an executable file name, searches for such file -- in the directories listed in system PATH. The returned value @@ -629,23 +630,19 @@ foreign import stdcall unsafe "SearchPathA" -> CString -> Ptr CString -> IO CInt -# if !defined(__GLASGOW_HASKELL__) -long_path_size :: Int -long_path_size = 4096 -# endif #else do path <- getEnv "PATH" - search (parseSearchPath path) + search (splitSearchPath path) where - fileName = binary `joinFileExt` exeExtension + fileName = binary <.> exeExtension search :: [FilePath] -> IO (Maybe FilePath) search [] = return Nothing search (d:ds) = do - let path = d `joinFileName` fileName - b <- doesFileExist path - if b then return (Just path) + let path = d fileName + b <- doesFileExist path + if b then return (Just path) else search ds #endif @@ -864,26 +861,24 @@ isDirectory stat = do return (s_isdir mode) fileNameEndClean :: String -> String -fileNameEndClean name = - if i > 0 && (ec == '\\' || ec == '/') then - fileNameEndClean (take i name) - else - name - where - i = (length name) - 1 - ec = name !! i - -foreign import ccall unsafe "__hscore_long_path_size" - long_path_size :: Int +fileNameEndClean name = if isDrive name then addTrailingPathSeparator name + else dropTrailingPathSeparator name -foreign import ccall unsafe "__hscore_R_OK" r_OK :: CMode -foreign import ccall unsafe "__hscore_W_OK" w_OK :: CMode -foreign import ccall unsafe "__hscore_X_OK" x_OK :: CMode +foreign import ccall unsafe "__hscore_R_OK" r_OK :: CInt +foreign import ccall unsafe "__hscore_W_OK" w_OK :: CInt +foreign import ccall unsafe "__hscore_X_OK" x_OK :: CInt foreign import ccall unsafe "__hscore_S_IRUSR" s_IRUSR :: CMode foreign import ccall unsafe "__hscore_S_IWUSR" s_IWUSR :: CMode foreign import ccall unsafe "__hscore_S_IXUSR" s_IXUSR :: CMode +foreign import ccall unsafe "__hscore_long_path_size" + long_path_size :: Int + +#else +long_path_size :: Int +long_path_size = 2048 -- // guess? + #endif /* __GLASGOW_HASKELL__ */ {- | Returns the current user's home directory. @@ -909,7 +904,7 @@ cannot be found. -} getHomeDirectory :: IO FilePath getHomeDirectory = -#if __GLASGOW_HASKELL__ && defined(mingw32_HOST_OS) +#if defined(mingw32_HOST_OS) allocaBytes long_path_size $ \pPath -> do r <- c_SHGetFolderPath nullPtr csidl_PROFILE nullPtr 0 pPath if (r < 0) @@ -951,7 +946,7 @@ cannot be found. -} getAppUserDataDirectory :: String -> IO FilePath getAppUserDataDirectory appName = do -#if __GLASGOW_HASKELL__ && defined(mingw32_HOST_OS) +#if defined(mingw32_HOST_OS) allocaBytes long_path_size $ \pPath -> do r <- c_SHGetFolderPath nullPtr csidl_APPDATA nullPtr 0 pPath when (r<0) (raiseUnsupported "System.Directory.getAppUserDataDirectory") @@ -985,7 +980,7 @@ cannot be found. -} getUserDocumentsDirectory :: IO FilePath getUserDocumentsDirectory = do -#if __GLASGOW_HASKELL__ && defined(mingw32_HOST_OS) +#if defined(mingw32_HOST_OS) allocaBytes long_path_size $ \pPath -> do r <- c_SHGetFolderPath nullPtr csidl_PERSONAL nullPtr 0 pPath when (r<0) (raiseUnsupported "System.Directory.getUserDocumentsDirectory") @@ -1022,7 +1017,7 @@ The function doesn\'t verify whether the path exists. -} getTemporaryDirectory :: IO FilePath getTemporaryDirectory = do -#if __GLASGOW_HASKELL__ && defined(mingw32_HOST_OS) +#if defined(mingw32_HOST_OS) allocaBytes long_path_size $ \pPath -> do r <- c_GetTempPath (fromIntegral long_path_size) pPath peekCString pPath @@ -1030,7 +1025,7 @@ getTemporaryDirectory = do catch (getEnv "TMPDIR") (\ex -> return "/tmp") #endif -#if __GLASGOW_HASKELL__ && defined(mingw32_HOST_OS) +#if defined(mingw32_HOST_OS) foreign import ccall unsafe "__hscore_getFolderPath" c_SHGetFolderPath :: Ptr () -> CInt @@ -1049,3 +1044,14 @@ raiseUnsupported loc = ioException (IOError Nothing UnsupportedOperation loc "unsupported operation" Nothing) #endif + +-- ToDo: This should be determined via autoconf (AC_EXEEXT) +-- | Extension for executable files +-- (typically @\"\"@ on Unix and @\"exe\"@ on Windows or OS\/2) +exeExtension :: String +#ifdef mingw32_HOST_OS +exeExtension = "exe" +#else +exeExtension = "" +#endif +