Sync EDKII BaseTools to BaseTools project r1903.
[efi/edk2/.git] / edk2 / BaseTools / Source / Python / Common / InfClassObjectLight.py
1 ## @file\r
2 # This file is used to define each component of INF file\r
3 #\r
4 # Copyright (c) 2007 - 2010, Intel Corporation\r
5 # All rights reserved. This program and the accompanying materials\r
6 # are licensed and made available under the terms and conditions of the BSD License\r
7 # which accompanies this distribution.  The full text of the license may be found at\r
8 # http://opensource.org/licenses/bsd-license.php\r
9 #\r
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12 #\r
13 \r
14 ##\r
15 # Import Modules\r
16 #\r
17 import os\r
18 import re\r
19 import EdkLogger\r
20 \r
21 from CommonDataClass.ModuleClass import *\r
22 from CommonDataClass import CommonClass\r
23 from String import *\r
24 from DataType import *\r
25 from BuildToolError import *\r
26 from Misc import sdict\r
27 from Misc import GetFiles\r
28 from Parsing import *\r
29 \r
30 # Global variable\r
31 Section = {TAB_UNKNOWN.upper() : MODEL_UNKNOWN,\r
32            TAB_INF_DEFINES.upper() : MODEL_META_DATA_HEADER,\r
33            TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION,\r
34            TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,\r
35            TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE,\r
36            TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,\r
37            TAB_PACKAGES.upper() : MODEL_META_DATA_PACKAGE,\r
38            TAB_NMAKE.upper() : MODEL_META_DATA_NMAKE,\r
39            TAB_INF_FIXED_PCD.upper() : MODEL_PCD_FIXED_AT_BUILD,\r
40            TAB_INF_PATCH_PCD.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,\r
41            TAB_INF_FEATURE_PCD.upper() : MODEL_PCD_FEATURE_FLAG,\r
42            TAB_INF_PCD_EX.upper() : MODEL_PCD_DYNAMIC_EX,\r
43            TAB_INF_PCD.upper() : MODEL_PCD_DYNAMIC,\r
44            TAB_SOURCES.upper() : MODEL_EFI_SOURCE_FILE,\r
45            TAB_GUIDS.upper() : MODEL_EFI_GUID,\r
46            TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,\r
47            TAB_PPIS.upper() : MODEL_EFI_PPI,\r
48            TAB_DEPEX.upper() : MODEL_EFI_DEPEX,\r
49            TAB_BINARIES.upper() : MODEL_EFI_BINARY_FILE,\r
50            TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION\r
51            }\r
52 \r
53 gComponentType2ModuleType = {\r
54     "LIBRARY"               :   "BASE",\r
55     "SECURITY_CORE"         :   "SEC",\r
56     "PEI_CORE"              :   "PEI_CORE",\r
57     "COMBINED_PEIM_DRIVER"  :   "PEIM",\r
58     "PIC_PEIM"              :   "PEIM",\r
59     "RELOCATABLE_PEIM"      :   "PEIM",\r
60     "PE32_PEIM"             :   "PEIM",\r
61     "BS_DRIVER"             :   "DXE_DRIVER",\r
62     "RT_DRIVER"             :   "DXE_RUNTIME_DRIVER",\r
63     "SAL_RT_DRIVER"         :   "DXE_SAL_DRIVER",\r
64     "APPLICATION"           :   "UEFI_APPLICATION",\r
65     "LOGO"                  :   "BASE",\r
66 }\r
67 \r
68 class InfHeader(ModuleHeaderClass):\r
69     _Mapping_ = {\r
70         # Required Fields\r
71         TAB_INF_DEFINES_BASE_NAME                   : "Name",\r
72         TAB_INF_DEFINES_FILE_GUID                   : "Guid",\r
73         TAB_INF_DEFINES_MODULE_TYPE                 : "ModuleType",\r
74         TAB_INF_DEFINES_EFI_SPECIFICATION_VERSION   : "UefiSpecificationVersion",\r
75         TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION  : "UefiSpecificationVersion",\r
76         TAB_INF_DEFINES_EDK_RELEASE_VERSION         : "EdkReleaseVersion",        \r
77 \r
78         # Optional Fields\r
79         TAB_INF_DEFINES_INF_VERSION                 : "InfVersion",\r
80         TAB_INF_DEFINES_BINARY_MODULE               : "BinaryModule",\r
81         TAB_INF_DEFINES_COMPONENT_TYPE              : "ComponentType",\r
82         TAB_INF_DEFINES_MAKEFILE_NAME               : "MakefileName",\r
83         TAB_INF_DEFINES_BUILD_NUMBER                : "BuildNumber",\r
84         TAB_INF_DEFINES_BUILD_TYPE                  : "BuildType",\r
85         TAB_INF_DEFINES_FFS_EXT                     : "FfsExt",\r
86         TAB_INF_DEFINES_FV_EXT                      : "FvExt",\r
87         TAB_INF_DEFINES_SOURCE_FV                   : "SourceFv",\r
88         TAB_INF_DEFINES_VERSION_NUMBER              : "VersionNumber",\r
89         TAB_INF_DEFINES_VERSION_STRING              : "VersionString",\r
90         TAB_INF_DEFINES_VERSION                     : "Version",\r
91         TAB_INF_DEFINES_PCD_IS_DRIVER               : "PcdIsDriver",\r
92         TAB_INF_DEFINES_TIANO_R8_FLASHMAP_H         : "TianoR8FlashMap_h",\r
93         TAB_INF_DEFINES_SHADOW                      : "Shadow",\r
94     }\r
95 \r
96     def __init__(self):\r
97         ModuleHeaderClass.__init__(self)\r
98         self.VersionNumber = ''\r
99         self.VersionString = ''\r
100         #print self.__dict__\r
101     def __setitem__(self, key, value):\r
102         self.__dict__[self._Mapping_[key]] = value\r
103     def __getitem__(self, key):\r
104         return self.__dict__[self._Mapping_[key]]\r
105     ## "in" test support\r
106     def __contains__(self, key):\r
107         return key in self._Mapping_\r
108 \r
109 ## InfObject\r
110 #\r
111 # This class defined basic Inf object which is used by inheriting\r
112\r
113 # @param object:       Inherited from object class\r
114 #\r
115 class InfObject(object):\r
116     def __init__(self):\r
117         object.__init__()\r
118 \r
119 ## Inf\r
120 #\r
121 # This class defined the structure used in Inf object\r
122\r
123 # @param InfObject:         Inherited from InfObject class\r
124 # @param Ffilename:         Input value for Ffilename of Inf file, default is None\r
125 # @param IsMergeAllArches:  Input value for IsMergeAllArches\r
126 #                           True is to merge all arches\r
127 #                           Fales is not to merge all arches\r
128 #                           default is False\r
129 # @param IsToModule:        Input value for IsToModule\r
130 #                           True is to transfer to ModuleObject automatically\r
131 #                           False is not to transfer to ModuleObject automatically\r
132 #                           default is False\r
133 # @param WorkspaceDir:      Input value for current workspace directory, default is None\r
134 #\r
135 # @var Identification:      To store value for Identification, it is a structure as Identification\r
136 # @var UserExtensions:      To store value for UserExtensions\r
137 # @var Module:              To store value for Module, it is a structure as ModuleClass\r
138 # @var WorkspaceDir:        To store value for WorkspaceDir\r
139 # @var KeyList:             To store value for KeyList, a list for all Keys used in Inf\r
140 #\r
141 class Inf(InfObject):\r
142     def __init__(self, Filename = None, IsToModule = False, WorkspaceDir = None, PackageDir = None, SupArchList = DataType.ARCH_LIST):\r
143         self.Identification = IdentificationClass()\r
144         self.Module = ModuleClass()\r
145         self.WorkspaceDir = WorkspaceDir\r
146         self.PackageDir = PackageDir\r
147         self.SupArchList = SupArchList\r
148         \r
149         self.KeyList = [\r
150             TAB_SOURCES, TAB_BUILD_OPTIONS, TAB_BINARIES, TAB_INCLUDES, TAB_GUIDS, \r
151             TAB_PROTOCOLS, TAB_PPIS, TAB_LIBRARY_CLASSES, TAB_PACKAGES, TAB_INF_FIXED_PCD, \r
152             TAB_INF_PATCH_PCD, TAB_INF_FEATURE_PCD, TAB_INF_PCD, TAB_INF_PCD_EX, \r
153             TAB_DEPEX, TAB_INF_DEFINES\r
154         ]\r
155         # Upper all KEYs to ignore case sensitive when parsing\r
156         self.KeyList = map(lambda c: c.upper(), self.KeyList)\r
157         \r
158         # Init RecordSet\r
159         self.RecordSet = {}        \r
160         for Key in self.KeyList:\r
161             self.RecordSet[Section[Key]] = []\r
162         \r
163         # Init Comment\r
164         self.SectionHeaderCommentDict = {}\r
165         \r
166         # Load Inf file if filename is not None\r
167         if Filename != None:\r
168             self.LoadInfFile(Filename)\r
169         \r
170         # Transfer to Module Object if IsToModule is True\r
171         if IsToModule:\r
172             self.InfToModule()\r
173 \r
174     ## Module Object to INF file\r
175     def ModuleToInf(self, Module):\r
176         Inf = ''\r
177         InfList = sdict()\r
178         SectionHeaderCommentDict = {}\r
179         if Module == None:\r
180             return Inf\r
181 \r
182         ModuleHeader = Module.ModuleHeader\r
183         TmpList = []\r
184         # Common define items\r
185         if ModuleHeader.Name:\r
186             TmpList.append(TAB_INF_DEFINES_BASE_NAME + ' = ' + ModuleHeader.Name)\r
187         if ModuleHeader.Guid:\r
188             TmpList.append(TAB_INF_DEFINES_FILE_GUID + ' = ' + ModuleHeader.Guid)\r
189         if ModuleHeader.Version:\r
190             TmpList.append(TAB_INF_DEFINES_VERSION_STRING + ' = ' + ModuleHeader.Version)\r
191         if ModuleHeader.ModuleType:\r
192             TmpList.append(TAB_INF_DEFINES_MODULE_TYPE + ' = ' + ModuleHeader.ModuleType)\r
193         if ModuleHeader.PcdIsDriver:\r
194             TmpList.append(TAB_INF_DEFINES_PCD_IS_DRIVER + ' = ' + ModuleHeader.PcdIsDriver)\r
195         # Externs\r
196         for Item in Module.Externs:\r
197             if Item.EntryPoint:\r
198                 TmpList.append(TAB_INF_DEFINES_ENTRY_POINT + ' = ' + Item.EntryPoint)\r
199             if Item.UnloadImage:\r
200                 TmpList.append(TAB_INF_DEFINES_UNLOAD_IMAGE + ' = ' + Item.UnloadImage)\r
201             if Item.Constructor:\r
202                 TmpList.append(TAB_INF_DEFINES_CONSTRUCTOR + ' = ' + Item.Constructor)\r
203             if Item.Destructor:\r
204                 TmpList.append(TAB_INF_DEFINES_DESTRUCTOR + ' = ' + Item.Destructor)\r
205         # Other define items\r
206         if Module.UserExtensions != None:\r
207             for Item in Module.UserExtensions.Defines:\r
208                 TmpList.append(Item)\r
209         InfList['Defines'] = TmpList\r
210         if ModuleHeader.Description != '':\r
211             SectionHeaderCommentDict['Defines'] = ModuleHeader.Description\r
212         \r
213         if Module.UserExtensions != None:\r
214             InfList['BuildOptions'] = Module.UserExtensions.BuildOptions\r
215         \r
216         for Item in Module.Includes:\r
217             Key = 'Includes.' + GetStringOfList(Item.SupArchList)\r
218             Value = GetHelpTextList(Item.HelpTextList)\r
219             Value.append(Item.FilePath)\r
220             GenMetaDatSectionItem(Key, Value, InfList)\r
221         \r
222         for Item in Module.LibraryClasses:\r
223             Key = 'LibraryClasses.' + GetStringOfList(Item.SupArchList)\r
224             Value = GetHelpTextList(Item.HelpTextList)\r
225             NewValue = Item.LibraryClass\r
226             if Item.RecommendedInstance:\r
227                 NewValue = NewValue + '|' + Item.RecommendedInstance\r
228             if Item.FeatureFlag:\r
229                 NewValue = NewValue + '|' + Item.FeatureFlag\r
230             Value.append(NewValue)    \r
231             GenMetaDatSectionItem(Key, Value, InfList)\r
232         \r
233         for Item in Module.PackageDependencies:\r
234             Key = 'Packages.' + GetStringOfList(Item.SupArchList)\r
235             Value = GetHelpTextList(Item.HelpTextList)\r
236             Value.append(Item.FilePath)\r
237             GenMetaDatSectionItem(Key, Value, InfList)\r
238         \r
239         for Item in Module.PcdCodes:\r
240             Key = 'Pcds' + Item.ItemType + '.' + GetStringOfList(Item.SupArchList)\r
241             Value = GetHelpTextList(Item.HelpTextList)\r
242             NewValue = Item.TokenSpaceGuidCName + '.' + Item.CName\r
243             if Item.DefaultValue != '':\r
244                 NewValue = NewValue + '|' + Item.DefaultValue\r
245             Value.append(NewValue)\r
246             GenMetaDatSectionItem(Key, Value, InfList)\r
247                \r
248         for Item in Module.Sources:\r
249             Key = 'Sources.' + GetStringOfList(Item.SupArchList)\r
250             Value = GetHelpTextList(Item.HelpTextList)\r
251             NewValue = Item.SourceFile\r
252             if Item.ToolChainFamily != '':\r
253                 NewValue = NewValue + '|' + Item.ToolChainFamily\r
254             if Item.TagName != '':\r
255                 NewValue = NewValue + '|' + Item.TagName\r
256             if Item.ToolCode != '':\r
257                 NewValue = NewValue + '|' + Item.ToolCode\r
258             if Item.FeatureFlag != '':\r
259                 NewValue = NewValue + '|' + Item.FeatureFlag\r
260             Value.append(NewValue)\r
261             if Item.HelpText != '':\r
262                 SectionHeaderCommentDict[Key] = Item.HelpText\r
263             GenMetaDatSectionItem(Key, Value, InfList)\r
264         \r
265         for Item in Module.Guids:\r
266             Key = 'Guids.' + GetStringOfList(Item.SupArchList)\r
267             Value = GetHelpTextList(Item.HelpTextList)\r
268             Value.append(Item.CName)\r
269             GenMetaDatSectionItem(Key, Value, InfList)\r
270         \r
271         for Item in Module.Protocols:\r
272             Key = 'Protocols.' + GetStringOfList(Item.SupArchList)\r
273             Value = GetHelpTextList(Item.HelpTextList)\r
274             Value.append(Item.CName)\r
275             GenMetaDatSectionItem(Key, Value, InfList)\r
276         \r
277         for Item in Module.Ppis:\r
278             Key = 'Ppis.' + GetStringOfList(Item.SupArchList)\r
279             Value = GetHelpTextList(Item.HelpTextList)\r
280             Value.append(Item.CName)\r
281             GenMetaDatSectionItem(Key, Value, InfList)\r
282         \r
283         if Module.PeiDepex:\r
284             Key = 'Depex'\r
285             Value = Module.PeiDepex.Depex\r
286             GenMetaDatSectionItem(Key, Value, InfList)\r
287         \r
288         if Module.DxeDepex:\r
289             Key = 'Depex'\r
290             Value = Module.DxeDepex.Depex\r
291             GenMetaDatSectionItem(Key, Value, InfList)\r
292         \r
293         if Module.SmmDepex:\r
294             Key = 'Depex'\r
295             Value = Module.SmmDepex.Depex\r
296             GenMetaDatSectionItem(Key, Value, InfList)\r
297         \r
298         for Item in Module.Binaries:\r
299             Key = 'Binaries.' + GetStringOfList(Item.SupArchList)\r
300             Value = GetHelpTextList(Item.HelpTextList)\r
301             NewValue = Item.FileType + '|' + Item.BinaryFile + '|' + Item.Target\r
302             if Item.FeatureFlag != '':\r
303                 NewValue = NewValue + '|' + Item.FeatureFlag\r
304             Value.append(NewValue)\r
305             GenMetaDatSectionItem(Key, Value, InfList)\r
306 \r
307         # Transfer Module to Inf\r
308         for Key in InfList:\r
309             if Key in SectionHeaderCommentDict:\r
310                 List = SectionHeaderCommentDict[Key].split('\r')\r
311                 for Item in List:\r
312                     Inf = Inf + Item + '\n'\r
313             Inf = Inf + '[' + Key + ']' + '\n'\r
314             for Value in InfList[Key]:\r
315                 if type(Value) == type([]):\r
316                     for SubValue in Value:\r
317                         Inf = Inf + '  ' + SubValue + '\n'\r
318                 else:\r
319                     Inf = Inf + '  ' + Value + '\n'\r
320             Inf = Inf + '\n'\r
321         \r
322         return Inf\r
323     \r
324     \r
325     ## Transfer to Module Object\r
326     # \r
327     # Transfer all contents of an Inf file to a standard Module Object\r
328     #\r
329     def InfToModule(self):\r
330         # Init global information for the file\r
331         ContainerFile = self.Identification.FullPath\r
332         \r
333         # Generate Module Header\r
334         self.GenModuleHeader(ContainerFile)\r
335         \r
336         # Generate BuildOptions\r
337         self.GenBuildOptions(ContainerFile)\r
338         \r
339         # Generate Includes\r
340         self.GenIncludes(ContainerFile)\r
341         \r
342         # Generate LibraryClasses\r
343         self.GenLibraryClasses(ContainerFile)\r
344         \r
345         # Generate Packages\r
346         self.GenPackages(ContainerFile)\r
347         \r
348         # Generate Pcds\r
349         self.GenPcds(ContainerFile)\r
350         \r
351         # Generate Sources\r
352         self.GenSources(ContainerFile)\r
353         \r
354         # Generate Guids\r
355         self.GenGuidProtocolPpis(DataType.TAB_GUIDS, ContainerFile)\r
356 \r
357         # Generate Protocols\r
358         self.GenGuidProtocolPpis(DataType.TAB_PROTOCOLS, ContainerFile)\r
359 \r
360         # Generate Ppis\r
361         self.GenGuidProtocolPpis(DataType.TAB_PPIS, ContainerFile)\r
362         \r
363         # Generate Depexes\r
364         self.GenDepexes(ContainerFile)\r
365         \r
366         # Generate Binaries\r
367         self.GenBinaries(ContainerFile)\r
368         \r
369         # Init MiscFiles\r
370         self.GenMiscFiles(ContainerFile)\r
371 \r
372     ## GenMiscFiles\r
373     #\r
374     def GenMiscFiles(self, ContainerFile):\r
375         MiscFiles = MiscFileClass()\r
376         MiscFiles.Name = 'ModuleFiles'\r
377         for Item in GetFiles(os.path.dirname(ContainerFile), ['CVS', '.svn'], False):\r
378             File = CommonClass.FileClass()\r
379             File.Filename = Item\r
380             MiscFiles.Files.append(File)\r
381         self.Module.MiscFiles = MiscFiles\r
382 \r
383     ## Load Inf file\r
384     #\r
385     # Load the file if it exists\r
386     #\r
387     # @param Filename:  Input value for filename of Inf file\r
388     #\r
389     def LoadInfFile(self, Filename):     \r
390         # Insert a record for file\r
391         Filename = NormPath(Filename)\r
392         \r
393         self.Identification.FullPath = Filename\r
394         (self.Identification.RelaPath, self.Identification.FileName) = os.path.split(Filename)\r
395         if self.Identification.FullPath.find(self.WorkspaceDir) > -1:\r
396             self.Identification.ModulePath = os.path.dirname(self.Identification.FullPath[len(self.WorkspaceDir) + 1:])        \r
397         if self.PackageDir:\r
398             self.Identification.PackagePath = self.PackageDir\r
399             if self.Identification.ModulePath.find(self.PackageDir) == 0:\r
400                 self.Identification.ModulePath = self.Identification.ModulePath[len(self.PackageDir) + 1:]\r
401         \r
402         # Init common datas\r
403         IfDefList, SectionItemList, CurrentSection, ArchList, ThirdList, IncludeFiles = \\r
404         [], [], TAB_UNKNOWN, [], [], []\r
405         LineNo = 0\r
406         \r
407         # Parse file content\r
408         IsFindBlockComment = False\r
409         ReservedLine = ''\r
410         Comment = ''\r
411         for Line in open(Filename, 'r'):\r
412             LineNo = LineNo + 1\r
413             # Remove comment block\r
414             if Line.find(TAB_COMMENT_R8_START) > -1:\r
415                 ReservedLine = GetSplitValueList(Line, TAB_COMMENT_R8_START, 1)[0]\r
416                 if ReservedLine.strip().startswith(TAB_COMMENT_SPLIT):\r
417                     Comment = Comment + Line.strip() + '\n'\r
418                     ReservedLine = ''\r
419                 else:\r
420                     Comment = Comment + Line[len(ReservedLine):] + '\n'\r
421                 IsFindBlockComment = True\r
422                 if not ReservedLine:\r
423                     continue\r
424             if Line.find(TAB_COMMENT_R8_END) > -1:\r
425                 Comment = Comment + Line[:Line.find(TAB_COMMENT_R8_END) + len(TAB_COMMENT_R8_END)] + '\n'\r
426                 Line = ReservedLine + GetSplitValueList(Line, TAB_COMMENT_R8_END, 1)[1]\r
427                 ReservedLine = ''\r
428                 IsFindBlockComment = False\r
429             if IsFindBlockComment:\r
430                 Comment = Comment + Line.strip() + '\n'\r
431                 continue\r
432             \r
433             # Remove comments at tail and remove spaces again\r
434             if Line.strip().startswith(TAB_COMMENT_SPLIT) or Line.strip().startswith('--/'):\r
435                 Comment = Comment + Line.strip() + '\n'\r
436             Line = CleanString(Line)\r
437             if Line == '':\r
438                 continue\r
439             \r
440             ## Find a new section tab\r
441             # First insert previous section items\r
442             # And then parse the content of the new section\r
443             if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END):\r
444                 if Line[1:3] == "--":\r
445                     continue\r
446                 Model = Section[CurrentSection.upper()]\r
447                 # Insert items data of previous section\r
448                 InsertSectionItems(Model, CurrentSection, SectionItemList, ArchList, ThirdList, self.RecordSet)\r
449                 \r
450                 # Parse the new section\r
451                 SectionItemList = []\r
452                 ArchList = []\r
453                 ThirdList = []\r
454                 \r
455                 CurrentSection = ''\r
456                 LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT)\r
457                 for Item in LineList:\r
458                     ItemList = GetSplitValueList(Item, TAB_SPLIT)\r
459                     if CurrentSection == '':\r
460                         CurrentSection = ItemList[0]\r
461                     else:\r
462                         if CurrentSection != ItemList[0]:\r
463                             EdkLogger.error("Parser", PARSER_ERROR, "Different section names '%s' and '%s' are found in one section definition, this is not allowed." % (CurrentSection, ItemList[0]), File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError)\r
464                     if CurrentSection.upper() not in self.KeyList:\r
465                         RaiseParserError(Line, CurrentSection, Filename, '', LineNo)\r
466                     ItemList.append('')\r
467                     ItemList.append('')\r
468                     if len(ItemList) > 5:\r
469                         RaiseParserError(Line, CurrentSection, Filename, '', LineNo)\r
470                     else:\r
471                         if ItemList[1] != '' and ItemList[1].upper() not in ARCH_LIST_FULL:\r
472                             EdkLogger.error("Parser", PARSER_ERROR, "Invalid Arch definition '%s' found" % ItemList[1], File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError)\r
473                         ArchList.append(ItemList[1].upper())\r
474                         ThirdList.append(ItemList[2])\r
475 \r
476                 if Comment:\r
477                     if Comment.endswith('\n'):\r
478                         Comment = Comment[:len(Comment) - len('\n')]\r
479                     self.SectionHeaderCommentDict[Section[CurrentSection.upper()]] = Comment\r
480                     Comment = ''\r
481                 continue\r
482             \r
483             # Not in any defined section\r
484             if CurrentSection == TAB_UNKNOWN:\r
485                 ErrorMsg = "%s is not in any defined section" % Line\r
486                 EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError)\r
487 \r
488             # Add a section item\r
489             SectionItemList.append([Line, LineNo, Comment])\r
490             Comment = ''\r
491             # End of parse\r
492         #End of For\r
493         \r
494         # Insert items data of last section\r
495         Model = Section[CurrentSection.upper()]\r
496         InsertSectionItems(Model, CurrentSection, SectionItemList, ArchList, ThirdList, self.RecordSet)\r
497         if Comment != '':\r
498             self.SectionHeaderCommentDict[Model] = Comment\r
499             Comment = ''\r
500 \r
501     ## Show detailed information of Module\r
502     #\r
503     # Print all members and their values of Module class\r
504     #\r
505     def ShowModule(self):\r
506         M = self.Module\r
507         print 'Filename =', M.ModuleHeader.FileName\r
508         print 'FullPath =', M.ModuleHeader.FullPath\r
509         print 'RelaPath =', M.ModuleHeader.RelaPath\r
510         print 'PackagePath =', M.ModuleHeader.PackagePath\r
511         print 'ModulePath =', M.ModuleHeader.ModulePath\r
512         print 'CombinePath =', M.ModuleHeader.CombinePath\r
513         \r
514         print 'BaseName =', M.ModuleHeader.Name\r
515         print 'Guid =', M.ModuleHeader.Guid\r
516         print 'Version =', M.ModuleHeader.Version\r
517 \r
518         print '\nIncludes ='\r
519         for Item in M.Includes:\r
520             print Item.FilePath, Item.SupArchList\r
521         print '\nLibraryClasses ='\r
522         for Item in M.LibraryClasses:\r
523             print Item.LibraryClass, Item.RecommendedInstance, Item.RecommendedInstanceGuid, Item.RecommendedInstanceVersion, Item.FeatureFlag, Item.SupModuleList, Item.SupArchList, Item.Define\r
524         print '\nPackageDependencies ='\r
525         for Item in M.PackageDependencies:\r
526             print Item.FilePath, Item.SupArchList, Item.FeatureFlag\r
527         print '\nPcds ='\r
528         for Item in M.PcdCodes:\r
529             print '\tCName=',Item.CName, 'TokenSpaceGuidCName=', Item.TokenSpaceGuidCName, 'DefaultValue=', Item.DefaultValue, 'ItemType=', Item.ItemType, Item.SupArchList\r
530         print '\nSources ='\r
531         for Source in M.Sources:\r
532             print Source.SourceFile, 'Fam=', Source.ToolChainFamily, 'Pcd=', Source.FeatureFlag, 'Tag=', Source.TagName, 'ToolCode=', Source.ToolCode, Source.SupArchList\r
533         print '\nGuids ='\r
534         for Item in M.Guids:\r
535             print Item.CName, Item.SupArchList, Item.FeatureFlag\r
536         print '\nProtocols ='\r
537         for Item in M.Protocols:\r
538             print Item.CName, Item.SupArchList, Item.FeatureFlag\r
539         print '\nPpis ='\r
540         for Item in M.Ppis:\r
541             print Item.CName, Item.SupArchList, Item.FeatureFlag\r
542         print '\nDepex ='\r
543         for Item in M.Depex:\r
544             print Item.Depex, Item.SupArchList, Item.Define\r
545         print '\nBinaries ='\r
546         for Binary in M.Binaries:\r
547             print 'Type=', Binary.FileType, 'Target=', Binary.Target, 'Name=', Binary.BinaryFile, 'FeatureFlag=', Binary.FeatureFlag, 'SupArchList=', Binary.SupArchList\r
548         print '\n*** FileList ***'\r
549         for Item in M.MiscFiles.Files:\r
550             print Item.Filename\r
551         print '****************\n'\r
552 \r
553     ## Convert [Defines] section content to ModuleHeaderClass\r
554     #\r
555     # Convert [Defines] section content to ModuleHeaderClass\r
556     #\r
557     # @param Defines        The content under [Defines] section\r
558     # @param ModuleHeader   An object of ModuleHeaderClass\r
559     # @param Arch           The supported ARCH\r
560     #\r
561     def GenModuleHeader(self, ContainerFile):\r
562         EdkLogger.debug(2, "Generate ModuleHeader ...")\r
563         # Update all defines item in database\r
564         RecordSet = self.RecordSet[MODEL_META_DATA_HEADER]\r
565         \r
566         ModuleHeader = ModuleHeaderClass()\r
567         ModuleExtern = ModuleExternClass()\r
568         OtherDefines = []\r
569         for Record in RecordSet:\r
570             ValueList = GetSplitValueList(Record[0], TAB_EQUAL_SPLIT)\r
571             if len(ValueList) != 2:\r
572                 OtherDefines.append(Record[0])\r
573             else:\r
574                 Name = ValueList[0]\r
575                 Value = ValueList[1]\r
576                 if Name == TAB_INF_DEFINES_BASE_NAME:\r
577                     ModuleHeader.Name = Value\r
578                     ModuleHeader.BaseName = Value\r
579                 elif Name == TAB_INF_DEFINES_FILE_GUID:\r
580                     ModuleHeader.Guid = Value\r
581                 elif Name == TAB_INF_DEFINES_VERSION_STRING:\r
582                     ModuleHeader.Version = Value\r
583                 elif Name == TAB_INF_DEFINES_PCD_IS_DRIVER:\r
584                     ModuleHeader.PcdIsDriver = Value\r
585                 elif Name == TAB_INF_DEFINES_MODULE_TYPE:\r
586                     ModuleHeader.ModuleType = Value\r
587                 elif Name in (TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION, TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION):\r
588                     ModuleHeader.UefiSpecificationVersion = Value\r
589                 elif Name == TAB_INF_DEFINES_PI_SPECIFICATION_VERSION:\r
590                     ModuleHeader.PiSpecificationVersion = Value\r
591                 elif Name == TAB_INF_DEFINES_ENTRY_POINT:\r
592                     ModuleExtern.EntryPoint = Value\r
593                 elif Name == TAB_INF_DEFINES_UNLOAD_IMAGE:\r
594                     ModuleExtern.UnloadImage = Value\r
595                 elif Name == TAB_INF_DEFINES_CONSTRUCTOR:\r
596                     ModuleExtern.Constructor = Value\r
597                 elif Name == TAB_INF_DEFINES_DESTRUCTOR:\r
598                     ModuleExtern.Destructor = Value\r
599                 else:\r
600                     OtherDefines.append(Record[0])\r
601         ModuleHeader.FileName = self.Identification.FileName\r
602         ModuleHeader.FullPath = self.Identification.FullPath\r
603         ModuleHeader.RelaPath = self.Identification.RelaPath\r
604         ModuleHeader.PackagePath = self.Identification.PackagePath\r
605         ModuleHeader.ModulePath = self.Identification.ModulePath\r
606         ModuleHeader.CombinePath = os.path.normpath(os.path.join(ModuleHeader.PackagePath, ModuleHeader.ModulePath, ModuleHeader.FileName))\r
607 \r
608         if MODEL_META_DATA_HEADER in self.SectionHeaderCommentDict:\r
609             ModuleHeader.Description = self.SectionHeaderCommentDict[MODEL_META_DATA_HEADER]\r
610         self.Module.ModuleHeader = ModuleHeader\r
611         self.Module.Externs.append(ModuleExtern)\r
612         UE = self.Module.UserExtensions\r
613         if UE == None:\r
614             UE = UserExtensionsClass()\r
615         UE.Defines = OtherDefines\r
616         self.Module.UserExtensions = UE\r
617         \r
618     ## GenBuildOptions\r
619     #\r
620     # Gen BuildOptions of Inf\r
621     # [<Family>:]<ToolFlag>=Flag\r
622     #\r
623     # @param ContainerFile: The Inf file full path \r
624     #\r
625     def GenBuildOptions(self, ContainerFile):\r
626         EdkLogger.debug(2, "Generate %s ..." % TAB_BUILD_OPTIONS)\r
627         BuildOptions = {}\r
628         # Get all BuildOptions\r
629         RecordSet = self.RecordSet[MODEL_META_DATA_BUILD_OPTION]\r
630         UE = self.Module.UserExtensions\r
631         if UE == None:\r
632             UE = UserExtensionsClass()\r
633         for Record in RecordSet:\r
634             UE.BuildOptions.append(Record[0])\r
635         self.Module.UserExtensions = UE\r
636         \r
637     ## GenIncludes\r
638     #\r
639     # Gen Includes of Inf\r
640     # \r
641     # @param ContainerFile: The Inf file full path \r
642     #\r
643     def GenIncludes(self, ContainerFile):\r
644         EdkLogger.debug(2, "Generate %s ..." % TAB_INCLUDES)\r
645         Includes = sdict()\r
646         # Get all Includes\r
647         RecordSet = self.RecordSet[MODEL_EFI_INCLUDE]\r
648         for Record in RecordSet:\r
649             Include = IncludeClass()\r
650             Include.FilePath = Record[0]\r
651             Include.SupArchList = Record[1]\r
652             if GenerateHelpText(Record[5], ''):\r
653                 Include.HelpTextList.append(GenerateHelpText(Record[5], ''))\r
654             self.Module.Includes.append(Include)\r
655             #self.Module.FileList.extend(GetFiles(os.path.normpath(os.path.join(self.Identification.FileRelativePath, Include.FilePath)), ['CVS', '.svn']))\r
656     \r
657     ## GenLibraryClasses\r
658     #\r
659     # Get LibraryClass of Inf\r
660     # <LibraryClassKeyWord>|<LibraryInstance>\r
661     #\r
662     # @param ContainerFile: The Inf file full path \r
663     #\r
664     def GenLibraryClasses(self, ContainerFile):\r
665         EdkLogger.debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES)\r
666         LibraryClasses = {}\r
667         # Get all LibraryClasses\r
668         RecordSet = self.RecordSet[MODEL_EFI_LIBRARY_CLASS]\r
669         for Record in RecordSet:\r
670             (LibClassName, LibClassIns, Pcd, SupModelList) = GetLibraryClassOfInf([Record[0], Record[4]], ContainerFile, self.WorkspaceDir, Record[2])            \r
671             LibraryClass = CommonClass.LibraryClassClass()\r
672             LibraryClass.LibraryClass = LibClassName\r
673             LibraryClass.RecommendedInstance = LibClassIns\r
674             LibraryClass.FeatureFlag = Pcd\r
675             LibraryClass.SupArchList = Record[1]\r
676             LibraryClass.SupModuleList = Record[4]\r
677             if GenerateHelpText(Record[5], ''):\r
678                 LibraryClass.HelpTextList.append(GenerateHelpText(Record[5], ''))\r
679             self.Module.LibraryClasses.append(LibraryClass)\r
680 \r
681     ## GenPackages\r
682     #\r
683     # Gen Packages of Inf\r
684     # \r
685     # @param ContainerFile: The Inf file full path \r
686     #\r
687     def GenPackages(self, ContainerFile):\r
688         EdkLogger.debug(2, "Generate %s ..." % TAB_PACKAGES)\r
689         Packages = {}\r
690         # Get all Packages\r
691         RecordSet = self.RecordSet[MODEL_META_DATA_PACKAGE]\r
692         for Record in RecordSet:\r
693             (PackagePath, Pcd) = GetPackage(Record[0], ContainerFile, self.WorkspaceDir, Record[2])\r
694             Package = ModulePackageDependencyClass()\r
695             Package.FilePath = NormPath(PackagePath)\r
696             Package.SupArchList = Record[1]\r
697             Package.FeatureFlag = Pcd\r
698             if GenerateHelpText(Record[5], ''):\r
699                 Package.HelpTextList.append(GenerateHelpText(Record[5], ''))\r
700             self.Module.PackageDependencies.append(Package)\r
701     \r
702     def AddPcd(self, CName, TokenSpaceGuidCName, DefaultValue, ItemType, Arch, HelpTextList):\r
703         Pcd = PcdClass()\r
704         Pcd.CName = CName\r
705         Pcd.TokenSpaceGuidCName = TokenSpaceGuidCName\r
706         Pcd.DefaultValue = DefaultValue\r
707         Pcd.ItemType = ItemType\r
708         Pcd.SupArchList = Arch\r
709         if GenerateHelpText(HelpTextList, ''):\r
710             Pcd.HelpTextList.append(GenerateHelpText(HelpTextList, ''))\r
711         self.Module.PcdCodes.append(Pcd)\r
712     \r
713     ## GenPcds\r
714     #\r
715     # Gen Pcds of Inf\r
716     # <TokenSpaceGuidCName>.<PcdCName>[|<Value>]\r
717     #\r
718     # @param ContainerFile: The Dec file full path \r
719     #\r
720     def GenPcds(self, ContainerFile):\r
721         EdkLogger.debug(2, "Generate %s ..." % TAB_PCDS)\r
722         Pcds = {}\r
723         PcdToken = {}\r
724         \r
725         # Get all Pcds\r
726         RecordSet1 = self.RecordSet[MODEL_PCD_FIXED_AT_BUILD]\r
727         RecordSet2 = self.RecordSet[MODEL_PCD_PATCHABLE_IN_MODULE]\r
728         RecordSet3 = self.RecordSet[MODEL_PCD_FEATURE_FLAG]\r
729         RecordSet4 = self.RecordSet[MODEL_PCD_DYNAMIC_EX]\r
730         RecordSet5 = self.RecordSet[MODEL_PCD_DYNAMIC]\r
731         \r
732         # Go through each arch\r
733         for Record in RecordSet1:\r
734             (TokenSpaceGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], TAB_PCDS_FIXED_AT_BUILD, ContainerFile, Record[2])\r
735             self.AddPcd(TokenName, TokenSpaceGuidCName, Value, Type, Record[1], Record[5])\r
736         for Record in RecordSet2:\r
737             (TokenSpaceGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], TAB_PCDS_PATCHABLE_IN_MODULE, ContainerFile, Record[2])\r
738             self.AddPcd(TokenName, TokenSpaceGuidCName, Value, Type, Record[1], Record[5])\r
739         for Record in RecordSet3:\r
740             (TokenSpaceGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], TAB_PCDS_FEATURE_FLAG, ContainerFile, Record[2])\r
741             self.AddPcd(TokenName, TokenSpaceGuidCName, Value, Type, Record[1], Record[5])\r
742         for Record in RecordSet4:\r
743             (TokenSpaceGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], TAB_PCDS_DYNAMIC_EX, ContainerFile, Record[2])\r
744             self.AddPcd(TokenName, TokenSpaceGuidCName, Value, Type, Record[1], Record[5])\r
745         for Record in RecordSet5:\r
746             (TokenSpaceGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], '', ContainerFile, Record[2])\r
747             self.AddPcd(TokenName, TokenSpaceGuidCName, Value, Type, Record[1], Record[5])\r
748         \r
749     ## GenSources\r
750     #\r
751     # Gen Sources of Inf\r
752     # <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]\r
753     #\r
754     # @param ContainerFile: The Dec file full path \r
755     #\r
756     def GenSources(self, ContainerFile):\r
757         EdkLogger.debug(2, "Generate %s ..." % TAB_SOURCES)\r
758         Sources = {}\r
759         \r
760         # Get all Sources\r
761         RecordSet = self.RecordSet[MODEL_EFI_SOURCE_FILE]\r
762         for Record in RecordSet:\r
763             (Filename, Family, TagName, ToolCode, Pcd) = GetSource(Record[0], ContainerFile, self.Identification.RelaPath, Record[2])\r
764             Source = ModuleSourceFileClass(Filename, TagName, ToolCode, Family, Pcd, Record[1])\r
765             if GenerateHelpText(Record[5], ''):\r
766                 Source.HelpTextList.append(GenerateHelpText(Record[5], ''))\r
767             if MODEL_EFI_SOURCE_FILE in self.SectionHeaderCommentDict:\r
768                 Source.HelpText = self.SectionHeaderCommentDict[MODEL_EFI_SOURCE_FILE]\r
769             self.Module.Sources.append(Source)\r
770             #self.Module.FileList.append(os.path.normpath(os.path.join(self.Identification.RelaPath, Filename)))\r
771 \r
772     ## GenDepexes\r
773     #\r
774     # Gen Depex of Inf\r
775     #\r
776     # @param ContainerFile: The Inf file full path \r
777     #\r
778     def GenDepexes(self, ContainerFile):\r
779         EdkLogger.debug(2, "Generate %s ..." % TAB_DEPEX)\r
780         Depex = {}\r
781         # Get all Depexes\r
782         RecordSet = self.RecordSet[MODEL_EFI_DEPEX]\r
783         DepexString = ''\r
784         for Record in RecordSet:\r
785             DepexString = DepexString + Record[0] + '\n'\r
786         Dep = ModuleDepexClass()\r
787         if DepexString.endswith('\n'):\r
788             DepexString = DepexString[:len(DepexString) - len('\n')]\r
789         Dep.Depex = DepexString\r
790         if self.Module.ModuleHeader.ModuleType in ['DXE_SMM_DRIVER']:\r
791             self.Module.SmmDepex = Dep\r
792         elif self.Module.ModuleHeader.ModuleType in ['PEI_CORE', 'PEIM']:\r
793             self.Module.PeiDepex = Dep\r
794         else:\r
795             self.Module.DxeDepex = Dep\r
796 #        for Record in RecordSet:\r
797 #            \r
798 #            Dep = ModuleDepexClass()\r
799 #            Dep.Depex = Record[0]\r
800 #            Dep.SupArchList = Record[1]\r
801 #            if GenerateHelpText(Record[5], ''):\r
802 #                Dep.HelpTextList.append(GenerateHelpText(Record[5], ''))\r
803 #            DepexString = DepexString + Dep\r
804 #            List.append(Dep)\r
805 #        self.Module.Depex = List\r
806 #        if self.Module.ModuleHeader.ModuleType in ['DXE_SMM_DRIVER']:\r
807 #            self.Module.SmmDepex = List\r
808 #        elif self.Module.ModuleHeader.ModuleType in ['PEI_CORE', 'PEIM']:\r
809 #            self.Module.PeiDepex = List\r
810 #        else:\r
811 #            self.Module.DxeDepex = List\r
812 \r
813     ## GenBinaries\r
814     #\r
815     # Gen Binary of Inf\r
816     # <FileType>|<Filename>|<Target>[|<TokenSpaceGuidCName>.<PcdCName>]\r
817     #\r
818     # @param ContainerFile: The Dec file full path \r
819     #\r
820     def GenBinaries(self, ContainerFile):\r
821         EdkLogger.debug(2, "Generate %s ..." % TAB_BINARIES)\r
822         Binaries = {}\r
823         \r
824         # Get all Guids\r
825         RecordSet = self.RecordSet[MODEL_EFI_BINARY_FILE]\r
826         for Record in RecordSet:\r
827             (FileType, Filename, Target, Pcd) = GetBinary(Record[0], ContainerFile, self.Identification.RelaPath, Record[2])\r
828             Binary = ModuleBinaryFileClass(Filename, FileType, Target, Pcd, Record[1])\r
829             if GenerateHelpText(Record[5], ''):\r
830                 Binary.HelpTextList.append(GenerateHelpText(Record[5], ''))\r
831             self.Module.Binaries.append(Binary)\r
832             #self.Module.FileList.append(os.path.normpath(os.path.join(self.Identification.RelaPath, Filename)))\r
833         \r
834     ## GenGuids\r
835     #\r
836     # Gen Guids of Inf\r
837     # <CName>=<GuidValue>\r
838     #\r
839     # @param ContainerFile: The Inf file full path \r
840     #\r
841     def GenGuidProtocolPpis(self, Type, ContainerFile):\r
842         EdkLogger.debug(2, "Generate %s ..." % Type)\r
843         Lists = {}\r
844         # Get all Items\r
845         if Type == TAB_GUIDS:\r
846             ListMember = self.Module.Guids\r
847         elif Type == TAB_PROTOCOLS:\r
848             ListMember = self.Module.Protocols\r
849         elif Type == TAB_PPIS:\r
850             ListMember = self.Module.Ppis\r
851 \r
852         RecordSet = self.RecordSet[Section[Type.upper()]]\r
853         for Record in RecordSet:\r
854             (Name, Value) = GetGuidsProtocolsPpisOfInf(Record[0], Type, ContainerFile, Record[2])\r
855             ListClass = GuidProtocolPpiCommonClass()\r
856             ListClass.CName = Name\r
857             ListClass.SupArchList = Record[1]\r
858             ListClass.FeatureFlag = Value\r
859             if GenerateHelpText(Record[5], ''):\r
860                 ListClass.HelpTextList.append(GenerateHelpText(Record[5], ''))\r
861             ListMember.append(ListClass)\r
862        \r
863 ##\r
864 #\r
865 # This acts like the main() function for the script, unless it is 'import'ed into another\r
866 # script.\r
867 #\r
868 if __name__ == '__main__':\r
869     EdkLogger.Initialize()\r
870     EdkLogger.SetLevel(EdkLogger.QUIET)\r
871         \r
872     W = os.getenv('WORKSPACE')\r
873     F = os.path.join(W, 'MdeModulePkg/Application/HelloWorld/HelloWorld.inf')\r
874     \r
875     P = Inf(os.path.normpath(F), True, W, 'MdeModulePkg')\r
876     P.ShowModule()\r
877     print P.ModuleToInf(P.Module)\r