]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py
BaseTools: Fix old python2 idioms
[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 - 2016, 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 from __future__ import print_function
19
20 ##
21 # Import Modules
22 #
23 import os.path
24 from os import sep
25 import platform
26
27 import re
28 import Logger.Log as Logger
29 from Logger import StringTable as ST
30 from Logger.ToolError import UPT_MUL_DEC_ERROR
31 from Logger.ToolError import FORMAT_INVALID
32
33 from Library.Parsing import NormPath
34 from Library.DataType import ARCH_LIST
35 from Library.DataType import TAB_GUIDS
36 from Library.DataType import TAB_PROTOCOLS
37 from Library.DataType import TAB_PPIS
38 from Library.DataType import TAB_DEC_DEFINES_PACKAGE_NAME
39 from Library.DataType import TAB_DEC_DEFINES_PACKAGE_GUID
40 from Library.DataType import TAB_DEC_DEFINES_PACKAGE_VERSION
41 from Library.DataType import TAB_DEC_DEFINES_DEC_SPECIFICATION
42 from Library.DataType import TAB_DEC_DEFINES_PKG_UNI_FILE
43 from Library.DataType import TAB_ARCH_COMMON
44 from Library.DataType import TAB_INCLUDES
45 from Library.DataType import TAB_LIBRARY_CLASSES
46 from Library.DataType import TAB_PCDS
47 from Library.DataType import TAB_PCDS_FIXED_AT_BUILD_NULL
48 from Library.DataType import TAB_PCDS_PATCHABLE_IN_MODULE_NULL
49 from Library.DataType import TAB_PCDS_FEATURE_FLAG_NULL
50 from Library.DataType import TAB_PCDS_DYNAMIC_EX_NULL
51 from Library.DataType import TAB_PCDS_DYNAMIC_NULL
52 from Library.DataType import TAB_PTR_TYPE_PCD
53 from Library.DataType import ITEM_UNDEFINED
54 from Library.DataType import TAB_DEC_BINARY_ABSTRACT
55 from Library.DataType import TAB_DEC_BINARY_DESCRIPTION
56 from Library.DataType import TAB_LANGUAGE_EN_US
57 from Library.DataType import TAB_BINARY_HEADER_IDENTIFIER
58 from Library.DataType import TAB_BINARY_HEADER_USERID
59 from Library.DataType import TAB_LANGUAGE_EN_X
60 from Library.DataType import TAB_LANGUAGE_EN
61 from Library.DataType import TAB_STR_TOKENCNAME
62 from Library.DataType import TAB_STR_TOKENPROMPT
63 from Library.DataType import TAB_STR_TOKENHELP
64 from Library.DataType import TAB_STR_TOKENERR
65 from Library.DataType import TAB_HEX_START
66 from Library.DataType import TAB_SPLIT
67 import Library.DataType as DT
68 from Library.CommentParsing import ParseHeaderCommentSection
69 from Library.CommentParsing import ParseGenericComment
70 from Library.CommentParsing import ParseDecPcdGenericComment
71 from Library.CommentParsing import ParseDecPcdTailComment
72 from Library.Misc import GetFiles
73 from Library.Misc import Sdict
74 from Library.Misc import GetRelativePath
75 from Library.Misc import PathClass
76 from Library.Misc import ValidateUNIFilePath
77 from Library.UniClassObject import UniFileClassObject
78 from Library.UniClassObject import ConvertSpecialUnicodes
79 from Library.UniClassObject import GetLanguageCode1766
80 from Library.ParserValidate import IsValidPath
81 from Parser.DecParser import Dec
82 from Object.POM.PackageObject import PackageObject
83 from Object.POM.CommonObject import UserExtensionObject
84 from Object.POM.CommonObject import IncludeObject
85 from Object.POM.CommonObject import GuidObject
86 from Object.POM.CommonObject import ProtocolObject
87 from Object.POM.CommonObject import PpiObject
88 from Object.POM.CommonObject import LibraryClassObject
89 from Object.POM.CommonObject import PcdObject
90 from Object.POM.CommonObject import TextObject
91 from Object.POM.CommonObject import MiscFileObject
92 from Object.POM.CommonObject import FileObject
93
94
95 ## DecPomAlignment
96 #
97 # Inherited from PackageObject
98 #
99 class DecPomAlignment(PackageObject):
100 def __init__(self, Filename, WorkspaceDir = None, CheckMulDec = False):
101 PackageObject.__init__(self)
102 self.UserExtensions = ''
103 self.WorkspaceDir = WorkspaceDir
104 self.SupArchList = ARCH_LIST
105 self.CheckMulDec = CheckMulDec
106 self.DecParser = None
107 self.UniFileClassObject = None
108 self.PcdDefaultValueDict = {}
109
110 #
111 # Load Dec file
112 #
113 self.LoadDecFile(Filename)
114
115 #
116 # Transfer to Package Object if IsToPackage is True
117 #
118 self.DecToPackage()
119
120 ## Load Dec file
121 #
122 # Load the file if it exists
123 #
124 # @param Filename: Input value for filename of Dec file
125 #
126 def LoadDecFile(self, Filename):
127 #
128 # Insert a record for file
129 #
130 Filename = NormPath(Filename)
131 (Path, Name) = os.path.split(Filename)
132 self.SetFullPath(Filename)
133 self.SetRelaPath(Path)
134 self.SetFileName(Name)
135 self.SetPackagePath(GetRelativePath(Path, self.WorkspaceDir))
136 self.SetCombinePath(GetRelativePath(Filename, self.WorkspaceDir))
137
138 self.DecParser = Dec(Filename)
139
140 ## Transfer to Package Object
141 #
142 # Transfer all contents of a Dec file to a standard Package Object
143 #
144 def DecToPackage(self):
145 #
146 # Init global information for the file
147 #
148 ContainerFile = self.GetFullPath()
149
150 #
151 # Generate Package Header
152 #
153 self.GenPackageHeader(ContainerFile)
154
155 #
156 # Generate Includes
157 #
158 self.GenIncludes(ContainerFile)
159
160 #
161 # Generate Guids
162 #
163 self.GenGuidProtocolPpis(TAB_GUIDS, ContainerFile)
164
165 #
166 # Generate Protocols
167 #
168 self.GenGuidProtocolPpis(TAB_PROTOCOLS, ContainerFile)
169
170 #
171 # Generate Ppis
172 #
173 self.GenGuidProtocolPpis(TAB_PPIS, ContainerFile)
174
175 #
176 # Generate LibraryClasses
177 #
178 self.GenLibraryClasses(ContainerFile)
179
180 #
181 # Generate Pcds
182 #
183 self.GenPcds(ContainerFile)
184
185 #
186 # Generate Module File list, will be used later on to generate
187 # distribution
188 #
189 self.GenModuleFileList(ContainerFile)
190
191 #
192 # Generate user extensions
193 #
194 self.GenUserExtensions()
195
196 ## Generate user extension
197 #
198 #
199 def GenUserExtensions(self):
200 UEObj = self.DecParser.GetUserExtensionSectionObject()
201 UEList = UEObj.GetAllUserExtensions()
202 for Item in UEList:
203 if not Item.UserString:
204 continue
205 UserExtension = UserExtensionObject()
206 UserId = Item.UserId
207 if UserId.startswith('"') and UserId.endswith('"'):
208 UserId = UserId[1:-1]
209 UserExtension.SetUserID(UserId)
210 Identifier = Item.IdString
211 if Identifier.startswith('"') and Identifier.endswith('"'):
212 Identifier = Identifier[1:-1]
213 #
214 # Generate miscellaneous files of DEC file
215 #
216 if UserId == 'TianoCore' and Identifier == 'ExtraFiles':
217 self.GenMiscFiles(Item.UserString)
218 UserExtension.SetIdentifier(Identifier)
219 UserExtension.SetStatement(Item.UserString)
220 UserExtension.SetSupArchList(
221 Item.ArchAndModuleType
222 )
223 self.SetUserExtensionList(
224 self.GetUserExtensionList() + [UserExtension]
225 )
226
227 # Add Private sections to UserExtension
228 if self.DecParser.GetPrivateSections():
229 PrivateUserExtension = UserExtensionObject()
230 PrivateUserExtension.SetStatement(self.DecParser.GetPrivateSections())
231 PrivateUserExtension.SetIdentifier(DT.TAB_PRIVATE)
232 PrivateUserExtension.SetUserID(DT.TAB_INTEL)
233 self.SetUserExtensionList(self.GetUserExtensionList() + [PrivateUserExtension])
234
235 ## Generate miscellaneous files on DEC file
236 #
237 #
238 def GenMiscFiles(self, Content):
239 MiscFileObj = MiscFileObject()
240 for Line in Content.splitlines():
241 FileName = ''
242 if '#' in Line:
243 FileName = Line[:Line.find('#')]
244 else:
245 FileName = Line
246 if FileName:
247 if IsValidPath(FileName, self.GetRelaPath()):
248 FileObj = FileObject()
249 FileObj.SetURI(FileName)
250 MiscFileObj.SetFileList(MiscFileObj.GetFileList()+[FileObj])
251 else:
252 Logger.Error("InfParser",
253 FORMAT_INVALID,
254 ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(Line),
255 File=self.GetFileName(),
256 ExtraData=Line)
257 self.SetMiscFileList(self.GetMiscFileList()+[MiscFileObj])
258
259 ## Generate Package Header
260 #
261 # Gen Package Header of Dec as <Key> = <Value>
262 #
263 # @param ContainerFile: The Dec file full path
264 #
265 def GenPackageHeader(self, ContainerFile):
266 Logger.Debug(2, "Generate PackageHeader ...")
267 DefinesDict = {}
268
269 #
270 # Update all defines item in database
271 #
272 DefObj = self.DecParser.GetDefineSectionObject()
273 for Item in DefObj.GetDefines():
274 #
275 # put items into Dict except for PackageName, Guid, Version, DEC_SPECIFICATION
276 #
277 SkipItemList = [TAB_DEC_DEFINES_PACKAGE_NAME, \
278 TAB_DEC_DEFINES_PACKAGE_GUID, TAB_DEC_DEFINES_PACKAGE_VERSION, \
279 TAB_DEC_DEFINES_DEC_SPECIFICATION, TAB_DEC_DEFINES_PKG_UNI_FILE]
280 if Item.Key in SkipItemList:
281 continue
282 DefinesDict['%s = %s' % (Item.Key, Item.Value)] = TAB_ARCH_COMMON
283
284 self.SetBaseName(DefObj.GetPackageName())
285 self.SetVersion(DefObj.GetPackageVersion())
286 # self.SetName(DefObj.GetPackageName() + ' Version ' + \
287 # DefObj.GetPackageVersion())
288 self.SetName(os.path.splitext(self.GetFileName())[0])
289 self.SetGuid(DefObj.GetPackageGuid())
290 if DefObj.GetPackageUniFile():
291 ValidateUNIFilePath(DefObj.GetPackageUniFile())
292 self.UniFileClassObject = \
293 UniFileClassObject([PathClass(os.path.join(DefObj.GetPackagePath(), DefObj.GetPackageUniFile()))])
294 else:
295 self.UniFileClassObject = None
296
297 if DefinesDict:
298 UserExtension = UserExtensionObject()
299 UserExtension.SetDefinesDict(DefinesDict)
300 UserExtension.SetIdentifier('DefineModifiers')
301 UserExtension.SetUserID('EDK2')
302 self.SetUserExtensionList(
303 self.GetUserExtensionList() + [UserExtension]
304 )
305
306 #
307 # Get File header information
308 #
309 if self.UniFileClassObject:
310 Lang = TAB_LANGUAGE_EN_X
311 else:
312 Lang = TAB_LANGUAGE_EN_US
313 Abstract, Description, Copyright, License = \
314 ParseHeaderCommentSection(self.DecParser.GetHeadComment(),
315 ContainerFile)
316 if Abstract:
317 self.SetAbstract((Lang, Abstract))
318 if Description:
319 self.SetDescription((Lang, Description))
320 if Copyright:
321 self.SetCopyright(('', Copyright))
322 if License:
323 self.SetLicense(('', License))
324
325 #
326 # Get Binary header information
327 #
328 if self.DecParser.BinaryHeadComment:
329 Abstract, Description, Copyright, License = \
330 ParseHeaderCommentSection(self.DecParser.BinaryHeadComment,
331 ContainerFile, True)
332
333 if not Abstract or not Description or not Copyright or not License:
334 Logger.Error('MkPkg',
335 FORMAT_INVALID,
336 ST.ERR_INVALID_BINARYHEADER_FORMAT,
337 ContainerFile)
338 else:
339 self.SetBinaryHeaderAbstract((Lang, Abstract))
340 self.SetBinaryHeaderDescription((Lang, Description))
341 self.SetBinaryHeaderCopyright(('', Copyright))
342 self.SetBinaryHeaderLicense(('', License))
343
344 BinaryAbstractList = []
345 BinaryDescriptionList = []
346
347 #Get Binary header from UNI file
348 # Initialize the UniStrDict dictionary, top keys are language codes
349 UniStrDict = {}
350 if self.UniFileClassObject:
351 UniStrDict = self.UniFileClassObject.OrderedStringList
352 for Lang in UniStrDict:
353 for StringDefClassObject in UniStrDict[Lang]:
354 Lang = GetLanguageCode1766(Lang)
355 if StringDefClassObject.StringName == TAB_DEC_BINARY_ABSTRACT:
356 if (Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)) \
357 not in self.GetBinaryHeaderAbstract():
358 BinaryAbstractList.append((Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)))
359 if StringDefClassObject.StringName == TAB_DEC_BINARY_DESCRIPTION:
360 if (Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)) \
361 not in self.GetBinaryHeaderDescription():
362 BinaryDescriptionList.append((Lang,
363 ConvertSpecialUnicodes(StringDefClassObject.StringValue)))
364 #Combine Binary header from DEC file and UNI file
365 BinaryAbstractList = self.GetBinaryHeaderAbstract() + BinaryAbstractList
366 BinaryDescriptionList = self.GetBinaryHeaderDescription() + BinaryDescriptionList
367 BinaryCopyrightList = self.GetBinaryHeaderCopyright()
368 BinaryLicenseList = self.GetBinaryHeaderLicense()
369 #Generate the UserExtensionObject for TianoCore."BinaryHeader"
370 if BinaryAbstractList or BinaryDescriptionList or BinaryCopyrightList or BinaryLicenseList:
371 BinaryUserExtension = UserExtensionObject()
372 BinaryUserExtension.SetBinaryAbstract(BinaryAbstractList)
373 BinaryUserExtension.SetBinaryDescription(BinaryDescriptionList)
374 BinaryUserExtension.SetBinaryCopyright(BinaryCopyrightList)
375 BinaryUserExtension.SetBinaryLicense(BinaryLicenseList)
376 BinaryUserExtension.SetIdentifier(TAB_BINARY_HEADER_IDENTIFIER)
377 BinaryUserExtension.SetUserID(TAB_BINARY_HEADER_USERID)
378 self.SetUserExtensionList(self.GetUserExtensionList() + [BinaryUserExtension])
379
380
381 ## GenIncludes
382 #
383 # Gen Includes of Dec
384 #
385 # @param ContainerFile: The Dec file full path
386 #
387 def GenIncludes(self, ContainerFile):
388 if ContainerFile:
389 pass
390 Logger.Debug(2, "Generate %s ..." % TAB_INCLUDES)
391 IncludesDict = Sdict()
392
393 IncObj = self.DecParser.GetIncludeSectionObject()
394 for Item in IncObj.GetAllIncludes():
395 IncludePath = os.path.normpath(Item.File)
396 if platform.system() != 'Windows' and platform.system() != 'Microsoft':
397 IncludePath = IncludePath.replace('\\', '/')
398 if IncludePath in IncludesDict:
399 if Item.GetArchList() == [TAB_ARCH_COMMON] or IncludesDict[IncludePath] == [TAB_ARCH_COMMON]:
400 IncludesDict[IncludePath] = [TAB_ARCH_COMMON]
401 else:
402 IncludesDict[IncludePath] = IncludesDict[IncludePath] + Item.GetArchList()
403 else:
404 IncludesDict[IncludePath] = Item.GetArchList()
405
406 #
407 # get the standardIncludeFileList(industry), packageIncludeFileList
408 # (others) for PackageObject
409 #
410 PackagePath = os.path.split(self.GetFullPath())[0]
411 IncludePathList = \
412 sorted([os.path.normpath(Path) + sep for Path in IncludesDict.keys()])
413
414 #
415 # get a non-overlap set of include path, IncludePathList should be
416 # sorted, and path should be end with path seperator '\'
417 #
418 NonOverLapList = []
419 for Path1 in IncludePathList:
420 for Path2 in NonOverLapList:
421 if Path1.startswith(Path2):
422 break
423 else:
424 NonOverLapList.append(Path1)
425 #
426 # revert the list so the longest path shown first in list, also need
427 # to remove the extra path seperator '\'
428 # as this list is used to search the supported Arch info
429 #
430 for IndexN in range (0, len(IncludePathList)):
431 IncludePathList[IndexN] = os.path.normpath(IncludePathList[IndexN])
432 IncludePathList.sort()
433 IncludePathList.reverse()
434 #
435 # save the include path list for later usage
436 #
437 self.SetIncludePathList(IncludePathList)
438 StandardIncludeFileList = []
439 PackageIncludeFileList = []
440
441 IncludeFileList = []
442 for Path in NonOverLapList:
443 FileList = GetFiles(os.path.join(PackagePath, Path), ['CVS', '.svn'], False)
444 IncludeFileList += [os.path.normpath(os.path.join(Path, File)) for File in FileList]
445 for Includefile in IncludeFileList:
446 ExtName = os.path.splitext(Includefile)[1]
447 if ExtName.upper() == '.DEC' and self.CheckMulDec:
448 Logger.Error('MkPkg',
449 UPT_MUL_DEC_ERROR,
450 ST.ERR_MUL_DEC_ERROR%(os.path.dirname(ContainerFile),
451 os.path.basename(ContainerFile),
452 Includefile))
453
454 FileCombinePath = os.path.dirname(Includefile)
455 Include = IncludeObject()
456 for Path in IncludePathList:
457 if FileCombinePath.startswith(Path):
458 SupArchList = IncludesDict[Path]
459 break
460 Include.SetFilePath(Includefile)
461 Include.SetSupArchList(SupArchList)
462 if Includefile.find('IndustryStandard') != -1:
463 StandardIncludeFileList.append(Include)
464 else:
465 PackageIncludeFileList.append(Include)
466
467 self.SetStandardIncludeFileList(StandardIncludeFileList)
468
469 #
470 # put include path into the PackageIncludeFileList
471 #
472 PackagePathList = []
473 IncObj = self.DecParser.GetIncludeSectionObject()
474 for Item in IncObj.GetAllIncludes():
475 IncludePath = Item.File
476 Include = IncludeObject()
477 Include.SetFilePath(IncludePath)
478 Include.SetSupArchList(Item.GetArchList())
479 PackagePathList.append(Include)
480 self.SetPackageIncludeFileList(PackagePathList + PackageIncludeFileList)
481
482 ## GenPpis
483 #
484 # Gen Ppis of Dec
485 # <CName>=<GuidValue>
486 #
487 # @param ContainerFile: The Dec file full path
488 #
489 def GenGuidProtocolPpis(self, Type, ContainerFile):
490 if ContainerFile:
491 pass
492 Logger.Debug(2, "Generate %s ..." % Type)
493
494 Obj = None
495 Factory = None
496 if Type == TAB_GUIDS:
497 Obj = self.DecParser.GetGuidSectionObject()
498 def CreateGuidObject():
499 Object = GuidObject()
500 Object.SetGuidTypeList([])
501 Object.SetUsage(None)
502 Object.SetName(None)
503 return Object
504 Factory = CreateGuidObject
505 elif Type == TAB_PROTOCOLS:
506 Obj = self.DecParser.GetProtocolSectionObject()
507
508 def CreateProtocolObject():
509 return ProtocolObject()
510 Factory = CreateProtocolObject
511 elif Type == TAB_PPIS:
512 Obj = self.DecParser.GetPpiSectionObject()
513
514 def CreatePpiObject():
515 return PpiObject()
516 Factory = CreatePpiObject
517 else:
518 #
519 # Should not be here
520 #
521 return
522
523 DeclarationsList = []
524
525 #
526 # Go through each arch
527 #
528 for Item in Obj.GetGuidStyleAllItems():
529 Name = Item.GuidCName
530 Value = Item.GuidString
531 HelpTxt = ParseGenericComment(Item.GetHeadComment() + \
532 Item.GetTailComment())
533
534 ListObject = Factory()
535 ListObject.SetCName(Name)
536 ListObject.SetGuid(Value)
537 ListObject.SetSupArchList(Item.GetArchList())
538 if HelpTxt:
539 if self.UniFileClassObject:
540 HelpTxt.SetLang(TAB_LANGUAGE_EN_X)
541 ListObject.SetHelpTextList([HelpTxt])
542
543 DeclarationsList.append(ListObject)
544
545 #
546 #GuidTypeList is abstracted from help
547 #
548 if Type == TAB_GUIDS:
549 self.SetGuidList(self.GetGuidList() + DeclarationsList)
550 elif Type == TAB_PROTOCOLS:
551 self.SetProtocolList(self.GetProtocolList() + DeclarationsList)
552 elif Type == TAB_PPIS:
553 self.SetPpiList(self.GetPpiList() + DeclarationsList)
554
555 ## GenLibraryClasses
556 #
557 # Gen LibraryClasses of Dec
558 # <CName>=<GuidValue>
559 #
560 # @param ContainerFile: The Dec file full path
561 #
562 def GenLibraryClasses(self, ContainerFile):
563 if ContainerFile:
564 pass
565 Logger.Debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES)
566 LibraryClassDeclarations = []
567
568 LibObj = self.DecParser.GetLibraryClassSectionObject()
569 for Item in LibObj.GetAllLibraryclasses():
570 LibraryClass = LibraryClassObject()
571 LibraryClass.SetLibraryClass(Item.Libraryclass)
572 LibraryClass.SetSupArchList(Item.GetArchList())
573 LibraryClass.SetIncludeHeader(Item.File)
574 HelpTxt = ParseGenericComment(Item.GetHeadComment() + \
575 Item.GetTailComment(), None, '@libraryclass')
576 if HelpTxt:
577 if self.UniFileClassObject:
578 HelpTxt.SetLang(TAB_LANGUAGE_EN_X)
579 LibraryClass.SetHelpTextList([HelpTxt])
580 LibraryClassDeclarations.append(LibraryClass)
581
582 self.SetLibraryClassList(self.GetLibraryClassList() + \
583 LibraryClassDeclarations)
584
585 ## GenPcds
586 #
587 # Gen Pcds of Dec
588 # <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
589 #
590 # @param ContainerFile: The Dec file full path
591 #
592 def GenPcds(self, ContainerFile):
593 Logger.Debug(2, "Generate %s ..." % TAB_PCDS)
594 PcdObj = self.DecParser.GetPcdSectionObject()
595 #
596 # Get all Pcds
597 #
598 PcdDeclarations = []
599 IterList = [
600 (TAB_PCDS_FIXED_AT_BUILD_NULL, 'FixedPcd'),
601 (TAB_PCDS_PATCHABLE_IN_MODULE_NULL, 'PatchPcd'),
602 (TAB_PCDS_FEATURE_FLAG_NULL, 'FeaturePcd'),
603 (TAB_PCDS_DYNAMIC_EX_NULL, 'PcdEx'),
604 (TAB_PCDS_DYNAMIC_NULL, 'Pcd')]
605
606 PromptStrList = []
607 HelpStrList = []
608 PcdErrStrList = []
609 # Initialize UniStrDict dictionary, top keys are language codes
610 UniStrDict = {}
611 StrList = []
612
613 Language = ''
614 if self.UniFileClassObject:
615 Language = TAB_LANGUAGE_EN_X
616 else:
617 Language = TAB_LANGUAGE_EN_US
618
619 if self.UniFileClassObject:
620 UniStrDict = self.UniFileClassObject.OrderedStringList
621 for Lang in UniStrDict:
622 for StringDefClassObject in UniStrDict[Lang]:
623 StrList = StringDefClassObject.StringName.split('_')
624 # StringName format is STR_<TOKENSPACECNAME>_<PCDCNAME>_PROMPT
625 if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[3] == TAB_STR_TOKENPROMPT:
626 PromptStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \
627 StringDefClassObject.StringValue))
628 # StringName format is STR_<TOKENSPACECNAME>_<PCDCNAME>_HELP
629 if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[3] == TAB_STR_TOKENHELP:
630 HelpStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \
631 StringDefClassObject.StringValue))
632 # StringName format is STR_<TOKENSPACECNAME>_ERR_##
633 if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[2] == TAB_STR_TOKENERR:
634 PcdErrStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \
635 StringDefClassObject.StringValue))
636 #
637 # For each PCD type
638 #
639 for PcdType, Type in IterList:
640 #
641 # Go through all archs
642 #
643 # for Arch in self.SupArchList + [TAB_ARCH_COMMON]:
644 #
645 for Item in PcdObj.GetPcdsByType(PcdType.upper()):
646 PcdDeclaration = GenPcdDeclaration(
647 ContainerFile,
648 (Item.TokenSpaceGuidCName, Item.TokenCName,
649 Item.DefaultValue, Item.DatumType, Item.TokenValue,
650 Type, Item.GetHeadComment(), Item.GetTailComment(), ''),
651 Language,
652 self.DecParser.GetDefineSectionMacro()
653 )
654 PcdDeclaration.SetSupArchList(Item.GetArchListOfType(PcdType))
655
656 #
657 # Get PCD error message from PCD error comment section in DEC file
658 #
659 for PcdErr in PcdDeclaration.GetPcdErrorsList():
660 if (PcdDeclaration.GetTokenSpaceGuidCName(), PcdErr.GetErrorNumber()) \
661 in self.DecParser.PcdErrorCommentDict:
662 Key = (PcdDeclaration.GetTokenSpaceGuidCName(), PcdErr.GetErrorNumber())
663 PcdErr.SetErrorMessageList(PcdErr.GetErrorMessageList() + \
664 [(Language, self.DecParser.PcdErrorCommentDict[Key])])
665
666 for Index in range(0, len(PromptStrList)):
667 StrNameList = PromptStrList[Index][1].split('_')
668 if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \
669 StrNameList[2].lower() == Item.TokenCName.lower():
670 TxtObj = TextObject()
671 TxtObj.SetLang(PromptStrList[Index][0])
672 TxtObj.SetString(PromptStrList[Index][2])
673 for Prompt in PcdDeclaration.GetPromptList():
674 if Prompt.GetLang() == TxtObj.GetLang() and \
675 Prompt.GetString() == TxtObj.GetString():
676 break
677 else:
678 PcdDeclaration.SetPromptList(PcdDeclaration.GetPromptList() + [TxtObj])
679
680 for Index in range(0, len(HelpStrList)):
681 StrNameList = HelpStrList[Index][1].split('_')
682 if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \
683 StrNameList[2].lower() == Item.TokenCName.lower():
684 TxtObj = TextObject()
685 TxtObj.SetLang(HelpStrList[Index][0])
686 TxtObj.SetString(HelpStrList[Index][2])
687 for HelpStrObj in PcdDeclaration.GetHelpTextList():
688 if HelpStrObj.GetLang() == TxtObj.GetLang() and \
689 HelpStrObj.GetString() == TxtObj.GetString():
690 break
691 else:
692 PcdDeclaration.SetHelpTextList(PcdDeclaration.GetHelpTextList() + [TxtObj])
693
694 #
695 # Get PCD error message from UNI file
696 #
697 for Index in range(0, len(PcdErrStrList)):
698 StrNameList = PcdErrStrList[Index][1].split('_')
699 if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \
700 StrNameList[2].lower() == TAB_STR_TOKENERR.lower():
701 for PcdErr in PcdDeclaration.GetPcdErrorsList():
702 if PcdErr.GetErrorNumber().lower() == (TAB_HEX_START + StrNameList[3]).lower() and \
703 (PcdErrStrList[Index][0], PcdErrStrList[Index][2]) not in PcdErr.GetErrorMessageList():
704 PcdErr.SetErrorMessageList(PcdErr.GetErrorMessageList() + \
705 [(PcdErrStrList[Index][0], PcdErrStrList[Index][2])])
706
707 #
708 # Check to prevent missing error message if a Pcd has the error code.
709 #
710 for PcdErr in PcdDeclaration.GetPcdErrorsList():
711 if PcdErr.GetErrorNumber().strip():
712 if not PcdErr.GetErrorMessageList():
713 Logger.Error('UPT',
714 FORMAT_INVALID,
715 ST.ERR_DECPARSE_PCD_UNMATCHED_ERRORCODE % PcdErr.GetErrorNumber(),
716 ContainerFile,
717 PcdErr.GetLineNum(),
718 PcdErr.GetFileLine())
719
720 PcdDeclarations.append(PcdDeclaration)
721 self.SetPcdList(self.GetPcdList() + PcdDeclarations)
722 self.CheckPcdValue()
723
724 ##
725 # Get error message via language
726 # @param ErrorMessageList: Error message tuple list the language and its message
727 # @param Lang: the language of setting
728 # @return: the error message described in the related UNI file
729 def GetEnErrorMessage(self, ErrorMessageList):
730 if self.FullPath:
731 pass
732 Lang = TAB_LANGUAGE_EN_US
733 for (Language, Message) in ErrorMessageList:
734 if Language == Lang:
735 return Message
736 for (Language, Message) in ErrorMessageList:
737 if Language.find(TAB_LANGUAGE_EN) >= 0:
738 return Message
739 else:
740 try:
741 return ErrorMessageList[0][1]
742 except IndexError:
743 return ''
744 return ''
745
746 ##
747 # Replace the strings for Python eval function.
748 # @param ReplaceValue: The string that needs to be replaced.
749 # @return: The string was replaced, then eval function is always making out it.
750 def ReplaceForEval(self, ReplaceValue, IsRange=False, IsExpr=False):
751 if self.FullPath:
752 pass
753 #
754 # deal with "NOT EQ", "NOT LT", "NOT GT", "NOT LE", "NOT GE", "NOT NOT"
755 #
756 NOTNOT_Pattern = '[\t\s]*NOT[\t\s]+NOT[\t\s]*'
757 NOTGE_Pattern = '[\t\s]*NOT[\t\s]+GE[\t\s]*'
758 NOTLE_Pattern = '[\t\s]*NOT[\t\s]+LE[\t\s]*'
759 NOTGT_Pattern = '[\t\s]*NOT[\t\s]+GT[\t\s]*'
760 NOTLT_Pattern = '[\t\s]*NOT[\t\s]+LT[\t\s]*'
761 NOTEQ_Pattern = '[\t\s]*NOT[\t\s]+EQ[\t\s]*'
762 ReplaceValue = re.compile(NOTNOT_Pattern).sub('', ReplaceValue)
763 ReplaceValue = re.compile(NOTLT_Pattern).sub('x >= ', ReplaceValue)
764 ReplaceValue = re.compile(NOTGT_Pattern).sub('x <= ', ReplaceValue)
765 ReplaceValue = re.compile(NOTLE_Pattern).sub('x > ', ReplaceValue)
766 ReplaceValue = re.compile(NOTGE_Pattern).sub('x < ', ReplaceValue)
767 ReplaceValue = re.compile(NOTEQ_Pattern).sub('x != ', ReplaceValue)
768
769 if IsRange:
770 ReplaceValue = ReplaceValue.replace('EQ', 'x ==')
771 ReplaceValue = ReplaceValue.replace('LT', 'x <')
772 ReplaceValue = ReplaceValue.replace('LE', 'x <=')
773 ReplaceValue = ReplaceValue.replace('GT', 'x >')
774 ReplaceValue = ReplaceValue.replace('GE', 'x >=')
775 ReplaceValue = ReplaceValue.replace('XOR', 'x ^')
776 elif IsExpr:
777 ReplaceValue = ReplaceValue.replace('EQ', '==')
778 ReplaceValue = ReplaceValue.replace('NE', '!=')
779 ReplaceValue = ReplaceValue.replace('LT', '<')
780 ReplaceValue = ReplaceValue.replace('LE', '<=')
781 ReplaceValue = ReplaceValue.replace('GT', '>')
782 ReplaceValue = ReplaceValue.replace('GE', '>=')
783 ReplaceValue = ReplaceValue.replace('XOR', '^')
784
785 ReplaceValue = ReplaceValue.replace('AND', 'and')
786 ReplaceValue = ReplaceValue.replace('&&', ' and ')
787 ReplaceValue = ReplaceValue.replace('xor', '^')
788 ReplaceValue = ReplaceValue.replace('OR', 'or')
789 ReplaceValue = ReplaceValue.replace('||', ' or ')
790 ReplaceValue = ReplaceValue.replace('NOT', 'not')
791 if ReplaceValue.find('!') >= 0 and ReplaceValue[ReplaceValue.index('!') + 1] != '=':
792 ReplaceValue = ReplaceValue.replace('!', ' not ')
793 if '.' in ReplaceValue:
794 Pattern = '[a-zA-Z0-9]{1,}\.[a-zA-Z0-9]{1,}'
795 MatchedList = re.findall(Pattern, ReplaceValue)
796 for MatchedItem in MatchedList:
797 if MatchedItem not in self.PcdDefaultValueDict:
798 Logger.Error("Dec File Parser", FORMAT_INVALID, Message=ST.ERR_DECPARSE_PCD_NODEFINED % MatchedItem,
799 File=self.FullPath)
800
801 ReplaceValue = ReplaceValue.replace(MatchedItem, self.PcdDefaultValueDict[MatchedItem])
802
803 return ReplaceValue
804
805 ##
806 # Check pcd's default value according to the pcd's description
807 #
808 def CheckPcdValue(self):
809 for Pcd in self.GetPcdList():
810 self.PcdDefaultValueDict[TAB_SPLIT.join((Pcd.GetTokenSpaceGuidCName(), Pcd.GetCName())).strip()] = \
811 Pcd.GetDefaultValue()
812
813 for Pcd in self.GetPcdList():
814 ValidationExpressions = []
815 PcdGuidName = TAB_SPLIT.join((Pcd.GetTokenSpaceGuidCName(), Pcd.GetCName()))
816 Valids = Pcd.GetPcdErrorsList()
817 for Valid in Valids:
818 Expression = Valid.GetExpression()
819 if Expression:
820 #
821 # Delete the 'L' prefix of a quoted string, this operation is for eval()
822 #
823 QUOTED_PATTERN = '[\t\s]*L?"[^"]*"'
824 QuotedMatchedObj = re.search(QUOTED_PATTERN, Expression)
825 if QuotedMatchedObj:
826 MatchedStr = QuotedMatchedObj.group().strip()
827 if MatchedStr.startswith('L'):
828 Expression = Expression.replace(MatchedStr, MatchedStr[1:].strip())
829
830 Expression = self.ReplaceForEval(Expression, IsExpr=True)
831 Expression = Expression.replace(PcdGuidName, 'x')
832 Message = self.GetEnErrorMessage(Valid.GetErrorMessageList())
833 ValidationExpressions.append((Expression, Message))
834
835 ValidList = Valid.GetValidValue()
836 if ValidList:
837 ValidValue = 'x in %s' % [eval(v) for v in ValidList.split(' ') if v]
838 Message = self.GetEnErrorMessage(Valid.GetErrorMessageList())
839 ValidationExpressions.append((ValidValue, Message))
840
841 ValidValueRange = Valid.GetValidValueRange()
842 if ValidValueRange:
843 ValidValueRange = self.ReplaceForEval(ValidValueRange, IsRange=True)
844 if ValidValueRange.find('-') >= 0:
845 ValidValueRange = ValidValueRange.replace('-', '<= x <=')
846 elif not ValidValueRange.startswith('x ') and not ValidValueRange.startswith('not ') \
847 and not ValidValueRange.startswith('not(') and not ValidValueRange.startswith('('):
848 ValidValueRange = 'x %s' % ValidValueRange
849 Message = self.GetEnErrorMessage(Valid.GetErrorMessageList())
850 ValidationExpressions.append((ValidValueRange, Message))
851
852 DefaultValue = self.PcdDefaultValueDict[PcdGuidName.strip()]
853 #
854 # Delete the 'L' prefix of a quoted string, this operation is for eval()
855 #
856 QUOTED_PATTERN = '[\t\s]*L?"[^"]*"'
857 QuotedMatchedObj = re.search(QUOTED_PATTERN, DefaultValue)
858 if QuotedMatchedObj:
859 MatchedStr = QuotedMatchedObj.group().strip()
860 if MatchedStr.startswith('L'):
861 DefaultValue = DefaultValue.replace(MatchedStr, MatchedStr[1:].strip())
862
863 try:
864 DefaultValue = eval(DefaultValue.replace('TRUE', 'True').replace('true', 'True')
865 .replace('FALSE', 'False').replace('false', 'False'))
866 except BaseException:
867 pass
868
869 for (Expression, Msg) in ValidationExpressions:
870 try:
871 if not eval(Expression, {'x':DefaultValue}):
872 Logger.Error("Dec File Parser", FORMAT_INVALID, ExtraData='%s, value = %s' %\
873 (PcdGuidName, DefaultValue), Message=Msg, File=self.FullPath)
874 except TypeError:
875 Logger.Error("Dec File Parser", FORMAT_INVALID, ExtraData=PcdGuidName, \
876 Message=Msg, File=self.FullPath)
877
878 ## GenModuleFileList
879 #
880 def GenModuleFileList(self, ContainerFile):
881 ModuleFileList = []
882 ContainerFileName = os.path.basename(ContainerFile)
883 ContainerFilePath = os.path.dirname(ContainerFile)
884 for Item in GetFiles(ContainerFilePath,
885 ['CVS', '.svn'] + self.GetIncludePathList(), False):
886 ExtName = os.path.splitext(Item)[1]
887 if ExtName.lower() == '.inf':
888 ModuleFileList.append(Item)
889 elif ExtName.upper() == '.DEC' and self.CheckMulDec:
890 if Item == ContainerFileName:
891 continue
892 Logger.Error('MkPkg',
893 UPT_MUL_DEC_ERROR,
894 ST.ERR_MUL_DEC_ERROR%(ContainerFilePath,
895 ContainerFileName,
896 Item))
897
898 self.SetModuleFileList(ModuleFileList)
899
900 ## Show detailed information of Package
901 #
902 # Print all members and their values of Package class
903 #
904 def ShowPackage(self):
905 print('\nName =', self.GetName())
906 print('\nBaseName =', self.GetBaseName())
907 print('\nVersion =', self.GetVersion())
908 print('\nGuid =', self.GetGuid())
909
910 print('\nStandardIncludes = %d ' \
911 % len(self.GetStandardIncludeFileList()), end=' ')
912 for Item in self.GetStandardIncludeFileList():
913 print(Item.GetFilePath(), ' ', Item.GetSupArchList())
914 print('\nPackageIncludes = %d \n' \
915 % len(self.GetPackageIncludeFileList()), end=' ')
916 for Item in self.GetPackageIncludeFileList():
917 print(Item.GetFilePath(), ' ', Item.GetSupArchList())
918
919 print('\nGuids =', self.GetGuidList())
920 for Item in self.GetGuidList():
921 print(Item.GetCName(), Item.GetGuid(), Item.GetSupArchList())
922 print('\nProtocols =', self.GetProtocolList())
923 for Item in self.GetProtocolList():
924 print(Item.GetCName(), Item.GetGuid(), Item.GetSupArchList())
925 print('\nPpis =', self.GetPpiList())
926 for Item in self.GetPpiList():
927 print(Item.GetCName(), Item.GetGuid(), Item.GetSupArchList())
928 print('\nLibraryClasses =', self.GetLibraryClassList())
929 for Item in self.GetLibraryClassList():
930 print(Item.GetLibraryClass(), Item.GetRecommendedInstance(), \
931 Item.GetSupArchList())
932 print('\nPcds =', self.GetPcdList())
933 for Item in self.GetPcdList():
934 print('CName=', Item.GetCName(), 'TokenSpaceGuidCName=', \
935 Item.GetTokenSpaceGuidCName(), \
936 'DefaultValue=', Item.GetDefaultValue(), \
937 'ValidUsage=', Item.GetValidUsage(), \
938 'SupArchList', Item.GetSupArchList(), \
939 'Token=', Item.GetToken(), 'DatumType=', Item.GetDatumType())
940
941 for Item in self.GetMiscFileList():
942 print(Item.GetName())
943 for FileObjectItem in Item.GetFileList():
944 print(FileObjectItem.GetURI())
945 print('****************\n')
946
947 ## GenPcdDeclaration
948 #
949 # @param ContainerFile: File name of the DEC file
950 # @param PcdInfo: Pcd information, of format (TokenGuidCName,
951 # TokenName, Value, DatumType, Token, Type,
952 # GenericComment, TailComment, Arch)
953 # @param Language: The language of HelpText, Prompt
954 #
955 def GenPcdDeclaration(ContainerFile, PcdInfo, Language, MacroReplaceDict):
956 HelpStr = ''
957 PromptStr = ''
958 TailHelpStr = ''
959 TokenGuidCName, TokenName, Value, DatumType, Token, Type, \
960 GenericComment, TailComment, Arch = PcdInfo
961 Pcd = PcdObject()
962 Pcd.SetCName(TokenName)
963 Pcd.SetToken(Token)
964 Pcd.SetTokenSpaceGuidCName(TokenGuidCName)
965 Pcd.SetDatumType(DatumType)
966 Pcd.SetDefaultValue(Value)
967 Pcd.SetValidUsage(Type)
968 #
969 # MaxDatumSize is required field for 'VOID*' PCD
970 #
971 if DatumType == TAB_PTR_TYPE_PCD:
972 Pcd.SetMaxDatumSize(ITEM_UNDEFINED)
973
974 SupArchList = [Arch]
975 Pcd.SetSupArchList(SupArchList)
976
977 if GenericComment:
978 HelpStr, PcdErrList, PromptStr = ParseDecPcdGenericComment(GenericComment,
979 ContainerFile,
980 TokenGuidCName,
981 TokenName,
982 MacroReplaceDict)
983 if PcdErrList:
984 Pcd.SetPcdErrorsList(PcdErrList)
985
986 if TailComment:
987 SupModuleList, TailHelpStr = ParseDecPcdTailComment(TailComment,
988 ContainerFile)
989 if SupModuleList:
990 Pcd.SetSupModuleList(SupModuleList)
991
992 if HelpStr and (not HelpStr.endswith('\n')) and TailHelpStr:
993 HelpStr += '\n'
994 HelpStr += TailHelpStr
995 if HelpStr:
996 HelpTxtObj = TextObject()
997 HelpTxtObj.SetLang(Language)
998 HelpTxtObj.SetString(HelpStr)
999 Pcd.SetHelpTextList([HelpTxtObj])
1000 if PromptStr:
1001 TxtObj = TextObject()
1002 TxtObj.SetLang(Language)
1003 TxtObj.SetString(PromptStr)
1004 Pcd.SetPromptList([TxtObj])
1005
1006 return Pcd