e1ed07acd8700bfdbb959ca7ec9822b5bfe27797
[people/mcb30/basetools.git] / Source / Python / Common / InfClassObject.py
1 # Copyright (c) 2007, Intel Corporation\r
2 # All rights reserved. This program and the accompanying materials\r
3 # are licensed and made available under the terms and conditions of the BSD License\r
4 # which accompanies this distribution.    The full text of the license may be found at\r
5 # http://opensource.org/licenses/bsd-license.php\r
6 #\r
7 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
8 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
9 \r
10 #\r
11 #This file is used to define each component of INF file\r
12 #\r
13 \r
14 import os\r
15 import EdkLogger\r
16 from CommonDataClass.CommonClass import LibraryClassClass\r
17 from CommonDataClass.ModuleClass import *\r
18 from String import *\r
19 from DataType import *\r
20 from Identification import *\r
21 from Dictionary import *\r
22 from BuildToolError import *\r
23 \r
24 class InfObject(object):\r
25     def __init__(self):\r
26         object.__init__()\r
27 \r
28 class InfDefines(InfObject):\r
29     def __init__(self):\r
30         self.DefinesDictionary = {\r
31             #Required\r
32             TAB_INF_DEFINES_BASE_NAME                               : [''],\r
33             TAB_INF_DEFINES_FILE_GUID                               : [''],\r
34             TAB_INF_DEFINES_MODULE_TYPE                             : [''],\r
35             TAB_INF_DEFINES_EFI_SPECIFICATION_VERSION               : [''],\r
36             TAB_INF_DEFINES_EDK_RELEASE_VERSION                     : [''],\r
37             \r
38             #Optional            \r
39             TAB_INF_DEFINES_INF_VERSION                             : [''],\r
40             TAB_INF_DEFINES_BINARY_MODULE                           : [''],\r
41             TAB_INF_DEFINES_LIBRARY_CLASS                           : [''],\r
42             TAB_INF_DEFINES_COMPONENT_TYPE                          : [''],\r
43             TAB_INF_DEFINES_MAKEFILE_NAME                           : [''],\r
44             TAB_INF_DEFINES_BUILD_NUMBER                            : [''],\r
45             TAB_INF_DEFINES_BUILD_TYPE                              : [''],\r
46             TAB_INF_DEFINES_FFS_EXT                                 : [''],\r
47             TAB_INF_DEFINES_FV_EXT                                  : [''],\r
48             TAB_INF_DEFINES_SOURCE_FV                               : [''],\r
49             TAB_INF_DEFINES_VERSION_NUMBER                          : [''],\r
50             TAB_INF_DEFINES_VERSION_STRING                          : [''],\r
51             TAB_INF_DEFINES_PCD_IS_DRIVER                           : [''],\r
52             TAB_INF_DEFINES_TIANO_R8_FLASHMAP_H                     : [''],\r
53             TAB_INF_DEFINES_ENTRY_POINT                             : [''],\r
54             TAB_INF_DEFINES_UNLOAD_IMAGE                            : [''],\r
55             TAB_INF_DEFINES_CONSTRUCTOR                             : [''],\r
56             TAB_INF_DEFINES_DESTRUCTOR                              : [''],\r
57             TAB_INF_DEFINES_DEFINE                                  : [''],\r
58             TAB_INF_DEFINES_SPEC                                    : [''],\r
59             TAB_INF_DEFINES_CUSTOM_MAKEFILE                         : ['']\r
60         }\r
61 \r
62 class InfContents(InfObject):\r
63     def __init__(self):\r
64         self.Sources = []\r
65         self.BuildOptions = []\r
66         self.Binaries = []\r
67         self.Includes = []\r
68         self.Guids = []\r
69         self.Protocols = []\r
70         self.Ppis = []\r
71         self.Libraries = []\r
72         self.LibraryClasses = []\r
73         self.Packages = []\r
74         self.PcdsFixedAtBuild = []\r
75         self.PcdsPatchableInModule = []\r
76         self.PcdsFeatureFlag = []\r
77         self.PcdsDynamic = []\r
78         self.PcdsDynamicEx = []\r
79         self.Depex = []\r
80         self.Nmake = []\r
81         \r
82 class Inf(InfObject):\r
83     def __init__(self, filename = None, isMergeAllArches = False, isToModule = False):\r
84         self.Identification = Identification()\r
85         self.Defines = InfDefines()\r
86         self.Contents = {}\r
87         self.UserExtensions = ''\r
88         self.Module = ModuleClass()\r
89         \r
90         for key in DataType.ARCH_LIST_FULL:\r
91             self.Contents[key] = InfContents()\r
92 \r
93         self.KeyList = [\r
94             TAB_SOURCES, TAB_BUILD_OPTIONS, TAB_BINARIES, TAB_INCLUDES, TAB_GUIDS, TAB_PROTOCOLS, TAB_PPIS, TAB_LIBRARY_CLASSES, TAB_PACKAGES, TAB_LIBRARIES, \\r
95             TAB_PCDS_FIXED_AT_BUILD_NULL, TAB_PCDS_PATCHABLE_IN_MODULE_NULL, TAB_PCDS_FEATURE_FLAG_NULL, \\r
96             TAB_PCDS_DYNAMIC_NULL, TAB_PCDS_DYNAMIC_EX_NULL, TAB_DEPEX, TAB_NMAKE\r
97         ]\r
98                 \r
99         if filename != None:\r
100             self.LoadInfFile(filename)\r
101         \r
102         if isMergeAllArches:\r
103             self.MergeAllArches()\r
104         \r
105         if isToModule:\r
106             self.InfToModule()\r
107     \r
108     def MergeAllArches(self):\r
109         for key in self.KeyList:\r
110             for arch in DataType.ARCH_LIST:\r
111                 Command = "self.Contents[arch]." + key + ".extend(" + "self.Contents['" + DataType.TAB_ARCH_COMMON + "']." + key + ")"\r
112                 eval(Command)     \r
113             \r
114     def ParseInf(self, Lines, Key, KeyField):\r
115         newKey = SplitModuleType(Key)\r
116         if newKey[0].find(DataType.TAB_LIBRARY_CLASSES.upper()) != -1:\r
117             GetLibraryClassesWithModuleType(Lines, Key, KeyField, TAB_COMMENT_SPLIT)\r
118         else:\r
119             GetMultipleValuesOfKeyFromLines(Lines, Key, KeyField, TAB_COMMENT_SPLIT)\r
120 \r
121     def InfToModule(self):\r
122         #\r
123         # Get value for Header\r
124         #\r
125         self.Module.Header.Name = self.Defines.DefinesDictionary[TAB_INF_DEFINES_BASE_NAME][0]\r
126         self.Module.Header.Guid = self.Defines.DefinesDictionary[TAB_INF_DEFINES_FILE_GUID][0]\r
127         self.Module.Header.Version = self.Defines.DefinesDictionary[TAB_INF_DEFINES_VERSION_NUMBER][0]\r
128         self.Module.Header.FileName = self.Identification.FileName\r
129         self.Module.Header.FullPath = self.Identification.FileFullPath\r
130         \r
131         self.Module.Header.EfiSpecificationVersion = self.Defines.DefinesDictionary[TAB_INF_DEFINES_EFI_SPECIFICATION_VERSION][0]\r
132         self.Module.Header.EdkReleaseVersion = self.Defines.DefinesDictionary[TAB_INF_DEFINES_EDK_RELEASE_VERSION][0]\r
133         self.Module.Header.InfVersion = self.Defines.DefinesDictionary[TAB_INF_DEFINES_INF_VERSION][0]\r
134                 \r
135         self.Module.Header.ModuleType = self.Defines.DefinesDictionary[TAB_INF_DEFINES_MODULE_TYPE][0]\r
136         self.Module.Header.BinaryModule = self.Defines.DefinesDictionary[TAB_INF_DEFINES_BINARY_MODULE][0]\r
137         self.Module.Header.ComponentType = self.Defines.DefinesDictionary[TAB_INF_DEFINES_COMPONENT_TYPE][0]\r
138         self.Module.Header.MakefileName = self.Defines.DefinesDictionary[TAB_INF_DEFINES_MAKEFILE_NAME][0]\r
139         self.Module.Header.BuildNumber = self.Defines.DefinesDictionary[TAB_INF_DEFINES_BUILD_NUMBER][0]\r
140         self.Module.Header.BuildType = self.Defines.DefinesDictionary[TAB_INF_DEFINES_BUILD_TYPE][0]\r
141         self.Module.Header.FfsExt = self.Defines.DefinesDictionary[TAB_INF_DEFINES_FFS_EXT][0]\r
142         self.Module.Header.FvExt = self.Defines.DefinesDictionary[TAB_INF_DEFINES_FV_EXT][0]\r
143         self.Module.Header.SourceFv = self.Defines.DefinesDictionary[TAB_INF_DEFINES_SOURCE_FV][0]\r
144         self.Module.Header.PcdIsDriver = self.Defines.DefinesDictionary[TAB_INF_DEFINES_PCD_IS_DRIVER][0]\r
145         self.Module.Header.TianoR8FlashMap_h = self.Defines.DefinesDictionary[TAB_INF_DEFINES_TIANO_R8_FLASHMAP_H][0]\r
146         \r
147         #LibraryClass of Define\r
148         if self.Defines.DefinesDictionary[TAB_INF_DEFINES_LIBRARY_CLASS][0] != '':\r
149             for Item in self.Defines.DefinesDictionary[TAB_INF_DEFINES_LIBRARY_CLASS]:\r
150                 List = GetSplitValueList(Item, DataType.TAB_VALUE_SPLIT, 1)\r
151                 Lib = LibraryClassClass()\r
152                 Lib.LibraryClass = CleanString(List[0])\r
153                 if len(List) == 1:\r
154                     Lib.SupModuleList = DataType.SUP_MODULE_LIST\r
155                 elif len(List) == 2:\r
156                     Lib.SupModuleList = GetSplitValueList(CleanString(List[1]), ' ')\r
157                 self.Module.Header.LibraryClass.append(Lib)\r
158         \r
159         #Custom makefile\r
160         if self.Defines.DefinesDictionary[TAB_INF_DEFINES_CUSTOM_MAKEFILE][0] != '':\r
161             for Item in self.Defines.DefinesDictionary[TAB_INF_DEFINES_CUSTOM_MAKEFILE]:\r
162                 List = Item.split(DataType.TAB_VALUE_SPLIT)\r
163                 if len(List) == 2:\r
164                     self.Module.Header.CustomMakefile[CleanString(List[0])] = CleanString(List[1])\r
165                 else:\r
166                     ErrorMsg = "Wrong CUSTOM_MAKEFILE statement '%s' found in section Defines in file '%s', correct format is 'CUSTOM_MAKEFILE = Family|Filename'" % (Item, self.Module.Header.FullPath) \r
167                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
168         \r
169         #EntryPoint and UnloadImage\r
170         if self.Defines.DefinesDictionary[TAB_INF_DEFINES_ENTRY_POINT][0] != '':\r
171             for Item in self.Defines.DefinesDictionary[TAB_INF_DEFINES_ENTRY_POINT]:\r
172                 Image = ModuleExternImageClass()\r
173                 Image.ModuleEntryPoint = CleanString(Item)\r
174                 self.Module.ExternImages.append(Image)\r
175         if self.Defines.DefinesDictionary[TAB_INF_DEFINES_UNLOAD_IMAGE][0] != '':\r
176             for Item in self.Defines.DefinesDictionary[TAB_INF_DEFINES_UNLOAD_IMAGE]:\r
177                 Image = ModuleExternImageClass()\r
178                 Image.ModuleUnloadImage = CleanString(Item)\r
179                 self.Module.ExternImages.append(Image)\r
180         \r
181         #Constructor and Destructor\r
182         if self.Defines.DefinesDictionary[TAB_INF_DEFINES_CONSTRUCTOR][0] != '':\r
183             for Item in self.Defines.DefinesDictionary[TAB_INF_DEFINES_CONSTRUCTOR]:\r
184                 LibraryClass = ModuleExternLibraryClass()\r
185                 LibraryClass.Constructor = CleanString(Item)\r
186                 self.Module.ExternLibraries.append(LibraryClass)\r
187         if self.Defines.DefinesDictionary[TAB_INF_DEFINES_DESTRUCTOR][0] != '':\r
188             for Item in self.Defines.DefinesDictionary[TAB_INF_DEFINES_DESTRUCTOR]:\r
189                 LibraryClass = ModuleExternLibraryClass()\r
190                 LibraryClass.Destructor = CleanString(Item)\r
191                 self.Module.ExternLibraries.append(LibraryClass)\r
192         \r
193         #Define\r
194         if self.Defines.DefinesDictionary[TAB_INF_DEFINES_DEFINE][0] != '':\r
195             for Item in self.Defines.DefinesDictionary[TAB_INF_DEFINES_DEFINE]:\r
196                 List = Item.split(DataType.TAB_EQUAL_SPLIT)\r
197                 if len(List) != 2:\r
198                     ErrorMsg = "Wrong DEFINE statement '%s' found in section Defines in file '%s', correct format is 'DEFINE <Word> = <Word>'" % (Item, self.Module.Header.FullPath) \r
199                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
200                 else:\r
201                     self.Module.Header.Define[CleanString(List[0])] = CleanString(List[1])\r
202         \r
203         #Spec\r
204         if self.Defines.DefinesDictionary[TAB_INF_DEFINES_SPEC][0] != '':\r
205             for Item in self.Defines.DefinesDictionary[TAB_INF_DEFINES_SPEC]:\r
206                 List = Item.split(DataType.TAB_EQUAL_SPLIT)\r
207                 if len(List) != 2:\r
208                     ErrorMsg = "Wrong SPEC statement '%s' found in section Defines in file '%s', correct format is 'SPEC <Word> = <Version>'" % (Item, self.Module.Header.FullPath) \r
209                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
210                 else:\r
211                     self.Module.Header.Specification[CleanString(List[0])] = CleanString(List[1])\r
212                 \r
213         #BuildOptions\r
214         BuildOptions = {}\r
215         for Arch in DataType.ARCH_LIST:\r
216             for Item in self.Contents[Arch].BuildOptions:\r
217                 MergeArches(BuildOptions, GetBuildOption(Item), Arch)\r
218         for Key in BuildOptions.keys():\r
219             BuildOption = BuildOptionClass(Key[0], Key[1], Key[2])\r
220             BuildOption.SupArchList = BuildOptions[Key]\r
221             self.Module.BuildOptions.append(BuildOption)    \r
222         \r
223         #Includes\r
224         Includes = {}\r
225         for Arch in DataType.ARCH_LIST:\r
226             for Item in self.Contents[Arch].Includes:\r
227                 MergeArches(Includes, Item, Arch)\r
228         for Key in Includes.keys():\r
229             Include = IncludeClass()\r
230             Include.FilePath = Key\r
231             Include.SupArchList = Includes[Key]\r
232             self.Module.Includes.append(Include)\r
233         \r
234         #Libraries\r
235         Libraries = {}\r
236         for Arch in DataType.ARCH_LIST:\r
237             for Item in self.Contents[Arch].Libraries:\r
238                 MergeArches(Libraries, Item, Arch)\r
239         for Key in Libraries.keys():\r
240             Library = ModuleLibraryClass()\r
241             Library.Library = Key\r
242             Library.SupArchList = Libraries[Key]\r
243             self.Module.Libraries.append(Library)\r
244         \r
245         #LibraryClasses\r
246         LibraryClasses = {}\r
247         Defines = {}\r
248         for Arch in DataType.ARCH_LIST:\r
249             for Item in self.Contents[Arch].LibraryClasses:\r
250                 Status = GenDefines(Item[0], Arch, Defines)\r
251                 if Status == 0:       # Find DEFINE statement\r
252                     pass\r
253                 elif Status == -1:    # Find DEFINE statement but in wrong format\r
254                     ErrorMsg = "Wrong DEFINE statement '%s' found in section LibraryClasses in file '%s', correct format is 'DEFINE <VarName> = <PATH>'" % (Item[0], self.Module.Header.FullPath) \r
255                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
256                 elif Status == 1:     # Not find DEFINE statement\r
257                     #{ (LibraryClass, Instance, PcdFeatureFlag, ModuleType1|ModuleType2|ModuleType3) : [Arch1, Arch2, ...] }\r
258                     ItemList = GetSplitValueList((Item[0] + DataType.TAB_VALUE_SPLIT * 2))\r
259                     MergeArches(LibraryClasses, (ItemList[0], ItemList[1], ItemList[2], DataType.TAB_VALUE_SPLIT.join(Item[1])), Arch)\r
260         for Key in LibraryClasses.keys():\r
261             KeyList = Key[0].split(DataType.TAB_VALUE_SPLIT)\r
262             LibraryClass = LibraryClassClass()\r
263             LibraryClass.Define = Defines\r
264             LibraryClass.LibraryClass = Key[0]\r
265             LibraryClass.RecommendedInstance = Key[1]\r
266             LibraryClass.FeatureFlag = Key[2]\r
267             LibraryClass.SupArchList = LibraryClasses[Key]\r
268             if Key[3] != ['']:\r
269                 LibraryClass.SupModuleList = GetSplitValueList(Key[3])\r
270             self.Module.LibraryClasses.append(LibraryClass)\r
271         \r
272         #Packages\r
273         Packages = {}\r
274         Defines = {}\r
275         for Arch in DataType.ARCH_LIST:\r
276             for Item in self.Contents[Arch].Packages:\r
277                 Status = GenDefines(Item, Arch, Defines)\r
278                 if Status == 0:       # Find DEFINE statement\r
279                     pass\r
280                 elif Status == -1:    # Find DEFINE statement but in wrong format\r
281                     ErrorMsg = "Wrong DEFINE statement '%s' found in section Packages in file '%s', correct format is 'DEFINE <VarName> = <PATH>'" % (Item, self.Module.Header.FullPath) \r
282                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
283                 elif Status == 1:     # Not find DEFINE statement\r
284                     MergeArches(Packages, Item, Arch)\r
285         for Key in Packages.keys():\r
286             Package = ModulePackageDependencyClass()\r
287             Package.Define = Defines\r
288             Package.FilePath = Key\r
289             Package.SupArchList = Packages[Key]\r
290             self.Module.PackageDependencies.append(Package)\r
291             \r
292         #Nmake\r
293         Nmakes = {}\r
294         for Arch in DataType.ARCH_LIST:\r
295             for Item in self.Contents[Arch].Nmake:\r
296                 MergeArches(Nmakes, Item, Arch)\r
297         for Key in Nmakes.keys():\r
298             List = GetSplitValueList(Key, DataType.TAB_EQUAL_SPLIT)\r
299             if len(List) != 2:\r
300                 ErrorMsg = "Wrong statement '%s' found in section Nmake in file '%s', correct format is '<Word>=<Word>'" % (Item, self.Module.Header.FullPath) \r
301                 raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
302             Nmake = ModuleNmakeClass()\r
303             Nmake.Name = List[0]\r
304             Nmake.Value = List[1]\r
305             Nmake.SupArchList = Nmakes[Key]\r
306             self.Module.Nmake.append(Nmake)\r
307         \r
308         #Pcds\r
309         Pcds = {}\r
310         for Arch in DataType.ARCH_LIST:\r
311             for Item in self.Contents[Arch].PcdsFixedAtBuild:\r
312                 Item = Item + DataType.TAB_VALUE_SPLIT\r
313                 List = GetSplitValueList(Item)\r
314                 if len(List) <= 2:\r
315                     ErrorMsg = "Wrong statement '%s' found in section PcdsFixedAtBuild in file '%s', correct format is '<TokenName>|<TSGuidName>[|<Value>]'" % (Item[0:-1], self.Module.Header.FullPath) \r
316                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
317                 MergeArches(Pcds, (List[0], List[1], List[2], TAB_PCDS_FIXED_AT_BUILD), Arch)\r
318             for Item in self.Contents[Arch].PcdsPatchableInModule:\r
319                 Item = Item + DataType.TAB_VALUE_SPLIT\r
320                 List = GetSplitValueList(Item)\r
321                 if len(List) <= 2:\r
322                     ErrorMsg = "Wrong statement '%s' found in section PcdsPatchableInModule in file '%s', correct format is '<TokenName>|<TSGuidName>[|<Value>]'" % (Item[0:-1], self.Module.Header.FullPath) \r
323                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
324                 MergeArches(Pcds, (List[0], List[1], List[2], TAB_PCDS_PATCHABLE_IN_MODULE), Arch)\r
325             for Item in self.Contents[Arch].PcdsFeatureFlag:\r
326                 Item = Item + DataType.TAB_VALUE_SPLIT\r
327                 List = GetSplitValueList(Item)\r
328                 if len(List) <= 2:\r
329                     ErrorMsg = "Wrong statement '%s' found in section PcdsFeatureFlag in file '%s', correct format is '<TokenName>|<TSGuidName>[|<Value>]'" % (Item[0:-1], self.Module.Header.FullPath) \r
330                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
331                 MergeArches(Pcds, (List[0], List[1], List[2], TAB_PCDS_FEATURE_FLAG), Arch)\r
332             for Item in self.Contents[Arch].PcdsDynamicEx:\r
333                 Item = Item + DataType.TAB_VALUE_SPLIT\r
334                 List = GetSplitValueList(Item)\r
335                 if len(List) <= 2:\r
336                     ErrorMsg = "Wrong statement '%s' found in section PcdsDynamicEx in file '%s', correct format is '<TokenName>|<TSGuidName>[|<Value>]'" % (Item[0:-1], self.Module.Header.FullPath) \r
337                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
338                 MergeArches(Pcds, (List[0], List[1], List[2], TAB_PCDS_DYNAMIC_EX), Arch)\r
339             for Item in self.Contents[Arch].PcdsDynamic:\r
340                 Item = Item + DataType.TAB_VALUE_SPLIT\r
341                 List = GetSplitValueList(Item)\r
342                 if len(List) <= 2:\r
343                     ErrorMsg = "Wrong statement '%s' found in section PcdsDynamic in file '%s', correct format is '<TokenName>|<TSGuidName>[|<Value>]'" % (Item[0:-1], self.Module.Header.FullPath) \r
344                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
345                 MergeArches(Pcds, (List[0], List[1], List[2], TAB_PCDS_DYNAMIC), Arch)\r
346         for Key in Pcds.keys():\r
347             Pcd = PcdClass()\r
348             Pcd.CName = Key[0]\r
349             Pcd.TokenSpaceGuidCName = Key[1]\r
350             Pcd.DefaultValue = Key[2]\r
351             Pcd.ItemType = Key[3]\r
352             Pcd.SupArchList = Pcds[Key]\r
353             self.Module.PcdCodes.append(Pcd)\r
354         \r
355         #Sources\r
356         Sources = {}\r
357         for Arch in DataType.ARCH_LIST:\r
358             for Item in self.Contents[Arch].Sources:\r
359                 Item = Item + DataType.TAB_VALUE_SPLIT * 4\r
360                 List = GetSplitValueList(Item)\r
361                 MergeArches(Sources, (List[0], List[1], List[2], List[3], List[4]), Arch)\r
362         for Key in Sources.keys():\r
363             Source = ModuleSourceFileClass(Key[0], Key[3], Key[4], Key[1], Key[2], Sources[Key])\r
364             self.Module.Sources.append(Source)\r
365         \r
366         #UserExtensions\r
367         if self.UserExtensions != '':\r
368             UserExtension = UserExtensionsClass()\r
369             Lines = self.UserExtensions.splitlines()\r
370             List = GetSplitValueList(Lines[0], DataType.TAB_SPLIT, 2)\r
371             if len(List) != 3:\r
372                 ErrorMsg = "Wrong statement '%s' found in section UserExtensions in file '%s', correct format is 'UserExtensions.UserId.'Identifier''" % (Item[0:-1], self.Module.Header.FullPath) \r
373                 raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
374             else:\r
375                 UserExtension.UserID = List[1]\r
376                 UserExtension.Identifier = List[2][0:-1].replace("'", '').replace('\"', '')\r
377                 for Line in Lines[1:]:\r
378                     UserExtension.Content = UserExtension.Content + CleanString(Line) + '\n'\r
379             self.Module.UserExtensions.append(UserExtension)\r
380         \r
381         #Guids\r
382         Guids = {}\r
383         for Arch in DataType.ARCH_LIST:\r
384             for Item in self.Contents[Arch].Guids:\r
385                 MergeArches(Guids, Item, Arch)\r
386         for Key in Guids.keys():\r
387             Guid = GuidClass()\r
388             Guid.CName = Key\r
389             Guid.SupArchList = Guids[Key]\r
390             self.Module.Guids.append(Guid)\r
391 \r
392         #Protocols\r
393         Protocols = {}\r
394         for Arch in DataType.ARCH_LIST:\r
395             for Item in self.Contents[Arch].Protocols:\r
396                 MergeArches(Protocols, Item, Arch)\r
397         for Key in Protocols.keys():\r
398             Protocol = ProtocolClass()\r
399             Protocol.CName = Key\r
400             Protocol.SupArchList = Protocols[Key]\r
401             self.Module.Protocols.append(Protocol)\r
402         \r
403         #Ppis\r
404         Ppis = {}\r
405         for Arch in DataType.ARCH_LIST:\r
406             for Item in self.Contents[Arch].Ppis:\r
407                 MergeArches(Ppis, Item, Arch)\r
408         for Key in Ppis.keys():\r
409             Ppi = PpiClass()\r
410             Ppi.CName = Key\r
411             Ppi.SupArchList = Ppis[Key]\r
412             self.Module.Ppis.append(Ppi)\r
413         \r
414         #Depex\r
415         Depex = {}\r
416         Defines = {}\r
417         for Arch in DataType.ARCH_LIST:\r
418             Line = ''\r
419             for Item in self.Contents[Arch].Depex:\r
420                 Status = GenDefines(Item, Arch, Defines)\r
421                 if Status == 0:       # Find DEFINE statement\r
422                     pass\r
423                 elif Status == -1:    # Find DEFINE statement but in wrong format\r
424                     ErrorMsg = "Wrong DEFINE statement '%s' found in section Depex in file '%s', correct format is 'DEFINE <VarName> = <PATH>'" % (Item, self.Module.Header.FullPath) \r
425                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
426                 elif Status == 1:     # Not find DEFINE statement\r
427                     Line = Line + Item + ' '\r
428             MergeArches(Depex, Line, Arch)\r
429         for Key in Depex.keys():\r
430             Dep = ModuleDepexClass()\r
431             Dep.Depex = Key\r
432             Dep.SupArchList = Depex[Key]\r
433             Dep.Define = Defines\r
434             self.Module.Depex.append(Dep)\r
435         \r
436         #Binaries\r
437         Binaries = {}\r
438         for Arch in DataType.ARCH_LIST:\r
439             for Item in self.Contents[Arch].Binaries:\r
440                 Item = Item + DataType.TAB_VALUE_SPLIT\r
441                 List = GetSplitValueList(Item)\r
442                 if len(List) < 4:\r
443                     ErrorMsg = "Wrong statement '%s' found in section Binaries in file '%s', correct format is '<FileType>|<Target>|<FileName>[|<PcdFeatureFlag>]'" % (Item[0:-1], self.Module.Header.FullPath) \r
444                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
445                 else:\r
446                     MergeArches(Binaries, (List[0], List[1], List[2], List[3]), Arch)\r
447         for Key in Binaries.keys():\r
448             Binary = ModuleBinaryFileClass(Key[2], Key[0], Key[1], Key[3], Binaries[Key])\r
449             self.Module.Binaries.append(Binary)\r
450         \r
451     def LoadInfFile(self, Filename):     \r
452         (Filepath, Name) = os.path.split(Filename)\r
453         self.Identification.FileName = Name\r
454         self.Identification.FileFullPath = Filename\r
455         self.Identification.FileRelativePath = Filepath\r
456         \r
457         f = open(Filename, 'r').read()\r
458         sects = f.split('[')\r
459         for sect in sects:\r
460             tab = (sect.split(TAB_SECTION_END, 1)[0]).upper()\r
461             if tab == TAB_INF_DEFINES.upper():\r
462                 GetSingleValueOfKeyFromLines(sect, self.Defines.DefinesDictionary, TAB_COMMENT_SPLIT, TAB_EQUAL_SPLIT, False, None)\r
463                 continue\r
464             if tab.find(DataType.TAB_USER_EXTENSIONS.upper()) > -1:\r
465                 self.UserExtensions = sect\r
466                 continue\r
467             for arch in DataType.ARCH_LIST_FULL + [DataType.TAB_ARCH_NULL]:\r
468                 for key in self.KeyList:\r
469                     if arch != DataType.TAB_ARCH_NULL:\r
470                         target = (key + DataType.TAB_SPLIT + arch).upper()\r
471                     else:\r
472                         target = key.upper()\r
473                     if SplitModuleType(tab)[0] == target:\r
474                         if arch != DataType.TAB_ARCH_NULL:\r
475                             Command = 'self.ParseInf(sect, tab, self.Contents[arch].' + key + ')'\r
476                             eval(Command)\r
477                             continue\r
478                         else:\r
479                             Command = "self.ParseInf(sect, tab, self.Contents['" + DataType.TAB_ARCH_COMMON + "']." + key + ')'\r
480                             eval(Command)\r
481                             continue\r
482         #EndFor\r
483 \r
484     def ShowInf(self):\r
485         print TAB_SECTION_START + TAB_INF_DEFINES + TAB_SECTION_END\r
486         printDict(self.Defines.DefinesDictionary)\r
487 \r
488         for key in self.KeyList:\r
489             for arch in DataType.ARCH_LIST_FULL:\r
490                 Command = "printList(TAB_SECTION_START + '" + \\r
491                           key + DataType.TAB_SPLIT + arch + \\r
492                           "' + TAB_SECTION_END, self.Contents[arch]." + key + ')'\r
493                 eval(Command)\r
494         print ""\r
495     \r
496     def ShowModule(self):\r
497         m = self.Module\r
498         print 'Filename =', m.Header.FileName\r
499         print 'FullPath =', m.Header.FullPath\r
500         print 'BaseName =', m.Header.Name\r
501         print 'Guid =', m.Header.Guid\r
502         print 'Version =', m.Header.Version\r
503         print 'InfVersion =', m.Header.InfVersion\r
504         print 'EfiSpecificationVersion =', m.Header.EfiSpecificationVersion\r
505         print 'EdkReleaseVersion =', m.Header.EdkReleaseVersion                \r
506         print 'ModuleType =', m.Header.ModuleType\r
507         print 'BinaryModule =', m.Header.BinaryModule\r
508         print 'ComponentType =', m.Header.ComponentType\r
509         print 'MakefileName =', m.Header.MakefileName\r
510         print 'BuildNumber =', m.Header.BuildNumber\r
511         print 'BuildType =', m.Header.BuildType\r
512         print 'FfsExt =', m.Header.FfsExt\r
513         print 'FvExt =', m.Header.FvExt\r
514         print 'SourceFv =', m.Header.SourceFv\r
515         print 'PcdIsDriver =', m.Header.PcdIsDriver\r
516         print 'TianoR8FlashMap_h =', m.Header.TianoR8FlashMap_h\r
517         print 'LibraryClass =', m.Header.LibraryClass\r
518         for Item in m.Header.LibraryClass:\r
519             print Item.LibraryClass, DataType.TAB_VALUE_SPLIT.join(Item.SupModuleList)\r
520         print 'CustomMakefile =', m.Header.CustomMakefile\r
521         for Item in self.Module.ExternImages:\r
522             print 'Entry_Point = %s, UnloadImage = %s' % (Item.ModuleEntryPoint, Item.ModuleUnloadImage)\r
523         for Item in self.Module.ExternLibraries:\r
524             print 'Constructor = %s, Destructor = %s' % (Item.Constructor, Item.Destructor)\r
525         print 'Define =', m.Header.Define\r
526         print 'Specification =', m.Header.Specification\r
527         print '\nBuildOptions =', m.BuildOptions\r
528         for Item in m.BuildOptions:\r
529             print Item.ToolChainFamily, Item.ToolChain, Item.Option, Item.SupArchList\r
530         print '\nIncludes =', m.Includes\r
531         for Item in m.Includes:\r
532             print Item.FilePath, Item.SupArchList\r
533         print '\nLibraries =', m.Libraries\r
534         for Item in m.Libraries:\r
535             print Item.Library, Item.SupArchList\r
536         print '\nLibraryClasses =', m.LibraryClasses\r
537         for Item in m.LibraryClasses:\r
538             print Item.LibraryClass, Item.RecommendedInstance, Item.FeatureFlag, Item.SupModuleList, Item.SupArchList, Item.Define\r
539         print '\nPackageDependencies =', m.PackageDependencies\r
540         for Item in m.PackageDependencies:\r
541             print Item.FilePath, Item.SupArchList, Item.Define\r
542         print '\nNmake =', m.Nmake\r
543         for Item in m.Nmake:\r
544             print Item.Name, Item.Value, Item.SupArchList\r
545         print '\nPcds =', m.PcdCodes\r
546         for Item in m.PcdCodes:\r
547             print Item.CName, Item.TokenSpaceGuidCName, Item.DefaultValue, Item.ItemType, Item.SupArchList\r
548         print '\nSources =', m.Sources\r
549         for Source in m.Sources:\r
550             print Source.SourceFile, Source.ToolChainFamily, Source.FeatureFlag, Source.TagName, Source.ToolCode, Source.SupArchList\r
551         print '\nUserExtensions =', m.UserExtensions\r
552         for UserExtension in m.UserExtensions:\r
553             print UserExtension.UserID, UserExtension.Identifier,UserExtension.Content\r
554         print '\nGuids =', m.Guids\r
555         for Item in m.Guids:\r
556             print Item.CName, Item.SupArchList\r
557         print '\nProtocols =', m.Protocols\r
558         for Item in m.Protocols:\r
559             print Item.CName, Item.SupArchList\r
560         print '\nPpis =', m.Ppis\r
561         for Item in m.Ppis:\r
562             print Item.CName, Item.SupArchList\r
563         print '\nDepex =', m.Depex\r
564         for Item in m.Depex:\r
565             print Item.Depex, Item.SupArchList, Item.Define\r
566         print '\nBinaries =', m.Binaries\r
567         for Binary in m.Binaries:\r
568             print Binary.FileType, Binary.Target, Binary.BinaryFile, Binary.FeatureFlag\r
569         \r
570 if __name__ == '__main__':\r
571     m = Inf()\r
572     directory = 'C:\Documents and Settings\\hchen30\\Desktop\\prototype\\inf'\r
573     fileList = []\r
574     \r
575     for f in os.listdir(directory):\r
576         if os.path.splitext(os.path.normcase(f))[1] == '.inf':\r
577             fileList.append(os.path.join(directory, os.path.normcase(f)))\r
578             \r
579     for f in fileList:\r
580         m = Inf(f, True, True)\r
581         #m.ShowInf()\r
582         m.ShowModule()\r