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