module Distribution.MacOSX.DG (
DG(..),
FDeps(..),
dgEmpty,
dgFDeps,
dgAddPaths,
dgAddFDeps
) where
import Data.Graph.Inductive.Graph as G
import Data.Graph.Inductive.Tree (Gr)
import Data.List
import Data.Maybe
data DG = DG (Gr FilePath ())
deriving Show
data FDeps = FDeps FilePath [FilePath]
deriving (Eq, Ord, Show)
dgAddFDeps :: DG -> FDeps -> DG
dgAddFDeps dg (FDeps src tgts) = dgAddDeps src tgts $ dg `dgAddPaths` (src:tgts)
dgFDeps :: DG -> [FDeps]
dgFDeps (DG g) = map mkFDep (G.labNodes g)
where mkFDep :: G.LNode FilePath -> FDeps
mkFDep (i, src) = FDeps src $ mapMaybe (G.lab g) (G.suc g i)
dgEmpty :: DG
dgEmpty = DG G.empty
dgPathIdx :: DG -> FilePath -> Maybe Int
dgPathIdx (DG g) p = case find (\x -> p == snd x) (G.labNodes g) of
Just (i, _) -> Just i
Nothing -> Nothing
dgHasPath :: DG -> FilePath -> Bool
dgHasPath dg p = case dgPathIdx dg p of
Just _ -> True
Nothing -> False
dgAddPaths :: DG -> [FilePath] -> DG
dgAddPaths = foldl dgAddPath
dgAddPath :: DG -> FilePath -> DG
dgAddPath dg@(DG g) p = if dg `dgHasPath` p then dg
else DG $ G.insNode (head $ G.newNodes 1 g, p) g
dgAddDeps :: FilePath -> [FilePath] -> DG -> DG
dgAddDeps src tgts dg = foldl dgAddDep dg $ zip (repeat src) tgts
dgAddDep :: DG -> (FilePath, FilePath) -> DG
dgAddDep dg@(DG g) (src, tgt) = DG $ G.insEdge (getI src, getI tgt, ()) g
where getI x = case dgPathIdx dg x of
Just x' -> x'
Nothing -> error "Can't happen"