1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
-----------------------------------------------------------------------------
-- |
-- 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
) where
import System.IO (hPutStrLn, stderr)
import System.Directory (doesFileExist)
import Data.List (intersperse)
import Control.Monad (when)
import Language.Preprocessor.Cpphs.Position (Posn,directory,cleanPath)
-- | 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 path warn =
try (cons dd (".":path))
where
dd = directory demand
cons x xs = if null x then xs else x:xs
try [] = do
when warn $
hPutStrLn stderr ("Warning: Can't find file \""++name
++"\" in directories\n\t"
++concat (intersperse "\n\t" (cons dd (".":path)))
++"\n Asked for by: "++show demand)
return ("missing file: "++name,"")
try (p:ps) = do
let file = cleanPath p++'/':cleanPath name
ok <- doesFileExist file
if not ok then try ps
else do content <- readFile file
return (file,content)
|