Add unique package identifiers (InstalledPackageId) in the package DB
[ghc-hetmet.git] / compiler / main / ParsePkgConf.y
1 {
2 {-# OPTIONS -fno-warn-unused-binds -fno-warn-unused-matches -fno-warn-missing-signatures -fno-warn-incomplete-patterns -Wwarn #-}
3 -- The above warning supression flag is a temporary kludge.
4 -- While working on this module you are encouraged to remove it and fix
5 -- any warnings in the module. See
6 --     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
7 -- for details
8
9 module ParsePkgConf( loadPackageConfig ) where
10
11 #include "HsVersions.h"
12
13 import Distribution.Package hiding ( depends )
14 import PackageConfig
15 import Lexer
16 import Module
17 import DynFlags
18 import FastString
19 import StringBuffer
20 import ErrUtils  ( mkLocMessage )
21 import SrcLoc
22 import Outputable
23 import Panic
24
25 }
26
27 %expect 0
28
29 %token
30  '{'            { L _ ITocurly }
31  '}'            { L _ ITccurly }
32  '['            { L _ ITobrack }
33  ']'            { L _ ITcbrack }
34  ','            { L _ ITcomma }
35  '='            { L _ ITequal }
36  VARID          { L _ (ITvarid    $$) }
37  CONID          { L _ (ITconid    $$) }
38  STRING         { L _ (ITstring   $$) }
39  INT            { L _ (ITinteger  $$) }
40
41 %monad { P } { >>= } { return }
42 %lexer { lexer } { L _ ITeof }
43 %name parse
44 %tokentype { Located Token }
45 %%
46
47 pkgconf :: { [ PackageConfig ] }
48         : '[' ']'                       { [] }
49         | '[' pkgs ']'                  { reverse $2 }
50
51 pkgs    :: { [ PackageConfig ] }
52         : pkg                           { [ $1 ] }
53         | pkgs ',' pkg                  { $3 : $1 }
54
55 pkg     :: { PackageConfig }
56         : CONID '{' fields '}'          { $3 defaultPackageConfig }
57
58 fields  :: { PackageConfig -> PackageConfig }
59         : field                         { \p -> $1 p }
60         | fields ',' field              { \p -> $1 ($3 p) }
61
62 field   :: { PackageConfig -> PackageConfig }
63         : VARID '=' pkgid
64                 {% case unpackFS $1 of
65                         "package"     -> return (\p -> p{package = $3})
66                         _             -> happyError
67                 }
68
69         | VARID '=' STRING              { id }
70                 -- we aren't interested in the string fields, they're all
71                 -- boring (copyright, maintainer etc.)
72                         
73         | VARID '=' CONID
74                 {% case unpackFS $1 of {
75                         "exposed" -> 
76                            case unpackFS $3 of {
77                                 "True"  -> return (\p -> p{exposed=True});
78                                 "False" -> return (\p -> p{exposed=False});
79                                 _       -> happyError };
80                         "license" -> return id; -- not interested
81                         _         -> happyError }
82                 }
83
84         | VARID '=' CONID STRING
85                 { \p -> case unpackFS $1 of
86                           "installedPackageId" ->
87                               p{installedPackageId = InstalledPackageId (unpackFS $4)}
88                           _ -> p -- another case of license
89                 }
90
91         | VARID '=' strlist             
92         {\p -> case unpackFS $1 of
93                 "exposedModules"    -> p{exposedModules    = map mkModuleNameFS $3}
94                 "hiddenModules"     -> p{hiddenModules     = map mkModuleNameFS $3}
95                 "importDirs"        -> p{importDirs        = map unpackFS $3}
96                 "libraryDirs"       -> p{libraryDirs       = map unpackFS $3}
97                 "hsLibraries"       -> p{hsLibraries       = map unpackFS $3}
98                 "extraLibraries"    -> p{extraLibraries    = map unpackFS $3}
99                 "extraGHCiLibraries"-> p{extraGHCiLibraries= map unpackFS $3}
100                 "includeDirs"       -> p{includeDirs       = map unpackFS $3}
101                 "includes"          -> p{includes          = map unpackFS $3}
102                 "hugsOptions"       -> p{hugsOptions       = map unpackFS $3}
103                 "ccOptions"         -> p{ccOptions         = map unpackFS $3}
104                 "ldOptions"         -> p{ldOptions         = map unpackFS $3}
105                 "frameworkDirs"     -> p{frameworkDirs     = map unpackFS $3}
106                 "frameworks"        -> p{frameworks        = map unpackFS $3}
107                 "haddockInterfaces" -> p{haddockInterfaces = map unpackFS $3}
108                 "haddockHTMLs"      -> p{haddockHTMLs      = map unpackFS $3}
109                 "depends"           -> p{depends = []}
110                         -- empty list only, non-empty handled below
111                 _ -> p
112         }
113
114         | VARID '=' ipidlist
115                 {% case unpackFS $1 of
116                         "depends"     -> return (\p -> p{depends = $3})
117                         _             -> happyError
118                 }
119
120 pkgid   :: { PackageIdentifier }
121         : CONID '{' VARID '=' CONID STRING ',' VARID '=' version '}'
122             {% case unpackFS $5 of
123                "PackageName" ->
124                    return $ PackageIdentifier {
125                                 pkgName = PackageName (unpackFS $6),
126                                 pkgVersion = $10
127                             }
128                _ -> happyError
129             }
130
131 version :: { Version }
132         : CONID '{' VARID '=' intlist ',' VARID '=' strlist '}'
133                         { Version{ versionBranch=$5, 
134                                    versionTags=map unpackFS $9 } }
135
136 ipid    :: { InstalledPackageId }
137         : CONID STRING
138             {% case unpackFS $1 of
139                "InstalledPackageId" -> return (InstalledPackageId (unpackFS $2))
140                _ -> happyError
141             }
142
143 ipidlist :: { [InstalledPackageId] }
144         : '[' ipids ']'         { $2 }
145         -- empty list case is covered by strlist, to avoid conflicts
146
147 ipids   :: { [InstalledPackageId] }
148         : ipid                          { [ $1 ] }
149         | ipid ',' ipids                { $1 : $3 }
150
151 intlist :: { [Int] }
152         : '[' ']'                       { [] }
153         | '[' ints ']'                  { $2 }
154
155 ints    :: { [Int] }
156         : INT                           { [ fromIntegral $1 ] }
157         | INT ',' ints                  { fromIntegral $1 : $3 }
158
159 strlist :: { [FastString] }
160         : '[' ']'                       { [] }
161         | '[' strs ']'                  { $2 }
162
163 strs    :: { [FastString] }
164         : STRING                        { [ $1 ] }
165         | STRING ',' strs               { $1 : $3 }
166
167 {
168 happyError :: P a
169 happyError = srcParseFail
170
171 loadPackageConfig :: DynFlags -> FilePath -> IO [PackageConfig]
172 loadPackageConfig dflags conf_filename = do
173    buf <- hGetStringBuffer conf_filename
174    let loc  = mkSrcLoc (mkFastString conf_filename) 1 0
175    case unP parse (mkPState buf loc dflags) of
176         PFailed span err -> 
177            ghcError (InstallationError (showSDoc (mkLocMessage span err)))
178
179         POk _ pkg_details -> do
180             return pkg_details
181 }