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