cpphs-1.20.4: Language/Preprocessor/Cpphs/ReadFirst.hs
-----------------------------------------------------------------------------
-- |
-- Module : ReadFirst
-- Copyright : 2004 Malcolm Wallace
-- Licence : LGPL
--
-- Maintainer : Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk>
-- Stability : experimental
-- Portability : All
--
-- Read the first file that matches in a list of search paths.
-----------------------------------------------------------------------------
module Language.Preprocessor.Cpphs.ReadFirst
( readFirst
, readFileUTF8
, writeFileUTF8
) where
import System.IO
import System.Directory (doesFileExist,findFile)
import System.FilePath (isRelative)
import Data.List (intersperse)
import Control.Exception as E
import Control.Monad (when)
import Language.Preprocessor.Cpphs.Position (Posn,directory)
-- | Attempt to read the given file from any location within the search path.
-- The first location found is returned, together with the file content.
-- (The directory of the calling file is always searched first, then
-- the current directory, finally any specified search path.)
readFirst :: String -- ^ filename
-> Posn -- ^ inclusion point
-> [String] -- ^ search path
-> Bool -- ^ report warnings?
-> IO ( FilePath
, String
) -- ^ discovered filepath, and file contents
readFirst name demand paths warn = do
case (isRelative name, directory demand) of
(False, _) -> try name []
(_, "") -> try name (".":paths)
(_, dd) -> try name (dd:".":paths)
where
try name ds = do
file <- findFile ds name
case file of
Just f -> do
content <- readFileUTF8 f
return (f,content)
Nothing -> do
hPutStrLn stderr ("Warning: Can't find file \""++name
++"\" in directories\n\t"
++concat (intersperse "\n\t" ds)
++"\n Asked for by: "++show demand)
return ("missing file: "++name,"")
readFileUTF8 :: FilePath -> IO String
readFileUTF8 file = do
h <- openFile file ReadMode
(do utf8r <- mkTextEncoding "UTF-8//ROUNDTRIP"
hSetEncoding h utf8r
hGetContents h) `E.onException` (hClose h)
writeFileUTF8 :: FilePath -> String -> IO ()
writeFileUTF8 f txt = withFile f WriteMode $ \hdl->
do utf8r <- mkTextEncoding "UTF-8//ROUNDTRIP"
hSetEncoding hdl utf8r
hPutStr hdl txt
`E.onException` (hClose hdl)