<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:SimSun;
        panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:DengXian;
        panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:"\@SimSun";
        panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
        {font-family:"\@DengXian";
        panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
p.MsoPlainText, li.MsoPlainText, div.MsoPlainText
        {mso-style-priority:99;
        mso-style-link:"Plain Text Char";
        margin:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.PlainTextChar
        {mso-style-name:"Plain Text Char";
        mso-style-priority:99;
        mso-style-link:"Plain Text";
        font-family:"Calibri",sans-serif;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="#954F72" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoPlainText">Hi Bret,<o:p></o:p></p>
<p class="MsoPlainText"><o:p> </o:p></p>
<p class="MsoPlainText">This patch adds the ECC check for structurePcd written in des/dsc file, as the origin check is only for non-structured Pcd.<o:p></o:p></p>
<p class="MsoPlainText"><o:p> </o:p></p>
<p class="MsoPlainText">Best Regards,<o:p></o:p></p>
<p class="MsoPlainText">Yuwei (Christine)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b>From:</b> Bret Barkelew <Bret.Barkelew@microsoft.com> <br>
<b>Sent:</b> Friday, April 2, 2021 12:43 AM<br>
<b>To:</b> devel@edk2.groups.io; Chen, Christine <yuwei.chen@intel.com><br>
<b>Cc:</b> Liang, MingyueX <mingyuex.liang@intel.com>; Feng, Bob C <bob.c.feng@intel.com>; Liming Gao <gaoliming@byosoft.com.cn><br>
<b>Subject:</b> RE: [EXTERNAL] [edk2-devel] [PATCH 1/1] BaseTools/Ecc: Update structpcd parsing method.<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">What does “update” mean in this context? What behavior is changing?<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- Bret <o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b>From: </b><a href="mailto:yuwei.chen=intel.com@groups.io">Yuwei Chen via groups.io</a><br>
<b>Sent: </b>Thursday, April 1, 2021 12:04 AM<br>
<b>To: </b><a href="mailto:devel@edk2.groups.io">devel@edk2.groups.io</a><br>
<b>Cc: </b><a href="mailto:mingyuex.liang@intel.com">mliang2x</a>; <a href="mailto:bob.c.feng@intel.com">
Feng, Bob C</a>; <a href="mailto:gaoliming@byosoft.com.cn">Liming Gao</a><br>
<b>Subject: </b>[EXTERNAL] [edk2-devel] [PATCH 1/1] BaseTools/Ecc: Update structpcd parsing method.<o:p></o:p></p>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-bottom:12.0pt">From: mliang2x <<a href="mailto:mingyuex.liang@intel.com">mingyuex.liang@intel.com</a>><br>
<br>
Update the pcdparser method in Dec and DSC files.<br>
<br>
Signed-off-by: Mingyue Liang <<a href="mailto:mingyuex.liang@intel.com">mingyuex.liang@intel.com</a>><br>
Cc: Bob Feng <<a href="mailto:bob.c.feng@intel.com">bob.c.feng@intel.com</a>><br>
Cc: Liming Gao <<a href="mailto:gaoliming@byosoft.com.cn">gaoliming@byosoft.com.cn</a>><br>
Cc: Yuwei Chen <<a href="mailto:yuwei.chen@intel.com">yuwei.chen@intel.com</a>><br>
---<br>
 .../Ecc/MetaFileWorkspace/MetaFileParser.py   | 464 ++++++++++--------<br>
 1 file changed, 265 insertions(+), 199 deletions(-)<br>
<br>
diff --git a/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py<br>
index 9c27c8e16a05..588d3dbe6ed5 100644<br>
--- a/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py<br>
+++ b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py<br>
@@ -22,7 +22,7 @@ import Ecc.EccToolError as EccToolError<br>
 from CommonDataClass.DataClass import *<br>
 from Common.DataType import *<br>
 from Common.StringUtils import *<br>
-from Common.Misc import GuidStructureStringToGuidString, CheckPcdDatum, PathClass, AnalyzePcdData<br>
+from Common.Misc import GuidStructureStringToGuidString, CheckPcdDatum, PathClass, AnalyzePcdData, AnalyzeDscPcd, AnalyzePcdExpression, ParseFieldValue, StructPattern<br>
 from Common.Expression import *<br>
 from CommonDataClass.Exceptions import *<br>
 <br>
@@ -31,6 +31,8 @@ from GenFds.FdfParser import FdfParser<br>
 from Common.LongFilePathSupport import OpenLongFilePath as open<br>
 from Common.LongFilePathSupport import CodecOpenLongFilePath<br>
 <br>
+CODEPattern = re.compile(r"{CODE\([a-fA-F0-9Xx\{\},\s]*\)}")<br>
+<br>
 ## A decorator used to parse macro definition<br>
 def ParseMacro(Parser):<br>
     def MacroParser(self):<br>
@@ -174,6 +176,11 @@ class MetaFileParser(object):<br>
         # UNI object and extra UNI object<br>
         self._UniObj = None<br>
         self._UniExtraObj = None<br>
+        # StructPcd var<br>
+        self._PcdCodeValue = ""<br>
+        self._PcdDataTypeCODE = False<br>
+        self._CurrentPcdName = ""<br>
+        self._GuidDict = {}  # for Parser PCD value {GUID(gTokeSpaceGuidName)}<br>
 <br>
     ## Store the parsed data in table<br>
     def _Store(self, *Args):<br>
@@ -395,6 +402,40 @@ class MetaFileParser(object):<br>
                 Macros.update(self._SectionsMacroDict[(self._SectionType, Scope1, Scope2)])<br>
         return Macros<br>
 <br>
+    def ProcessMultipleLineCODEValue(self, Content):<br>
+        CODEBegin = False<br>
+        CODELine = ""<br>
+        continuelinecount = 0<br>
+        newContent = []<br>
+        for Index in range(0, len(Content)):<br>
+            Line = Content[Index]<br>
+            if CODEBegin:<br>
+                CODELine = CODELine + Line<br>
+                continuelinecount +=1<br>
+                if ")}" in Line:<br>
+                    newContent.append(CODELine)<br>
+                    for _ in range(continuelinecount):<br>
+                        newContent.append("")<br>
+                    CODEBegin = False<br>
+                    CODELine = ""<br>
+                    continuelinecount = 0<br>
+            else:<br>
+                if not Line:<br>
+                    newContent.append(Line)<br>
+                    continue<br>
+                if "{CODE(" not in Line:<br>
+                    newContent.append(Line)<br>
+                    continue<br>
+                elif CODEPattern.findall(Line):<br>
+                    newContent.append(Line)<br>
+                    continue<br>
+                else:<br>
+                    CODEBegin = True<br>
+                    CODELine = Line<br>
+<br>
+        return newContent<br>
+<br>
+<br>
     _SectionParser  = {}<br>
     Finished        = property(_GetFinished, _SetFinished)<br>
     _Macros         = property(_GetMacros)<br>
@@ -812,6 +853,8 @@ class DscParser(MetaFileParser):<br>
             Content = open(str(self.MetaFile.Path), 'r').readlines()<br>
         except:<br>
             EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)<br>
+<br>
+        Content = self.ProcessMultipleLineCODEValue(Content)<br>
         #<br>
         # Insert a record for file<br>
         #<br>
@@ -1018,24 +1061,71 @@ class DscParser(MetaFileParser):<br>
     #<br>
     @ParseMacro<br>
     def _PcdParser(self):<br>
+        if self._PcdDataTypeCODE:<br>
+            self._PcdCodeValue = self._PcdCodeValue + "\n " + self._CurrentLine<br>
+            if self._CurrentLine.endswith(")}"):<br>
+                self._CurrentLine = "|".join((self._CurrentPcdName, self._PcdCodeValue))<br>
+                self._PcdDataTypeCODE = False<br>
+                self._PcdCodeValue = ""<br>
+            else:<br>
+                self._ValueList = None<br>
+                return<br>
         TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)<br>
+        self._CurrentPcdName = TokenList[0]<br>
+        if len(TokenList) == 2 and TokenList[1].strip().startswith("{CODE"):<br>
+            self._PcdDataTypeCODE = True<br>
+            self._PcdCodeValue = TokenList[1].strip()<br>
+<br>
+        if self._PcdDataTypeCODE:<br>
+            if self._CurrentLine.endswith(")}"):<br>
+                self._PcdDataTypeCODE = False<br>
+                self._PcdCodeValue = ""<br>
+            else:<br>
+                self._ValueList = None<br>
+                return<br>
         self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)<br>
+        PcdNameTockens = GetSplitValueList(TokenList[0], TAB_SPLIT)<br>
+        if len(PcdNameTockens) == 2:<br>
+            self._ValueList[0], self._ValueList[1] = PcdNameTockens[0], PcdNameTockens[1]<br>
+        elif len(PcdNameTockens) == 3:<br>
+            self._ValueList[0], self._ValueList[1] = ".".join((PcdNameTockens[0], PcdNameTockens[1])), PcdNameTockens[2]<br>
+        elif len(PcdNameTockens) > 3:<br>
+            self._ValueList[0], self._ValueList[1] = ".".join((PcdNameTockens[0], PcdNameTockens[1])), ".".join(PcdNameTockens[2:])<br>
         if len(TokenList) == 2:<br>
             self._ValueList[2] = TokenList[1]<br>
         if self._ValueList[0] == '' or self._ValueList[1] == '':<br>
             EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",<br>
                             ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",<br>
-                            File=self.MetaFile, Line=self._LineIndex+1)<br>
+                            File=self.MetaFile, Line=self._LineIndex + 1)<br>
         if self._ValueList[2] == '':<br>
+            #<br>
+            # The PCD values are optional for FIXEDATBUILD, PATCHABLEINMODULE, Dynamic/DynamicEx default<br>
+            #<br>
+            if self._SectionType in (MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):<br>
+                return<br>
             EdkLogger.error('Parser', FORMAT_INVALID, "No PCD value given",<br>
                             ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",<br>
-                            File=self.MetaFile, Line=self._LineIndex+1)<br>
+                            File=self.MetaFile, Line=self._LineIndex + 1)<br>
+<br>
+        # Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD<br>
+        ValueList = GetSplitValueList(self._ValueList[2])<br>
+        if len(ValueList) > 1 and ValueList[1] in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64] \<br>
+                              and self._ItemType in [MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT]:<br>
+            EdkLogger.error('Parser', FORMAT_INVALID, "The datum type '%s' of PCD is wrong" % ValueList[1],<br>
+                            ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)<br>
+<br>
+        # Validate the VariableName of DynamicHii and DynamicExHii for PCD Entry must not be an empty string<br>
+        if self._ItemType in [MODEL_PCD_DYNAMIC_HII, MODEL_PCD_DYNAMIC_EX_HII]:<br>
+            DscPcdValueList = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT, 1)<br>
+            if len(DscPcdValueList[0].replace('L', '').replace('"', '').strip()) == 0:<br>
+                EdkLogger.error('Parser', FORMAT_INVALID, "The VariableName field in the HII format PCD entry must not be an empty string",<br>
+                            ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)<br>
         # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.<br>
         DscPcdValueList = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT, 1)<br>
         if DscPcdValueList[0] in ['True', 'true', 'TRUE']:<br>
-            self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '1', 1);<br>
+            self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '1', 1)<br>
         elif DscPcdValueList[0] in ['False', 'false', 'FALSE']:<br>
-            self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '0', 1);<br>
+            self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '0', 1)<br>
 <br>
     ## [components] section parser<br>
     @ParseMacro<br>
@@ -1502,6 +1592,10 @@ class DecParser(MetaFileParser):<br>
         self._include_flag = False<br>
         self._package_flag = False<br>
 <br>
+        self._AllPCDs = [] # Only for check duplicate PCD<br>
+        self._AllPcdDict = {}<br>
+<br>
+<br>
     ## Parser starter<br>
     def Start(self):<br>
         Content = ''<br>
@@ -1510,6 +1604,7 @@ class DecParser(MetaFileParser):<br>
         except:<br>
             EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)<br>
 <br>
+        Content = self.ProcessMultipleLineCODEValue(Content)<br>
         #<br>
         # Insert a record for file<br>
         #<br>
@@ -1707,51 +1802,6 @@ class DecParser(MetaFileParser):<br>
                 namelist[2] = ".".join((arrayindex,namelist[2]))<br>
         return namelist<br>
 <br>
-    def StructPcdParser(self):<br>
-        self._ValueList[0] = self._CurrentStructurePcdName<br>
-<br>
-        if "|" not in self._CurrentLine:<br>
-            if "<HeaderFiles>" == self._CurrentLine:<br>
-                self._include_flag = True<br>
-                self._package_flag = False<br>
-                self._ValueList = None<br>
-                return<br>
-            if "<Packages>" == self._CurrentLine:<br>
-                self._package_flag = True<br>
-                self._ValueList = None<br>
-                self._include_flag = False<br>
-                return<br>
-<br>
-            if self._include_flag:<br>
-                self._ValueList[1] = "<HeaderFiles>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()<br>
-                self._ValueList[2] = self._CurrentLine<br>
-            if self._package_flag and "}" != self._CurrentLine:<br>
-                self._ValueList[1] = "<Packages>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()<br>
-                self._ValueList[2] = self._CurrentLine<br>
-            if self._CurrentLine == "}":<br>
-                self._package_flag = False<br>
-                self._include_flag = False<br>
-                self._ValueList = None<br>
-        else:<br>
-            PcdTockens = self._CurrentLine.split(TAB_VALUE_SPLIT)<br>
-            PcdNames = self.ParsePcdName(PcdTockens[0].split(TAB_SPLIT))<br>
-            if len(PcdNames) == 2:<br>
-                if PcdNames[1].strip().endswith("]"):<br>
-                    PcdName = PcdNames[1][:PcdNames[1].index('[')]<br>
-                    Index = PcdNames[1][PcdNames[1].index('['):]<br>
-                    self._ValueList[0] = TAB_SPLIT.join((PcdNames[0], PcdName))<br>
-                    self._ValueList[1] = Index<br>
-                    self._ValueList[2] = PcdTockens[1]<br>
-                else:<br>
-                    self._CurrentStructurePcdName = ""<br>
-            else:<br>
-                if self._CurrentStructurePcdName != TAB_SPLIT.join(PcdNames[:2]):<br>
-                    EdkLogger.error('Parser', FORMAT_INVALID, "Pcd Name does not match: %s and %s " % (<br>
-                    self._CurrentStructurePcdName, TAB_SPLIT.join(PcdNames[:2])),<br>
-                                    File=self.MetaFile, Line=self._LineIndex + 1)<br>
-                self._ValueList[1] = TAB_SPLIT.join(PcdNames[2:])<br>
-                self._ValueList[2] = PcdTockens[1]<br>
-<br>
     ## PCD sections parser<br>
     #<br>
     #   [PcdsFixedAtBuild]<br>
@@ -1763,159 +1813,175 @@ class DecParser(MetaFileParser):<br>
     @ParseMacro<br>
     def _PcdParser(self):<br>
         if self._CurrentStructurePcdName:<br>
-            self.StructPcdParser()<br>
-            return<br>
-        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)<br>
-        self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)<br>
-        # check PCD information<br>
-        if self._ValueList[0] == '' or self._ValueList[1] == '':<br>
-            EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",<br>
-                            ExtraData=self._CurrentLine + \<br>
-                                      " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",<br>
-                            File=self.MetaFile, Line=self._LineIndex+1)<br>
-        # check PCD datum information<br>
-        if len(TokenList) < 2 or TokenList[1] == '':<br>
-            EdkLogger.error('Parser', FORMAT_INVALID, "No PCD Datum information given",<br>
-                            ExtraData=self._CurrentLine + \<br>
-                                      " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",<br>
-                            File=self.MetaFile, Line=self._LineIndex+1)<br>
-<br>
-<br>
-        ValueRe  = re.compile(r'^\s*L?\".*\|.*\"')<br>
-        PtrValue = ValueRe.findall(TokenList[1])<br>
-<br>
-        # Has VOID* type string, may contain "|" character in the string.<br>
-        if len(PtrValue) != 0:<br>
-            ptrValueList = re.sub(ValueRe, '', TokenList[1])<br>
-            ValueList    = GetSplitValueList(ptrValueList)<br>
-            ValueList[0] = PtrValue[0]<br>
-        else:<br>
-            ValueList = GetSplitValueList(TokenList[1])<br>
-<br>
-<br>
-        # check if there's enough datum information given<br>
-        if len(ValueList) != 3:<br>
-            EdkLogger.error('Parser', FORMAT_INVALID, "Invalid PCD Datum information given",<br>
-                            ExtraData=self._CurrentLine + \<br>
-                                      " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",<br>
-                            File=self.MetaFile, Line=self._LineIndex+1)<br>
-        # check default value<br>
-        if ValueList[0] == '':<br>
-            EdkLogger.error('Parser', FORMAT_INVALID, "Missing DefaultValue in PCD Datum information",<br>
-                            ExtraData=self._CurrentLine + \<br>
-                                      " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",<br>
-                            File=self.MetaFile, Line=self._LineIndex+1)<br>
-        # check datum type<br>
-        if ValueList[1] == '':<br>
-            EdkLogger.error('Parser', FORMAT_INVALID, "Missing DatumType in PCD Datum information",<br>
-                            ExtraData=self._CurrentLine + \<br>
-                                      " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",<br>
-                            File=self.MetaFile, Line=self._LineIndex+1)<br>
-        # check token of the PCD<br>
-        if ValueList[2] == '':<br>
-            EdkLogger.error('Parser', FORMAT_INVALID, "Missing Token in PCD Datum information",<br>
-                            ExtraData=self._CurrentLine + \<br>
-                                      " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",<br>
-                            File=self.MetaFile, Line=self._LineIndex+1)<br>
-        # check format of default value against the datum type<br>
-        IsValid, Cause = CheckPcdDatum(ValueList[1], ValueList[0])<br>
-        if not IsValid:<br>
-            EdkLogger.error('Parser', FORMAT_INVALID, Cause, ExtraData=self._CurrentLine,<br>
-                            File=self.MetaFile, Line=self._LineIndex+1)<br>
-        if Cause == "StructurePcd":<br>
-            self._CurrentStructurePcdName = TAB_SPLIT.join(self._ValueList[0:2])<br>
             self._ValueList[0] = self._CurrentStructurePcdName<br>
-            self._ValueList[1] = ValueList[1].strip()<br>
 <br>
-        if EccGlobalData.gConfig.UniCheckPCDInfo == '1' or EccGlobalData.gConfig.UniCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':<br>
-            # check Description, Prompt information<br>
-            PatternDesc = re.compile('##\s*([\x21-\x7E\s]*)', re.S)<br>
-            PatternPrompt = re.compile('#\s+@Prompt\s+([\x21-\x7E\s]*)', re.S)<br>
-            Description = None<br>
-            Prompt = None<br>
-            # check @ValidRange, @ValidList and @Expression format valid<br>
-            ErrorCodeValid = '0x0 <= %s <= 0xFFFFFFFF'<br>
-            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]+)'<br>
-            PatternValidRng = re.compile('^' + '(NOT)?\s*' + PatternValidRangeIn + '$')<br>
-            for Comment in self._Comments:<br>
-                Comm = Comment[0].strip()<br>
-                if not Comm:<br>
-                    continue<br>
-                if not Description:<br>
-                    Description = PatternDesc.findall(Comm)<br>
-                if not Prompt:<br>
-                    Prompt = PatternPrompt.findall(Comm)<br>
-                if Comm[0] == '#':<br>
-                    ValidFormt = Comm.lstrip('#')<br>
-                    ValidFormt = ValidFormt.lstrip()<br>
-                    if ValidFormt[0:11] == '@ValidRange':<br>
-                        ValidFormt = ValidFormt[11:]<br>
-                        ValidFormt = ValidFormt.lstrip()<br>
-                        try:<br>
-                            ErrorCode, Expression = ValidFormt.split('|', 1)<br>
-                        except ValueError:<br>
-                            ErrorCode = '0x0'<br>
-                            Expression = ValidFormt<br>
-                        ErrorCode, Expression = ErrorCode.strip(), Expression.strip()<br>
-                        try:<br>
-                            if not eval(ErrorCodeValid % ErrorCode):<br>
-                                EdkLogger.warn('Parser', '@ValidRange ErrorCode(%s) of PCD %s is not valid UINT32 value.' % (ErrorCode, TokenList[0]))<br>
-                        except:<br>
-                            EdkLogger.warn('Parser', '@ValidRange ErrorCode(%s) of PCD %s is not valid UINT32 value.' % (ErrorCode, TokenList[0]))<br>
-                        if not PatternValidRng.search(Expression):<br>
-                            EdkLogger.warn('Parser', '@ValidRange Expression(%s) of PCD %s is incorrect format.' % (Expression, TokenList[0]))<br>
-                    if ValidFormt[0:10] == '@ValidList':<br>
-                        ValidFormt = ValidFormt[10:]<br>
-                        ValidFormt = ValidFormt.lstrip()<br>
-                        try:<br>
-                            ErrorCode, Expression = ValidFormt.split('|', 1)<br>
-                        except ValueError:<br>
-                            ErrorCode = '0x0'<br>
-                            Expression = ValidFormt<br>
-                        ErrorCode, Expression = ErrorCode.strip(), Expression.strip()<br>
-                        try:<br>
-                            if not eval(ErrorCodeValid % ErrorCode):<br>
-                                EdkLogger.warn('Parser', '@ValidList ErrorCode(%s) of PCD %s is not valid UINT32 value.' % (ErrorCode, TokenList[0]))<br>
-                        except:<br>
-                            EdkLogger.warn('Parser', '@ValidList ErrorCode(%s) of PCD %s is not valid UINT32 value.' % (ErrorCode, TokenList[0]))<br>
-                        Values = Expression.split(',')<br>
-                        for Value in Values:<br>
-                            Value = Value.strip()<br>
-                            try:<br>
-                                eval(Value)<br>
-                            except:<br>
-                                EdkLogger.warn('Parser', '@ValidList Expression of PCD %s include a invalid value(%s).' % (TokenList[0], Value))<br>
-                                break<br>
-                    if ValidFormt[0:11] == '@Expression':<br>
-                        ValidFormt = ValidFormt[11:]<br>
-                        ValidFormt = ValidFormt.lstrip()<br>
-                        try:<br>
-                            ErrorCode, Expression = ValidFormt.split('|', 1)<br>
-                        except ValueError:<br>
-                            ErrorCode = '0x0'<br>
-                            Expression = ValidFormt<br>
-                        ErrorCode, Expression = ErrorCode.strip(), Expression.strip()<br>
-                        try:<br>
-                            if not eval(ErrorCodeValid % ErrorCode):<br>
-                                EdkLogger.warn('Parser', '@Expression ErrorCode(%s) of PCD %s is not valid UINT32 value.' % (ErrorCode, TokenList[0]))<br>
-                        except:<br>
-                            EdkLogger.warn('Parser', '@Expression ErrorCode(%s) of PCD %s is not valid UINT32 value.' % (ErrorCode, TokenList[0]))<br>
-                        if not Expression:<br>
-                            EdkLogger.warn('Parser', '@Expression Expression of PCD %s is incorrect format.' % TokenList[0])<br>
-            if not Description:<br>
-                EdkLogger.warn('Parser', 'PCD %s Description information is not provided.' % TokenList[0])<br>
-            if not Prompt:<br>
-                EdkLogger.warn('Parser', 'PCD %s Prompt information is not provided.' % TokenList[0])<br>
-            # check Description, Prompt localization information<br>
-            if self._UniObj:<br>
-                self._UniObj.CheckPcdInfo(TokenList[0])<br>
+            if "|" not in self._CurrentLine:<br>
+                if "<HeaderFiles>" == self._CurrentLine:<br>
+                    self._include_flag = True<br>
+                    self._package_flag = False<br>
+                    self._ValueList = None<br>
+                    return<br>
+                if "<Packages>" == self._CurrentLine:<br>
+                    self._package_flag = True<br>
+                    self._ValueList = None<br>
+                    self._include_flag = False<br>
+                    return<br>
 <br>
-        if ValueList[0] in ['True', 'true', 'TRUE']:<br>
-            ValueList[0] = '1'<br>
-        elif ValueList[0] in ['False', 'false', 'FALSE']:<br>
-            ValueList[0] = '0'<br>
+                if self._include_flag:<br>
+                    self._ValueList[1] = "<HeaderFiles>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()<br>
+                    self._ValueList[2] = self._CurrentLine<br>
+                if self._package_flag and "}" != self._CurrentLine:<br>
+                    self._ValueList[1] = "<Packages>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()<br>
+                    self._ValueList[2] = self._CurrentLine<br>
+                if self._CurrentLine == "}":<br>
+                    self._package_flag = False<br>
+                    self._include_flag = False<br>
+                    self._ValueList = None<br>
+                    return<br>
+            else:<br>
+                PcdTockens = self._CurrentLine.split(TAB_VALUE_SPLIT)<br>
+                PcdNames = self.ParsePcdName(PcdTockens[0].split(TAB_SPLIT))<br>
+                if len(PcdNames) == 2:<br>
+                    if PcdNames[1].strip().endswith("]"):<br>
+                        PcdName = PcdNames[1][:PcdNames[1].index('[')]<br>
+                        Index = PcdNames[1][PcdNames[1].index('['):]<br>
+                        self._ValueList[0] = TAB_SPLIT.join((PcdNames[0],PcdName))<br>
+                        self._ValueList[1] = Index<br>
+                        self._ValueList[2] = PcdTockens[1]<br>
+                    else:<br>
+                        self._CurrentStructurePcdName = ""<br>
+                else:<br>
+                    if self._CurrentStructurePcdName != TAB_SPLIT.join(PcdNames[:2]):<br>
+                        EdkLogger.error('Parser', FORMAT_INVALID, "Pcd Name does not match: %s and %s " % (self._CurrentStructurePcdName, TAB_SPLIT.join(PcdNames[:2])),<br>
+                                File=self.MetaFile, Line=self._LineIndex + 1)<br>
+                    self._ValueList[1] = TAB_SPLIT.join(PcdNames[2:])<br>
+                    self._ValueList[2] = PcdTockens[1]<br>
 <br>
-        self._ValueList[2] = ValueList[0].strip() + '|' + ValueList[1].strip() + '|' + ValueList[2].strip()<br>
+        if not self._CurrentStructurePcdName:<br>
+            if self._PcdDataTypeCODE:<br>
+                if ")}" in self._CurrentLine:<br>
+                    ValuePart, RestofValue = self._CurrentLine.split(")}")<br>
+                    self._PcdCodeValue = self._PcdCodeValue + "\n " + ValuePart<br>
+                    self._CurrentLine = "|".join((self._CurrentPcdName, self._PcdCodeValue, RestofValue))<br>
+                    self._PcdDataTypeCODE = False<br>
+                    self._PcdCodeValue = ""<br>
+                else:<br>
+                    self._PcdCodeValue = self._PcdCodeValue + "\n " + self._CurrentLine<br>
+                    self._ValueList = None<br>
+                    return<br>
+            TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)<br>
+            self._CurrentPcdName = TokenList[0]<br>
+            if len(TokenList) == 2 and TokenList[1].strip().startswith("{CODE"):<br>
+                if ")}" in self._CurrentLine:<br>
+                    self._PcdDataTypeCODE = False<br>
+                    self._PcdCodeValue = ""<br>
+                else:<br>
+                    self._PcdDataTypeCODE = True<br>
+                    self._PcdCodeValue = TokenList[1].strip()<br>
+                    self._ValueList = None<br>
+                    return<br>
+<br>
+            self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)<br>
+            ValueRe = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*')<br>
+            # check PCD information<br>
+            if self._ValueList[0] == '' or self._ValueList[1] == '':<br>
+                EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",<br>
+                                ExtraData=self._CurrentLine + \<br>
+                                          " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",<br>
+                                File=self.MetaFile, Line=self._LineIndex+1)<br>
+            # check format of token space GUID CName<br>
+            if not ValueRe.match(self._ValueList[0]):<br>
+                EdkLogger.error('Parser', FORMAT_INVALID,<br>
+                                "The format of the token space GUID CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",<br>
+                                ExtraData=self._CurrentLine + \<br>
+                                          " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",<br>
+                                File=self.MetaFile, Line=self._LineIndex + 1)<br>
+            # check format of PCD CName<br>
+            if not ValueRe.match(self._ValueList[1]):<br>
+                EdkLogger.error('Parser', FORMAT_INVALID,<br>
+                                "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",<br>
+                                ExtraData=self._CurrentLine + \<br>
+                                          " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",<br>
+                                File=self.MetaFile, Line=self._LineIndex + 1)<br>
+<br>
+            # check PCD datum information<br>
+            if len(TokenList) < 2 or TokenList[1] == '':<br>
+                EdkLogger.error('Parser', FORMAT_INVALID, "No PCD Datum information given",<br>
+                                ExtraData=self._CurrentLine + \<br>
+                                          " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",<br>
+                                File=self.MetaFile, Line=self._LineIndex+1)<br>
+<br>
+<br>
+            ValueRe = re.compile(r'^\s*L?\".*\|.*\"')<br>
+            PtrValue = ValueRe.findall(TokenList[1])<br>
+<br>
+            # Has VOID* type string, may contain "|" character in the string.<br>
+            if len(PtrValue) != 0:<br>
+                ptrValueList = re.sub(ValueRe, '', TokenList[1])<br>
+                ValueList = AnalyzePcdExpression(ptrValueList)<br>
+                ValueList[0] = PtrValue[0]<br>
+            else:<br>
+                ValueList = AnalyzePcdExpression(TokenList[1])<br>
+<br>
+<br>
+            # check if there's enough datum information given<br>
+            if len(ValueList) != 3:<br>
+                EdkLogger.error('Parser', FORMAT_INVALID, "Invalid PCD Datum information given",<br>
+                                ExtraData=self._CurrentLine + \<br>
+                                          " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",<br>
+                                File=self.MetaFile, Line=self._LineIndex + 1)<br>
+            # check default value<br>
+            if ValueList[0] == '':<br>
+                EdkLogger.error('Parser', FORMAT_INVALID, "Missing DefaultValue in PCD Datum information",<br>
+                                ExtraData=self._CurrentLine + \<br>
+                                          " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",<br>
+                                File=self.MetaFile, Line=self._LineIndex + 1)<br>
+            # check datum type<br>
+            if ValueList[1] == '':<br>
+                EdkLogger.error('Parser', FORMAT_INVALID, "Missing DatumType in PCD Datum information",<br>
+                                ExtraData=self._CurrentLine + \<br>
+                                          " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",<br>
+                                File=self.MetaFile, Line=self._LineIndex + 1)<br>
+            # check token of the PCD<br>
+            if ValueList[2] == '':<br>
+                EdkLogger.error('Parser', FORMAT_INVALID, "Missing Token in PCD Datum information",<br>
+                                ExtraData=self._CurrentLine + \<br>
+                                          " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",<br>
+                                File=self.MetaFile, Line=self._LineIndex + 1)<br>
+<br>
+            PcdValue = ValueList[0]<br>
+            if PcdValue:<br>
+                try:<br>
+                    self._GuidDict.update(self._AllPcdDict)<br>
+                    ValueList[0] = ValueExpressionEx(ValueList[0], ValueList[1], self._GuidDict)(True)<br>
+                except BadExpression as Value:<br>
+                    EdkLogger.error('Parser', FORMAT_INVALID, Value, ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)<br>
+            # check format of default value against the datum type<br>
+            IsValid, Cause = CheckPcdDatum(ValueList[1], ValueList[0])<br>
+            if not IsValid:<br>
+                EdkLogger.error('Parser', FORMAT_INVALID, Cause, ExtraData=self._CurrentLine,<br>
+                                File=self.MetaFile, Line=self._LineIndex + 1)<br>
+<br>
+            if Cause == "StructurePcd":<br>
+                self._CurrentStructurePcdName = TAB_SPLIT.join(self._ValueList[0:2])<br>
+                self._ValueList[0] = self._CurrentStructurePcdName<br>
+                self._ValueList[1] = ValueList[1].strip()<br>
+<br>
+            if ValueList[0] in ['True', 'true', 'TRUE']:<br>
+                ValueList[0] = '1'<br>
+            elif ValueList[0] in ['False', 'false', 'FALSE']:<br>
+                ValueList[0] = '0'<br>
+<br>
+            # check for duplicate PCD definition<br>
+            if (self._Scope[0], self._ValueList[0], self._ValueList[1]) in self._AllPCDs:<br>
+                EdkLogger.error('Parser', FORMAT_INVALID,<br>
+                                "The same PCD name and GUID have been already defined",<br>
+                                ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)<br>
+            else:<br>
+                self._AllPCDs.append((self._Scope[0], self._ValueList[0], self._ValueList[1]))<br>
+                self._AllPcdDict[TAB_SPLIT.join(self._ValueList[0:2])] = ValueList[0]<br>
+<br>
+            self._ValueList[2] = ValueList[0].strip() + '|' + ValueList[1].strip() + '|' + ValueList[2].strip()<br>
 <br>
     _SectionParser = {<br>
         MODEL_META_DATA_HEADER          :   MetaFileParser._DefineParser,<br>
-- <br>
2.26.2.windows.1<br>
<br>
<br>
<br>
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</body>
</html>


 <div width="1" style="color:white;clear:both">_._,_._,_</div> <hr> Groups.io Links:<p>   You receive all messages sent to this group.    <p> <a target="_blank" href="https://edk2.groups.io/g/devel/message/73809">View/Reply Online (#73809)</a> |    |  <a target="_blank" href="https://groups.io/mt/81782034/1813853">Mute This Topic</a>  | <a href="https://edk2.groups.io/g/devel/post">New Topic</a><br>    <a href="https://edk2.groups.io/g/devel/editsub/1813853">Your Subscription</a> | <a href="mailto:devel+owner@edk2.groups.io">Contact Group Owner</a> |  <a href="https://edk2.groups.io/g/devel/unsub">Unsubscribe</a>  [edk2-devel-archive@redhat.com]<br> <div width="1" style="color:white;clear:both">_._,_._,_</div>