Ah! Gotcha. I missed that this was specific to ECC. Thanks! - Bret From: Chen, Christine Sent: Wednesday, April 7, 2021 6:42 PM To: Bret Barkelew; devel@edk2.groups.io Cc: Liang, MingyueX; Feng, Bob C; Liming Gao Subject: RE: [EXTERNAL] [edk2-devel] [PATCH 1/1] BaseTools/Ecc: Update structpcd parsing method. Hi Bret, This patch adds the ECC check for structurePcd written in des/dsc file, as the origin check is only for non-structured Pcd. Best Regards, Yuwei (Christine) From: Bret Barkelew Sent: Friday, April 2, 2021 12:43 AM To: devel@edk2.groups.io; Chen, Christine Cc: Liang, MingyueX ; Feng, Bob C ; Liming Gao Subject: RE: [EXTERNAL] [edk2-devel] [PATCH 1/1] BaseTools/Ecc: Update structpcd parsing method. What does “update” mean in this context? What behavior is changing? - Bret From: Yuwei Chen via groups.io Sent: Thursday, April 1, 2021 12:04 AM To: devel@edk2.groups.io Cc: mliang2x; Feng, Bob C; Liming Gao Subject: [EXTERNAL] [edk2-devel] [PATCH 1/1] BaseTools/Ecc: Update structpcd parsing method. From: mliang2x > Update the pcdparser method in Dec and DSC files. Signed-off-by: Mingyue Liang > Cc: Bob Feng > Cc: Liming Gao > Cc: Yuwei Chen > --- .../Ecc/MetaFileWorkspace/MetaFileParser.py | 464 ++++++++++-------- 1 file changed, 265 insertions(+), 199 deletions(-) diff --git a/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py index 9c27c8e16a05..588d3dbe6ed5 100644 --- a/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py +++ b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py @@ -22,7 +22,7 @@ import Ecc.EccToolError as EccToolError from CommonDataClass.DataClass import * from Common.DataType import * from Common.StringUtils import * -from Common.Misc import GuidStructureStringToGuidString, CheckPcdDatum, PathClass, AnalyzePcdData +from Common.Misc import GuidStructureStringToGuidString, CheckPcdDatum, PathClass, AnalyzePcdData, AnalyzeDscPcd, AnalyzePcdExpression, ParseFieldValue, StructPattern from Common.Expression import * from CommonDataClass.Exceptions import * @@ -31,6 +31,8 @@ from GenFds.FdfParser import FdfParser from Common.LongFilePathSupport import OpenLongFilePath as open from Common.LongFilePathSupport import CodecOpenLongFilePath +CODEPattern = re.compile(r"{CODE\([a-fA-F0-9Xx\{\},\s]*\)}") + ## A decorator used to parse macro definition def ParseMacro(Parser): def MacroParser(self): @@ -174,6 +176,11 @@ class MetaFileParser(object): # UNI object and extra UNI object self._UniObj = None self._UniExtraObj = None + # StructPcd var + self._PcdCodeValue = "" + self._PcdDataTypeCODE = False + self._CurrentPcdName = "" + self._GuidDict = {} # for Parser PCD value {GUID(gTokeSpaceGuidName)} ## Store the parsed data in table def _Store(self, *Args): @@ -395,6 +402,40 @@ class MetaFileParser(object): Macros.update(self._SectionsMacroDict[(self._SectionType, Scope1, Scope2)]) return Macros + def ProcessMultipleLineCODEValue(self, Content): + CODEBegin = False + CODELine = "" + continuelinecount = 0 + newContent = [] + for Index in range(0, len(Content)): + Line = Content[Index] + if CODEBegin: + CODELine = CODELine + Line + continuelinecount +=1 + if ")}" in Line: + newContent.append(CODELine) + for _ in range(continuelinecount): + newContent.append("") + CODEBegin = False + CODELine = "" + continuelinecount = 0 + else: + if not Line: + newContent.append(Line) + continue + if "{CODE(" not in Line: + newContent.append(Line) + continue + elif CODEPattern.findall(Line): + newContent.append(Line) + continue + else: + CODEBegin = True + CODELine = Line + + return newContent + + _SectionParser = {} Finished = property(_GetFinished, _SetFinished) _Macros = property(_GetMacros) @@ -812,6 +853,8 @@ class DscParser(MetaFileParser): Content = open(str(self.MetaFile.Path), 'r').readlines() except: EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile) + + Content = self.ProcessMultipleLineCODEValue(Content) # # Insert a record for file # @@ -1018,24 +1061,71 @@ class DscParser(MetaFileParser): # @ParseMacro def _PcdParser(self): + if self._PcdDataTypeCODE: + self._PcdCodeValue = self._PcdCodeValue + "\n " + self._CurrentLine + if self._CurrentLine.endswith(")}"): + self._CurrentLine = "|".join((self._CurrentPcdName, self._PcdCodeValue)) + self._PcdDataTypeCODE = False + self._PcdCodeValue = "" + else: + self._ValueList = None + return TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1) + self._CurrentPcdName = TokenList[0] + if len(TokenList) == 2 and TokenList[1].strip().startswith("{CODE"): + self._PcdDataTypeCODE = True + self._PcdCodeValue = TokenList[1].strip() + + if self._PcdDataTypeCODE: + if self._CurrentLine.endswith(")}"): + self._PcdDataTypeCODE = False + self._PcdCodeValue = "" + else: + self._ValueList = None + return self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT) + PcdNameTockens = GetSplitValueList(TokenList[0], TAB_SPLIT) + if len(PcdNameTockens) == 2: + self._ValueList[0], self._ValueList[1] = PcdNameTockens[0], PcdNameTockens[1] + elif len(PcdNameTockens) == 3: + self._ValueList[0], self._ValueList[1] = ".".join((PcdNameTockens[0], PcdNameTockens[1])), PcdNameTockens[2] + elif len(PcdNameTockens) > 3: + self._ValueList[0], self._ValueList[1] = ".".join((PcdNameTockens[0], PcdNameTockens[1])), ".".join(PcdNameTockens[2:]) if len(TokenList) == 2: self._ValueList[2] = TokenList[1] if self._ValueList[0] == '' or self._ValueList[1] == '': EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified", ExtraData=self._CurrentLine + " (.|)", - File=self.MetaFile, Line=self._LineIndex+1) + File=self.MetaFile, Line=self._LineIndex + 1) if self._ValueList[2] == '': + # + # The PCD values are optional for FIXEDATBUILD, PATCHABLEINMODULE, Dynamic/DynamicEx default + # + if self._SectionType in (MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT): + return EdkLogger.error('Parser', FORMAT_INVALID, "No PCD value given", ExtraData=self._CurrentLine + " (.|)", - File=self.MetaFile, Line=self._LineIndex+1) + File=self.MetaFile, Line=self._LineIndex + 1) + + # Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD + ValueList = GetSplitValueList(self._ValueList[2]) + if len(ValueList) > 1 and ValueList[1] in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64] \ + and self._ItemType in [MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT]: + EdkLogger.error('Parser', FORMAT_INVALID, "The datum type '%s' of PCD is wrong" % ValueList[1], + ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1) + + # Validate the VariableName of DynamicHii and DynamicExHii for PCD Entry must not be an empty string + if self._ItemType in [MODEL_PCD_DYNAMIC_HII, MODEL_PCD_DYNAMIC_EX_HII]: + DscPcdValueList = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT, 1) + if len(DscPcdValueList[0].replace('L', '').replace('"', '').strip()) == 0: + EdkLogger.error('Parser', FORMAT_INVALID, "The VariableName field in the HII format PCD entry must not be an empty string", + ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1) # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0. DscPcdValueList = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT, 1) if DscPcdValueList[0] in ['True', 'true', 'TRUE']: - self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '1', 1); + self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '1', 1) elif DscPcdValueList[0] in ['False', 'false', 'FALSE']: - self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '0', 1); + self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '0', 1) ## [components] section parser @ParseMacro @@ -1502,6 +1592,10 @@ class DecParser(MetaFileParser): self._include_flag = False self._package_flag = False + self._AllPCDs = [] # Only for check duplicate PCD + self._AllPcdDict = {} + + ## Parser starter def Start(self): Content = '' @@ -1510,6 +1604,7 @@ class DecParser(MetaFileParser): except: EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile) + Content = self.ProcessMultipleLineCODEValue(Content) # # Insert a record for file # @@ -1707,51 +1802,6 @@ class DecParser(MetaFileParser): namelist[2] = ".".join((arrayindex,namelist[2])) return namelist - def StructPcdParser(self): - self._ValueList[0] = self._CurrentStructurePcdName - - if "|" not in self._CurrentLine: - if "" == self._CurrentLine: - self._include_flag = True - self._package_flag = False - self._ValueList = None - return - if "" == self._CurrentLine: - self._package_flag = True - self._ValueList = None - self._include_flag = False - return - - if self._include_flag: - self._ValueList[1] = "_" + md5(self._CurrentLine.encode('utf-8')).hexdigest() - self._ValueList[2] = self._CurrentLine - if self._package_flag and "}" != self._CurrentLine: - self._ValueList[1] = "_" + md5(self._CurrentLine.encode('utf-8')).hexdigest() - self._ValueList[2] = self._CurrentLine - if self._CurrentLine == "}": - self._package_flag = False - self._include_flag = False - self._ValueList = None - else: - PcdTockens = self._CurrentLine.split(TAB_VALUE_SPLIT) - PcdNames = self.ParsePcdName(PcdTockens[0].split(TAB_SPLIT)) - if len(PcdNames) == 2: - if PcdNames[1].strip().endswith("]"): - PcdName = PcdNames[1][:PcdNames[1].index('[')] - Index = PcdNames[1][PcdNames[1].index('['):] - self._ValueList[0] = TAB_SPLIT.join((PcdNames[0], PcdName)) - self._ValueList[1] = Index - self._ValueList[2] = PcdTockens[1] - else: - self._CurrentStructurePcdName = "" - else: - if self._CurrentStructurePcdName != TAB_SPLIT.join(PcdNames[:2]): - EdkLogger.error('Parser', FORMAT_INVALID, "Pcd Name does not match: %s and %s " % ( - self._CurrentStructurePcdName, TAB_SPLIT.join(PcdNames[:2])), - File=self.MetaFile, Line=self._LineIndex + 1) - self._ValueList[1] = TAB_SPLIT.join(PcdNames[2:]) - self._ValueList[2] = PcdTockens[1] - ## PCD sections parser # # [PcdsFixedAtBuild] @@ -1763,159 +1813,175 @@ class DecParser(MetaFileParser): @ParseMacro def _PcdParser(self): if self._CurrentStructurePcdName: - self.StructPcdParser() - return - TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1) - self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT) - # check PCD information - if self._ValueList[0] == '' or self._ValueList[1] == '': - EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified", - ExtraData=self._CurrentLine + \ - " (.|||)", - File=self.MetaFile, Line=self._LineIndex+1) - # check PCD datum information - if len(TokenList) < 2 or TokenList[1] == '': - EdkLogger.error('Parser', FORMAT_INVALID, "No PCD Datum information given", - ExtraData=self._CurrentLine + \ - " (.|||)", - File=self.MetaFile, Line=self._LineIndex+1) - - - ValueRe = re.compile(r'^\s*L?\".*\|.*\"') - PtrValue = ValueRe.findall(TokenList[1]) - - # Has VOID* type string, may contain "|" character in the string. - if len(PtrValue) != 0: - ptrValueList = re.sub(ValueRe, '', TokenList[1]) - ValueList = GetSplitValueList(ptrValueList) - ValueList[0] = PtrValue[0] - else: - ValueList = GetSplitValueList(TokenList[1]) - - - # check if there's enough datum information given - if len(ValueList) != 3: - EdkLogger.error('Parser', FORMAT_INVALID, "Invalid PCD Datum information given", - ExtraData=self._CurrentLine + \ - " (.|||)", - File=self.MetaFile, Line=self._LineIndex+1) - # check default value - if ValueList[0] == '': - EdkLogger.error('Parser', FORMAT_INVALID, "Missing DefaultValue in PCD Datum information", - ExtraData=self._CurrentLine + \ - " (.|||)", - File=self.MetaFile, Line=self._LineIndex+1) - # check datum type - if ValueList[1] == '': - EdkLogger.error('Parser', FORMAT_INVALID, "Missing DatumType in PCD Datum information", - ExtraData=self._CurrentLine + \ - " (.|||)", - File=self.MetaFile, Line=self._LineIndex+1) - # check token of the PCD - if ValueList[2] == '': - EdkLogger.error('Parser', FORMAT_INVALID, "Missing Token in PCD Datum information", - ExtraData=self._CurrentLine + \ - " (.|||)", - File=self.MetaFile, Line=self._LineIndex+1) - # check format of default value against the datum type - IsValid, Cause = CheckPcdDatum(ValueList[1], ValueList[0]) - if not IsValid: - EdkLogger.error('Parser', FORMAT_INVALID, Cause, ExtraData=self._CurrentLine, - File=self.MetaFile, Line=self._LineIndex+1) - if Cause == "StructurePcd": - self._CurrentStructurePcdName = TAB_SPLIT.join(self._ValueList[0:2]) self._ValueList[0] = self._CurrentStructurePcdName - self._ValueList[1] = ValueList[1].strip() - if EccGlobalData.gConfig.UniCheckPCDInfo == '1' or EccGlobalData.gConfig.UniCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': - # check Description, Prompt information - PatternDesc = re.compile('##\s*([\x21-\x7E\s]*)', re.S) - PatternPrompt = re.compile('#\s+@Prompt\s+([\x21-\x7E\s]*)', re.S) - Description = None - Prompt = None - # check @ValidRange, @ValidList and @Expression format valid - ErrorCodeValid = '0x0 <= %s <= 0xFFFFFFFF' - PatternValidRangeIn = '(NOT)?\s*(\d+\s*-\s*\d+|0[xX][a-fA-F0-9]+\s*-\s*0[xX][a-fA-F0-9]+|LT\s*\d+|LT\s*0[xX][a-fA-F0-9]+|GT\s*\d+|GT\s*0[xX][a-fA-F0-9]+|LE\s*\d+|LE\s*0[xX][a-fA-F0-9]+|GE\s*\d+|GE\s*0[xX][a-fA-F0-9]+|XOR\s*\d+|XOR\s*0[xX][a-fA-F0-9]+|EQ\s*\d+|EQ\s*0[xX][a-fA-F0-9]+)' - PatternValidRng = re.compile('^' + '(NOT)?\s*' + PatternValidRangeIn + '$') - for Comment in self._Comments: - Comm = Comment[0].strip() - if not Comm: - continue - if not Description: - Description = PatternDesc.findall(Comm) - if not Prompt: - Prompt = PatternPrompt.findall(Comm) - if Comm[0] == '#': - ValidFormt = Comm.lstrip('#') - ValidFormt = ValidFormt.lstrip() - if ValidFormt[0:11] == '@ValidRange': - ValidFormt = ValidFormt[11:] - ValidFormt = ValidFormt.lstrip() - try: - ErrorCode, Expression = ValidFormt.split('|', 1) - except ValueError: - ErrorCode = '0x0' - Expression = ValidFormt - ErrorCode, Expression = ErrorCode.strip(), Expression.strip() - try: - if not eval(ErrorCodeValid % ErrorCode): - EdkLogger.warn('Parser', '@ValidRange ErrorCode(%s) of PCD %s is not valid UINT32 value.' % (ErrorCode, TokenList[0])) - except: - EdkLogger.warn('Parser', '@ValidRange ErrorCode(%s) of PCD %s is not valid UINT32 value.' % (ErrorCode, TokenList[0])) - if not PatternValidRng.search(Expression): - EdkLogger.warn('Parser', '@ValidRange Expression(%s) of PCD %s is incorrect format.' % (Expression, TokenList[0])) - if ValidFormt[0:10] == '@ValidList': - ValidFormt = ValidFormt[10:] - ValidFormt = ValidFormt.lstrip() - try: - ErrorCode, Expression = ValidFormt.split('|', 1) - except ValueError: - ErrorCode = '0x0' - Expression = ValidFormt - ErrorCode, Expression = ErrorCode.strip(), Expression.strip() - try: - if not eval(ErrorCodeValid % ErrorCode): - EdkLogger.warn('Parser', '@ValidList ErrorCode(%s) of PCD %s is not valid UINT32 value.' % (ErrorCode, TokenList[0])) - except: - EdkLogger.warn('Parser', '@ValidList ErrorCode(%s) of PCD %s is not valid UINT32 value.' % (ErrorCode, TokenList[0])) - Values = Expression.split(',') - for Value in Values: - Value = Value.strip() - try: - eval(Value) - except: - EdkLogger.warn('Parser', '@ValidList Expression of PCD %s include a invalid value(%s).' % (TokenList[0], Value)) - break - if ValidFormt[0:11] == '@Expression': - ValidFormt = ValidFormt[11:] - ValidFormt = ValidFormt.lstrip() - try: - ErrorCode, Expression = ValidFormt.split('|', 1) - except ValueError: - ErrorCode = '0x0' - Expression = ValidFormt - ErrorCode, Expression = ErrorCode.strip(), Expression.strip() - try: - if not eval(ErrorCodeValid % ErrorCode): - EdkLogger.warn('Parser', '@Expression ErrorCode(%s) of PCD %s is not valid UINT32 value.' % (ErrorCode, TokenList[0])) - except: - EdkLogger.warn('Parser', '@Expression ErrorCode(%s) of PCD %s is not valid UINT32 value.' % (ErrorCode, TokenList[0])) - if not Expression: - EdkLogger.warn('Parser', '@Expression Expression of PCD %s is incorrect format.' % TokenList[0]) - if not Description: - EdkLogger.warn('Parser', 'PCD %s Description information is not provided.' % TokenList[0]) - if not Prompt: - EdkLogger.warn('Parser', 'PCD %s Prompt information is not provided.' % TokenList[0]) - # check Description, Prompt localization information - if self._UniObj: - self._UniObj.CheckPcdInfo(TokenList[0]) + if "|" not in self._CurrentLine: + if "" == self._CurrentLine: + self._include_flag = True + self._package_flag = False + self._ValueList = None + return + if "" == self._CurrentLine: + self._package_flag = True + self._ValueList = None + self._include_flag = False + return - if ValueList[0] in ['True', 'true', 'TRUE']: - ValueList[0] = '1' - elif ValueList[0] in ['False', 'false', 'FALSE']: - ValueList[0] = '0' + if self._include_flag: + self._ValueList[1] = "_" + md5(self._CurrentLine.encode('utf-8')).hexdigest() + self._ValueList[2] = self._CurrentLine + if self._package_flag and "}" != self._CurrentLine: + self._ValueList[1] = "_" + md5(self._CurrentLine.encode('utf-8')).hexdigest() + self._ValueList[2] = self._CurrentLine + if self._CurrentLine == "}": + self._package_flag = False + self._include_flag = False + self._ValueList = None + return + else: + PcdTockens = self._CurrentLine.split(TAB_VALUE_SPLIT) + PcdNames = self.ParsePcdName(PcdTockens[0].split(TAB_SPLIT)) + if len(PcdNames) == 2: + if PcdNames[1].strip().endswith("]"): + PcdName = PcdNames[1][:PcdNames[1].index('[')] + Index = PcdNames[1][PcdNames[1].index('['):] + self._ValueList[0] = TAB_SPLIT.join((PcdNames[0],PcdName)) + self._ValueList[1] = Index + self._ValueList[2] = PcdTockens[1] + else: + self._CurrentStructurePcdName = "" + else: + if self._CurrentStructurePcdName != TAB_SPLIT.join(PcdNames[:2]): + EdkLogger.error('Parser', FORMAT_INVALID, "Pcd Name does not match: %s and %s " % (self._CurrentStructurePcdName, TAB_SPLIT.join(PcdNames[:2])), + File=self.MetaFile, Line=self._LineIndex + 1) + self._ValueList[1] = TAB_SPLIT.join(PcdNames[2:]) + self._ValueList[2] = PcdTockens[1] - self._ValueList[2] = ValueList[0].strip() + '|' + ValueList[1].strip() + '|' + ValueList[2].strip() + if not self._CurrentStructurePcdName: + if self._PcdDataTypeCODE: + if ")}" in self._CurrentLine: + ValuePart, RestofValue = self._CurrentLine.split(")}") + self._PcdCodeValue = self._PcdCodeValue + "\n " + ValuePart + self._CurrentLine = "|".join((self._CurrentPcdName, self._PcdCodeValue, RestofValue)) + self._PcdDataTypeCODE = False + self._PcdCodeValue = "" + else: + self._PcdCodeValue = self._PcdCodeValue + "\n " + self._CurrentLine + self._ValueList = None + return + TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1) + self._CurrentPcdName = TokenList[0] + if len(TokenList) == 2 and TokenList[1].strip().startswith("{CODE"): + if ")}" in self._CurrentLine: + self._PcdDataTypeCODE = False + self._PcdCodeValue = "" + else: + self._PcdDataTypeCODE = True + self._PcdCodeValue = TokenList[1].strip() + self._ValueList = None + return + + self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT) + ValueRe = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*') + # check PCD information + if self._ValueList[0] == '' or self._ValueList[1] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified", + ExtraData=self._CurrentLine + \ + " (.|||)", + File=self.MetaFile, Line=self._LineIndex+1) + # check format of token space GUID CName + if not ValueRe.match(self._ValueList[0]): + EdkLogger.error('Parser', FORMAT_INVALID, + "The format of the token space GUID CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'", + ExtraData=self._CurrentLine + \ + " (.|||)", + File=self.MetaFile, Line=self._LineIndex + 1) + # check format of PCD CName + if not ValueRe.match(self._ValueList[1]): + EdkLogger.error('Parser', FORMAT_INVALID, + "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'", + ExtraData=self._CurrentLine + \ + " (.|||)", + File=self.MetaFile, Line=self._LineIndex + 1) + + # check PCD datum information + if len(TokenList) < 2 or TokenList[1] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "No PCD Datum information given", + ExtraData=self._CurrentLine + \ + " (.|||)", + File=self.MetaFile, Line=self._LineIndex+1) + + + ValueRe = re.compile(r'^\s*L?\".*\|.*\"') + PtrValue = ValueRe.findall(TokenList[1]) + + # Has VOID* type string, may contain "|" character in the string. + if len(PtrValue) != 0: + ptrValueList = re.sub(ValueRe, '', TokenList[1]) + ValueList = AnalyzePcdExpression(ptrValueList) + ValueList[0] = PtrValue[0] + else: + ValueList = AnalyzePcdExpression(TokenList[1]) + + + # check if there's enough datum information given + if len(ValueList) != 3: + EdkLogger.error('Parser', FORMAT_INVALID, "Invalid PCD Datum information given", + ExtraData=self._CurrentLine + \ + " (.|||)", + File=self.MetaFile, Line=self._LineIndex + 1) + # check default value + if ValueList[0] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "Missing DefaultValue in PCD Datum information", + ExtraData=self._CurrentLine + \ + " (.|||)", + File=self.MetaFile, Line=self._LineIndex + 1) + # check datum type + if ValueList[1] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "Missing DatumType in PCD Datum information", + ExtraData=self._CurrentLine + \ + " (.|||)", + File=self.MetaFile, Line=self._LineIndex + 1) + # check token of the PCD + if ValueList[2] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "Missing Token in PCD Datum information", + ExtraData=self._CurrentLine + \ + " (.|||)", + File=self.MetaFile, Line=self._LineIndex + 1) + + PcdValue = ValueList[0] + if PcdValue: + try: + self._GuidDict.update(self._AllPcdDict) + ValueList[0] = ValueExpressionEx(ValueList[0], ValueList[1], self._GuidDict)(True) + except BadExpression as Value: + EdkLogger.error('Parser', FORMAT_INVALID, Value, ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1) + # check format of default value against the datum type + IsValid, Cause = CheckPcdDatum(ValueList[1], ValueList[0]) + if not IsValid: + EdkLogger.error('Parser', FORMAT_INVALID, Cause, ExtraData=self._CurrentLine, + File=self.MetaFile, Line=self._LineIndex + 1) + + if Cause == "StructurePcd": + self._CurrentStructurePcdName = TAB_SPLIT.join(self._ValueList[0:2]) + self._ValueList[0] = self._CurrentStructurePcdName + self._ValueList[1] = ValueList[1].strip() + + if ValueList[0] in ['True', 'true', 'TRUE']: + ValueList[0] = '1' + elif ValueList[0] in ['False', 'false', 'FALSE']: + ValueList[0] = '0' + + # check for duplicate PCD definition + if (self._Scope[0], self._ValueList[0], self._ValueList[1]) in self._AllPCDs: + EdkLogger.error('Parser', FORMAT_INVALID, + "The same PCD name and GUID have been already defined", + ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1) + else: + self._AllPCDs.append((self._Scope[0], self._ValueList[0], self._ValueList[1])) + self._AllPcdDict[TAB_SPLIT.join(self._ValueList[0:2])] = ValueList[0] + + self._ValueList[2] = ValueList[0].strip() + '|' + ValueList[1].strip() + '|' + ValueList[2].strip() _SectionParser = { MODEL_META_DATA_HEADER : MetaFileParser._DefineParser, -- 2.26.2.windows.1