git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@466 7335b...
[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             else:\r
271                 LibraryClass.SupModuleList = DataType.SUP_MODULE_LIST\r
272             self.Module.LibraryClasses.append(LibraryClass)\r
273         \r
274         #Packages\r
275         Packages = {}\r
276         Defines = {}\r
277         for Arch in DataType.ARCH_LIST:\r
278             for Item in self.Contents[Arch].Packages:\r
279                 Status = GenDefines(Item, Arch, Defines)\r
280                 if Status == 0:       # Find DEFINE statement\r
281                     pass\r
282                 elif Status == -1:    # Find DEFINE statement but in wrong format\r
283                     ErrorMsg = "Wrong DEFINE statement '%s' found in section Packages in file '%s', correct format is 'DEFINE <VarName> = <PATH>'" % (Item, self.Module.Header.FullPath) \r
284                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
285                 elif Status == 1:     # Not find DEFINE statement\r
286                     MergeArches(Packages, Item, Arch)\r
287         for Key in Packages.keys():\r
288             Package = ModulePackageDependencyClass()\r
289             Package.Define = Defines\r
290             Package.FilePath = Key\r
291             Package.SupArchList = Packages[Key]\r
292             self.Module.PackageDependencies.append(Package)\r
293             \r
294         #Nmake\r
295         Nmakes = {}\r
296         for Arch in DataType.ARCH_LIST:\r
297             for Item in self.Contents[Arch].Nmake:\r
298                 MergeArches(Nmakes, Item, Arch)\r
299         for Key in Nmakes.keys():\r
300             List = GetSplitValueList(Key, DataType.TAB_EQUAL_SPLIT)\r
301             if len(List) != 2:\r
302                 ErrorMsg = "Wrong statement '%s' found in section Nmake in file '%s', correct format is '<Word>=<Word>'" % (Item, self.Module.Header.FullPath) \r
303                 raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
304             Nmake = ModuleNmakeClass()\r
305             Nmake.Name = List[0]\r
306             Nmake.Value = List[1]\r
307             Nmake.SupArchList = Nmakes[Key]\r
308             self.Module.Nmake.append(Nmake)\r
309         \r
310         #Pcds\r
311         Pcds = {}\r
312         for Arch in DataType.ARCH_LIST:\r
313             for Item in self.Contents[Arch].PcdsFixedAtBuild:\r
314                 Item = Item + DataType.TAB_VALUE_SPLIT\r
315                 List = GetSplitValueList(Item)\r
316                 if len(List) <= 2:\r
317                     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
318                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
319                 MergeArches(Pcds, (List[0], List[1], List[2], TAB_PCDS_FIXED_AT_BUILD), Arch)\r
320             for Item in self.Contents[Arch].PcdsPatchableInModule:\r
321                 Item = Item + DataType.TAB_VALUE_SPLIT\r
322                 List = GetSplitValueList(Item)\r
323                 if len(List) <= 2:\r
324                     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
325                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
326                 MergeArches(Pcds, (List[0], List[1], List[2], TAB_PCDS_PATCHABLE_IN_MODULE), Arch)\r
327             for Item in self.Contents[Arch].PcdsFeatureFlag:\r
328                 Item = Item + DataType.TAB_VALUE_SPLIT\r
329                 List = GetSplitValueList(Item)\r
330                 if len(List) <= 2:\r
331                     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
332                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
333                 MergeArches(Pcds, (List[0], List[1], List[2], TAB_PCDS_FEATURE_FLAG), Arch)\r
334             for Item in self.Contents[Arch].PcdsDynamicEx:\r
335                 Item = Item + DataType.TAB_VALUE_SPLIT\r
336                 List = GetSplitValueList(Item)\r
337                 if len(List) <= 2:\r
338                     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
339                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
340                 MergeArches(Pcds, (List[0], List[1], List[2], TAB_PCDS_DYNAMIC_EX), Arch)\r
341             for Item in self.Contents[Arch].PcdsDynamic:\r
342                 Item = Item + DataType.TAB_VALUE_SPLIT\r
343                 List = GetSplitValueList(Item)\r
344                 if len(List) <= 2:\r
345                     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
346                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
347                 MergeArches(Pcds, (List[0], List[1], List[2], TAB_PCDS_DYNAMIC), Arch)\r
348         for Key in Pcds.keys():\r
349             Pcd = PcdClass()\r
350             Pcd.CName = Key[0]\r
351             Pcd.TokenSpaceGuidCName = Key[1]\r
352             Pcd.DefaultValue = Key[2]\r
353             Pcd.ItemType = Key[3]\r
354             Pcd.SupArchList = Pcds[Key]\r
355             self.Module.PcdCodes.append(Pcd)\r
356         \r
357         #Sources\r
358         Sources = {}\r
359         for Arch in DataType.ARCH_LIST:\r
360             for Item in self.Contents[Arch].Sources:\r
361                 Item = Item + DataType.TAB_VALUE_SPLIT * 4\r
362                 List = GetSplitValueList(Item)\r
363                 MergeArches(Sources, (List[0], List[1], List[2], List[3], List[4]), Arch)\r
364         for Key in Sources.keys():\r
365             Source = ModuleSourceFileClass(Key[0], Key[3], Key[4], Key[1], Key[2], Sources[Key])\r
366             self.Module.Sources.append(Source)\r
367         \r
368         #UserExtensions\r
369         if self.UserExtensions != '':\r
370             UserExtension = UserExtensionsClass()\r
371             Lines = self.UserExtensions.splitlines()\r
372             List = GetSplitValueList(Lines[0], DataType.TAB_SPLIT, 2)\r
373             if len(List) != 3:\r
374                 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
375                 raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
376             else:\r
377                 UserExtension.UserID = List[1]\r
378                 UserExtension.Identifier = List[2][0:-1].replace("'", '').replace('\"', '')\r
379                 for Line in Lines[1:]:\r
380                     UserExtension.Content = UserExtension.Content + CleanString(Line) + '\n'\r
381             self.Module.UserExtensions.append(UserExtension)\r
382         \r
383         #Guids\r
384         Guids = {}\r
385         for Arch in DataType.ARCH_LIST:\r
386             for Item in self.Contents[Arch].Guids:\r
387                 MergeArches(Guids, Item, Arch)\r
388         for Key in Guids.keys():\r
389             Guid = GuidClass()\r
390             Guid.CName = Key\r
391             Guid.SupArchList = Guids[Key]\r
392             self.Module.Guids.append(Guid)\r
393 \r
394         #Protocols\r
395         Protocols = {}\r
396         for Arch in DataType.ARCH_LIST:\r
397             for Item in self.Contents[Arch].Protocols:\r
398                 MergeArches(Protocols, Item, Arch)\r
399         for Key in Protocols.keys():\r
400             Protocol = ProtocolClass()\r
401             Protocol.CName = Key\r
402             Protocol.SupArchList = Protocols[Key]\r
403             self.Module.Protocols.append(Protocol)\r
404         \r
405         #Ppis\r
406         Ppis = {}\r
407         for Arch in DataType.ARCH_LIST:\r
408             for Item in self.Contents[Arch].Ppis:\r
409                 MergeArches(Ppis, Item, Arch)\r
410         for Key in Ppis.keys():\r
411             Ppi = PpiClass()\r
412             Ppi.CName = Key\r
413             Ppi.SupArchList = Ppis[Key]\r
414             self.Module.Ppis.append(Ppi)\r
415         \r
416         #Depex\r
417         Depex = {}\r
418         Defines = {}\r
419         for Arch in DataType.ARCH_LIST:\r
420             Line = ''\r
421             for Item in self.Contents[Arch].Depex:\r
422                 Status = GenDefines(Item, Arch, Defines)\r
423                 if Status == 0:       # Find DEFINE statement\r
424                     pass\r
425                 elif Status == -1:    # Find DEFINE statement but in wrong format\r
426                     ErrorMsg = "Wrong DEFINE statement '%s' found in section Depex in file '%s', correct format is 'DEFINE <VarName> = <PATH>'" % (Item, self.Module.Header.FullPath) \r
427                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
428                 elif Status == 1:     # Not find DEFINE statement\r
429                     Line = Line + Item + ' '\r
430             MergeArches(Depex, Line, Arch)\r
431         for Key in Depex.keys():\r
432             Dep = ModuleDepexClass()\r
433             Dep.Depex = Key\r
434             Dep.SupArchList = Depex[Key]\r
435             Dep.Define = Defines\r
436             self.Module.Depex.append(Dep)\r
437         \r
438         #Binaries\r
439         Binaries = {}\r
440         for Arch in DataType.ARCH_LIST:\r
441             for Item in self.Contents[Arch].Binaries:\r
442                 Item = Item + DataType.TAB_VALUE_SPLIT\r
443                 List = GetSplitValueList(Item)\r
444                 if len(List) < 4:\r
445                     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
446                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
447                 else:\r
448                     MergeArches(Binaries, (List[0], List[1], List[2], List[3]), Arch)\r
449         for Key in Binaries.keys():\r
450             Binary = ModuleBinaryFileClass(Key[2], Key[0], Key[1], Key[3], Binaries[Key])\r
451             self.Module.Binaries.append(Binary)\r
452         \r
453     def LoadInfFile(self, Filename):     \r
454         (Filepath, Name) = os.path.split(Filename)\r
455         self.Identification.FileName = Name\r
456         self.Identification.FileFullPath = Filename\r
457         self.Identification.FileRelativePath = Filepath\r
458         \r
459         f = open(Filename, 'r').read()\r
460         sects = f.split('[')\r
461         for sect in sects:\r
462             tab = (sect.split(TAB_SECTION_END, 1)[0]).upper()\r
463             if tab == TAB_INF_DEFINES.upper():\r
464                 GetSingleValueOfKeyFromLines(sect, self.Defines.DefinesDictionary, TAB_COMMENT_SPLIT, TAB_EQUAL_SPLIT, False, None)\r
465                 continue\r
466             if tab.find(DataType.TAB_USER_EXTENSIONS.upper()) > -1:\r
467                 self.UserExtensions = sect\r
468                 continue\r
469             for arch in DataType.ARCH_LIST_FULL + [DataType.TAB_ARCH_NULL]:\r
470                 for key in self.KeyList:\r
471                     if arch != DataType.TAB_ARCH_NULL:\r
472                         target = (key + DataType.TAB_SPLIT + arch).upper()\r
473                     else:\r
474                         target = key.upper()\r
475                     if SplitModuleType(tab)[0] == target:\r
476                         if arch != DataType.TAB_ARCH_NULL:\r
477                             Command = 'self.ParseInf(sect, tab, self.Contents[arch].' + key + ')'\r
478                             eval(Command)\r
479                             continue\r
480                         else:\r
481                             Command = "self.ParseInf(sect, tab, self.Contents['" + DataType.TAB_ARCH_COMMON + "']." + key + ')'\r
482                             eval(Command)\r
483                             continue\r
484         #EndFor\r
485 \r
486     def ShowInf(self):\r
487         print TAB_SECTION_START + TAB_INF_DEFINES + TAB_SECTION_END\r
488         printDict(self.Defines.DefinesDictionary)\r
489 \r
490         for key in self.KeyList:\r
491             for arch in DataType.ARCH_LIST_FULL:\r
492                 Command = "printList(TAB_SECTION_START + '" + \\r
493                           key + DataType.TAB_SPLIT + arch + \\r
494                           "' + TAB_SECTION_END, self.Contents[arch]." + key + ')'\r
495                 eval(Command)\r
496         print ""\r
497     \r
498     def ShowModule(self):\r
499         m = self.Module\r
500         print 'Filename =', m.Header.FileName\r
501         print 'FullPath =', m.Header.FullPath\r
502         print 'BaseName =', m.Header.Name\r
503         print 'Guid =', m.Header.Guid\r
504         print 'Version =', m.Header.Version\r
505         print 'InfVersion =', m.Header.InfVersion\r
506         print 'EfiSpecificationVersion =', m.Header.EfiSpecificationVersion\r
507         print 'EdkReleaseVersion =', m.Header.EdkReleaseVersion                \r
508         print 'ModuleType =', m.Header.ModuleType\r
509         print 'BinaryModule =', m.Header.BinaryModule\r
510         print 'ComponentType =', m.Header.ComponentType\r
511         print 'MakefileName =', m.Header.MakefileName\r
512         print 'BuildNumber =', m.Header.BuildNumber\r
513         print 'BuildType =', m.Header.BuildType\r
514         print 'FfsExt =', m.Header.FfsExt\r
515         print 'FvExt =', m.Header.FvExt\r
516         print 'SourceFv =', m.Header.SourceFv\r
517         print 'PcdIsDriver =', m.Header.PcdIsDriver\r
518         print 'TianoR8FlashMap_h =', m.Header.TianoR8FlashMap_h\r
519         print 'LibraryClass =', m.Header.LibraryClass\r
520         for Item in m.Header.LibraryClass:\r
521             print Item.LibraryClass, DataType.TAB_VALUE_SPLIT.join(Item.SupModuleList)\r
522         print 'CustomMakefile =', m.Header.CustomMakefile\r
523         for Item in self.Module.ExternImages:\r
524             print 'Entry_Point = %s, UnloadImage = %s' % (Item.ModuleEntryPoint, Item.ModuleUnloadImage)\r
525         for Item in self.Module.ExternLibraries:\r
526             print 'Constructor = %s, Destructor = %s' % (Item.Constructor, Item.Destructor)\r
527         print 'Define =', m.Header.Define\r
528         print 'Specification =', m.Header.Specification\r
529         print '\nBuildOptions =', m.BuildOptions\r
530         for Item in m.BuildOptions:\r
531             print Item.ToolChainFamily, Item.ToolChain, Item.Option, Item.SupArchList\r
532         print '\nIncludes =', m.Includes\r
533         for Item in m.Includes:\r
534             print Item.FilePath, Item.SupArchList\r
535         print '\nLibraries =', m.Libraries\r
536         for Item in m.Libraries:\r
537             print Item.Library, Item.SupArchList\r
538         print '\nLibraryClasses =', m.LibraryClasses\r
539         for Item in m.LibraryClasses:\r
540             print Item.LibraryClass, Item.RecommendedInstance, Item.FeatureFlag, Item.SupModuleList, Item.SupArchList, Item.Define\r
541         print '\nPackageDependencies =', m.PackageDependencies\r
542         for Item in m.PackageDependencies:\r
543             print Item.FilePath, Item.SupArchList, Item.Define\r
544         print '\nNmake =', m.Nmake\r
545         for Item in m.Nmake:\r
546             print Item.Name, Item.Value, Item.SupArchList\r
547         print '\nPcds =', m.PcdCodes\r
548         for Item in m.PcdCodes:\r
549             print Item.CName, Item.TokenSpaceGuidCName, Item.DefaultValue, Item.ItemType, Item.SupArchList\r
550         print '\nSources =', m.Sources\r
551         for Source in m.Sources:\r
552             print Source.SourceFile, Source.ToolChainFamily, Source.FeatureFlag, Source.TagName, Source.ToolCode, Source.SupArchList\r
553         print '\nUserExtensions =', m.UserExtensions\r
554         for UserExtension in m.UserExtensions:\r
555             print UserExtension.UserID, UserExtension.Identifier,UserExtension.Content\r
556         print '\nGuids =', m.Guids\r
557         for Item in m.Guids:\r
558             print Item.CName, Item.SupArchList\r
559         print '\nProtocols =', m.Protocols\r
560         for Item in m.Protocols:\r
561             print Item.CName, Item.SupArchList\r
562         print '\nPpis =', m.Ppis\r
563         for Item in m.Ppis:\r
564             print Item.CName, Item.SupArchList\r
565         print '\nDepex =', m.Depex\r
566         for Item in m.Depex:\r
567             print Item.Depex, Item.SupArchList, Item.Define\r
568         print '\nBinaries =', m.Binaries\r
569         for Binary in m.Binaries:\r
570             print Binary.FileType, Binary.Target, Binary.BinaryFile, Binary.FeatureFlag\r
571         \r
572 if __name__ == '__main__':\r
573     m = Inf()\r
574     directory = 'C:\MyWorkspace\MdePkg\Library\BaseLib'\r
575     fileList = []\r
576     \r
577     for f in os.listdir(directory):\r
578         if os.path.splitext(os.path.normcase(f))[1] == '.inf':\r
579             fileList.append(os.path.join(directory, os.path.normcase(f)))\r
580             \r
581     for f in fileList:\r
582         m = Inf(f, True, True)\r
583         #m.ShowInf()\r
584         m.ShowModule()\r