BaseTools: Update --pcd parser to support flexible pcd format

This patch update --pcd parser to support flexible pcd format.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
Yonghong Zhu
2018-03-07 14:14:43 +08:00
parent 0f228f19fb
commit 8565b5829c
8 changed files with 159 additions and 268 deletions

View File

@ -15,7 +15,7 @@
from Common.GlobalData import * from Common.GlobalData import *
from CommonDataClass.Exceptions import BadExpression from CommonDataClass.Exceptions import BadExpression
from CommonDataClass.Exceptions import WrnExpression from CommonDataClass.Exceptions import WrnExpression
from Misc import GuidStringToGuidStructureString, ParseFieldValue from Misc import GuidStringToGuidStructureString, ParseFieldValue, IsFieldValueAnArray
import Common.EdkLogger as EdkLogger import Common.EdkLogger as EdkLogger
import copy import copy
@ -125,6 +125,25 @@ def IsValidCString(Str):
return False return False
return True return True
def BuildOptionValue(PcdValue, GuidDict):
IsArray = False
if PcdValue.startswith('H'):
InputValue = PcdValue[1:]
elif PcdValue.startswith("L'") or PcdValue.startswith("'"):
InputValue = PcdValue
elif PcdValue.startswith('L'):
InputValue = 'L"' + PcdValue[1:] + '"'
else:
InputValue = PcdValue
if IsFieldValueAnArray(InputValue):
IsArray = True
if IsArray:
try:
PcdValue = ValueExpressionEx(InputValue, 'VOID*', GuidDict)(True)
except:
pass
return PcdValue
## ReplaceExprMacro ## ReplaceExprMacro
# #
def ReplaceExprMacro(String, Macros, ExceptionList = None): def ReplaceExprMacro(String, Macros, ExceptionList = None):

View File

@ -1441,6 +1441,22 @@ def ParseConsoleLog(Filename):
Opr.close() Opr.close()
Opw.close() Opw.close()
def IsFieldValueAnArray (Value):
Value = Value.strip()
if Value.startswith('GUID') and Value.endswith(')'):
return True
if Value.startswith('L"') and Value.endswith('"') and len(list(Value[2:-1])) > 1:
return True
if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1:
return True
if Value[0] == '{' and Value[-1] == '}':
return True
if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
return True
if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
return True
return False
def AnalyzePcdExpression(Setting): def AnalyzePcdExpression(Setting):
Setting = Setting.strip() Setting = Setting.strip()
# There might be escaped quote in a string: \", \\\" , \', \\\' # There might be escaped quote in a string: \", \\\" , \', \\\'
@ -2377,31 +2393,6 @@ def PackRegistryFormatGuid(Guid):
int(Guid[4][-2:], 16) int(Guid[4][-2:], 16)
) )
def BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, Value):
if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64,'BOOLEAN']:
if Value.startswith('L') or Value.startswith('"'):
if not Value[1]:
EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')
Value = Value
elif Value.startswith('H'):
if not Value[1]:
EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')
Value = Value[1:]
else:
if not Value[0]:
EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')
Value = '"' + Value + '"'
IsValid, Cause = CheckPcdDatum(PcdDatumType, Value)
if not IsValid:
EdkLogger.error("build", FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))
if PcdDatumType == 'BOOLEAN':
Value = Value.upper()
if Value == 'TRUE' or Value == '1':
Value = '1'
elif Value == 'FALSE' or Value == '0':
Value = '0'
return Value
## Get the integer value from string like "14U" or integer like 2 ## Get the integer value from string like "14U" or integer like 2
# #
# @param Input The object that may be either a integer value or a string # @param Input The object that may be either a integer value or a string

View File

@ -928,6 +928,7 @@ class FdfParser:
if GlobalData.BuildOptionPcd: if GlobalData.BuildOptionPcd:
for Item in GlobalData.BuildOptionPcd: for Item in GlobalData.BuildOptionPcd:
PcdName, TmpValue = Item.split("=") PcdName, TmpValue = Item.split("=")
TmpValue = BuildOptionValue(TmpValue, {})
MacroDict[PcdName.strip()] = TmpValue MacroDict[PcdName.strip()] = TmpValue
# Highest priority # Highest priority

View File

@ -1,7 +1,7 @@
## @file ## @file
# process FFS generation from INF statement # process FFS generation from INF statement
# #
# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2014-2016 Hewlett-Packard Development Company, L.P.<BR> # Copyright (c) 2014-2016 Hewlett-Packard Development Company, L.P.<BR>
# #
# This program and the accompanying materials # This program and the accompanying materials
@ -274,7 +274,9 @@ class FfsInfStatement(FfsInfStatementClassObject):
if GlobalData.BuildOptionPcd: if GlobalData.BuildOptionPcd:
for pcd in GlobalData.BuildOptionPcd: for pcd in GlobalData.BuildOptionPcd:
if PcdKey == (pcd[1], pcd[0]): if PcdKey == (pcd[1], pcd[0]):
DefaultValue = pcd[2] if pcd[2]:
continue
DefaultValue = pcd[3]
BuildOptionOverride = True BuildOptionOverride = True
break break
@ -288,15 +290,15 @@ class FfsInfStatement(FfsInfStatementClassObject):
except BadExpression: except BadExpression:
EdkLogger.error("GenFds", GENFDS_ERROR, 'PCD [%s.%s] Value "%s"' %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValue), File=self.InfFileName) EdkLogger.error("GenFds", GENFDS_ERROR, 'PCD [%s.%s] Value "%s"' %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValue), File=self.InfFileName)
if Pcd.DefaultValue: if Pcd.InfDefaultValue:
try: try:
Pcd.DefaultValue = ValueExpressionEx(Pcd.DefaultValue, Pcd.DatumType, Platform._GuidDict)(True) Pcd.InfDefaultValue = ValueExpressionEx(Pcd.InfDefaultValue, Pcd.DatumType, Platform._GuidDict)(True)
except BadExpression: except BadExpression:
EdkLogger.error("GenFds", GENFDS_ERROR, 'PCD [%s.%s] Value "%s"' %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DefaultValue),File=self.InfFileName) EdkLogger.error("GenFds", GENFDS_ERROR, 'PCD [%s.%s] Value "%s"' %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DefaultValue),File=self.InfFileName)
# Check value, if value are equal, no need to patch # Check value, if value are equal, no need to patch
if Pcd.DatumType == "VOID*": if Pcd.DatumType == "VOID*":
if Pcd.DefaultValue == DefaultValue or DefaultValue in [None, '']: if Pcd.InfDefaultValue == DefaultValue or DefaultValue in [None, '']:
continue continue
# Get the string size from FDF or DSC # Get the string size from FDF or DSC
if DefaultValue[0] == 'L': if DefaultValue[0] == 'L':
@ -310,15 +312,15 @@ class FfsInfStatement(FfsInfStatementClassObject):
Pcd.MaxDatumSize = PatchPcd.MaxDatumSize Pcd.MaxDatumSize = PatchPcd.MaxDatumSize
# If no defined the maximum size in DSC, try to get current size from INF # If no defined the maximum size in DSC, try to get current size from INF
if Pcd.MaxDatumSize in ['', None]: if Pcd.MaxDatumSize in ['', None]:
Pcd.MaxDatumSize = str(len(Pcd.DefaultValue.split(','))) Pcd.MaxDatumSize = str(len(Pcd.InfDefaultValue.split(',')))
else: else:
Base1 = Base2 = 10 Base1 = Base2 = 10
if Pcd.DefaultValue.upper().startswith('0X'): if Pcd.InfDefaultValue.upper().startswith('0X'):
Base1 = 16 Base1 = 16
if DefaultValue.upper().startswith('0X'): if DefaultValue.upper().startswith('0X'):
Base2 = 16 Base2 = 16
try: try:
PcdValueInImg = int(Pcd.DefaultValue, Base1) PcdValueInImg = int(Pcd.InfDefaultValue, Base1)
PcdValueInDscOrFdf = int(DefaultValue, Base2) PcdValueInDscOrFdf = int(DefaultValue, Base2)
if PcdValueInImg == PcdValueInDscOrFdf: if PcdValueInImg == PcdValueInDscOrFdf:
continue continue

View File

@ -38,8 +38,6 @@ from Common.Misc import DirCache, PathClass
from Common.Misc import SaveFileOnChange from Common.Misc import SaveFileOnChange
from Common.Misc import ClearDuplicatedInf from Common.Misc import ClearDuplicatedInf
from Common.Misc import GuidStructureStringToGuidString from Common.Misc import GuidStructureStringToGuidString
from Common.Misc import CheckPcdDatum
from Common.Misc import BuildOptionPcdValueFormat
from Common.BuildVersion import gBUILD_VERSION from Common.BuildVersion import gBUILD_VERSION
from Common.MultipleWorkspace import MultipleWorkspace as mws from Common.MultipleWorkspace import MultipleWorkspace as mws
import FfsFileStatement import FfsFileStatement
@ -369,53 +367,6 @@ def SingleCheckCallback(option, opt_str, value, parser):
else: else:
parser.error("Option %s only allows one instance in command line!" % option) parser.error("Option %s only allows one instance in command line!" % option)
def CheckBuildOptionPcd():
for Arch in GenFdsGlobalVariable.ArchList:
PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag)
for i, pcd in enumerate(GlobalData.BuildOptionPcd):
if type(pcd) is tuple:
continue
(pcdname, pcdvalue) = pcd.split('=')
if not pcdvalue:
EdkLogger.error('GenFds', OPTION_MISSING, "No Value specified for the PCD %s." % (pcdname))
if '.' in pcdname:
(TokenSpaceGuidCName, TokenCName) = pcdname.split('.')
HasTokenSpace = True
else:
TokenCName = pcdname
TokenSpaceGuidCName = ''
HasTokenSpace = False
TokenSpaceGuidCNameList = []
FoundFlag = False
PcdDatumType = ''
NewValue = ''
for package in PkgList:
for key in package.Pcds:
PcdItem = package.Pcds[key]
if HasTokenSpace:
if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):
PcdDatumType = PcdItem.DatumType
NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
FoundFlag = True
else:
if PcdItem.TokenCName == TokenCName:
if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:
if len (TokenSpaceGuidCNameList) < 1:
TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
PcdDatumType = PcdItem.DatumType
TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName
NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
FoundFlag = True
else:
EdkLogger.error(
'GenFds',
PCD_VALIDATION_INFO_ERROR,
"The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
)
GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, NewValue)
## FindExtendTool() ## FindExtendTool()
# #
# Find location of tools to process data # Find location of tools to process data

View File

@ -21,7 +21,7 @@ from Common.String import *
from Common.DataType import * from Common.DataType import *
from Common.Misc import * from Common.Misc import *
from types import * from types import *
from Common.Expression import *
from CommonDataClass.CommonClass import SkuInfoClass from CommonDataClass.CommonClass import SkuInfoClass
from Common.TargetTxtClassObject import * from Common.TargetTxtClassObject import *
from Common.ToolDefClassObject import * from Common.ToolDefClassObject import *
@ -905,36 +905,6 @@ class DscBuildData(PlatformBuildClassObject):
if isinstance(self._Pcds[pcd],StructurePcd) and (self._Pcds[pcd].PcdValueFromComm or self._Pcds[pcd].PcdFieldValueFromComm): if isinstance(self._Pcds[pcd],StructurePcd) and (self._Pcds[pcd].PcdValueFromComm or self._Pcds[pcd].PcdFieldValueFromComm):
UpdateCommandLineValue(self._Pcds[pcd]) UpdateCommandLineValue(self._Pcds[pcd])
def GetFieldValueFromComm(self,ValueStr,TokenSpaceGuidCName, TokenCName, FieldName):
PredictedFieldType = "VOID*"
if ValueStr.startswith('L'):
if not ValueStr[1]:
EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')
ValueStr = ValueStr[0] + '"' + ValueStr[1:] + '"'
PredictedFieldType = "VOID*"
elif ValueStr.startswith('H') or ValueStr.startswith('{'):
EdkLogger.error("build", FORMAT_INVALID, 'Currently we do not support assign H"{...}" format for Pcd field.', ExtraData="%s.%s.%s from command line" % (TokenSpaceGuidCName, TokenCName, FieldName))
ValueStr = ValueStr[1:]
PredictedFieldType = "VOID*"
elif ValueStr.upper() in ['TRUE', '0X1', '0X01', '1', 'FALSE', '0X0', '0X00', '0']:
PredictedFieldType = "BOOLEAN"
elif ValueStr.isdigit() or ValueStr.upper().startswith('0X'):
PredictedFieldType = TAB_UINT16
else:
if not ValueStr[0]:
EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')
ValueStr = '"' + ValueStr + '"'
PredictedFieldType = "VOID*"
IsValid, Cause = CheckPcdDatum(PredictedFieldType, ValueStr)
if not IsValid:
EdkLogger.error("build", FORMAT_INVALID, Cause, ExtraData="%s.%s.%s from command line" % (TokenSpaceGuidCName, TokenCName, FieldName))
if PredictedFieldType == 'BOOLEAN':
ValueStr = ValueStr.upper()
if ValueStr == 'TRUE' or ValueStr == '1':
ValueStr = '1'
elif ValueStr == 'FALSE' or ValueStr == '0':
ValueStr = '0'
return ValueStr
def __ParsePcdFromCommandLine(self): def __ParsePcdFromCommandLine(self):
if GlobalData.BuildOptionPcd: if GlobalData.BuildOptionPcd:
for i, pcd in enumerate(GlobalData.BuildOptionPcd): for i, pcd in enumerate(GlobalData.BuildOptionPcd):
@ -975,148 +945,118 @@ class DscBuildData(PlatformBuildClassObject):
TokenSpaceGuidCNameList = [] TokenSpaceGuidCNameList = []
FoundFlag = False FoundFlag = False
PcdDatumType = '' PcdDatumType = ''
NewValue = '' DisplayName = TokenCName
if FieldName:
DisplayName = TokenCName + '.' + FieldName
if not HasTokenSpace: if not HasTokenSpace:
for key in self.DecPcds:
if TokenCName == key[0]:
if TokenSpaceGuidCName:
EdkLogger.error(
'build',
AUTOGEN_ERROR,
"The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, TokenSpaceGuidCName, key[1])
)
else:
TokenSpaceGuidCName = key[1]
FoundFlag = True
else:
if (TokenCName, TokenSpaceGuidCName) in self.DecPcds:
FoundFlag = True
if FieldName:
NewValue = self.GetFieldValueFromComm(pcdvalue, TokenSpaceGuidCName, TokenCName, FieldName)
GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName,NewValue,("build command options",1))
else:
# Replace \' to ', \\\' to \'
pcdvalue = pcdvalue.replace("\\\\\\'", '\\\\\\"').replace('\\\'', '\'').replace('\\\\\\"', "\\'")
for key in self.DecPcds: for key in self.DecPcds:
PcdItem = self.DecPcds[key] PcdItem = self.DecPcds[key]
if HasTokenSpace: if TokenCName == PcdItem.TokenCName:
if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):
PcdDatumType = PcdItem.DatumType
if pcdvalue.startswith('H'):
try:
pcdvalue = ValueExpressionEx(pcdvalue[1:], PcdDatumType, self._GuidDict)(True)
except BadExpression, Value:
EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
(TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:
pcdvalue = 'H' + pcdvalue
elif pcdvalue.startswith("L'"):
try:
pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)
except BadExpression, Value:
EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
(TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:
pcdvalue = 'H' + pcdvalue
elif pcdvalue.startswith("'"):
try:
pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)
except BadExpression, Value:
EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
(TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:
pcdvalue = 'H' + pcdvalue
elif pcdvalue.startswith('L'):
pcdvalue = 'L"' + pcdvalue[1:] + '"'
try:
pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)
except BadExpression, Value:
EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
(TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
else:
try:
pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)
except BadExpression, Value:
try:
pcdvalue = '"' + pcdvalue + '"'
pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)
except BadExpression, Value:
EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
(TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
FoundFlag = True
else:
if PcdItem.TokenCName == TokenCName:
if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList: if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:
if len (TokenSpaceGuidCNameList) < 1: if len (TokenSpaceGuidCNameList) < 1:
TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName) TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
PcdDatumType = PcdItem.DatumType
TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName
if pcdvalue.startswith('H'): PcdDatumType = PcdItem.DatumType
try:
pcdvalue = ValueExpressionEx(pcdvalue[1:], PcdDatumType, self._GuidDict)(True)
except BadExpression, Value:
EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
(TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64,'BOOLEAN']:
pcdvalue = 'H' + pcdvalue
elif pcdvalue.startswith("L'"):
try:
pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(
True)
except BadExpression, Value:
EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
(TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:
pcdvalue = 'H' + pcdvalue
elif pcdvalue.startswith("'"):
try:
pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(
True)
except BadExpression, Value:
EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
(TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:
pcdvalue = 'H' + pcdvalue
elif pcdvalue.startswith('L'):
pcdvalue = 'L"' + pcdvalue[1:] + '"'
try:
pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(
True)
except BadExpression, Value:
EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
(TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
else:
try:
pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)
except BadExpression, Value:
try:
pcdvalue = '"' + pcdvalue + '"'
pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)
except BadExpression, Value:
EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
(TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
FoundFlag = True FoundFlag = True
else: else:
EdkLogger.error( EdkLogger.error(
'build', 'build',
AUTOGEN_ERROR, AUTOGEN_ERROR,
"The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0]) "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (DisplayName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
) )
GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName,NewValue,("build command options",1)) else:
if (TokenCName, TokenSpaceGuidCName) in self.DecPcds:
FoundFlag = True
if not FoundFlag: if not FoundFlag:
if HasTokenSpace: if HasTokenSpace:
EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, TokenCName)) EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, DisplayName))
else: else:
EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (TokenCName)) EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (DisplayName))
pcdvalue = pcdvalue.replace("\\\\\\'", '\\\\\\"').replace('\\\'', '\'').replace('\\\\\\"', "\\'")
if FieldName:
pcdvalue = self.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict, FieldName)
else:
pcdvalue = self.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict)
IsValid, Cause = CheckPcdDatum(PcdDatumType, pcdvalue)
if not IsValid:
EdkLogger.error("build", FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))
GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue,("build command options",1))
for BuildData in self._Bdb._CACHE_.values(): for BuildData in self._Bdb._CACHE_.values():
if BuildData.MetaFile.Ext == '.dec' or BuildData.MetaFile.Ext == '.dsc': if BuildData.MetaFile.Ext == '.dec' or BuildData.MetaFile.Ext == '.dsc':
continue continue
for key in BuildData.Pcds: for key in BuildData.Pcds:
PcdItem = BuildData.Pcds[key] PcdItem = BuildData.Pcds[key]
if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName) and FieldName =="": if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName) and FieldName =="":
PcdItem.DefaultValue = NewValue PcdItem.DefaultValue = pcdvalue
def HandleFlexiblePcd(self, TokenSpaceGuidCName, TokenCName, PcdValue, PcdDatumType, GuidDict, FieldName=''):
if FieldName:
IsArray = False
TokenCName += '.' + FieldName
if PcdValue.startswith('H'):
if FieldName and IsFieldValueAnArray(PcdValue[1:]):
PcdDatumType = 'VOID*'
IsArray = True
if FieldName and not IsArray:
return PcdValue
try:
PcdValue = ValueExpressionEx(PcdValue[1:], PcdDatumType, GuidDict)(True)
except BadExpression, Value:
EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
(TokenSpaceGuidCName, TokenCName, PcdValue, Value))
elif PcdValue.startswith("L'") or PcdValue.startswith("'"):
if FieldName and IsFieldValueAnArray(PcdValue):
PcdDatumType = 'VOID*'
IsArray = True
if FieldName and not IsArray:
return PcdValue
try:
PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
except BadExpression, Value:
EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
(TokenSpaceGuidCName, TokenCName, PcdValue, Value))
elif PcdValue.startswith('L'):
PcdValue = 'L"' + PcdValue[1:] + '"'
if FieldName and IsFieldValueAnArray(PcdValue):
PcdDatumType = 'VOID*'
IsArray = True
if FieldName and not IsArray:
return PcdValue
try:
PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
except BadExpression, Value:
EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
(TokenSpaceGuidCName, TokenCName, PcdValue, Value))
else:
if PcdValue.upper() == 'FALSE':
PcdValue = str(0)
if PcdValue.upper() == 'TRUE':
PcdValue = str(1)
if not FieldName:
if PcdDatumType not in ['UINT8','UINT16','UINT32','UINT64','BOOLEAN']:
PcdValue = '"' + PcdValue + '"'
else:
IsArray = False
Base = 10
if PcdValue.upper().startswith('0X'):
Base = 16
try:
Num = int(PcdValue, Base)
except:
PcdValue = '"' + PcdValue + '"'
if IsFieldValueAnArray(PcdValue):
PcdDatumType = 'VOID*'
IsArray = True
if not IsArray:
return PcdValue
try:
PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
except BadExpression, Value:
EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
(TokenSpaceGuidCName, TokenCName, PcdValue, Value))
return PcdValue
## Retrieve all PCD settings in platform ## Retrieve all PCD settings in platform
def _GetPcds(self): def _GetPcds(self):
if self._Pcds == None: if self._Pcds == None:
@ -1555,22 +1495,6 @@ class DscBuildData(PlatformBuildClassObject):
return str(max([pcd_size for pcd_size in [get_length(item) for item in sku_values]])) return str(max([pcd_size for pcd_size in [get_length(item) for item in sku_values]]))
def IsFieldValueAnArray (self, Value):
Value = Value.strip()
if Value.startswith('GUID') and Value.endswith(')'):
return True
if Value.startswith('L"') and Value.endswith('"') and len(list(Value[2:-1])) > 1:
return True
if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1:
return True
if Value[0] == '{' and Value[-1] == '}':
return True
if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
return True
if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
return True
return False
def ExecuteCommand (self, Command): def ExecuteCommand (self, Command):
try: try:
Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
@ -1617,7 +1541,7 @@ class DscBuildData(PlatformBuildClassObject):
continue continue
for FieldName in FieldList: for FieldName in FieldList:
FieldName = "." + FieldName FieldName = "." + FieldName
IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0]) IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')): if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
try: try:
Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True) Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)
@ -1647,7 +1571,7 @@ class DscBuildData(PlatformBuildClassObject):
continue continue
for FieldName in FieldList: for FieldName in FieldList:
FieldName = "." + FieldName FieldName = "." + FieldName
IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0]) IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')): if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
try: try:
Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True) Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)
@ -1671,7 +1595,7 @@ class DscBuildData(PlatformBuildClassObject):
CApp = CApp + "// From Command Line \n" CApp = CApp + "// From Command Line \n"
for FieldName in Pcd.PcdFieldValueFromComm: for FieldName in Pcd.PcdFieldValueFromComm:
FieldName = "." + FieldName FieldName = "." + FieldName
IsArray = self.IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0]) IsArray = IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0])
if IsArray and not (Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].endswith('}')): if IsArray and not (Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].endswith('}')):
try: try:
Value = ValueExpressionEx(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True) Value = ValueExpressionEx(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)
@ -1704,7 +1628,7 @@ class DscBuildData(PlatformBuildClassObject):
CApp = CApp + ' UINT32 FieldSize;\n' CApp = CApp + ' UINT32 FieldSize;\n'
CApp = CApp + ' CHAR8 *Value;\n' CApp = CApp + ' CHAR8 *Value;\n'
DefaultValueFromDec = Pcd.DefaultValueFromDec DefaultValueFromDec = Pcd.DefaultValueFromDec
IsArray = self.IsFieldValueAnArray(Pcd.DefaultValueFromDec) IsArray = IsFieldValueAnArray(Pcd.DefaultValueFromDec)
if IsArray: if IsArray:
try: try:
DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, "VOID*")(True) DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, "VOID*")(True)
@ -1725,7 +1649,7 @@ class DscBuildData(PlatformBuildClassObject):
if not FieldList: if not FieldList:
continue continue
for FieldName in FieldList: for FieldName in FieldList:
IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0]) IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
if IsArray: if IsArray:
try: try:
FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True) FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)
@ -1775,7 +1699,7 @@ class DscBuildData(PlatformBuildClassObject):
if not FieldList: if not FieldList:
continue continue
if pcddefaultvalue and FieldList == pcddefaultvalue: if pcddefaultvalue and FieldList == pcddefaultvalue:
IsArray = self.IsFieldValueAnArray(FieldList) IsArray = IsFieldValueAnArray(FieldList)
if IsArray: if IsArray:
try: try:
FieldList = ValueExpressionEx(FieldList, "VOID*")(True) FieldList = ValueExpressionEx(FieldList, "VOID*")(True)
@ -1805,7 +1729,7 @@ class DscBuildData(PlatformBuildClassObject):
continue continue
if (SkuName,DefaultStoreName) == ('DEFAULT','STANDARD') or (( (SkuName,'') not in Pcd.ValueChain) and ( (SkuName,DefaultStoreName) not in Pcd.ValueChain )): if (SkuName,DefaultStoreName) == ('DEFAULT','STANDARD') or (( (SkuName,'') not in Pcd.ValueChain) and ( (SkuName,DefaultStoreName) not in Pcd.ValueChain )):
for FieldName in FieldList: for FieldName in FieldList:
IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0]) IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
if IsArray: if IsArray:
try: try:
FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True) FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)
@ -1846,7 +1770,7 @@ class DscBuildData(PlatformBuildClassObject):
if not FieldList: if not FieldList:
continue continue
if pcddefaultvalue and FieldList == pcddefaultvalue: if pcddefaultvalue and FieldList == pcddefaultvalue:
IsArray = self.IsFieldValueAnArray(FieldList) IsArray = IsFieldValueAnArray(FieldList)
if IsArray: if IsArray:
try: try:
FieldList = ValueExpressionEx(FieldList, "VOID*")(True) FieldList = ValueExpressionEx(FieldList, "VOID*")(True)
@ -1865,7 +1789,7 @@ class DscBuildData(PlatformBuildClassObject):
CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
continue continue
for FieldName in FieldList: for FieldName in FieldList:
IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0]) IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
if IsArray: if IsArray:
try: try:
FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True) FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)

View File

@ -1246,6 +1246,7 @@ class DscParser(MetaFileParser):
if GlobalData.BuildOptionPcd: if GlobalData.BuildOptionPcd:
for Item in GlobalData.BuildOptionPcd: for Item in GlobalData.BuildOptionPcd:
PcdName, TmpValue = Item.split("=") PcdName, TmpValue = Item.split("=")
TmpValue = BuildOptionValue(TmpValue, self._GuidDict)
Macros[PcdName.strip()] = TmpValue Macros[PcdName.strip()] = TmpValue
return Macros return Macros

View File

@ -977,7 +977,9 @@ class PcdReport(object):
if GlobalData.BuildOptionPcd: if GlobalData.BuildOptionPcd:
for pcd in GlobalData.BuildOptionPcd: for pcd in GlobalData.BuildOptionPcd:
if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (pcd[0], pcd[1]): if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (pcd[0], pcd[1]):
PcdValue = pcd[2] if pcd[2]:
continue
PcdValue = pcd[3]
Pcd.DefaultValue = PcdValue Pcd.DefaultValue = PcdValue
BuildOptionMatch = True BuildOptionMatch = True
break break