imported fquery-0.2
[fquery.git] / Adelie / Depend.hs
blobeab3c349af7905426eaac77dae032303e47d003d
1 -- Depend.hs
2 --
3 -- Module for parsing DEPEND and RDEPEND files, located in
4 -- portageDB/cateogry/package/.
6 module Adelie.Depend (
7 Version,
8 Dependency(..),
10 dependFromCatName,
11 readDepend,
12 putDependency
13 ) where
15 import Char (isSpace)
16 import List (nub)
17 import Text.ParserCombinators.Parsec
18 import Text.ParserCombinators.Parsec.Language
19 import Text.ParserCombinators.Parsec.Token
21 import Adelie.Portage
23 type Version = String
25 data Dependency
26 = GreaterEqual String Version
27 | Equal String Version
28 | Unstable String Version
29 | NotInstalled String
30 | Any String
31 deriving (Eq, Show)
33 ----------------------------------------------------------------
35 dependFromCatName :: (String, String) -> String
36 dependFromCatName (cat, name) = concatPath [portageDB,cat,name,"RDEPEND"]
38 ----------------------------------------------------------------
40 readDepend :: FilePath -> [String] -> IO [Dependency]
41 readDepend fn iUse = do
42 r <- (start_parser fn) `catch` (\ _ -> return $ Right [])
43 case r of
44 Left err -> putStr "Parse error at " >> print err >> error "Aborting"
45 Right x -> return $ nub x
46 where start_parser = parseFromFile (dependParser iUse)
48 ----------------------------------------------------------------
50 putDependency :: Dependency -> IO ()
51 putDependency (GreaterEqual p v) = putStr $ ">=" ++ p ++ '-':v
52 putDependency (Equal p v) = putStr $ '=':p ++ '-':v
53 putDependency (Unstable p v) = putStr $ '~':p ++ '-':v
54 putDependency (NotInstalled p) = putStr $ '!':p
55 putDependency (Any p) = putStr p
57 ----------------------------------------------------------------
59 dependParser :: [String] -> Parser [Dependency]
60 dependParser iUse = do
61 skip <- spaces
62 packages <- many (dependParser' iUse)
63 return $ concat packages
65 dependParser' :: [String] -> Parser [Dependency]
66 dependParser' iUse = lexeme tp pp
67 where tp = makeTokenParser emptyDef
68 pp = parseOr iUse
69 <|> parsePackageOrUse iUse
71 parseOr :: [String] -> Parser [Dependency]
72 parseOr iUse = do { string "||"
73 ; spaces
74 ; parseBrackets iUse
77 parsePackageOrUse :: [String] -> Parser [Dependency]
78 parsePackageOrUse iUse =
79 do { p <- parsePackageOrUseWord
80 ; do { char '?' -- useFlag
81 ; spaces
82 ; r <- parseBrackets iUse
83 ; let filt | head p == '!' = not $ (tail p) `elem` iUse
84 | otherwise = p `elem` iUse
85 ; if filt
86 then return r
87 else return []
89 <|> return [toDependency p]
92 parsePackageOrUseWord :: Parser String
93 parsePackageOrUseWord = many1 (satisfy cond)
94 where
95 cond '?' = False
96 cond ')' = False
97 cond x = not $ isSpace x
99 parseBrackets :: [String] -> Parser [Dependency]
100 parseBrackets iUse = do { char '('
101 ; spaces
102 ; r <- manyTill (dependParser' iUse) (try (char ')'))
103 ; return $ concat r
106 ----------------------------------------------------------------
108 breakVersion :: String -> (String, String)
109 breakVersion str = (n, v)
110 where n = dropVersion str
111 v = drop (length n+1) str
113 toDependency :: String -> Dependency
115 toDependency ('>':'=':str) = (GreaterEqual n v)
116 where (n, v) = breakVersion str
118 toDependency ('=':str) = (Equal n v)
119 where (n, v) = breakVersion str
121 toDependency ('~':str) = (Unstable n v)
122 where (n, v) = breakVersion str
124 toDependency ('!':n) = (NotInstalled n)
126 toDependency n = (Any n)