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