module Curry.Files.PathUtils(
takeBaseName,
dropExtension,
takeExtension,
lookupModule, lookupFile, lookupInterface,
getCurryPath,
writeModule,readModule,
doesModuleExist,maybeReadModule,getModuleModTime) where
import System.FilePath
import System.Directory
import System.Time (ClockTime)
import Control.Monad (unless)
import Curry.Base.Ident
import Curry.Files.Filenames
lookupModule :: [FilePath] -> [FilePath] -> ModuleIdent
-> IO (Maybe FilePath)
lookupModule paths libraryPaths m
= lookupFile ("" : paths ++ libraryPaths) moduleExts fn
where fn = foldr1 catPath (moduleQualifiers m)
catPath :: FilePath -> FilePath -> FilePath
catPath = combine
lookupInterface :: [FilePath] -> ModuleIdent -> IO (Maybe FilePath)
lookupInterface ps m = lookupFile ("":ps) [flatIntExt] ifn
where ifn = foldr1 catPath (moduleQualifiers m)
lookupFile :: [FilePath] -> [String] -> String -> IO (Maybe FilePath)
lookupFile paths exts file = lookupFile' paths'
where
paths' = do p <- paths
e <- exts
let fn = p `combine` replaceExtension file e
[fn, inCurrySubdir fn]
lookupFile' [] = return Nothing
lookupFile' (fn:ps)
= do so <- doesFileExist fn
if so then return (Just fn) else lookupFile' ps
inSubdir :: FilePath -> FilePath -> FilePath
inSubdir sub fn = joinPath $ add (splitDirectories fn)
where
add ps@[_] = sub:ps
add ps@[p,_] | p==sub = ps
add (p:ps) = p:add ps
add [] = error "inSubdir: called with empty path"
currySubdir :: String
currySubdir = ".curry"
inCurrySubdir :: FilePath -> FilePath
inCurrySubdir = inSubdir currySubdir
writeModule :: FilePath -> String -> IO ()
writeModule filename contents = do
let filename' = inCurrySubdir filename
subdir = takeDirectory filename'
ensureDirectoryExists subdir
writeFile filename' contents
ensureDirectoryExists :: FilePath -> IO ()
ensureDirectoryExists dir
= do ex <- doesDirectoryExist dir
unless ex (createDirectory dir)
onExistingFileDo :: (FilePath -> IO a) -> FilePath -> IO a
onExistingFileDo act filename = do
ex <- doesFileExist filename
if ex then act filename
else act $ inCurrySubdir filename
readModule :: FilePath -> IO String
readModule = onExistingFileDo readFile
maybeReadModule :: FilePath -> IO (Maybe String)
maybeReadModule filename =
catch (readModule filename >>= return . Just) (\_ -> return Nothing)
doesModuleExist :: FilePath -> IO Bool
doesModuleExist = onExistingFileDo doesFileExist
getModuleModTime :: FilePath -> IO ClockTime
getModuleModTime = onExistingFileDo getModificationTime
getCurryPath :: [FilePath] -> FilePath -> IO (Maybe FilePath)
getCurryPath paths fn = lookupFile filepaths exts fn
where
filepaths = "":paths'
fnext = takeExtension fn
exts | null fnext = sourceExts
| otherwise = [fnext]
paths' | pathSeparator `elem` fn = []
| otherwise = paths