BaseTools: support PCD value to use expression in the DEC file

This patch add the support for Pcd value to use expression in the DEC file.

Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py
index c99716d..3be1f0f 100644
--- a/BaseTools/Source/Python/Common/Misc.py
+++ b/BaseTools/Source/Python/Common/Misc.py
@@ -1412,32 +1412,7 @@
     Opr.close()

     Opw.close()

 

-## AnalyzeDscPcd

-#

-#  Analyze DSC PCD value, since there is no data type info in DSC

-#  This fuction is used to match functions (AnalyzePcdData, AnalyzeHiiPcdData, AnalyzeVpdPcdData) used for retrieving PCD value from database

-#  1. Feature flag: TokenSpace.PcdCName|PcdValue

-#  2. Fix and Patch:TokenSpace.PcdCName|PcdValue[|MaxSize]

-#  3. Dynamic default:

-#     TokenSpace.PcdCName|PcdValue[|VOID*[|MaxSize]]

-#     TokenSpace.PcdCName|PcdValue

-#  4. Dynamic VPD:

-#     TokenSpace.PcdCName|VpdOffset[|VpdValue]

-#     TokenSpace.PcdCName|VpdOffset[|MaxSize[|VpdValue]]

-#  5. Dynamic HII:

-#     TokenSpace.PcdCName|HiiString|VaiableGuid|VariableOffset[|HiiValue]

-#  PCD value needs to be located in such kind of string, and the PCD value might be an expression in which

-#    there might have "|" operator, also in string value.

-#

-#  @param Setting: String contain information described above with "TokenSpace.PcdCName|" stripped

-#  @param PcdType: PCD type: feature, fixed, dynamic default VPD HII

-#  @param DataType: The datum type of PCD: VOID*, UNIT, BOOL

-#  @retval:

-#    ValueList: A List contain fields described above

-#    IsValid:   True if conforming EBNF, otherwise False

-#    Index:     The index where PcdValue is in ValueList

-#

-def AnalyzeDscPcd(Setting, PcdType, DataType=''):

+def AnalyzePcdExpression(Setting):

     Setting = Setting.strip()

     # There might be escaped quote in a string: \", \\\"

     Data = Setting.replace('\\\\', '//').replace('\\\"', '\\\'')

@@ -1467,6 +1442,36 @@
         FieldList.append(Setting[StartPos:Pos].strip())

         StartPos = Pos + 1

 

+    return FieldList

+

+## AnalyzeDscPcd

+#

+#  Analyze DSC PCD value, since there is no data type info in DSC

+#  This fuction is used to match functions (AnalyzePcdData, AnalyzeHiiPcdData, AnalyzeVpdPcdData) used for retrieving PCD value from database

+#  1. Feature flag: TokenSpace.PcdCName|PcdValue

+#  2. Fix and Patch:TokenSpace.PcdCName|PcdValue[|MaxSize]

+#  3. Dynamic default:

+#     TokenSpace.PcdCName|PcdValue[|VOID*[|MaxSize]]

+#     TokenSpace.PcdCName|PcdValue

+#  4. Dynamic VPD:

+#     TokenSpace.PcdCName|VpdOffset[|VpdValue]

+#     TokenSpace.PcdCName|VpdOffset[|MaxSize[|VpdValue]]

+#  5. Dynamic HII:

+#     TokenSpace.PcdCName|HiiString|VaiableGuid|VariableOffset[|HiiValue]

+#  PCD value needs to be located in such kind of string, and the PCD value might be an expression in which

+#    there might have "|" operator, also in string value.

+#

+#  @param Setting: String contain information described above with "TokenSpace.PcdCName|" stripped

+#  @param PcdType: PCD type: feature, fixed, dynamic default VPD HII

+#  @param DataType: The datum type of PCD: VOID*, UNIT, BOOL

+#  @retval:

+#    ValueList: A List contain fields described above

+#    IsValid:   True if conforming EBNF, otherwise False

+#    Index:     The index where PcdValue is in ValueList

+#

+def AnalyzeDscPcd(Setting, PcdType, DataType=''):

+    FieldList = AnalyzePcdExpression(Setting)

+

     IsValid = True

     if PcdType in (MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_FEATURE_FLAG):

         Value = FieldList[0]

diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py
index 82d874f..1a5fdf5 100644
--- a/BaseTools/Source/Python/Workspace/MetaFileParser.py
+++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py
@@ -26,7 +26,7 @@
 from CommonDataClass.DataClass import *

 from Common.DataType import *

 from Common.String import *

-from Common.Misc import GuidStructureStringToGuidString, CheckPcdDatum, PathClass, AnalyzePcdData, AnalyzeDscPcd

+from Common.Misc import GuidStructureStringToGuidString, CheckPcdDatum, PathClass, AnalyzePcdData, AnalyzeDscPcd, AnalyzePcdExpression

 from Common.Expression import *

 from CommonDataClass.Exceptions import *

 from Common.LongFilePathSupport import OpenLongFilePath as open

@@ -1635,6 +1635,7 @@
         self._Comments = []

         self._Version = 0x00010005  # Only EDK2 dec file is supported

         self._AllPCDs = [] # Only for check duplicate PCD

+        self._AllPcdDict = {}

 

     ## Parser starter

     def Start(self):

@@ -1848,10 +1849,10 @@
         # Has VOID* type string, may contain "|" character in the string. 

         if len(PtrValue) != 0:

             ptrValueList = re.sub(ValueRe, '', TokenList[1])

-            ValueList = GetSplitValueList(ptrValueList)

+            ValueList = AnalyzePcdExpression(ptrValueList)

             ValueList[0] = PtrValue[0]

         else:

-            ValueList = GetSplitValueList(TokenList[1])

+            ValueList = AnalyzePcdExpression(TokenList[1])

 

 

         # check if there's enough datum information given

@@ -1878,6 +1879,19 @@
                             ExtraData=self._CurrentLine + \

                                       " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",

                             File=self.MetaFile, Line=self._LineIndex + 1)

+

+        PcdValue = ValueList[0]

+        if PcdValue:

+            try:

+                ValueList[0] = ValueExpression(PcdValue, self._AllPcdDict)(True)

+            except WrnExpression, Value:

+                ValueList[0] = Value.result

+

+        if ValueList[0] == 'True':

+            ValueList[0] = '1'

+        if ValueList[0] == 'False':

+            ValueList[0] = '0'

+

         # check format of default value against the datum type

         IsValid, Cause = CheckPcdDatum(ValueList[1], ValueList[0])

         if not IsValid:

@@ -1896,6 +1910,7 @@
                             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()