]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py
Sync BaseTools Branch (version r2271) to EDKII main trunk.
[mirror_edk2.git] / BaseTools / Source / Python / UPT / PomAdapter / DecPomAlignment.py
1 ## @file DecPomAlignment.py
2 # This file contained the adapter for convert INF parser object to POM Object
3 #
4 # Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
5 #
6 # This program and the accompanying materials are licensed and made available
7 # under the terms and conditions of the BSD License which accompanies this
8 # distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
10 #
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 #
14
15 '''
16 DecPomAlignment
17 '''
18
19 ##
20 # Import Modules
21 #
22 import os.path
23 from os import sep
24 import platform
25
26 import Logger.Log as Logger
27 from Logger import StringTable as ST
28 from Logger.ToolError import UPT_MUL_DEC_ERROR
29
30 from Library.Parsing import NormPath
31 from Library.DataType import ARCH_LIST
32 from Library.DataType import TAB_GUIDS
33 from Library.DataType import TAB_PROTOCOLS
34 from Library.DataType import TAB_PPIS
35 from Library.DataType import TAB_DEC_DEFINES_PACKAGE_NAME
36 from Library.DataType import TAB_DEC_DEFINES_PACKAGE_GUID
37 from Library.DataType import TAB_DEC_DEFINES_PACKAGE_VERSION
38 from Library.DataType import TAB_DEC_DEFINES_DEC_SPECIFICATION
39 from Library.DataType import TAB_ARCH_COMMON
40 from Library.CommentParsing import ParseHeaderCommentSection
41 from Library.DataType import TAB_INCLUDES
42 from Library.CommentParsing import ParseGenericComment
43 from Library.DataType import TAB_LIBRARY_CLASSES
44 from Library.DataType import TAB_PCDS
45 from Library.DataType import TAB_PCDS_FIXED_AT_BUILD_NULL
46 from Library.DataType import TAB_PCDS_PATCHABLE_IN_MODULE_NULL
47 from Library.DataType import TAB_PCDS_FEATURE_FLAG_NULL
48 from Library.DataType import TAB_PCDS_DYNAMIC_EX_NULL
49 from Library.DataType import TAB_PCDS_DYNAMIC_NULL
50 from Library.DataType import TAB_PTR_TYPE_PCD
51 from Library.DataType import ITEM_UNDEFINED
52 from Library.CommentParsing import ParseDecPcdGenericComment
53 from Library.CommentParsing import ParseDecPcdTailComment
54 from Library.Misc import GetFiles
55 from Library.Misc import Sdict
56 from Parser.DecParser import Dec
57
58 from Object.POM.PackageObject import PackageObject
59 from Object.POM.CommonObject import UserExtensionObject
60 from Object.POM.CommonObject import IncludeObject
61 from Object.POM.CommonObject import GuidObject
62 from Object.POM.CommonObject import ProtocolObject
63 from Object.POM.CommonObject import PpiObject
64 from Object.POM.CommonObject import LibraryClassObject
65 from Object.POM.CommonObject import PcdObject
66 from Object.POM.CommonObject import TextObject
67
68
69 ## DecPomAlignment
70 #
71 # Inherited from PackageObject
72 #
73 class DecPomAlignment(PackageObject):
74 def __init__(self, Filename, WorkspaceDir = None, CheckMulDec = False):
75 PackageObject.__init__(self)
76 self.UserExtensions = ''
77 self.WorkspaceDir = WorkspaceDir
78 self.SupArchList = ARCH_LIST
79 self.CheckMulDec = CheckMulDec
80 self.DecParser = None
81
82 #
83 # Load Dec file
84 #
85 self.LoadDecFile(Filename)
86
87 #
88 # Transfer to Package Object if IsToPackage is True
89 #
90 self.DecToPackage()
91
92 ## Load Dec file
93 #
94 # Load the file if it exists
95 #
96 # @param Filename: Input value for filename of Dec file
97 #
98 def LoadDecFile(self, Filename):
99 #
100 # Insert a record for file
101 #
102 Filename = NormPath(Filename)
103 (Path, Name) = os.path.split(Filename)
104 self.SetFullPath(Filename)
105 self.SetRelaPath(Path)
106 self.SetFileName(Name)
107 self.SetPackagePath(Path[Path.upper().find(self.WorkspaceDir.upper()) + len(self.WorkspaceDir) + 1:])
108 self.SetCombinePath(Filename[Filename.upper().find(self.WorkspaceDir.upper()) + len(self.WorkspaceDir) + 1:])
109
110 self.DecParser = Dec(Filename)
111
112 ## Transfer to Package Object
113 #
114 # Transfer all contents of a Dec file to a standard Package Object
115 #
116 def DecToPackage(self):
117 #
118 # Init global information for the file
119 #
120 ContainerFile = self.GetFullPath()
121
122 #
123 # Generate Package Header
124 #
125 self.GenPackageHeader(ContainerFile)
126
127 #
128 # Generate Includes
129 #
130 self.GenIncludes(ContainerFile)
131
132 #
133 # Generate Guids
134 #
135 self.GenGuidProtocolPpis(TAB_GUIDS, ContainerFile)
136
137 #
138 # Generate Protocols
139 #
140 self.GenGuidProtocolPpis(TAB_PROTOCOLS, ContainerFile)
141
142 #
143 # Generate Ppis
144 #
145 self.GenGuidProtocolPpis(TAB_PPIS, ContainerFile)
146
147 #
148 # Generate LibraryClasses
149 #
150 self.GenLibraryClasses(ContainerFile)
151
152 #
153 # Generate Pcds
154 #
155 self.GenPcds(ContainerFile)
156
157 #
158 # Generate Module File list, will be used later on to generate
159 # distribution
160 #
161 self.GenModuleFileList(ContainerFile)
162
163 #
164 # Generate user extensions
165 #
166 self.GenUserExtensions()
167
168 ## Generate user extention
169 #
170 #
171 def GenUserExtensions(self):
172 UEObj = self.DecParser.GetUserExtensionSectionObject()
173 UEList = UEObj.GetAllUserExtensions()
174 for Item in UEList:
175 if not Item.UserString:
176 continue
177 UserExtension = UserExtensionObject()
178 UserId = Item.UserId
179 if UserId.startswith('"') and UserId.endswith('"'):
180 UserId = UserId[1:-1]
181 UserExtension.SetUserID(UserId)
182 Identifier = Item.IdString
183 if Identifier.startswith('"') and Identifier.endswith('"'):
184 Identifier = Identifier[1:-1]
185 UserExtension.SetIdentifier(Identifier)
186 UserExtension.SetStatement(Item.UserString)
187 UserExtension.SetSupArchList(
188 Item.ArchAndModuleType
189 )
190 self.SetUserExtensionList(
191 self.GetUserExtensionList() + [UserExtension]
192 )
193
194 ## Generate Package Header
195 #
196 # Gen Package Header of Dec as <Key> = <Value>
197 #
198 # @param ContainerFile: The Dec file full path
199 #
200 def GenPackageHeader(self, ContainerFile):
201 Logger.Debug(2, "Generate PackageHeader ...")
202 DefinesDict = {}
203
204 #
205 # Update all defines item in database
206 #
207 DefObj = self.DecParser.GetDefineSectionObject()
208 for Item in DefObj.GetDefines():
209 #
210 # put items into Dict except for PackageName, Guid, Version, DEC_SPECIFICATION
211 #
212 SkipItemList = [TAB_DEC_DEFINES_PACKAGE_NAME, \
213 TAB_DEC_DEFINES_PACKAGE_GUID, TAB_DEC_DEFINES_PACKAGE_VERSION, TAB_DEC_DEFINES_DEC_SPECIFICATION]
214 if Item.Key in SkipItemList:
215 continue
216 DefinesDict['%s = %s' % (Item.Key, Item.Value)] = TAB_ARCH_COMMON
217
218 self.SetBaseName(DefObj.GetPackageName())
219 self.SetVersion(DefObj.GetPackageVersion())
220 # self.SetName(DefObj.GetPackageName() + ' Version ' + \
221 # DefObj.GetPackageVersion())
222 self.SetName(os.path.splitext(self.GetFileName())[0])
223 self.SetGuid(DefObj.GetPackageGuid())
224
225 if DefinesDict:
226 UserExtension = UserExtensionObject()
227 UserExtension.SetDefinesDict(DefinesDict)
228 UserExtension.SetIdentifier('DefineModifiers')
229 UserExtension.SetUserID('EDK2')
230 self.SetUserExtensionList(
231 self.GetUserExtensionList() + [UserExtension]
232 )
233
234 #
235 # Get All header comment section information
236 #
237 Abstract, Description, Copyright, License = \
238 ParseHeaderCommentSection(self.DecParser.GetHeadComment(),
239 ContainerFile)
240 self.SetAbstract(Abstract)
241 self.SetDescription(Description)
242 self.SetCopyright(Copyright)
243 self.SetLicense(License)
244
245 ## GenIncludes
246 #
247 # Gen Includes of Dec
248 #
249 # @param ContainerFile: The Dec file full path
250 #
251 def GenIncludes(self, ContainerFile):
252 if ContainerFile:
253 pass
254 Logger.Debug(2, "Generate %s ..." % TAB_INCLUDES)
255 IncludesDict = Sdict()
256
257 IncObj = self.DecParser.GetIncludeSectionObject()
258 for Item in IncObj.GetAllIncludes():
259 IncludePath = os.path.normpath(Item.File)
260 if platform.system() != 'Windows':
261 IncludePath = IncludePath.replace('\\', '/')
262 if IncludePath in IncludesDict:
263 if Item.GetArchList() == [TAB_ARCH_COMMON] or IncludesDict[IncludePath] == [TAB_ARCH_COMMON]:
264 IncludesDict[IncludePath] = [TAB_ARCH_COMMON]
265 else:
266 IncludesDict[IncludePath] = IncludesDict[IncludePath] + Item.GetArchList()
267 else:
268 IncludesDict[IncludePath] = Item.GetArchList()
269
270 #
271 # get the standardIncludeFileList(industry), packageIncludeFileList
272 # (others) for PackageObject
273 #
274 PackagePath = os.path.split(self.GetFullPath())[0]
275 IncludePathList = \
276 [os.path.normpath(Path) + sep for Path in IncludesDict.keys()]
277 IncludePathList.sort()
278
279 #
280 # get a non-overlap set of include path, IncludePathList should be
281 # sorted, and path should be end with path seperator '\'
282 #
283 NonOverLapList = []
284 for Path1 in IncludePathList:
285 for Path2 in NonOverLapList:
286 if Path1.startswith(Path2):
287 break
288 else:
289 NonOverLapList.append(Path1)
290 #
291 # revert the list so the longest path shown first in list, also need
292 # to remove the extra path seperator '\'
293 # as this list is used to search the supported Arch info
294 #
295 for IndexN in range (0, len(IncludePathList)):
296 IncludePathList[IndexN] = os.path.normpath(IncludePathList[IndexN])
297 IncludePathList.sort()
298 IncludePathList.reverse()
299 #
300 # save the include path list for later usage
301 #
302 self.SetIncludePathList(IncludePathList)
303 StandardIncludeFileList = []
304 PackageIncludeFileList = []
305
306 IncludeFileList = []
307 for Path in NonOverLapList:
308 FileList = GetFiles(os.path.join(PackagePath, Path), ['CVS', '.svn'], False)
309 IncludeFileList += [os.path.normpath(os.path.join(Path, File)) for File in FileList]
310 for Includefile in IncludeFileList:
311 ExtName = os.path.splitext(Includefile)[1]
312 if ExtName.upper() == '.DEC' and self.CheckMulDec:
313 Logger.Error('MkPkg',
314 UPT_MUL_DEC_ERROR,
315 ST.ERR_MUL_DEC_ERROR%(os.path.dirname(ContainerFile),
316 os.path.basename(ContainerFile),
317 Includefile))
318
319 FileCombinePath = os.path.dirname(Includefile)
320 Include = IncludeObject()
321 for Path in IncludePathList:
322 if FileCombinePath.startswith(Path):
323 SupArchList = IncludesDict[Path]
324 break
325 Include.SetFilePath(Includefile)
326 Include.SetSupArchList(SupArchList)
327 if Includefile.find('IndustryStandard') != -1:
328 StandardIncludeFileList.append(Include)
329 else:
330 PackageIncludeFileList.append(Include)
331
332 self.SetStandardIncludeFileList(StandardIncludeFileList)
333
334 #
335 # put include path into the PackageIncludeFileList
336 #
337 PackagePathList = []
338 IncObj = self.DecParser.GetIncludeSectionObject()
339 for Item in IncObj.GetAllIncludes():
340 IncludePath = Item.File
341 Include = IncludeObject()
342 Include.SetFilePath(IncludePath)
343 Include.SetSupArchList(Item.GetArchList())
344 PackagePathList.append(Include)
345 self.SetPackageIncludeFileList(PackagePathList + PackageIncludeFileList)
346
347 ## GenPpis
348 #
349 # Gen Ppis of Dec
350 # <CName>=<GuidValue>
351 #
352 # @param ContainerFile: The Dec file full path
353 #
354 def GenGuidProtocolPpis(self, Type, ContainerFile):
355 if ContainerFile:
356 pass
357 Logger.Debug(2, "Generate %s ..." % Type)
358
359 Obj = None
360 Factory = None
361 if Type == TAB_GUIDS:
362 Obj = self.DecParser.GetGuidSectionObject()
363 def CreateGuidObject():
364 Object = GuidObject()
365 Object.SetGuidTypeList([])
366 Object.SetUsage(None)
367 Object.SetName(None)
368 return Object
369 Factory = CreateGuidObject
370 elif Type == TAB_PROTOCOLS:
371 Obj = self.DecParser.GetProtocolSectionObject()
372
373 def CreateProtocolObject():
374 return ProtocolObject()
375 Factory = CreateProtocolObject
376 elif Type == TAB_PPIS:
377 Obj = self.DecParser.GetPpiSectionObject()
378
379 def CreatePpiObject():
380 return PpiObject()
381 Factory = CreatePpiObject
382 else:
383 #
384 # Should not be here
385 #
386 return
387
388 DeclarationsList = []
389
390 #
391 # Go through each arch
392 #
393 for Item in Obj.GetGuidStyleAllItems():
394 Name = Item.GuidCName
395 Value = Item.GuidString
396 HelpTxt = ParseGenericComment(Item.GetHeadComment() + \
397 Item.GetTailComment())
398
399 ListObject = Factory()
400 ListObject.SetCName(Name)
401 ListObject.SetGuid(Value)
402 ListObject.SetSupArchList(Item.GetArchList())
403 if HelpTxt:
404 ListObject.SetHelpTextList([HelpTxt])
405
406 DeclarationsList.append(ListObject)
407
408 #
409 #GuidTypeList is abstracted from help
410 #
411 if Type == TAB_GUIDS:
412 self.SetGuidList(self.GetGuidList() + DeclarationsList)
413 elif Type == TAB_PROTOCOLS:
414 self.SetProtocolList(self.GetProtocolList() + DeclarationsList)
415 elif Type == TAB_PPIS:
416 self.SetPpiList(self.GetPpiList() + DeclarationsList)
417
418 ## GenLibraryClasses
419 #
420 # Gen LibraryClasses of Dec
421 # <CName>=<GuidValue>
422 #
423 # @param ContainerFile: The Dec file full path
424 #
425 def GenLibraryClasses(self, ContainerFile):
426 if ContainerFile:
427 pass
428 Logger.Debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES)
429 LibraryClassDeclarations = []
430
431 LibObj = self.DecParser.GetLibraryClassSectionObject()
432 for Item in LibObj.GetAllLibraryclasses():
433 LibraryClass = LibraryClassObject()
434 LibraryClass.SetLibraryClass(Item.Libraryclass)
435 LibraryClass.SetSupArchList(Item.GetArchList())
436 LibraryClass.SetIncludeHeader(Item.File)
437 HelpTxt = ParseGenericComment(Item.GetHeadComment() + \
438 Item.GetTailComment(), None, '@libraryclass')
439 if HelpTxt:
440 LibraryClass.SetHelpTextList([HelpTxt])
441 LibraryClassDeclarations.append(LibraryClass)
442
443 self.SetLibraryClassList(self.GetLibraryClassList() + \
444 LibraryClassDeclarations)
445
446 ## GenPcds
447 #
448 # Gen Pcds of Dec
449 # <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
450 #
451 # @param ContainerFile: The Dec file full path
452 #
453 def GenPcds(self, ContainerFile):
454 Logger.Debug(2, "Generate %s ..." % TAB_PCDS)
455
456 PcdObj = self.DecParser.GetPcdSectionObject()
457 #
458 # Get all Pcds
459 #
460 PcdDeclarations = []
461 IterList = [
462 (TAB_PCDS_FIXED_AT_BUILD_NULL, 'FixedPcd'),
463 (TAB_PCDS_PATCHABLE_IN_MODULE_NULL, 'PatchPcd'),
464 (TAB_PCDS_FEATURE_FLAG_NULL, 'FeaturePcd'),
465 (TAB_PCDS_DYNAMIC_EX_NULL, 'PcdEx'),
466 (TAB_PCDS_DYNAMIC_NULL, 'Pcd')]
467 #
468 # For each PCD type
469 #
470 for PcdType, Type in IterList:
471 #
472 # Go through all archs
473 #
474 # for Arch in self.SupArchList + [TAB_ARCH_COMMON]:
475 #
476 for Item in PcdObj.GetPcdsByType(PcdType.upper()):
477 PcdDeclaration = GenPcdDeclaration(
478 ContainerFile,
479 (Item.TokenSpaceGuidCName, Item.TokenCName,
480 Item.DefaultValue, Item.DatumType, Item.TokenValue,
481 Type, Item.GetHeadComment(), Item.GetTailComment(),
482 '')
483 )
484 PcdDeclaration.SetSupArchList(Item.GetArchListOfType(PcdType))
485 PcdDeclarations.append(PcdDeclaration)
486
487 self.SetPcdList(self.GetPcdList() + PcdDeclarations)
488
489
490 ## GenModuleFileList
491 #
492 def GenModuleFileList(self, ContainerFile):
493 ModuleFileList = []
494 ContainerFileName = os.path.basename(ContainerFile)
495 ContainerFilePath = os.path.dirname(ContainerFile)
496 for Item in GetFiles(ContainerFilePath,
497 ['CVS', '.svn'] + self.GetIncludePathList(), False):
498 ExtName = os.path.splitext(Item)[1]
499 if ExtName.lower() == '.inf':
500 ModuleFileList.append(Item)
501 elif ExtName.upper() == '.DEC' and self.CheckMulDec:
502 if Item == ContainerFileName:
503 continue
504 Logger.Error('MkPkg',
505 UPT_MUL_DEC_ERROR,
506 ST.ERR_MUL_DEC_ERROR%(ContainerFilePath,
507 ContainerFileName,
508 Item))
509
510 self.SetModuleFileList(ModuleFileList)
511
512 ## Show detailed information of Package
513 #
514 # Print all members and their values of Package class
515 #
516 def ShowPackage(self):
517 print '\nName =', self.GetName()
518 print '\nBaseName =', self.GetBaseName()
519 print '\nVersion =', self.GetVersion()
520 print '\nGuid =', self.GetGuid()
521
522 print '\nStandardIncludes = %d ' \
523 % len(self.GetStandardIncludeFileList()),
524 for Item in self.GetStandardIncludeFileList():
525 print Item.GetFilePath(), ' ', Item.GetSupArchList()
526 print '\nPackageIncludes = %d \n' \
527 % len(self.GetPackageIncludeFileList()),
528 for Item in self.GetPackageIncludeFileList():
529 print Item.GetFilePath(), ' ', Item.GetSupArchList()
530
531 print '\nGuids =', self.GetGuidList()
532 for Item in self.GetGuidList():
533 print Item.GetCName(), Item.GetGuid(), Item.GetSupArchList()
534 print '\nProtocols =', self.GetProtocolList()
535 for Item in self.GetProtocolList():
536 print Item.GetCName(), Item.GetGuid(), Item.GetSupArchList()
537 print '\nPpis =', self.GetPpiList()
538 for Item in self.GetPpiList():
539 print Item.GetCName(), Item.GetGuid(), Item.GetSupArchList()
540 print '\nLibraryClasses =', self.GetLibraryClassList()
541 for Item in self.GetLibraryClassList():
542 print Item.GetLibraryClass(), Item.GetRecommendedInstance(), \
543 Item.GetSupArchList()
544 print '\nPcds =', self.GetPcdList()
545 for Item in self.GetPcdList():
546 print 'CName=', Item.GetCName(), 'TokenSpaceGuidCName=', \
547 Item.GetTokenSpaceGuidCName(), \
548 'DefaultValue=', Item.GetDefaultValue(), \
549 'ValidUsage=', Item.GetValidUsage(), \
550 'SupArchList', Item.GetSupArchList(), \
551 'Token=', Item.GetToken(), 'DatumType=', Item.GetDatumType()
552
553 for Item in self.GetMiscFileList():
554 print Item.GetName()
555 for FileObjectItem in Item.GetFileList():
556 print FileObjectItem.GetURI()
557 print '****************\n'
558
559 ## GenPcdDeclaration
560 #
561 # @param ContainerFile: File name of the DEC file
562 # @param PcdInfo: Pcd information, of format (TokenGuidCName,
563 # TokenName, Value, DatumType, Token, Type,
564 # GenericComment, TailComment, Arch)
565 #
566 def GenPcdDeclaration(ContainerFile, PcdInfo):
567 HelpStr = ''
568 TailHelpStr = ''
569 TokenGuidCName, TokenName, Value, DatumType, Token, Type, \
570 GenericComment, TailComment, Arch = PcdInfo
571 Pcd = PcdObject()
572 Pcd.SetCName(TokenName)
573 Pcd.SetToken(Token)
574 Pcd.SetTokenSpaceGuidCName(TokenGuidCName)
575 Pcd.SetDatumType(DatumType)
576 Pcd.SetDefaultValue(Value)
577 Pcd.SetValidUsage(Type)
578 #
579 # MaxDatumSize is required field for 'VOID*' PCD
580 #
581 if DatumType == TAB_PTR_TYPE_PCD:
582 Pcd.SetMaxDatumSize(ITEM_UNDEFINED)
583
584 SupArchList = [Arch]
585 Pcd.SetSupArchList(SupArchList)
586
587 if GenericComment:
588 HelpStr, PcdErr = ParseDecPcdGenericComment(GenericComment,
589 ContainerFile)
590 if PcdErr:
591 Pcd.SetPcdErrorsList([PcdErr])
592
593 if TailComment:
594 SupModuleList, TailHelpStr = ParseDecPcdTailComment(TailComment,
595 ContainerFile)
596 if SupModuleList:
597 Pcd.SetSupModuleList(SupModuleList)
598
599 if HelpStr and (not HelpStr.endswith('\n')) and TailHelpStr:
600 HelpStr += '\n'
601 HelpStr += TailHelpStr
602 if HelpStr:
603 HelpTxtObj = TextObject()
604 HelpTxtObj.SetString(HelpStr)
605 Pcd.SetHelpTextList([HelpTxtObj])
606
607 return Pcd