mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-10-30 18:53:45 +01:00 
			
		
		
		
	https://bugzilla.tianocore.org/show_bug.cgi?id=1373 Replace BSD 2-Clause License with BSD+Patent License. This change is based on the following emails: https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html RFCs with detailed process for the license change: V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Bob Feng <bob.c.feng@intel.com>
		
			
				
	
	
		
			670 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			670 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| ## @file
 | |
| # This file is used to define class objects of INF file [Pcds] section.
 | |
| # It will consumed by InfParser.
 | |
| #
 | |
| # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
 | |
| #
 | |
| # SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| '''
 | |
| InfPcdObject
 | |
| '''
 | |
| import os
 | |
| import re
 | |
| 
 | |
| from Logger import StringTable as ST
 | |
| from Logger import ToolError
 | |
| import Logger.Log as Logger
 | |
| from Library import GlobalData
 | |
| from Library import DataType as DT
 | |
| 
 | |
| from Library.Misc import Sdict
 | |
| from Library.Misc import GetHelpStringByRemoveHashKey
 | |
| from Library.ParserValidate import IsValidPcdType
 | |
| from Library.ParserValidate import IsValidCVariableName
 | |
| from Library.ParserValidate import IsValidPcdValue
 | |
| from Library.ParserValidate import IsValidArch
 | |
| from Library.CommentParsing import ParseComment
 | |
| from Library.StringUtils import GetSplitValueList
 | |
| from Library.StringUtils import IsHexDigitUINT32
 | |
| from Library.ExpressionValidate import IsValidFeatureFlagExp
 | |
| from Parser.InfAsBuiltProcess import GetPackageListInfo
 | |
| from Parser.DecParser import Dec
 | |
| 
 | |
| from Object.Parser.InfPackagesObject import InfPackageItem
 | |
| 
 | |
| def ValidateArch(ArchItem, PcdTypeItem1, LineNo, SupArchDict, SupArchList):
 | |
|     #
 | |
|     # Validate Arch
 | |
|     #
 | |
|     if (ArchItem == '' or ArchItem is None):
 | |
|         ArchItem = 'COMMON'
 | |
| 
 | |
|     if PcdTypeItem1.upper != DT.TAB_INF_FEATURE_PCD.upper():
 | |
|         ArchList = GetSplitValueList(ArchItem, ' ')
 | |
|         for ArchItemNew in ArchList:
 | |
|             if not IsValidArch(ArchItemNew):
 | |
|                 Logger.Error("InfParser",
 | |
|                              ToolError.FORMAT_INVALID,
 | |
|                              ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID % (ArchItemNew),
 | |
|                              File=GlobalData.gINF_MODULE_NAME,
 | |
|                              Line=LineNo,
 | |
|                              ExtraData=ArchItemNew)
 | |
|         SupArchDict[PcdTypeItem1] = ArchList
 | |
|     else:
 | |
|         SupArchList.append(ArchItem)
 | |
| 
 | |
|     return SupArchList, SupArchDict
 | |
| 
 | |
| def ParsePcdComment(CommentList, PcdTypeItem, PcdItemObj):
 | |
|     CommentInsList = []
 | |
|     PreUsage = None
 | |
|     PreHelpText = ''
 | |
|     BlockFlag = -1
 | |
|     FFEHelpText = ''
 | |
|     CommentItemHelpText = ''
 | |
|     Count = 0
 | |
|     for CommentItem in CommentList:
 | |
|         Count = Count + 1
 | |
|         CommentItemUsage, CommentType, CommentString, CommentItemHelpText = ParseComment(CommentItem,
 | |
|                                                                              DT.ALL_USAGE_TOKENS,
 | |
|                                                                              {},
 | |
|                                                                              [],
 | |
|                                                                              False)
 | |
|         if CommentType and CommentString:
 | |
|             pass
 | |
| 
 | |
|         if PcdTypeItem == 'FeaturePcd':
 | |
|             CommentItemUsage = DT.USAGE_ITEM_CONSUMES
 | |
|             if CommentItemHelpText is None:
 | |
|                 CommentItemHelpText = ''
 | |
| 
 | |
|             if Count == 1:
 | |
|                 FFEHelpText = CommentItemHelpText
 | |
|             else:
 | |
|                 FFEHelpText = FFEHelpText + DT.END_OF_LINE + CommentItemHelpText
 | |
| 
 | |
|             if Count == len(CommentList):
 | |
|                 CommentItemHelpText = FFEHelpText
 | |
|                 BlockFlag = 4
 | |
|             else:
 | |
|                 continue
 | |
| 
 | |
|         if CommentItemHelpText is None:
 | |
|             CommentItemHelpText = ''
 | |
|             if Count == len(CommentList) and CommentItemUsage == DT.ITEM_UNDEFINED:
 | |
|                 CommentItemHelpText = DT.END_OF_LINE
 | |
| 
 | |
|         if Count == len(CommentList) and (BlockFlag == 1 or BlockFlag == 2):
 | |
|             if CommentItemUsage == DT.ITEM_UNDEFINED:
 | |
|                 BlockFlag = 4
 | |
|             else:
 | |
|                 BlockFlag = 3
 | |
|         elif BlockFlag == -1 and Count == len(CommentList):
 | |
|             BlockFlag = 4
 | |
| 
 | |
|         if BlockFlag == -1 or BlockFlag == 1 or BlockFlag == 2:
 | |
|             if CommentItemUsage == DT.ITEM_UNDEFINED:
 | |
|                 if BlockFlag == -1:
 | |
|                     BlockFlag = 1
 | |
|                 elif BlockFlag == 1:
 | |
|                     BlockFlag = 2
 | |
|             else:
 | |
|                 if BlockFlag == 1 or BlockFlag == 2:
 | |
|                     BlockFlag = 3
 | |
|                 elif BlockFlag == -1:
 | |
|                     BlockFlag = 4
 | |
|         #
 | |
|         # Combine two comment line if they are generic comment
 | |
|         #
 | |
|         if CommentItemUsage == PreUsage == DT.ITEM_UNDEFINED:
 | |
|             CommentItemHelpText = PreHelpText + DT.END_OF_LINE + CommentItemHelpText
 | |
| 
 | |
|             PreHelpText = CommentItemHelpText
 | |
| 
 | |
|         if BlockFlag == 4:
 | |
|             CommentItemIns = InfPcdItemCommentContent()
 | |
|             CommentItemIns.SetUsageItem(CommentItemUsage)
 | |
|             CommentItemIns.SetHelpStringItem(CommentItemHelpText)
 | |
|             CommentInsList.append(CommentItemIns)
 | |
| 
 | |
|             BlockFlag = -1
 | |
|             PreUsage = None
 | |
|             PreHelpText = ''
 | |
| 
 | |
|         elif BlockFlag == 3:
 | |
|             #
 | |
|             # Add previous help string
 | |
|             #
 | |
|             CommentItemIns = InfPcdItemCommentContent()
 | |
|             CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED)
 | |
|             if PreHelpText == '' or PreHelpText.endswith(DT.END_OF_LINE):
 | |
|                 PreHelpText += DT.END_OF_LINE
 | |
|             CommentItemIns.SetHelpStringItem(PreHelpText)
 | |
|             CommentInsList.append(CommentItemIns)
 | |
|             #
 | |
|             # Add Current help string
 | |
|             #
 | |
|             CommentItemIns = InfPcdItemCommentContent()
 | |
|             CommentItemIns.SetUsageItem(CommentItemUsage)
 | |
|             CommentItemIns.SetHelpStringItem(CommentItemHelpText)
 | |
|             CommentInsList.append(CommentItemIns)
 | |
| 
 | |
|             BlockFlag = -1
 | |
|             PreUsage = None
 | |
|             PreHelpText = ''
 | |
| 
 | |
|         else:
 | |
|             PreUsage = CommentItemUsage
 | |
|             PreHelpText = CommentItemHelpText
 | |
| 
 | |
|     PcdItemObj.SetHelpStringList(CommentInsList)
 | |
| 
 | |
|     return PcdItemObj
 | |
| 
 | |
| class InfPcdItemCommentContent():
 | |
|     def __init__(self):
 | |
|         #
 | |
|         # ## SOMETIMES_CONSUMES ## HelpString
 | |
|         #
 | |
|         self.UsageItem = ''
 | |
|         #
 | |
|         # Help String
 | |
|         #
 | |
|         self.HelpStringItem = ''
 | |
| 
 | |
|     def SetUsageItem(self, UsageItem):
 | |
|         self.UsageItem = UsageItem
 | |
|     def GetUsageItem(self):
 | |
|         return self.UsageItem
 | |
| 
 | |
|     def SetHelpStringItem(self, HelpStringItem):
 | |
|         self.HelpStringItem = HelpStringItem
 | |
|     def GetHelpStringItem(self):
 | |
|         return self.HelpStringItem
 | |
| 
 | |
| ## InfPcdItem
 | |
| #
 | |
| # This class defined Pcd item used in Module files
 | |
| #
 | |
| # @param CName:                Input value for CName, default is ''
 | |
| # @param Token:                Input value for Token, default is ''
 | |
| # @param TokenSpaceGuidCName:  Input value for TokenSpaceGuidCName, default
 | |
| #                              is ''
 | |
| # @param DatumType:            Input value for DatumType, default is ''
 | |
| # @param MaxDatumSize:         Input value for MaxDatumSize, default is ''
 | |
| # @param DefaultValue:         Input value for DefaultValue, default is ''
 | |
| # @param ItemType:             Input value for ItemType, default is ''
 | |
| # @param ValidUsage:           Input value for ValidUsage, default is []
 | |
| # @param SkuInfoList:          Input value for SkuInfoList, default is {}
 | |
| # @param SupModuleList:        Input value for SupModuleList, default is []
 | |
| #
 | |
| class InfPcdItem():
 | |
|     def __init__(self):
 | |
|         self.CName = ''
 | |
|         self.Token = ''
 | |
|         self.TokenSpaceGuidCName = ''
 | |
|         self.TokenSpaceGuidValue = ''
 | |
|         self.DatumType = ''
 | |
|         self.MaxDatumSize = ''
 | |
|         self.DefaultValue = ''
 | |
|         self.Offset = ''
 | |
|         self.ValidUsage = ''
 | |
|         self.ItemType = ''
 | |
|         self.SupModuleList = []
 | |
|         self.HelpStringList = []
 | |
|         self.FeatureFlagExp = ''
 | |
|         self.SupArchList = []
 | |
|         self.PcdErrorsList = []
 | |
| 
 | |
|     def SetCName(self, CName):
 | |
|         self.CName = CName
 | |
|     def GetCName(self):
 | |
|         return self.CName
 | |
| 
 | |
|     def SetToken(self, Token):
 | |
|         self.Token = Token
 | |
|     def GetToken(self):
 | |
|         return self.Token
 | |
| 
 | |
|     def SetTokenSpaceGuidCName(self, TokenSpaceGuidCName):
 | |
|         self.TokenSpaceGuidCName = TokenSpaceGuidCName
 | |
|     def GetTokenSpaceGuidCName(self):
 | |
|         return self.TokenSpaceGuidCName
 | |
| 
 | |
|     def SetTokenSpaceGuidValue(self, TokenSpaceGuidValue):
 | |
|         self.TokenSpaceGuidValue = TokenSpaceGuidValue
 | |
|     def GetTokenSpaceGuidValue(self):
 | |
|         return self.TokenSpaceGuidValue
 | |
| 
 | |
|     def SetDatumType(self, DatumType):
 | |
|         self.DatumType = DatumType
 | |
|     def GetDatumType(self):
 | |
|         return self.DatumType
 | |
| 
 | |
|     def SetMaxDatumSize(self, MaxDatumSize):
 | |
|         self.MaxDatumSize = MaxDatumSize
 | |
|     def GetMaxDatumSize(self):
 | |
|         return self.MaxDatumSize
 | |
| 
 | |
|     def SetDefaultValue(self, DefaultValue):
 | |
|         self.DefaultValue = DefaultValue
 | |
|     def GetDefaultValue(self):
 | |
|         return self.DefaultValue
 | |
| 
 | |
|     def SetPcdErrorsList(self, PcdErrorsList):
 | |
|         self.PcdErrorsList = PcdErrorsList
 | |
|     def GetPcdErrorsList(self):
 | |
|         return self.PcdErrorsList
 | |
| 
 | |
|     def SetItemType(self, ItemType):
 | |
|         self.ItemType = ItemType
 | |
|     def GetItemType(self):
 | |
|         return self.ItemType
 | |
| 
 | |
|     def SetSupModuleList(self, SupModuleList):
 | |
|         self.SupModuleList = SupModuleList
 | |
|     def GetSupModuleList(self):
 | |
|         return self.SupModuleList
 | |
| 
 | |
|     def SetHelpStringList(self, HelpStringList):
 | |
|         self.HelpStringList = HelpStringList
 | |
|     def GetHelpStringList(self):
 | |
|         return self.HelpStringList
 | |
| 
 | |
|     def SetFeatureFlagExp(self, FeatureFlagExp):
 | |
|         self.FeatureFlagExp = FeatureFlagExp
 | |
|     def GetFeatureFlagExp(self):
 | |
|         return self.FeatureFlagExp
 | |
| 
 | |
|     def SetSupportArchList(self, ArchList):
 | |
|         self.SupArchList = ArchList
 | |
|     def GetSupportArchList(self):
 | |
|         return self.SupArchList
 | |
| 
 | |
|     def SetOffset(self, Offset):
 | |
|         self.Offset = Offset
 | |
|     def GetOffset(self):
 | |
|         return self.Offset
 | |
| 
 | |
|     def SetValidUsage(self, ValidUsage):
 | |
|         self.ValidUsage = ValidUsage
 | |
| 
 | |
|     def GetValidUsage(self):
 | |
|         return self.ValidUsage
 | |
| 
 | |
| ##
 | |
| #
 | |
| #
 | |
| #
 | |
| class InfPcdObject():
 | |
|     def __init__(self, FileName):
 | |
|         self.Pcds = Sdict()
 | |
|         self.FileName = FileName
 | |
| 
 | |
|     def SetPcds(self, PcdContent, KeysList=None, PackageInfo=None):
 | |
| 
 | |
|         if GlobalData.gIS_BINARY_INF:
 | |
|             self.SetAsBuildPcds(PcdContent, KeysList, PackageInfo)
 | |
|             return True
 | |
| 
 | |
|         #
 | |
|         # Validate Arch
 | |
|         #
 | |
|         SupArchList = []
 | |
|         SupArchDict = {}
 | |
|         PcdTypeItem = ''
 | |
|         for (PcdTypeItem1, ArchItem, LineNo) in KeysList:
 | |
|             SupArchList, SupArchDict = ValidateArch(ArchItem, PcdTypeItem1, LineNo, SupArchDict, SupArchList)
 | |
| 
 | |
|             #
 | |
|             # Validate PcdType
 | |
|             #
 | |
|             if (PcdTypeItem1 == '' or PcdTypeItem1 is None):
 | |
|                 return False
 | |
|             else:
 | |
|                 if not IsValidPcdType(PcdTypeItem1):
 | |
|                     Logger.Error("InfParser",
 | |
|                                  ToolError.FORMAT_INVALID,
 | |
|                                  ST.ERR_INF_PARSER_PCD_SECTION_TYPE_ERROR % (DT.PCD_USAGE_TYPE_LIST_OF_MODULE),
 | |
|                                  File=GlobalData.gINF_MODULE_NAME,
 | |
|                                  Line=LineNo,
 | |
|                                  ExtraData=PcdTypeItem1)
 | |
|                     return False
 | |
| 
 | |
|             PcdTypeItem = PcdTypeItem1
 | |
| 
 | |
|             for PcdItem in PcdContent:
 | |
|                 PcdItemObj = InfPcdItem()
 | |
|                 CommentList = PcdItem[1]
 | |
|                 CurrentLineOfPcdItem = PcdItem[2]
 | |
|                 PcdItem = PcdItem[0]
 | |
| 
 | |
|                 if CommentList is not None and len(CommentList) != 0:
 | |
|                     PcdItemObj = ParsePcdComment(CommentList, PcdTypeItem, PcdItemObj)
 | |
|                 else:
 | |
|                     CommentItemIns = InfPcdItemCommentContent()
 | |
|                     CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED)
 | |
|                     PcdItemObj.SetHelpStringList([CommentItemIns])
 | |
| 
 | |
|                 if len(PcdItem) >= 1 and len(PcdItem) <= 3:
 | |
|                     PcdItemObj = SetPcdName(PcdItem, CurrentLineOfPcdItem, PcdItemObj)
 | |
| 
 | |
|                 if len(PcdItem) >= 2 and len(PcdItem) <= 3:
 | |
|                     #
 | |
|                     # Contain PcdName and Value, validate value.
 | |
|                     #
 | |
|                     if IsValidPcdValue(PcdItem[1]) or PcdItem[1].strip() == "":
 | |
|                         PcdItemObj.SetDefaultValue(PcdItem[1])
 | |
|                     else:
 | |
|                         Logger.Error("InfParser",
 | |
|                                      ToolError.FORMAT_INVALID,
 | |
|                                      ST.ERR_INF_PARSER_PCD_VALUE_INVALID,
 | |
|                                      File=CurrentLineOfPcdItem[2],
 | |
|                                      Line=CurrentLineOfPcdItem[1],
 | |
|                                      ExtraData=PcdItem[1])
 | |
| 
 | |
|                 if len(PcdItem) == 3:
 | |
|                     #
 | |
|                     # Contain PcdName, value, and FeatureFlag express
 | |
|                     #
 | |
|                     #
 | |
|                     # Validate Feature Flag Express
 | |
|                     #
 | |
|                     if PcdItem[2].strip() == '':
 | |
|                         Logger.Error("InfParser",
 | |
|                                      ToolError.FORMAT_INVALID,
 | |
|                                      ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
 | |
|                                      File=CurrentLineOfPcdItem[2],
 | |
|                                      Line=CurrentLineOfPcdItem[1],
 | |
|                                      ExtraData=CurrentLineOfPcdItem[0])
 | |
|                     #
 | |
|                     # Validate FFE
 | |
|                     #
 | |
|                     FeatureFlagRtv = IsValidFeatureFlagExp(PcdItem[2].strip())
 | |
|                     if not FeatureFlagRtv[0]:
 | |
|                         Logger.Error("InfParser",
 | |
|                                      ToolError.FORMAT_INVALID,
 | |
|                                      ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID % (FeatureFlagRtv[1]),
 | |
|                                      File=CurrentLineOfPcdItem[2],
 | |
|                                      Line=CurrentLineOfPcdItem[1],
 | |
|                                      ExtraData=CurrentLineOfPcdItem[0])
 | |
|                     PcdItemObj.SetFeatureFlagExp(PcdItem[2])
 | |
| 
 | |
|                 if len(PcdItem) < 1 or len(PcdItem) > 3:
 | |
|                     Logger.Error("InfParser",
 | |
|                                  ToolError.FORMAT_INVALID,
 | |
|                                  ST.ERR_INF_PARSER_PCD_SECTION_CONTENT_ERROR,
 | |
|                                  File=CurrentLineOfPcdItem[2],
 | |
|                                  Line=CurrentLineOfPcdItem[1],
 | |
|                                  ExtraData=CurrentLineOfPcdItem[0])
 | |
|                     return False
 | |
| 
 | |
|                 if PcdTypeItem.upper != DT.TAB_INF_FEATURE_PCD.upper():
 | |
|                     PcdItemObj.SetSupportArchList(SupArchDict[PcdTypeItem])
 | |
|                 else:
 | |
|                     PcdItemObj.SetSupportArchList(SupArchList)
 | |
| 
 | |
|                 if (PcdTypeItem, PcdItemObj) in self.Pcds:
 | |
|                     PcdsList = self.Pcds[PcdTypeItem, PcdItemObj]
 | |
|                     PcdsList.append(PcdItemObj)
 | |
|                     self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList
 | |
|                 else:
 | |
|                     PcdsList = []
 | |
|                     PcdsList.append(PcdItemObj)
 | |
|                     self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList
 | |
| 
 | |
|         return True
 | |
| 
 | |
|     def SetAsBuildPcds(self, PcdContent, KeysList=None, PackageInfo=None):
 | |
|         for PcdItem in PcdContent:
 | |
|             PcdItemObj = InfPcdItem()
 | |
|             CommentList = PcdItem[1]
 | |
|             CurrentLineOfPcdItem = PcdItem[2]
 | |
|             PcdItem = PcdItem[0]
 | |
|             CommentString = ''
 | |
| 
 | |
|             for CommentLine in CommentList:
 | |
|                 CommentString = GetHelpStringByRemoveHashKey(CommentLine)
 | |
|                 CommentItemIns = InfPcdItemCommentContent()
 | |
|                 CommentItemIns.SetHelpStringItem(CommentString)
 | |
|                 CommentItemIns.SetUsageItem(CommentString)
 | |
|                 PcdItemObj.SetHelpStringList(PcdItemObj.GetHelpStringList() + [CommentItemIns])
 | |
|                 if PcdItemObj.GetValidUsage():
 | |
|                     PcdItemObj.SetValidUsage(PcdItemObj.GetValidUsage() + DT.TAB_VALUE_SPLIT + CommentString)
 | |
|                 else:
 | |
|                     PcdItemObj.SetValidUsage(CommentString)
 | |
| 
 | |
|             PcdItemObj.SetItemType(KeysList[0][0])
 | |
|             #
 | |
|             # Set PcdTokenSpaceCName and CName
 | |
|             #
 | |
|             PcdItemObj = SetPcdName(PcdItem, CurrentLineOfPcdItem, PcdItemObj)
 | |
|             #
 | |
|             # Set Value/DatumType/OffSet/Token
 | |
|             #
 | |
|             PcdItemObj = SetValueDatumTypeMaxSizeToken(PcdItem,
 | |
|                                                       CurrentLineOfPcdItem,
 | |
|                                                       PcdItemObj,
 | |
|                                                       KeysList[0][1],
 | |
|                                                       PackageInfo)
 | |
| 
 | |
|             PcdTypeItem = KeysList[0][0]
 | |
|             if (PcdTypeItem, PcdItemObj) in self.Pcds:
 | |
|                 PcdsList = self.Pcds[PcdTypeItem, PcdItemObj]
 | |
|                 PcdsList.append(PcdItemObj)
 | |
|                 self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList
 | |
|             else:
 | |
|                 PcdsList = []
 | |
|                 PcdsList.append(PcdItemObj)
 | |
|                 self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList
 | |
| 
 | |
|     def GetPcds(self):
 | |
|         return self.Pcds
 | |
| 
 | |
| def ParserPcdInfoInDec(String):
 | |
|     ValueList = GetSplitValueList(String, DT.TAB_VALUE_SPLIT, 3)
 | |
| 
 | |
|     #
 | |
|     # DatumType, Token
 | |
|     #
 | |
|     return ValueList[2], ValueList[3]
 | |
| 
 | |
| def SetValueDatumTypeMaxSizeToken(PcdItem, CurrentLineOfPcdItem, PcdItemObj, Arch, PackageInfo=None):
 | |
|     #
 | |
|     # Package information not been generated currently, we need to parser INF file to get information.
 | |
|     #
 | |
|     if not PackageInfo:
 | |
|         PackageInfo = []
 | |
|         InfFileName = CurrentLineOfPcdItem[2]
 | |
|         PackageInfoList = GetPackageListInfo(InfFileName, GlobalData.gWORKSPACE, -1)
 | |
|         for PackageInfoListItem in PackageInfoList:
 | |
|             PackageInfoIns = InfPackageItem()
 | |
|             PackageInfoIns.SetPackageName(PackageInfoListItem)
 | |
|             PackageInfo.append(PackageInfoIns)
 | |
| 
 | |
|     PcdInfoInDecHasFound = False
 | |
|     for PackageItem in PackageInfo:
 | |
|         if PcdInfoInDecHasFound:
 | |
|             break
 | |
|         PackageName = PackageItem.PackageName
 | |
|         #
 | |
|         # Open DEC file to get information
 | |
|         #
 | |
|         FullFileName = os.path.normpath(os.path.realpath(os.path.join(GlobalData.gWORKSPACE, PackageName)))
 | |
| 
 | |
|         DecParser = None
 | |
|         if FullFileName not in GlobalData.gPackageDict:
 | |
|             DecParser = Dec(FullFileName)
 | |
|             GlobalData.gPackageDict[FullFileName] = DecParser
 | |
|         else:
 | |
|             DecParser = GlobalData.gPackageDict[FullFileName]
 | |
| 
 | |
|         #
 | |
|         # Find PCD information.
 | |
|         #
 | |
|         DecPcdsDict = DecParser.GetPcdSectionObject().ValueDict
 | |
|         for Key in DecPcdsDict.keys():
 | |
|             if (Key[0] == 'PCDSDYNAMICEX' and PcdItemObj.GetItemType() == 'PcdEx') and \
 | |
|                 (Key[1] == 'COMMON' or Key[1] == Arch):
 | |
|                 for PcdInDec in DecPcdsDict[Key]:
 | |
|                     if PcdInDec.TokenCName == PcdItemObj.CName and \
 | |
|                        PcdInDec.TokenSpaceGuidCName == PcdItemObj.TokenSpaceGuidCName:
 | |
|                         PcdItemObj.SetToken(PcdInDec.TokenValue)
 | |
|                         PcdItemObj.SetDatumType(PcdInDec.DatumType)
 | |
|                         PcdItemObj.SetSupportArchList([Arch])
 | |
|                         PcdItemObj.SetDefaultValue(PcdInDec.DefaultValue)
 | |
| 
 | |
|             if (Key[0] == 'PCDSPATCHABLEINMODULE' and PcdItemObj.GetItemType() == 'PatchPcd') and \
 | |
|            (Key[1] == 'COMMON' or Key[1] == Arch):
 | |
|                 for PcdInDec in DecPcdsDict[Key]:
 | |
|                     if PcdInDec.TokenCName == PcdItemObj.CName and \
 | |
|                        PcdInDec.TokenSpaceGuidCName == PcdItemObj.TokenSpaceGuidCName:
 | |
|                         PcdItemObj.SetToken(PcdInDec.TokenValue)
 | |
|                         PcdItemObj.SetDatumType(PcdInDec.DatumType)
 | |
|                         PcdItemObj.SetSupportArchList([Arch])
 | |
| 
 | |
|         if PcdItemObj.GetDatumType() == 'VOID*':
 | |
|             if len(PcdItem) > 1:
 | |
|                 PcdItemObj.SetMaxDatumSize('%s' % (len(GetSplitValueList(PcdItem[1], DT.TAB_COMMA_SPLIT))))
 | |
| 
 | |
|         DecGuidsDict = DecParser.GetGuidSectionObject().ValueDict
 | |
|         for Key in DecGuidsDict.keys():
 | |
|             if Key == 'COMMON' or Key == Arch:
 | |
|                 for GuidInDec in DecGuidsDict[Key]:
 | |
|                     if GuidInDec.GuidCName == PcdItemObj.TokenSpaceGuidCName:
 | |
|                         PcdItemObj.SetTokenSpaceGuidValue(GuidInDec.GuidString)
 | |
| 
 | |
|     if PcdItemObj.GetItemType().upper() == DT.TAB_INF_PATCH_PCD.upper():
 | |
|         #
 | |
|         # Validate Value.
 | |
|         #
 | |
|         # convert the value from a decimal 0 to a formatted hex value.
 | |
|         if PcdItem[1] == "0":
 | |
|             DatumType = PcdItemObj.GetDatumType()
 | |
|             if DatumType == "UINT8":
 | |
|                 PcdItem[1] = "0x00"
 | |
|             if DatumType == "UINT16":
 | |
|                 PcdItem[1] = "0x0000"
 | |
|             if DatumType == "UINT32":
 | |
|                 PcdItem[1] = "0x00000000"
 | |
|             if DatumType == "UINT64":
 | |
|                 PcdItem[1] = "0x0000000000000000"
 | |
| 
 | |
|         if ValidatePcdValueOnDatumType(PcdItem[1], PcdItemObj.GetDatumType()):
 | |
|             PcdItemObj.SetDefaultValue(PcdItem[1])
 | |
|         else:
 | |
|             Logger.Error("InfParser",
 | |
|                      ToolError.FORMAT_INVALID,
 | |
|                      ST.ERR_ASBUILD_PCD_VALUE_INVALID % ("\"" + PcdItem[1] + "\"", "\"" +
 | |
|                                                        PcdItemObj.GetDatumType() + "\""),
 | |
|                      File=CurrentLineOfPcdItem[2],
 | |
|                      Line=CurrentLineOfPcdItem[1],
 | |
|                      ExtraData=CurrentLineOfPcdItem[0])
 | |
|         #
 | |
|         # validate offset
 | |
|         #
 | |
|         if PcdItemObj.GetItemType().upper() == DT.TAB_INF_PATCH_PCD.upper():
 | |
|             if not IsHexDigitUINT32(PcdItem[2]):
 | |
|                 Logger.Error("InfParser",
 | |
|                          ToolError.FORMAT_INVALID,
 | |
|                          ST.ERR_ASBUILD_PCD_OFFSET_FORMAT_INVALID % ("\"" + PcdItem[2] + "\""),
 | |
|                          File=CurrentLineOfPcdItem[2],
 | |
|                          Line=CurrentLineOfPcdItem[1],
 | |
|                          ExtraData=CurrentLineOfPcdItem[0])
 | |
|             PcdItemObj.SetOffset(PcdItem[2])
 | |
| 
 | |
|     if PcdItemObj.GetToken() == '' or PcdItemObj.GetDatumType() == '':
 | |
|         Logger.Error("InfParser",
 | |
|                      ToolError.FORMAT_INVALID,
 | |
|                      ST.ERR_ASBUILD_PCD_DECLARITION_MISS % ("\"" + PcdItem[0] + "\""),
 | |
|                      File=CurrentLineOfPcdItem[2],
 | |
|                      Line=CurrentLineOfPcdItem[1],
 | |
|                      ExtraData=CurrentLineOfPcdItem[0])
 | |
| 
 | |
|     return PcdItemObj
 | |
| 
 | |
| def ValidatePcdValueOnDatumType(Value, Type):
 | |
| 
 | |
|     Value = Value.strip()
 | |
|     #
 | |
|     # Boolean type only allow 0x00 or 0x01 as value per INF spec
 | |
|     #
 | |
|     if Type == 'BOOLEAN':
 | |
|         if not (Value == '0x00' or Value == '0x01'):
 | |
|             return False
 | |
|     elif Type == 'VOID*':
 | |
|         if not Value.startswith("{"):
 | |
|             return False
 | |
|         if not Value.endswith("}"):
 | |
|             return False
 | |
|         #
 | |
|         # Strip "{" at head and "}" at tail.
 | |
|         #
 | |
|         Value = Value[1:-1]
 | |
|         ValueList = GetSplitValueList(Value, DT.TAB_COMMA_SPLIT)
 | |
| 
 | |
|         ReIsValidHexByte = re.compile("^0x[0-9a-f]{1,2}$", re.IGNORECASE)
 | |
|         for ValueItem in ValueList:
 | |
|             if not ReIsValidHexByte.match(ValueItem):
 | |
|                 return False
 | |
| 
 | |
|     elif Type == 'UINT8' or Type == 'UINT16' or Type == 'UINT32' or Type == 'UINT64':
 | |
| 
 | |
|         ReIsValidUint8z = re.compile('^0[x|X][a-fA-F0-9]{2}$')
 | |
|         ReIsValidUint16z = re.compile('^0[x|X][a-fA-F0-9]{4}$')
 | |
|         ReIsValidUint32z = re.compile('^0[x|X][a-fA-F0-9]{8}$')
 | |
|         ReIsValidUint64z = re.compile('^0[x|X][a-fA-F0-9]{16}$')
 | |
| 
 | |
|         if not ReIsValidUint8z.match(Value) and Type == 'UINT8':
 | |
|             return False
 | |
|         elif not ReIsValidUint16z.match(Value) and  Type == 'UINT16':
 | |
|             return False
 | |
|         elif not ReIsValidUint32z.match(Value) and  Type == 'UINT32':
 | |
|             return False
 | |
|         elif not ReIsValidUint64z.match(Value) and  Type == 'UINT64':
 | |
|             return False
 | |
|     else:
 | |
|         #
 | |
|         # Since we assume the DEC file always correct, should never go to here.
 | |
|         #
 | |
|         pass
 | |
| 
 | |
|     return True
 | |
| 
 | |
| def SetPcdName(PcdItem, CurrentLineOfPcdItem, PcdItemObj):
 | |
|     #
 | |
|     # Only PCD Name specified
 | |
|     # <PcdName> ::= <TokenSpaceGuidCName> "." <TokenCName>
 | |
|     #
 | |
|     PcdId = GetSplitValueList(PcdItem[0], DT.TAB_SPLIT)
 | |
|     if len(PcdId) != 2:
 | |
|         Logger.Error("InfParser",
 | |
|                      ToolError.FORMAT_INVALID,
 | |
|                      ST.ERR_INF_PARSER_PCD_NAME_FORMAT_ERROR,
 | |
|                      File=CurrentLineOfPcdItem[2],
 | |
|                      Line=CurrentLineOfPcdItem[1],
 | |
|                      ExtraData=CurrentLineOfPcdItem[0])
 | |
|     else:
 | |
|         #
 | |
|         # Validate PcdTokenSpaceGuidCName
 | |
|         #
 | |
|         if not IsValidCVariableName(PcdId[0]):
 | |
|             Logger.Error("InfParser",
 | |
|                          ToolError.FORMAT_INVALID,
 | |
|                          ST.ERR_INF_PARSER_PCD_CVAR_GUID,
 | |
|                          File=CurrentLineOfPcdItem[2],
 | |
|                          Line=CurrentLineOfPcdItem[1],
 | |
|                          ExtraData=PcdId[0])
 | |
|         if not IsValidCVariableName(PcdId[1]):
 | |
|             Logger.Error("InfParser",
 | |
|                          ToolError.FORMAT_INVALID,
 | |
|                          ST.ERR_INF_PARSER_PCD_CVAR_PCDCNAME,
 | |
|                          File=CurrentLineOfPcdItem[2],
 | |
|                          Line=CurrentLineOfPcdItem[1],
 | |
|                          ExtraData=PcdId[1])
 | |
|         PcdItemObj.SetTokenSpaceGuidCName(PcdId[0])
 | |
|         PcdItemObj.SetCName(PcdId[1])
 | |
| 
 | |
|     return PcdItemObj
 |