Fix whitespace
[haskell-directory.git] / System / Directory.hs
index 6fff3ad..e6b49c2 100644 (file)
@@ -39,6 +39,7 @@ module System.Directory
     , copyFile                  -- :: FilePath -> FilePath -> IO ()
     
     , canonicalizePath
+    , makeRelativeToCurrentDirectory
     , findExecutable
 
     -- * Existence tests
@@ -65,14 +66,13 @@ 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__
@@ -82,7 +82,7 @@ import Hugs.Directory
 import Foreign
 import Foreign.C
 
-{-# CFILES cbits/PrelIOUtils.c #-}
+{-# 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 ()
@@ -542,26 +543,27 @@ However, it certainly isn't always what you want.
 copyFile :: FilePath -> FilePath -> IO ()
 copyFile fromFPath toFPath =
 #if (!(defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ > 600))
-       do readFile fromFPath >>= writeFile toFPath
-          try (copyPermissions fromFPath toFPath)
-          return ()
+        do readFile fromFPath >>= writeFile toFPath
+           try (copyPermissions fromFPath toFPath)
+           return ()
 #else
-       (bracket (openBinaryFile fromFPath ReadMode) hClose $ \hFrom ->
-        bracket (openBinaryFile toFPath WriteMode) hClose $ \hTo ->
-        allocaBytes bufferSize $ \buffer -> do
-               copyContents hFrom hTo buffer
-               try (copyPermissions fromFPath toFPath)
-               return ()) `catch` (ioError . changeFunName)
-       where
-               bufferSize = 1024
-               
-               changeFunName (IOError h iot fun str mb_fp) = IOError h iot "copyFile" str mb_fp
-               
-               copyContents hFrom hTo buffer = do
-                       count <- hGetBuf hFrom buffer bufferSize
-                       when (count > 0) $ do
-                               hPutBuf hTo buffer count
-                               copyContents hFrom hTo buffer
+        (bracket (openBinaryFile fromFPath ReadMode) hClose $ \hFrom ->
+         bracket (openBinaryFile toFPath WriteMode) hClose $ \hTo ->
+         allocaBytes bufferSize $ \buffer -> do
+                copyContents hFrom hTo buffer
+                try (copyPermissions fromFPath toFPath)
+                return ()) `catch` (ioError . changeFunName)
+        where
+                bufferSize = 1024
+
+                changeFunName (IOError h iot fun str mb_fp)
+                 = IOError h iot "copyFile" str mb_fp
+
+                copyContents hFrom hTo buffer = do
+                        count <- hGetBuf hFrom buffer bufferSize
+                        when (count > 0) $ do
+                                hPutBuf hTo buffer count
+                                copyContents hFrom hTo buffer
 #endif
 
 -- | Given path referring to a file or directory, returns a
@@ -597,6 +599,12 @@ foreign import ccall unsafe "realpath"
                               -> IO CString
 #endif
 
+-- | '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 
 -- is the path to the found executable or Nothing if there isn't
@@ -626,16 +634,16 @@ foreign import stdcall unsafe "SearchPathA"
 #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
 
@@ -854,28 +862,26 @@ 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
+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
 
-#endif /* __GLASGOW_HASKELL__ */
-
 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.
 
 The directory returned is expected to be writable by the current user,
@@ -1039,3 +1045,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
+