From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.43; helo=mga05.intel.com; envelope-from=yonghong.zhu@intel.com; receiver=edk2-devel@lists.01.org Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id AAA232256860F for ; Thu, 8 Mar 2018 20:25:51 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Mar 2018 20:32:08 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.47,443,1515484800"; d="scan'208";a="23211556" Received: from shwdeopenpsi168.ccr.corp.intel.com ([10.239.158.129]) by orsmga007.jf.intel.com with ESMTP; 08 Mar 2018 20:32:07 -0800 From: Yonghong Zhu To: edk2-devel@lists.01.org Date: Fri, 9 Mar 2018 12:32:05 +0800 Message-Id: <1520569925-7236-1-git-send-email-yonghong.zhu@intel.com> X-Mailer: git-send-email 2.6.1.windows.1 Subject: [Patch V2] BaseTools: Update --pcd parser to support flexible pcd format X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 09 Mar 2018 04:25:54 -0000 This patch update --pcd parser to support flexible pcd format. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Yonghong Zhu --- BaseTools/Source/Python/Common/Expression.py | 21 +- BaseTools/Source/Python/Common/Misc.py | 41 ++- BaseTools/Source/Python/GenFds/FdfParser.py | 1 + BaseTools/Source/Python/GenFds/FfsInfStatement.py | 18 +- BaseTools/Source/Python/GenFds/GenFds.py | 49 ---- BaseTools/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 5a0ade9..79dc83e 100644 --- a/BaseTools/Source/Python/Common/Expression.py +++ b/BaseTools/Source/Python/Common/Expression.py @@ -13,11 +13,11 @@ ## Import Modules # 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 ERR_STRING_EXPR = 'This operator cannot be used in string expression: [%s].' ERR_SNYTAX = 'Syntax error, the rest of expression cannot be evaluated: [%s].' @@ -123,10 +123,29 @@ def IsValidCString(Str): ValidString = re.compile(r'[_a-zA-Z][_0-9a-zA-Z]*$') if not ValidString.match(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): StrList = SplitString(String) for i, String in enumerate(StrList): diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py index af374d8..2086b4c 100644 --- a/BaseTools/Source/Python/Common/Misc.py +++ b/BaseTools/Source/Python/Common/Misc.py @@ -1439,10 +1439,26 @@ def ParseConsoleLog(Filename): Opw.write('%s\n' % Line) 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: \", \\\" , \', \\\' Data = Setting # There might be '|' in string and in ( ... | ... ), replace it with '-' @@ -2375,35 +2391,10 @@ def PackRegistryFormatGuid(Guid): int(Guid[4][-6:-4], 16), int(Guid[4][-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 # # @param Input The object that may be either a integer value or a string # # @retval Value The integer value that the input represents diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py index fc2b409..76d7e6a 100644 --- a/BaseTools/Source/Python/GenFds/FdfParser.py +++ b/BaseTools/Source/Python/GenFds/FdfParser.py @@ -926,10 +926,11 @@ class FdfParser: MacroDict.update(GlobalData.gGlobalDefines) MacroDict.update(GlobalData.gCommandLineDefines) if GlobalData.BuildOptionPcd: for Item in GlobalData.BuildOptionPcd: PcdName, TmpValue = Item.split("=") + TmpValue = BuildOptionValue(TmpValue, {}) MacroDict[PcdName.strip()] = TmpValue # Highest priority return MacroDict diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py index dfff892..a348233 100644 --- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py +++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py @@ -1,9 +1,9 @@ ## @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 # 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 @@ -272,11 +272,13 @@ class FfsInfStatement(FfsInfStatementClassObject): # Override Patchable PCD value by the value from Build Option BuildOptionOverride = False 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 if not DscOverride and not FdfOverride and not BuildOptionOverride: continue @@ -286,19 +288,19 @@ class FfsInfStatement(FfsInfStatementClassObject): try: DefaultValue = ValueExpressionEx(DefaultValue, Pcd.DatumType, Platform._GuidDict)(True) 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': # Remove L"", but the '\0' must be appended MaxDatumSize = str((len(DefaultValue) - 2) * 2) @@ -308,19 +310,19 @@ class FfsInfStatement(FfsInfStatementClassObject): MaxDatumSize = str(len(DefaultValue) - 1) if DscOverride: 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 except: continue diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py index 9ca7c87..4c56cbb 100644 --- a/BaseTools/Source/Python/GenFds/GenFds.py +++ b/BaseTools/Source/Python/GenFds/GenFds.py @@ -36,12 +36,10 @@ from Common import EdkLogger from Common.String import * 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 import glob from struct import unpack @@ -367,57 +365,10 @@ def SingleCheckCallback(option, opt_str, value, parser): setattr(parser.values, option.dest, value) gParamCheck.append(option) 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 # # @param KeyStringList Filter for inputs of section generation diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py index e72b777..91b3a27 100644 --- a/BaseTools/Source/Python/Workspace/DscBuildData.py +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py @@ -19,11 +19,11 @@ # 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 * from MetaDataTable import * from MetaFileTable import * @@ -903,40 +903,10 @@ class DscBuildData(PlatformBuildClassObject): pcd.PcdValueFromComm = pcd.SkuInfoList.get("DEFAULT").DefaultValue for pcd in self._Pcds: 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): if type(pcd) is tuple: continue @@ -973,152 +943,122 @@ class DscBuildData(PlatformBuildClassObject): TokenSpaceGuidCName = '' HasTokenSpace = False 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: self._Pcds = sdict() self.__ParsePcdFromCommandLine() @@ -1553,26 +1493,10 @@ class DscBuildData(PlatformBuildClassObject): return len(Value) - 2 return len(Value) 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) except: EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % Command) @@ -1615,11 +1539,11 @@ class DscBuildData(PlatformBuildClassObject): for FieldList in [Pcd.DefaultValues]: if not FieldList: 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) except BadExpression: EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % @@ -1645,11 +1569,11 @@ class DscBuildData(PlatformBuildClassObject): for FieldList in [Pcd.SkuOverrideValues[skuname].get(defaultstorenameitem)]: if not FieldList: 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) except BadExpression: EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % @@ -1669,11 +1593,11 @@ class DscBuildData(PlatformBuildClassObject): CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0]) if Pcd.PcdFieldValueFromComm: 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) except BadExpression: EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % @@ -1702,11 +1626,11 @@ class DscBuildData(PlatformBuildClassObject): CApp = "// Default value in Dec \n" CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType) 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) except BadExpression: EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" % @@ -1723,11 +1647,11 @@ class DscBuildData(PlatformBuildClassObject): CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) for FieldList in [Pcd.DefaultValues]: 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) except BadExpression: EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % @@ -1773,11 +1697,11 @@ class DscBuildData(PlatformBuildClassObject): pcddefaultvalue = Pcd.DscRawValue.get(SkuName,{}).get(DefaultStoreName) for FieldList in [pcddefaultvalue,inherit_OverrideValues.get(DefaultStoreName)]: if not FieldList: continue if pcddefaultvalue and FieldList == pcddefaultvalue: - IsArray = self.IsFieldValueAnArray(FieldList) + IsArray = IsFieldValueAnArray(FieldList) if IsArray: try: FieldList = ValueExpressionEx(FieldList, "VOID*")(True) except BadExpression: EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" % @@ -1803,11 +1727,11 @@ class DscBuildData(PlatformBuildClassObject): CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName,{}).get(DefaultStoreName)) CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) 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) except BadExpression: EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % @@ -1844,11 +1768,11 @@ class DscBuildData(PlatformBuildClassObject): pcddefaultvalue = Pcd.PcdValueFromComm for FieldList in [pcddefaultvalue,Pcd.PcdFieldValueFromComm]: if not FieldList: continue if pcddefaultvalue and FieldList == pcddefaultvalue: - IsArray = self.IsFieldValueAnArray(FieldList) + IsArray = IsFieldValueAnArray(FieldList) if IsArray: try: FieldList = ValueExpressionEx(FieldList, "VOID*")(True) except BadExpression: EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Command: %s" % @@ -1863,11 +1787,11 @@ class DscBuildData(PlatformBuildClassObject): # CApp = CApp + ' Value = %s; // From Command Line.\n' % (self.IntToCString(Value, ValueSize)) 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) except BadExpression: EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py index 6809003..69bdf21 100644 --- a/BaseTools/Source/Python/Workspace/MetaFileParser.py +++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py @@ -1244,10 +1244,11 @@ class DscParser(MetaFileParser): if self._ItemType not in [MODEL_META_DATA_DEFINE, MODEL_META_DATA_GLOBAL_DEFINE]: Macros.update(self._Symbols) if GlobalData.BuildOptionPcd: for Item in GlobalData.BuildOptionPcd: PcdName, TmpValue = Item.split("=") + TmpValue = BuildOptionValue(TmpValue, self._GuidDict) Macros[PcdName.strip()] = TmpValue return Macros def _PostProcess(self): Processer = { diff --git a/BaseTools/Source/Python/build/BuildReport.py b/BaseTools/Source/Python/build/BuildReport.py index 89bdfa1..d555dce 100644 --- a/BaseTools/Source/Python/build/BuildReport.py +++ b/BaseTools/Source/Python/build/BuildReport.py @@ -975,11 +975,13 @@ class PcdReport(object): BuildOptionMatch = False 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 if First: -- 2.6.1.windows.1