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