on 32cc7dc help sign in
Idris-dev/src/Util/System.hs
107 lines 3.8 kB history raw
1{-# LANGUAGE CPP, ForeignFunctionInterface #-}
2module Util.System(tempfile,withTempdir,rmFile,catchIO, isWindows,
3 writeSource, writeSourceText, readSource,
4 setupBundledCC, isATTY) where
6-- System helper functions.
8import Control.Exception as CE
9import Control.Monad (when)
10import qualified Data.Text as T
11import qualified Data.Text.IO as TIO
13import Foreign.C
15import System.Directory (getTemporaryDirectory
16 , removeFile
17 , removeDirectoryRecursive
18 , createDirectoryIfMissing
19 )
20import System.FilePath ((</>), normalise)
21import System.IO
22import System.Info
23import System.IO.Error
25#ifdef FREESTANDING
26import Tools_idris
27import System.Environment (getEnv, setEnv, getExecutablePath)
28#endif
30catchIO :: IO a -> (IOError -> IO a) -> IO a
31catchIO = CE.catch
33throwIO :: IOError -> IO a
34throwIO = CE.throw
36isWindows :: Bool
37isWindows = os `elem` ["win32", "mingw32", "cygwin32"]
39-- | Create a temp file with the extensiom ext (in the format ".xxx")
40tempfile :: String -> IO (FilePath, Handle)
41tempfile ext = do dir <- getTemporaryDirectory
42 openTempFile (normalise dir) $ "idris" ++ ext
44-- | Read a source file, same as readFile but make sure the encoding is utf-8.
45readSource :: FilePath -> IO String
46readSource f = do h <- openFile f ReadMode
47 hSetEncoding h utf8
48 hGetContents h
50-- | Write a source file, same as writeFile except the encoding is set to utf-8
51writeSource :: FilePath -> String -> IO ()
52writeSource f s = withFile f WriteMode (\h -> hSetEncoding h utf8 >> hPutStr h s)
54-- | Write a utf-8 source file from Text
55writeSourceText :: FilePath -> T.Text -> IO ()
56writeSourceText f s = withFile f WriteMode (\h -> hSetEncoding h utf8 >> TIO.hPutStr h s)
58foreign import ccall "isatty" isATTYRaw :: CInt -> IO CInt
60isATTY :: IO Bool
61isATTY = do
62 tty <- isATTYRaw 1 -- fd stdout
63 return $ tty /= 0
65withTempdir :: String -> (FilePath -> IO a) -> IO a
66withTempdir subdir callback
67 = do dir <- getTemporaryDirectory
68 let tmpDir = normalise dir </> subdir
69 removeLater <- catchIO (createDirectoryIfMissing True tmpDir >> return True)
70 (\ ioError -> if isAlreadyExistsError ioError then return False
71 else throw ioError
72 )
73 result <- callback tmpDir
74 when removeLater $ removeDirectoryRecursive tmpDir
75 return result
77rmFile :: FilePath -> IO ()
78rmFile f = do
79 result <- try (removeFile f)
80 case result of
81 Right _ -> putStrLn $ "Removed: " ++ f
82 Left err -> handleExists err
83 where handleExists e
84 | isDoesNotExistError e = return ()
85 | otherwise = putStrLn $ "WARNING: Cannot remove file "
86 ++ f ++ ", Error msg:" ++ show e
88setupBundledCC :: IO()
89#ifdef FREESTANDING
90setupBundledCC = when hasBundledToolchain
91 $ do
92 exePath <- getExecutablePath
93 path <- getEnv "PATH"
94 tcDir <- return getToolchainDir
95 absolute <- return $ isAbsolute tcDir
96 target <- return $
97 if absolute
98 then tcDir
99 else dropFileName exePath ++ tcDir
100 let pathSep = if isWindows then ";" else ":"
101 present <- doesDirectoryExist target
102 when present
103 $ do newPath <- return $ target ++ pathSep ++ path
104 setEnv "PATH" newPath
105#else
106setupBundledCC = return ()
107#endif