* [PATCH 1/1] BaseTools/Ecc: Update structpcd parsing method.
@ 2021-04-01 7:03 Yuwei Chen
2021-04-01 16:43 ` [EXTERNAL] [edk2-devel] " Bret Barkelew
0 siblings, 1 reply; 4+ messages in thread
From: Yuwei Chen @ 2021-04-01 7:03 UTC (permalink / raw)
To: devel; +Cc: mliang2x, Bob Feng, Liming Gao
From: mliang2x <mingyuex.liang@intel.com>
Update the pcdparser method in Dec and DSC files.
Signed-off-by: Mingyue Liang <mingyuex.liang@intel.com>
Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Yuwei Chen <yuwei.chen@intel.com>
---
.../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 + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
- 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 + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
- 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 "<HeaderFiles>" == self._CurrentLine:
- self._include_flag = True
- self._package_flag = False
- self._ValueList = None
- return
- if "<Packages>" == self._CurrentLine:
- self._package_flag = True
- self._ValueList = None
- self._include_flag = False
- return
-
- if self._include_flag:
- self._ValueList[1] = "<HeaderFiles>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()
- self._ValueList[2] = self._CurrentLine
- if self._package_flag and "}" != self._CurrentLine:
- self._ValueList[1] = "<Packages>_" + 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 "<HeaderFiles>" == self._CurrentLine:
+ self._include_flag = True
+ self._package_flag = False
+ self._ValueList = None
+ return
+ if "<Packages>" == 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] = "<HeaderFiles>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()
+ self._ValueList[2] = self._CurrentLine
+ if self._package_flag and "}" != self._CurrentLine:
+ self._ValueList[1] = "<Packages>_" + 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [EXTERNAL] [edk2-devel] [PATCH 1/1] BaseTools/Ecc: Update structpcd parsing method.
2021-04-01 7:03 [PATCH 1/1] BaseTools/Ecc: Update structpcd parsing method Yuwei Chen
@ 2021-04-01 16:43 ` Bret Barkelew
2021-04-08 1:42 ` Yuwei Chen
0 siblings, 1 reply; 4+ messages in thread
From: Bret Barkelew @ 2021-04-01 16:43 UTC (permalink / raw)
To: devel@edk2.groups.io, Chen, Yuwei; +Cc: mliang2x, Feng, Bob C, Liming Gao
[-- Attachment #1: Type: text/plain, Size: 32453 bytes --]
What does “update” mean in this context? What behavior is changing?
- Bret
From: Yuwei Chen via groups.io<mailto:yuwei.chen=intel.com@groups.io>
Sent: Thursday, April 1, 2021 12:04 AM
To: devel@edk2.groups.io<mailto:devel@edk2.groups.io>
Cc: mliang2x<mailto:mingyuex.liang@intel.com>; Feng, Bob C<mailto:bob.c.feng@intel.com>; Liming Gao<mailto:gaoliming@byosoft.com.cn>
Subject: [EXTERNAL] [edk2-devel] [PATCH 1/1] BaseTools/Ecc: Update structpcd parsing method.
From: mliang2x <mingyuex.liang@intel.com>
Update the pcdparser method in Dec and DSC files.
Signed-off-by: Mingyue Liang <mingyuex.liang@intel.com>
Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Yuwei Chen <yuwei.chen@intel.com>
---
.../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 + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
- 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 + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
- 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 "<HeaderFiles>" == self._CurrentLine:
- self._include_flag = True
- self._package_flag = False
- self._ValueList = None
- return
- if "<Packages>" == self._CurrentLine:
- self._package_flag = True
- self._ValueList = None
- self._include_flag = False
- return
-
- if self._include_flag:
- self._ValueList[1] = "<HeaderFiles>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()
- self._ValueList[2] = self._CurrentLine
- if self._package_flag and "}" != self._CurrentLine:
- self._ValueList[1] = "<Packages>_" + 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 "<HeaderFiles>" == self._CurrentLine:
+ self._include_flag = True
+ self._package_flag = False
+ self._ValueList = None
+ return
+ if "<Packages>" == 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] = "<HeaderFiles>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()
+ self._ValueList[2] = self._CurrentLine
+ if self._package_flag and "}" != self._CurrentLine:
+ self._ValueList[1] = "<Packages>_" + 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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
[-- Attachment #2: Type: text/html, Size: 77538 bytes --]
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [EXTERNAL] [edk2-devel] [PATCH 1/1] BaseTools/Ecc: Update structpcd parsing method.
2021-04-01 16:43 ` [EXTERNAL] [edk2-devel] " Bret Barkelew
@ 2021-04-08 1:42 ` Yuwei Chen
2021-04-08 16:43 ` Bret Barkelew
0 siblings, 1 reply; 4+ messages in thread
From: Yuwei Chen @ 2021-04-08 1:42 UTC (permalink / raw)
To: Bret Barkelew, devel@edk2.groups.io
Cc: Liang, MingyueX, Feng, Bob C, Liming Gao
[-- Attachment #1: Type: text/plain, Size: 33171 bytes --]
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 <Bret.Barkelew@microsoft.com>
Sent: Friday, April 2, 2021 12:43 AM
To: devel@edk2.groups.io; Chen, Christine <yuwei.chen@intel.com>
Cc: Liang, MingyueX <mingyuex.liang@intel.com>; Feng, Bob C <bob.c.feng@intel.com>; Liming Gao <gaoliming@byosoft.com.cn>
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<mailto:yuwei.chen=intel.com@groups.io>
Sent: Thursday, April 1, 2021 12:04 AM
To: devel@edk2.groups.io<mailto:devel@edk2.groups.io>
Cc: mliang2x<mailto:mingyuex.liang@intel.com>; Feng, Bob C<mailto:bob.c.feng@intel.com>; Liming Gao<mailto:gaoliming@byosoft.com.cn>
Subject: [EXTERNAL] [edk2-devel] [PATCH 1/1] BaseTools/Ecc: Update structpcd parsing method.
From: mliang2x <mingyuex.liang@intel.com<mailto:mingyuex.liang@intel.com>>
Update the pcdparser method in Dec and DSC files.
Signed-off-by: Mingyue Liang <mingyuex.liang@intel.com<mailto:mingyuex.liang@intel.com>>
Cc: Bob Feng <bob.c.feng@intel.com<mailto:bob.c.feng@intel.com>>
Cc: Liming Gao <gaoliming@byosoft.com.cn<mailto:gaoliming@byosoft.com.cn>>
Cc: Yuwei Chen <yuwei.chen@intel.com<mailto:yuwei.chen@intel.com>>
---
.../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 + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
- 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 + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
- 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 "<HeaderFiles>" == self._CurrentLine:
- self._include_flag = True
- self._package_flag = False
- self._ValueList = None
- return
- if "<Packages>" == self._CurrentLine:
- self._package_flag = True
- self._ValueList = None
- self._include_flag = False
- return
-
- if self._include_flag:
- self._ValueList[1] = "<HeaderFiles>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()
- self._ValueList[2] = self._CurrentLine
- if self._package_flag and "}" != self._CurrentLine:
- self._ValueList[1] = "<Packages>_" + 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 "<HeaderFiles>" == self._CurrentLine:
+ self._include_flag = True
+ self._package_flag = False
+ self._ValueList = None
+ return
+ if "<Packages>" == 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] = "<HeaderFiles>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()
+ self._ValueList[2] = self._CurrentLine
+ if self._package_flag and "}" != self._CurrentLine:
+ self._ValueList[1] = "<Packages>_" + 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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
[-- Attachment #2: Type: text/html, Size: 79668 bytes --]
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [EXTERNAL] [edk2-devel] [PATCH 1/1] BaseTools/Ecc: Update structpcd parsing method.
2021-04-08 1:42 ` Yuwei Chen
@ 2021-04-08 16:43 ` Bret Barkelew
0 siblings, 0 replies; 4+ messages in thread
From: Bret Barkelew @ 2021-04-08 16:43 UTC (permalink / raw)
To: Chen, Yuwei, devel@edk2.groups.io
Cc: Liang, MingyueX, Feng, Bob C, Liming Gao
[-- Attachment #1: Type: text/plain, Size: 33687 bytes --]
Ah! Gotcha. I missed that this was specific to ECC. Thanks!
- Bret
From: Chen, Christine<mailto:yuwei.chen@intel.com>
Sent: Wednesday, April 7, 2021 6:42 PM
To: Bret Barkelew<mailto:Bret.Barkelew@microsoft.com>; devel@edk2.groups.io<mailto:devel@edk2.groups.io>
Cc: Liang, MingyueX<mailto:mingyuex.liang@intel.com>; Feng, Bob C<mailto:bob.c.feng@intel.com>; Liming Gao<mailto:gaoliming@byosoft.com.cn>
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 <Bret.Barkelew@microsoft.com>
Sent: Friday, April 2, 2021 12:43 AM
To: devel@edk2.groups.io; Chen, Christine <yuwei.chen@intel.com>
Cc: Liang, MingyueX <mingyuex.liang@intel.com>; Feng, Bob C <bob.c.feng@intel.com>; Liming Gao <gaoliming@byosoft.com.cn>
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<mailto:yuwei.chen=intel.com@groups.io>
Sent: Thursday, April 1, 2021 12:04 AM
To: devel@edk2.groups.io<mailto:devel@edk2.groups.io>
Cc: mliang2x<mailto:mingyuex.liang@intel.com>; Feng, Bob C<mailto:bob.c.feng@intel.com>; Liming Gao<mailto:gaoliming@byosoft.com.cn>
Subject: [EXTERNAL] [edk2-devel] [PATCH 1/1] BaseTools/Ecc: Update structpcd parsing method.
From: mliang2x <mingyuex.liang@intel.com<mailto:mingyuex.liang@intel.com>>
Update the pcdparser method in Dec and DSC files.
Signed-off-by: Mingyue Liang <mingyuex.liang@intel.com<mailto:mingyuex.liang@intel.com>>
Cc: Bob Feng <bob.c.feng@intel.com<mailto:bob.c.feng@intel.com>>
Cc: Liming Gao <gaoliming@byosoft.com.cn<mailto:gaoliming@byosoft.com.cn>>
Cc: Yuwei Chen <yuwei.chen@intel.com<mailto:yuwei.chen@intel.com>>
---
.../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 + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
- 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 + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
- 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 "<HeaderFiles>" == self._CurrentLine:
- self._include_flag = True
- self._package_flag = False
- self._ValueList = None
- return
- if "<Packages>" == self._CurrentLine:
- self._package_flag = True
- self._ValueList = None
- self._include_flag = False
- return
-
- if self._include_flag:
- self._ValueList[1] = "<HeaderFiles>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()
- self._ValueList[2] = self._CurrentLine
- if self._package_flag and "}" != self._CurrentLine:
- self._ValueList[1] = "<Packages>_" + 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- 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 "<HeaderFiles>" == self._CurrentLine:
+ self._include_flag = True
+ self._package_flag = False
+ self._ValueList = None
+ return
+ if "<Packages>" == 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] = "<HeaderFiles>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()
+ self._ValueList[2] = self._CurrentLine
+ if self._package_flag and "}" != self._CurrentLine:
+ self._ValueList[1] = "<Packages>_" + 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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 + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ 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
[-- Attachment #2: Type: text/html, Size: 80252 bytes --]
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-04-08 16:43 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-04-01 7:03 [PATCH 1/1] BaseTools/Ecc: Update structpcd parsing method Yuwei Chen
2021-04-01 16:43 ` [EXTERNAL] [edk2-devel] " Bret Barkelew
2021-04-08 1:42 ` Yuwei Chen
2021-04-08 16:43 ` Bret Barkelew
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox