From 8565b5829c1f30408020a4adb37074dba5492378 Mon Sep 17 00:00:00 2001 From: Yonghong Zhu Date: Wed, 7 Mar 2018 14:14:43 +0800 Subject: [PATCH] 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 Reviewed-by: Liming Gao --- BaseTools/Source/Python/Common/Expression.py | 21 +- BaseTools/Source/Python/Common/Misc.py | 41 +-- BaseTools/Source/Python/GenFds/FdfParser.py | 1 + .../Source/Python/GenFds/FfsInfStatement.py | 18 +- BaseTools/Source/Python/GenFds/GenFds.py | 49 --- .../Source/Python/Workspace/DscBuildData.py | 292 +++++++----------- .../Source/Python/Workspace/MetaFileParser.py | 1 + BaseTools/Source/Python/build/BuildReport.py | 4 +- 8 files changed, 159 insertions(+), 268 deletions(-) diff --git a/BaseTools/Source/Python/Common/Expression.py b/BaseTools/Source/Python/Common/Expression.py index 5a0ade9e7e..79dc83efc3 100644 --- a/BaseTools/Source/Python/Common/Expression.py +++ b/BaseTools/Source/Python/Common/Expression.py @@ -15,7 +15,7 @@ from Common.GlobalData import * from CommonDataClass.Exceptions import BadExpression from CommonDataClass.Exceptions import WrnExpression -from Misc import GuidStringToGuidStructureString, ParseFieldValue +from Misc import GuidStringToGuidStructureString, ParseFieldValue, IsFieldValueAnArray import Common.EdkLogger as EdkLogger import copy @@ -125,6 +125,25 @@ def IsValidCString(Str): return False 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 # def ReplaceExprMacro(String, Macros, ExceptionList = None): diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py index af374d804d..2086b4c69d 100644 --- a/BaseTools/Source/Python/Common/Misc.py +++ b/BaseTools/Source/Python/Common/Misc.py @@ -1441,6 +1441,22 @@ def ParseConsoleLog(Filename): Opr.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): Setting = Setting.strip() # There might be escaped quote in a string: \", \\\" , \', \\\' @@ -2377,31 +2393,6 @@ def PackRegistryFormatGuid(Guid): 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 # # @param Input The object that may be either a integer value or a string diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py index fc2b409847..76d7e6ac19 100644 --- a/BaseTools/Source/Python/GenFds/FdfParser.py +++ b/BaseTools/Source/Python/GenFds/FdfParser.py @@ -928,6 +928,7 @@ class FdfParser: if GlobalData.BuildOptionPcd: for Item in GlobalData.BuildOptionPcd: PcdName, TmpValue = Item.split("=") + TmpValue = BuildOptionValue(TmpValue, {}) MacroDict[PcdName.strip()] = TmpValue # Highest priority diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py index dfff892e21..a348233911 100644 --- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py +++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py @@ -1,7 +1,7 @@ ## @file # process FFS generation from INF statement # -# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
# Copyright (c) 2014-2016 Hewlett-Packard Development Company, L.P.
# # This program and the accompanying materials @@ -274,7 +274,9 @@ class FfsInfStatement(FfsInfStatementClassObject): if GlobalData.BuildOptionPcd: for pcd in GlobalData.BuildOptionPcd: if PcdKey == (pcd[1], pcd[0]): - DefaultValue = pcd[2] + if pcd[2]: + continue + DefaultValue = pcd[3] BuildOptionOverride = True break @@ -288,15 +290,15 @@ class FfsInfStatement(FfsInfStatementClassObject): except BadExpression: 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: - Pcd.DefaultValue = ValueExpressionEx(Pcd.DefaultValue, Pcd.DatumType, Platform._GuidDict)(True) + Pcd.InfDefaultValue = ValueExpressionEx(Pcd.InfDefaultValue, Pcd.DatumType, Platform._GuidDict)(True) except BadExpression: 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 if Pcd.DatumType == "VOID*": - if Pcd.DefaultValue == DefaultValue or DefaultValue in [None, '']: + if Pcd.InfDefaultValue == DefaultValue or DefaultValue in [None, '']: continue # Get the string size from FDF or DSC if DefaultValue[0] == 'L': @@ -310,15 +312,15 @@ class FfsInfStatement(FfsInfStatementClassObject): Pcd.MaxDatumSize = PatchPcd.MaxDatumSize # If no defined the maximum size in DSC, try to get current size from INF if Pcd.MaxDatumSize in ['', None]: - Pcd.MaxDatumSize = str(len(Pcd.DefaultValue.split(','))) + Pcd.MaxDatumSize = str(len(Pcd.InfDefaultValue.split(','))) else: Base1 = Base2 = 10 - if Pcd.DefaultValue.upper().startswith('0X'): + if Pcd.InfDefaultValue.upper().startswith('0X'): Base1 = 16 if DefaultValue.upper().startswith('0X'): Base2 = 16 try: - PcdValueInImg = int(Pcd.DefaultValue, Base1) + PcdValueInImg = int(Pcd.InfDefaultValue, Base1) PcdValueInDscOrFdf = int(DefaultValue, Base2) if PcdValueInImg == PcdValueInDscOrFdf: continue diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py index 9ca7c8706a..4c56cbb02a 100644 --- a/BaseTools/Source/Python/GenFds/GenFds.py +++ b/BaseTools/Source/Python/GenFds/GenFds.py @@ -38,8 +38,6 @@ from Common.Misc import DirCache, PathClass from Common.Misc import SaveFileOnChange from Common.Misc import ClearDuplicatedInf from Common.Misc import GuidStructureStringToGuidString -from Common.Misc import CheckPcdDatum -from Common.Misc import BuildOptionPcdValueFormat from Common.BuildVersion import gBUILD_VERSION from Common.MultipleWorkspace import MultipleWorkspace as mws import FfsFileStatement @@ -369,53 +367,6 @@ def SingleCheckCallback(option, opt_str, value, parser): else: 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() # # Find location of tools to process data diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py index e72b7779ce..91b3a2737d 100644 --- a/BaseTools/Source/Python/Workspace/DscBuildData.py +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py @@ -21,7 +21,7 @@ from Common.String import * from Common.DataType import * from Common.Misc import * from types import * - +from Common.Expression import * from CommonDataClass.CommonClass import SkuInfoClass from Common.TargetTxtClassObject 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): 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): if GlobalData.BuildOptionPcd: for i, pcd in enumerate(GlobalData.BuildOptionPcd): @@ -975,148 +945,118 @@ class DscBuildData(PlatformBuildClassObject): TokenSpaceGuidCNameList = [] FoundFlag = False PcdDatumType = '' - NewValue = '' + DisplayName = TokenCName + if FieldName: + DisplayName = TokenCName + '.' + FieldName 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 + PcdItem = self.DecPcds[key] + if TokenCName == PcdItem.TokenCName: + if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList: + if len (TokenSpaceGuidCNameList) < 1: + TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName) + TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName + PcdDatumType = PcdItem.DatumType + FoundFlag = True + else: + EdkLogger.error( + 'build', + AUTOGEN_ERROR, + "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (DisplayName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0]) + ) 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: - PcdItem = self.DecPcds[key] - if HasTokenSpace: - 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 len (TokenSpaceGuidCNameList) < 1: - TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName) - PcdDatumType = PcdItem.DatumType - TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName - 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: - EdkLogger.error( - 'build', - AUTOGEN_ERROR, - "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0]) - ) - GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName,NewValue,("build command options",1)) if not FoundFlag: 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: - 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(): if BuildData.MetaFile.Ext == '.dec' or BuildData.MetaFile.Ext == '.dsc': continue for key in BuildData.Pcds: PcdItem = BuildData.Pcds[key] 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 def _GetPcds(self): 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]])) - 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): try: Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) @@ -1617,7 +1541,7 @@ class DscBuildData(PlatformBuildClassObject): continue for FieldName in FieldList: 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('}')): try: Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True) @@ -1647,7 +1571,7 @@ class DscBuildData(PlatformBuildClassObject): continue for FieldName in FieldList: 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('}')): try: Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True) @@ -1671,7 +1595,7 @@ class DscBuildData(PlatformBuildClassObject): CApp = CApp + "// From Command Line \n" for FieldName in Pcd.PcdFieldValueFromComm: 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('}')): try: 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 + ' CHAR8 *Value;\n' DefaultValueFromDec = Pcd.DefaultValueFromDec - IsArray = self.IsFieldValueAnArray(Pcd.DefaultValueFromDec) + IsArray = IsFieldValueAnArray(Pcd.DefaultValueFromDec) if IsArray: try: DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, "VOID*")(True) @@ -1725,7 +1649,7 @@ class DscBuildData(PlatformBuildClassObject): if not FieldList: continue for FieldName in FieldList: - IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0]) + IsArray = IsFieldValueAnArray(FieldList[FieldName][0]) if IsArray: try: FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True) @@ -1775,7 +1699,7 @@ class DscBuildData(PlatformBuildClassObject): if not FieldList: continue if pcddefaultvalue and FieldList == pcddefaultvalue: - IsArray = self.IsFieldValueAnArray(FieldList) + IsArray = IsFieldValueAnArray(FieldList) if IsArray: try: FieldList = ValueExpressionEx(FieldList, "VOID*")(True) @@ -1805,7 +1729,7 @@ class DscBuildData(PlatformBuildClassObject): continue if (SkuName,DefaultStoreName) == ('DEFAULT','STANDARD') or (( (SkuName,'') not in Pcd.ValueChain) and ( (SkuName,DefaultStoreName) not in Pcd.ValueChain )): for FieldName in FieldList: - IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0]) + IsArray = IsFieldValueAnArray(FieldList[FieldName][0]) if IsArray: try: FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True) @@ -1846,7 +1770,7 @@ class DscBuildData(PlatformBuildClassObject): if not FieldList: continue if pcddefaultvalue and FieldList == pcddefaultvalue: - IsArray = self.IsFieldValueAnArray(FieldList) + IsArray = IsFieldValueAnArray(FieldList) if IsArray: try: FieldList = ValueExpressionEx(FieldList, "VOID*")(True) @@ -1865,7 +1789,7 @@ class DscBuildData(PlatformBuildClassObject): CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) continue for FieldName in FieldList: - IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0]) + IsArray = IsFieldValueAnArray(FieldList[FieldName][0]) if IsArray: try: FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True) diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py index 6809003d98..69bdf2161b 100644 --- a/BaseTools/Source/Python/Workspace/MetaFileParser.py +++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py @@ -1246,6 +1246,7 @@ class DscParser(MetaFileParser): if GlobalData.BuildOptionPcd: for Item in GlobalData.BuildOptionPcd: PcdName, TmpValue = Item.split("=") + TmpValue = BuildOptionValue(TmpValue, self._GuidDict) Macros[PcdName.strip()] = TmpValue return Macros diff --git a/BaseTools/Source/Python/build/BuildReport.py b/BaseTools/Source/Python/build/BuildReport.py index 89bdfa1d86..d555dce9b3 100644 --- a/BaseTools/Source/Python/build/BuildReport.py +++ b/BaseTools/Source/Python/build/BuildReport.py @@ -977,7 +977,9 @@ class PcdReport(object): if GlobalData.BuildOptionPcd: for pcd in GlobalData.BuildOptionPcd: if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (pcd[0], pcd[1]): - PcdValue = pcd[2] + if pcd[2]: + continue + PcdValue = pcd[3] Pcd.DefaultValue = PcdValue BuildOptionMatch = True break -- 2.39.2