Added conditional statement support for DSC file
authorjwang36 <jwang36@7335b38e-4728-0410-8992-fb3ffe349368>
Thu, 3 Apr 2008 03:15:54 +0000 (03:15 +0000)
committerjwang36 <jwang36@7335b38e-4728-0410-8992-fb3ffe349368>
Thu, 3 Apr 2008 03:15:54 +0000 (03:15 +0000)
git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@1113 7335b38e-4728-0410-8992-fb3ffe349368

Source/Python/Common/Misc.py
Source/Python/Workspace/MetaDataTable.py
Source/Python/Workspace/MetaFileParser.py
Source/Python/Workspace/MetaFileTable.py
Source/Python/Workspace/WorkspaceDatabase.py

index b6cf632..4229d8a 100755 (executable)
@@ -23,6 +23,7 @@ import time
 import re\r
 import cPickle\r
 from UserDict import IterableUserDict\r
+from UserList import UserList\r
 \r
 from Common import EdkLogger as EdkLogger\r
 from BuildToolError import *\r
@@ -645,6 +646,26 @@ class tdict:
         if self._Level_ > 1:\r
             for Key in self.data:\r
                 self.data[Key].SetSingleMode()\r
+\r
+## Boolean chain list\r
+# \r
+class Blist(UserList):\r
+    def __init__(self, initlist=None):\r
+        UserList.__init__(self, initlist)\r
+    def __setitem__(self, i, item):\r
+        if item not in [True, False]:\r
+            if item == 0:\r
+                item = False\r
+            else:\r
+                item = True\r
+        self.data[i] = item\r
+    def _GetResult(self):\r
+        Value = True\r
+        for item in self.data:\r
+            Value &= item\r
+        return Value\r
+    Result = property(_GetResult)\r
+\r
 ##\r
 #\r
 # This acts like the main() function for the script, unless it is 'import'ed into another\r
index fae94e7..7b66123 100644 (file)
@@ -230,6 +230,9 @@ class TableFile(Table):
             return None\r
         return RecordList[0][0]\r
 \r
+    def SetFileTimeStamp(self, FileId, TimeStamp):\r
+        self.Exec("update %s set TimeStamp=%s where ID='%s'" % (self.Table, TimeStamp, FileId))\r
+\r
 ## TableDataModel\r
 #\r
 # This class defined a table used for data model\r
index 9869f35..715082d 100644 (file)
@@ -22,6 +22,7 @@ import Common.EdkLogger as EdkLogger
 from CommonDataClass.DataClass import *\r
 from Common.DataType import *\r
 from Common.String import *\r
+from Common.Misc import Blist\r
 \r
 class MetaFileParser(object):\r
     _DataType = {}\r
@@ -47,6 +48,7 @@ class MetaFileParser(object):
         self._SubsectionType = MODEL_UNKNOWN\r
         self._SubsectionName = ''\r
         self._LastItem = -1\r
+        self._Enabled = 0\r
 \r
     def _Store(self, *Args):\r
         return self._Table.Insert(*Args)\r
@@ -276,8 +278,22 @@ class DscParser(MetaFileParser):
         TAB_PCDS_DYNAMIC_EX_VPD_NULL.upper(),\r
         ]\r
 \r
+    _OP_ = {\r
+        "!"     :   lambda a:   not a,\r
+        "!="    :   lambda a,b: a!=b,\r
+        "=="    :   lambda a,b: a==b,\r
+        ">"     :   lambda a,b: a>b,\r
+        "<"     :   lambda a,b: a<b,\r
+        "=>"    :   lambda a,b: a>=b,\r
+        ">="    :   lambda a,b: a>=b,\r
+        "<="    :   lambda a,b: a<=b,\r
+        "=<"    :   lambda a,b: a<=b,\r
+    }\r
+\r
     def __init__(self, FilePath, FileId, FileType, Table, Macros={}, Owner=-1, From=-1):\r
         MetaFileParser.__init__(self, FilePath, FileType, Table, Macros, Owner, From)\r
+        # to store conditional directive evaluation result\r
+        self._Eval = Blist()\r
 \r
     def Start(self):\r
         try:\r
@@ -330,8 +346,8 @@ class DscParser(MetaFileParser):
                 continue\r
 \r
             # \r
-            # Model, Value1, Value2, Value3, Value4, Value5, Arch, Platform, BelongsToFile=-1, \r
-            # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, BelongsToItem=-1, FeatureFlag='', \r
+            # Model, Value1, Value2, Value3, Arch, Platform, BelongsToFile=-1, \r
+            # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, BelongsToItem=-1, \r
             # Enabled=-1\r
             # \r
             for Arch, ModuleType in self._Scope:\r
@@ -348,7 +364,7 @@ class DscParser(MetaFileParser):
                     -1,\r
                     self._LineIndex+1,\r
                     -1,\r
-                    0\r
+                    self._Enabled\r
                     )\r
         self._Done()\r
 \r
@@ -400,10 +416,60 @@ class DscParser(MetaFileParser):
                 Parser.Start()\r
             except:\r
                 EdkLogger.error("DscParser", PARSER_ERROR, File=self._FilePath, Line=self._LineIndex+1,\r
-                                ExtraData="'Failed to parse content in file %s" % IncludedFile)\r
+                                ExtraData="Failed to parse content in file %s" % IncludedFile)\r
             self._SectionName = Parser._SectionName\r
             self._SectionType = Parser._SectionType\r
             self._Scope       = Parser._Scope\r
+        else:\r
+            if DirectiveName in ["!IF", "!IFDEF", "!IFNDEF"]:\r
+                # evaluate the expression\r
+                Result = self._Evaluate(self._ValueList[1])\r
+                if DirectiveName == "!IFNDEF":\r
+                    Result = not Result\r
+                self._Eval.append(Result)\r
+            elif DirectiveName in ["!ELSEIF"]:\r
+                # evaluate the expression\r
+                self._Eval[-1] = (not self._Eval[-1]) & self._Evaluate(self._ValueList[1])\r
+            elif DirectiveName in ["!ELSE"]:\r
+                self._Eval[-1] = not self._Eval[-1]\r
+            elif DirectiveName in ["!ENDIF"]:\r
+                if len(self._Eval) > 0:\r
+                    self._Eval.pop()\r
+                else:\r
+                    EdkLogger.error("DscParser", FORMAT_INVALID, "!if..[!else]..!endif doesn't match",\r
+                                    File=self._FilePath, Line=self._LineIndex+1)\r
+            if self._Eval.Result == False:\r
+                self._Enabled = 0 - len(self._Eval)\r
+            else:\r
+                self._Enabled = len(self._Eval)\r
+\r
+    def _Evaluate(self, Expression):\r
+        TokenList = Expression.split()\r
+        TokenNumber = len(TokenList)\r
+        if TokenNumber == 1:\r
+            return TokenList[0] in self._Macros\r
+        elif TokenNumber == 2:\r
+            Op = TokenList[0]\r
+            if Op not in self._OP_:\r
+                EdkLogger.error('DscParser', FORMAT_INVALID, File=self._FilePath, \r
+                                Line=self._LineIndex+1, ExtraData=Expression)\r
+            if TokenList[1].upper() == 'TRUE':\r
+                Value = True\r
+            else:\r
+                Value = False\r
+            return self._OP_[Op](Value)\r
+        elif TokenNumber == 3:\r
+            Name = TokenList[0]\r
+            if Name not in self._Macros:\r
+                return False\r
+            Value = TokenList[2]\r
+            if Value[0] in ["'", '"']:\r
+                Value = Value[1:-1]\r
+            Op = TokenList[1]\r
+            return self._OP_[Op](self._Macros[Macro], Value)\r
+        else:\r
+            EdkLogger.error('DscParser', FORMAT_INVALID, File=self._FilePath, Line=self._LineIndex+1,\r
+                            ExtraData=Expression)\r
 \r
     def _BuildOptionParser(self):\r
         TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
index 1c1e790..6e3d95d 100644 (file)
@@ -85,7 +85,7 @@ class ModuleTable(Table):
     # @retval:       A recordSet of all found records \r
     #\r
     def Query(self, Model, Value1=None, Arch=None, Platform=None):\r
-        ConditionString = "Model=%s" % Model\r
+        ConditionString = "Model=%s AND Enabled>=0" % Model\r
         if Value1 == None:\r
             ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"\r
         else:\r
@@ -165,7 +165,7 @@ class PackageTable(Table):
     # @retval:       A recordSet of all found records \r
     #\r
     def Query(self, Model, Value1=None, Arch=None):\r
-        ConditionString = "Model=%s" % Model\r
+        ConditionString = "Model=%s AND Enabled>=0" % Model\r
         if Value1 == None:\r
             ValueString = "Value1,Value2,Value3,Scope1,ID,StartLine"\r
         else:\r
@@ -245,7 +245,7 @@ class PlatformTable(Table):
     # @retval:       A recordSet of all found records \r
     #\r
     def Query(self, Model, Value1=None, Scope1=None, Scope2=None, BelongsToItem=None, FromItem=None):\r
-        ConditionString = "Model=%s" % Model\r
+        ConditionString = "Model=%s AND Enabled>=0" % Model\r
         if Value1 == None:\r
             ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"\r
         else:\r
index 82778cf..fe75e52 100644 (file)
@@ -1295,7 +1295,7 @@ class InfBuildData(ModuleBuildClassObject):
         # \r
         # R8.x modules\r
         # \r
-        if self._AutoGenVersion < 0x00010005:\r
+        if self._AutoGenVersion < 0x00010005:   # _AutoGenVersion may be None, which is less than anything\r
             if self._ComponentType in self._MODULE_TYPE_:\r
                 self._ModuleType = self._MODULE_TYPE_[self._ComponentType]\r
             if self._ComponentType == 'LIBRARY':\r
@@ -1853,6 +1853,9 @@ class WorkspaceDatabase(object):
     def GetTimeStamp(self, FileId):\r
         return self.TblFile.GetFileTimeStamp(FileId)\r
 \r
+    def SetTimeStamp(self, FileId, TimeStamp):\r
+        return self.TblFile.SetFileTimeStamp(FileId, TimeStamp)\r
+\r
     def CheckIntegrity(self, TableName):\r
         Result = self.Cur.execute("select min(ID) from %s" % (TableName)).fetchall()\r
         if Result[0][0] != -1:\r
@@ -1868,10 +1871,12 @@ class WorkspaceDatabase(object):
     def __setitem__(self, FilePath, FileType):\r
         FileId = self.GetFileId(FilePath)\r
         if FileId != None:\r
+            TimeStamp = os.stat(FilePath)[8]\r
             TableName = self.GetTableName(FileType, FileId)\r
-            if self.CheckIntegrity(TableName):\r
-                TimeStamp = os.stat(FilePath)[8]\r
-                if TimeStamp == self.GetTimeStamp(FileId):\r
+            if TimeStamp != self.GetTimeStamp(FileId):\r
+                self.SetTimeStamp(FileId, TimeStamp)\r
+            else:\r
+                if self.CheckIntegrity(TableName) == True:\r
                     return\r
         else:\r
             FileId = self.TblFile.InsertFile(FilePath, FileType)\r