mirror of
https://github.com/acidanthera/audk.git
synced 2025-04-08 17:05:09 +02:00
1. Add a recovery mode for UPT failure 2. Add UNI file support 3. Add binary file header support 4. Add support for PCD error message 5. Add support for replace 6. Format generated INF/DEC files 7. Update dependency check 8. Other minor fixes Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Hess Chen <hesheng.chen@intel.com> Reviewed-by: Gao, Liming <liming.gao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15896 6f19259b-4bc3-4df7-8a09-765794883524
676 lines
26 KiB
Python
676 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 - 2014, Intel Corporation. All rights reserved.<BR>
|
|
#
|
|
# This program and the accompanying materials are licensed and made available
|
|
# under the terms and conditions of the BSD License which accompanies this
|
|
# distribution. The full text of the license may be found at
|
|
# http://opensource.org/licenses/bsd-license.php
|
|
#
|
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
'''
|
|
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.String import GetSplitValueList
|
|
from Library.String 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 == 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 == 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 == 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 == 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 != 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 self.Pcds.has_key((PcdTypeItem, PcdItemObj)):
|
|
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 self.Pcds.has_key((PcdTypeItem, PcdItemObj)):
|
|
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
|