Added for database based build infrastructure
authorjwang36 <jwang36@7335b38e-4728-0410-8992-fb3ffe349368>
Tue, 1 Apr 2008 15:51:25 +0000 (15:51 +0000)
committerjwang36 <jwang36@7335b38e-4728-0410-8992-fb3ffe349368>
Tue, 1 Apr 2008 15:51:25 +0000 (15:51 +0000)
git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@1099 7335b38e-4728-0410-8992-fb3ffe349368

Source/Python/Workspace/BuildClassObject.py [new file with mode: 0644]
Source/Python/Workspace/MetaDataTable.py [new file with mode: 0644]
Source/Python/Workspace/MetaFileParser.py [new file with mode: 0644]
Source/Python/Workspace/MetaFileTable.py [new file with mode: 0644]
Source/Python/Workspace/WorkspaceBuild.py [new file with mode: 0644]
Source/Python/Workspace/WorkspaceDatabase.py [new file with mode: 0644]
Source/Python/Workspace/__init__.py [new file with mode: 0644]

diff --git a/Source/Python/Workspace/BuildClassObject.py b/Source/Python/Workspace/BuildClassObject.py
new file mode 100644 (file)
index 0000000..a3778a8
--- /dev/null
@@ -0,0 +1,358 @@
+## @file\r
+# This file is used to define each component of the build database\r
+#\r
+# Copyright (c) 2007 ~ 2008, Intel Corporation\r
+# All rights reserved. This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+\r
+## PcdClassObject\r
+#\r
+# This Class is used for PcdObject\r
+# \r
+# @param object:             Inherited from object class\r
+# @param Name:               Input value for Name of Pcd, default is None\r
+# @param Guid:               Input value for Guid of Pcd, default is None\r
+# @param Type:               Input value for Type of Pcd, default is None\r
+# @param DatumType:          Input value for DatumType of Pcd, default is None\r
+# @param Value:              Input value for Value of Pcd, default is None\r
+# @param Token:              Input value for Token of Pcd, default is None\r
+# @param MaxDatumSize:       Input value for MaxDatumSize of Pcd, default is None\r
+# @param SkuInfoList:        Input value for SkuInfoList of Pcd, default is {}\r
+# @param IsOverrided:        Input value for IsOverrided of Pcd, default is False\r
+#\r
+# @var TokenCName:           To store value for TokenCName\r
+# @var TokenSpaceGuidCName:  To store value for TokenSpaceGuidCName\r
+# @var Type:                 To store value for Type\r
+# @var DatumType:            To store value for DatumType\r
+# @var TokenValue:           To store value for TokenValue\r
+# @var MaxDatumSize:         To store value for MaxDatumSize\r
+# @var SkuInfoList:          To store value for SkuInfoList\r
+# @var IsOverrided:          To store value for IsOverrided\r
+# @var Phase:                To store value for Phase, default is "DXE"\r
+#\r
+class PcdClassObject(object):\r
+    def __init__(self, Name = None, Guid = None, Type = None, DatumType = None, Value = None, Token = None, MaxDatumSize = None, SkuInfoList = {}, IsOverrided = False):\r
+        self.TokenCName = Name\r
+        self.TokenSpaceGuidCName = Guid\r
+        self.Type = Type\r
+        self.DatumType = DatumType\r
+        self.DefaultValue = Value\r
+        self.TokenValue = Token\r
+        self.MaxDatumSize = MaxDatumSize\r
+        self.SkuInfoList = SkuInfoList\r
+        self.IsOverrided = IsOverrided\r
+        self.Phase = "DXE"\r
+\r
+    ## Convert the class to a string\r
+    #\r
+    #  Convert each member of the class to string\r
+    #  Organize to a signle line format string\r
+    #\r
+    #  @retval Rtn Formatted String\r
+    #\r
+    def __str__(self):\r
+        Rtn = '\tTokenCName=' + str(self.TokenCName) + ', ' + \\r
+              'TokenSpaceGuidCName=' + str(self.TokenSpaceGuidCName) + ', ' + \\r
+              'Type=' + str(self.Type) + ', ' + \\r
+              'DatumType=' + str(self.DatumType) + ', ' + \\r
+              'DefaultValue=' + str(self.DefaultValue) + ', ' + \\r
+              'TokenValue=' + str(self.TokenValue) + ', ' + \\r
+              'MaxDatumSize=' + str(self.MaxDatumSize) + ', '\r
+        for Item in self.SkuInfoList.values():\r
+            Rtn = Rtn + 'SkuId=' + Item.SkuId + ', ' + 'SkuIdName=' + Item.SkuIdName\r
+        Rtn = Rtn + str(self.IsOverrided)\r
+\r
+        return Rtn\r
+\r
+    ## Override __eq__ function\r
+    #\r
+    # Check whether pcds are the same\r
+    #\r
+    # @retval False The two pcds are different\r
+    # @retval True  The two pcds are the same\r
+    #\r
+    def __eq__(self, Other):\r
+        return Other != None and self.TokenCName == Other.TokenCName and self.TokenSpaceGuidCName == Other.TokenSpaceGuidCName\r
+\r
+    ## Override __hash__ function\r
+    #\r
+    # Use (TokenCName, TokenSpaceGuidCName) as key in hash table\r
+    #\r
+    # @retval truple() Key for hash table\r
+    #\r
+    def __hash__(self):\r
+        return hash((self.TokenCName, self.TokenSpaceGuidCName))\r
+\r
+## LibraryClassObject\r
+#\r
+# This Class defines LibraryClassObject used in BuildDatabase\r
+# \r
+# @param object:      Inherited from object class\r
+# @param Name:        Input value for LibraryClassName, default is None\r
+# @param SupModList:  Input value for SupModList, default is []\r
+# @param Type:        Input value for Type, default is None\r
+#\r
+# @var LibraryClass:  To store value for LibraryClass\r
+# @var SupModList:    To store value for SupModList\r
+# @var Type:          To store value for Type\r
+#\r
+class LibraryClassObject(object):\r
+    def __init__(self, Name = None, SupModList = [], Type = None):\r
+        self.LibraryClass = Name\r
+        self.SupModList = SupModList\r
+        if Type != None:\r
+            self.SupModList = CleanString(Type).split(DataType.TAB_SPACE_SPLIT)\r
+\r
+## ModuleBuildClassObject\r
+#\r
+# This Class defines ModuleBuildClass\r
+# \r
+# @param object:               Inherited from object class\r
+#\r
+# @var DescFilePath:           To store value for DescFilePath\r
+# @var BaseName:               To store value for BaseName\r
+# @var ModuleType:             To store value for ModuleType\r
+# @var Guid:                   To store value for Guid\r
+# @var Version:                To store value for Version\r
+# @var PcdIsDriver:            To store value for PcdIsDriver\r
+# @var BinaryModule:           To store value for BinaryModule\r
+# @var CustomMakefile:         To store value for CustomMakefile\r
+# @var Specification:          To store value for Specification\r
+# @var Shadow                  To store value for Shadow\r
+# @var LibraryClass:           To store value for LibraryClass, it is a list structure as\r
+#                              [ LibraryClassObject, ...]\r
+# @var ModuleEntryPointList:   To store value for ModuleEntryPointList\r
+# @var ModuleUnloadImageList:  To store value for ModuleUnloadImageList\r
+# @var ConstructorList:        To store value for ConstructorList\r
+# @var DestructorList:         To store value for DestructorList\r
+# @var Binaries:               To store value for Binaries, it is a list structure as\r
+#                              [ ModuleBinaryClassObject, ...]\r
+# @var Sources:                To store value for Sources, it is a list structure as\r
+#                              [ ModuleSourceFilesClassObject, ... ]\r
+# @var LibraryClasses:         To store value for LibraryClasses, it is a set structure as\r
+#                              { [LibraryClassName, ModuleType] : LibraryClassInfFile }\r
+# @var Protocols:              To store value for Protocols, it is a list structure as\r
+#                              [ ProtocolName, ... ]\r
+# @var Ppis:                   To store value for Ppis, it is a list structure as\r
+#                              [ PpiName, ... ]\r
+# @var Guids:                  To store value for Guids, it is a list structure as\r
+#                              [ GuidName, ... ]\r
+# @var Includes:               To store value for Includes, it is a list structure as\r
+#                              [ IncludePath, ... ]\r
+# @var Packages:               To store value for Packages, it is a list structure as\r
+#                              [ DecFileName, ... ]\r
+# @var Pcds:                   To store value for Pcds, it is a set structure as\r
+#                              { [(PcdCName, PcdGuidCName)] : PcdClassObject}\r
+# @var BuildOptions:           To store value for BuildOptions, it is a set structure as\r
+#                              { [BuildOptionKey] : BuildOptionValue}\r
+# @var Depex:                  To store value for Depex\r
+#\r
+class ModuleBuildClassObject(object):\r
+    def __init__(self):\r
+        self.AutoGenVersion          = 0\r
+        self.DescFilePath            = ''\r
+        self.BaseName                = ''\r
+        self.ModuleType              = ''\r
+        self.Guid                    = ''\r
+        self.Version                 = ''\r
+        self.PcdIsDriver             = ''\r
+        self.BinaryModule            = ''\r
+        self.Shadow                  = ''\r
+        self.CustomMakefile          = {}\r
+        self.Specification           = {}\r
+        self.LibraryClass            = []\r
+        self.ModuleEntryPointList    = []\r
+        self.ModuleUnloadImageList   = []\r
+        self.ConstructorList         = []\r
+        self.DestructorList          = []\r
+\r
+        self.Binaries                = []\r
+        self.Sources                 = []\r
+        self.LibraryClasses          = sdict()\r
+        self.Libraries               = []\r
+        self.Protocols               = []\r
+        self.Ppis                    = []\r
+        self.Guids                   = []\r
+        self.Includes                = []\r
+        self.Packages                = []\r
+        self.Pcds                    = {}\r
+        self.BuildOptions            = {}\r
+        self.Depex                   = ''\r
+\r
+    ## Convert the class to a string\r
+    #\r
+    #  Convert member DescFilePath of the class to a string\r
+    #\r
+    #  @retval string Formatted String\r
+    #\r
+    def __str__(self):\r
+        return self.DescFilePath\r
+\r
+    ## Override __eq__ function\r
+    #\r
+    # Check whether ModuleBuildClassObjects are the same\r
+    #\r
+    # @retval False The two ModuleBuildClassObjects are different\r
+    # @retval True  The two ModuleBuildClassObjects are the same\r
+    #\r
+    def __eq__(self, Other):\r
+        return self.DescFilePath == str(Other)\r
+\r
+    ## Override __hash__ function\r
+    #\r
+    # Use DescFilePath as key in hash table\r
+    #\r
+    # @retval string Key for hash table\r
+    #\r
+    def __hash__(self):\r
+        return hash(self.DescFilePath)\r
+\r
+## PackageBuildClassObject\r
+#\r
+# This Class defines PackageBuildClass\r
+# \r
+# @param object:        Inherited from object class\r
+#\r
+# @var DescFilePath:    To store value for DescFilePath\r
+# @var PackageName:     To store value for PackageName\r
+# @var Guid:            To store value for Guid\r
+# @var Version:         To store value for Version\r
+# @var Protocols:       To store value for Protocols, it is a set structure as\r
+#                       { [ProtocolName] : Protocol Guid, ... }\r
+# @var Ppis:            To store value for Ppis, it is a set structure as\r
+#                       { [PpiName] : Ppi Guid, ... }\r
+# @var Guids:           To store value for Guids, it is a set structure as\r
+#                       { [GuidName] : Guid, ... }\r
+# @var Includes:        To store value for Includes, it is a list structure as\r
+#                       [ IncludePath, ... ]\r
+# @var LibraryClasses:  To store value for LibraryClasses, it is a set structure as\r
+#                       { [LibraryClassName] : LibraryClassInfFile }\r
+# @var Pcds:            To store value for Pcds, it is a set structure as\r
+#                       { [(PcdCName, PcdGuidCName)] : PcdClassObject}\r
+#\r
+class PackageBuildClassObject(object):\r
+    def __init__(self):\r
+        self.DescFilePath            = ''\r
+        self.PackageName             = ''\r
+        self.Guid                    = ''\r
+        self.Version                 = ''\r
+\r
+        self.Protocols               = {}\r
+        self.Ppis                    = {}\r
+        self.Guids                   = {}\r
+        self.Includes                = []\r
+        self.LibraryClasses          = {}\r
+        self.Pcds                    = {}\r
+\r
+    ## Convert the class to a string\r
+    #\r
+    #  Convert member DescFilePath of the class to a string\r
+    #\r
+    #  @retval string Formatted String\r
+    #\r
+    def __str__(self):\r
+        return self.DescFilePath\r
+\r
+    ## Override __eq__ function\r
+    #\r
+    # Check whether PackageBuildClassObjects are the same\r
+    #\r
+    # @retval False The two PackageBuildClassObjects are different\r
+    # @retval True  The two PackageBuildClassObjects are the same\r
+    #\r
+    def __eq__(self, Other):\r
+        return self.DescFilePath == str(Other)\r
+\r
+    ## Override __hash__ function\r
+    #\r
+    # Use DescFilePath as key in hash table\r
+    #\r
+    # @retval string Key for hash table\r
+    #\r
+    def __hash__(self):\r
+        return hash(self.DescFilePath)\r
+\r
+## PlatformBuildClassObject\r
+#\r
+# This Class defines PlatformBuildClass\r
+# \r
+# @param object:          Inherited from object class\r
+#\r
+# @var DescFilePath:      To store value for DescFilePath\r
+# @var PlatformName:      To store value for PlatformName\r
+# @var Guid:              To store value for Guid\r
+# @var Version:           To store value for Version\r
+# @var DscSpecification:  To store value for DscSpecification\r
+# @var OutputDirectory:   To store value for OutputDirectory\r
+# @var FlashDefinition:   To store value for FlashDefinition\r
+# @var BuildNumber:       To store value for BuildNumber\r
+# @var MakefileName:      To store value for MakefileName\r
+# @var SkuIds:            To store value for SkuIds, it is a set structure as\r
+#                         { 'SkuName' : SkuId, '!include' : includefilename, ...}\r
+# @var Modules:           To store value for Modules, it is a list structure as\r
+#                         [ InfFileName, ... ]\r
+# @var Libraries:         To store value for Libraries, it is a list structure as\r
+#                         [ InfFileName, ... ]\r
+# @var LibraryClasses:    To store value for LibraryClasses, it is a set structure as\r
+#                         { (LibraryClassName, ModuleType) : LibraryClassInfFile }\r
+# @var Pcds:              To store value for Pcds, it is a set structure as\r
+#                         { [(PcdCName, PcdGuidCName)] : PcdClassObject }\r
+# @var BuildOptions:      To store value for BuildOptions, it is a set structure as\r
+#                         { [BuildOptionKey] : BuildOptionValue }\r
+#\r
+class PlatformBuildClassObject(object):\r
+    def __init__(self):\r
+        self.DescFilePath            = ''\r
+        self.PlatformName            = ''\r
+        self.Guid                    = ''\r
+        self.Version                 = ''\r
+        self.DscSpecification        = ''\r
+        self.OutputDirectory         = ''\r
+        self.FlashDefinition         = ''\r
+        self.BuildNumber             = ''\r
+        self.MakefileName            = ''\r
+\r
+        self.SkuIds                  = {}\r
+        self.Modules                 = []\r
+        self.LibraryInstances        = []\r
+        self.LibraryClasses          = {}\r
+        self.Libraries               = {}\r
+        self.Pcds                    = {}\r
+        self.BuildOptions            = {}\r
+\r
+    ## Convert the class to a string\r
+    #\r
+    #  Convert member DescFilePath of the class to a string\r
+    #\r
+    #  @retval string Formatted String\r
+    #\r
+    def __str__(self):\r
+        return self.DescFilePath\r
+\r
+    ## Override __eq__ function\r
+    #\r
+    # Check whether PlatformBuildClassObjects are the same\r
+    #\r
+    # @retval False The two PlatformBuildClassObjects are different\r
+    # @retval True  The two PlatformBuildClassObjects are the same\r
+    #\r
+    def __eq__(self, other):\r
+        return self.DescFilePath == str(other)\r
+\r
+    ## Override __hash__ function\r
+    #\r
+    # Use DescFilePath as key in hash table\r
+    #\r
+    # @retval string Key for hash table\r
+    #\r
+    def __hash__(self):\r
+        return hash(self.DescFilePath)\r
+\r
+\r
diff --git a/Source/Python/Workspace/MetaDataTable.py b/Source/Python/Workspace/MetaDataTable.py
new file mode 100644 (file)
index 0000000..507e6ae
--- /dev/null
@@ -0,0 +1,292 @@
+## @file\r
+# This file is used to create/update/query/erase table for files\r
+#\r
+# Copyright (c) 2008, Intel Corporation\r
+# All rights reserved. This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+##\r
+# Import Modules\r
+#\r
+import os\r
+\r
+import Common.EdkLogger as EdkLogger\r
+from Common.String import ConvertToSqlString\r
+from CommonDataClass import DataClass\r
+from CommonDataClass.DataClass import FileClass\r
+\r
+## TableFile\r
+#\r
+# This class defined a common table\r
+# \r
+# @param object:     Inherited from object class\r
+#\r
+# @param Cursor:     Cursor of the database\r
+# @param TableName:  Name of the table\r
+#\r
+class Table(object):\r
+    _COLUMN_ = ''\r
+    _ID_STEP_ = 1\r
+    _ID_MAX_ = 0x80000000\r
+    _DUMMY_ = 0\r
+\r
+    def __init__(self, Cursor, Name='', IdBase=0, Temporary=False):\r
+        self.Cur = Cursor\r
+        self.Table = Name\r
+        self.IdBase = int(IdBase)\r
+        self.ID = int(IdBase)\r
+        self.Temporary = Temporary\r
+\r
+    def __str__(self):\r
+        return self.Table\r
+\r
+    ## Create table\r
+    #\r
+    # Create a table\r
+    #\r
+    def Create(self, NewTable=True):\r
+        if NewTable:\r
+            self.Drop()\r
+\r
+        if self.Temporary:\r
+            SqlCommand = """create temp table IF NOT EXISTS %s (%s)""" % (self.Table, self._COLUMN_)\r
+        else:\r
+            SqlCommand = """create table IF NOT EXISTS %s (%s)""" % (self.Table, self._COLUMN_)\r
+        self.Cur.execute(SqlCommand)\r
+        self.ID = self.GetId()\r
+\r
+    ## Insert table\r
+    #\r
+    # Insert a record into a table\r
+    #\r
+    def Insert(self, *Args):\r
+        self.ID = self.ID + self._ID_STEP_\r
+        if self.ID >= (self.IdBase + self._ID_MAX_):\r
+            self.ID = self.IdBase + self._ID_STEP_\r
+        Values = ", ".join([str(Arg) for Arg in Args])\r
+        SqlCommand = "insert into %s values(%s, %s)" % (self.Table, self.ID, Values)\r
+        self.Cur.execute(SqlCommand)\r
+        return self.ID\r
+    \r
+    ## Query table\r
+    #\r
+    # Query all records of the table\r
+    #  \r
+    def Query(self):\r
+        SqlCommand = """select * from %s""" % self.Table\r
+        self.Cur.execute(SqlCommand)\r
+        for Rs in self.Cur:\r
+            EdkLogger.verbose(str(Rs))        \r
+        TotalCount = self.GetId()\r
+\r
+    ## Drop a table\r
+    #\r
+    # Drop the table\r
+    #\r
+    def Drop(self):\r
+        SqlCommand = """drop table IF EXISTS %s""" % self.Table\r
+        self.Cur.execute(SqlCommand)\r
+    \r
+    ## Get count\r
+    #\r
+    # Get a count of all records of the table\r
+    #\r
+    # @retval Count:  Total count of all records\r
+    #\r
+    def GetCount(self):\r
+        SqlCommand = """select count(ID) from %s""" % self.Table        \r
+        Record = self.Cur.execute(SqlCommand).fetchall()\r
+        return Record[0][0]\r
+        \r
+    def GetId(self):\r
+        SqlCommand = """select max(ID) from %s""" % self.Table        \r
+        Record = self.Cur.execute(SqlCommand).fetchall()\r
+        Id = Record[0][0]\r
+        if Id == None:\r
+            Id = self.IdBase\r
+        return Id\r
+    \r
+    ## Init the ID of the table\r
+    #\r
+    # Init the ID of the table\r
+    #\r
+    def InitID(self):\r
+        self.ID = self.GetId()\r
+    \r
+    ## Exec\r
+    #\r
+    # Exec Sql Command, return result\r
+    #\r
+    # @param SqlCommand:  The SqlCommand to be executed\r
+    #\r
+    # @retval RecordSet:  The result after executed\r
+    #\r
+    def Exec(self, SqlCommand):\r
+        # "###", SqlCommand\r
+        self.Cur.execute(SqlCommand)\r
+        RecordSet = self.Cur.fetchall()\r
+        return RecordSet\r
+\r
+    def SetEndFlag(self):\r
+        self.Exec("insert into %s values(%s)" % (self.Table, self._DUMMY_))\r
+\r
+    def IsIntegral(self):\r
+        Result = self.Exec("select min(ID) from %s" % (self.Table))\r
+        if Result[0][0] != -1:\r
+            return False\r
+        return True\r
+\r
+## TableFile\r
+#\r
+# This class defined a table used for file\r
+# \r
+# @param object:       Inherited from object class\r
+#\r
+class TableFile(Table):\r
+    _COLUMN_ = '''\r
+        ID INTEGER PRIMARY KEY,\r
+        Name VARCHAR NOT NULL,\r
+        ExtName VARCHAR,\r
+        Path VARCHAR,\r
+        FullPath VARCHAR NOT NULL,\r
+        Model INTEGER DEFAULT 0,\r
+        TimeStamp SINGLE NOT NULL\r
+        '''\r
+    def __init__(self, Cursor):\r
+        Table.__init__(self, Cursor, 'File')\r
+    \r
+    ## Insert table\r
+    #\r
+    # Insert a record into table File\r
+    #\r
+    # @param Name:      Name of a File\r
+    # @param ExtName:   ExtName of a File\r
+    # @param Path:      Path of a File\r
+    # @param FullPath:  FullPath of a File\r
+    # @param Model:     Model of a File\r
+    # @param TimeStamp: TimeStamp of a File\r
+    #\r
+    def Insert(self, Name, ExtName, Path, FullPath, Model, TimeStamp):\r
+        (Name, ExtName, Path, FullPath) = ConvertToSqlString((Name, ExtName, Path, FullPath))\r
+        return Table.Insert(\r
+            self, \r
+            Name,\r
+            ExtName, \r
+            Path, \r
+            FullPath, \r
+            Model, \r
+            TimeStamp\r
+            )\r
+\r
+    ## InsertFile\r
+    #\r
+    # Insert one file to table\r
+    #\r
+    # @param FileFullPath:  The full path of the file\r
+    # @param Model:         The model of the file \r
+    # \r
+    # @retval FileID:       The ID after record is inserted\r
+    #\r
+    def InsertFile(self, FileFullPath, Model):\r
+        (Filepath, Name) = os.path.split(FileFullPath)\r
+        (Root, Ext) = os.path.splitext(FileFullPath)\r
+        TimeStamp = os.stat(FileFullPath)[8]\r
+        File = FileClass(-1, Name, Ext, Filepath, FileFullPath, Model, '', [], [], [])\r
+        return self.Insert(\r
+            Name, \r
+            Ext, \r
+            Filepath, \r
+            FileFullPath, \r
+            Model, \r
+            TimeStamp\r
+            )\r
+\r
+    def GetFileId(self, FilePath):\r
+        QueryScript = "select ID from %s where FullPath = '%s'" % (self.Table, FilePath)\r
+        RecordList = self.Exec(QueryScript)\r
+        if len(RecordList) == 0:\r
+            return None\r
+        return RecordList[0][0]\r
+\r
+    def GetFileType(self, FileId):\r
+        QueryScript = "select Model from %s where ID = '%s'" % (self.Table, FileId)\r
+        RecordList = self.Exec(QueryScript)\r
+        if len(RecordList) == 0:\r
+            return None\r
+        return RecordList[0][0]\r
+\r
+    def GetFileTimeStamp(self, FileId):\r
+        QueryScript = "select TimeStamp from %s where ID = '%s'" % (self.Table, FileId)\r
+        RecordList = self.Exec(QueryScript)\r
+        if len(RecordList) == 0:\r
+            return None\r
+        return RecordList[0][0]\r
+\r
+## TableDataModel\r
+#\r
+# This class defined a table used for data model\r
+# \r
+# @param object:       Inherited from object class\r
+#\r
+#\r
+class TableDataModel(Table):\r
+    _COLUMN_ = """\r
+        ID INTEGER PRIMARY KEY,\r
+        CrossIndex INTEGER NOT NULL,\r
+        Name VARCHAR NOT NULL,\r
+        Description VARCHAR\r
+        """\r
+    def __init__(self, Cursor):\r
+        Table.__init__(self, Cursor, 'DataModel')\r
+    \r
+    ## Insert table\r
+    #\r
+    # Insert a record into table DataModel\r
+    #\r
+    # @param ID:           ID of a ModelType\r
+    # @param CrossIndex:   CrossIndex of a ModelType\r
+    # @param Name:         Name of a ModelType\r
+    # @param Description:  Description of a ModelType\r
+    #\r
+    def Insert(self, CrossIndex, Name, Description):\r
+        (Name, Description) = ConvertToSqlString((Name, Description))\r
+        return Table.Insert(self, CrossIndex, Name, Description)\r
+    \r
+    ## Init table\r
+    #\r
+    # Create all default records of table DataModel\r
+    #  \r
+    def InitTable(self):\r
+        EdkLogger.verbose("\nInitialize table DataModel started ...")\r
+        Count = self.GetCount()\r
+        if Count != None and Count != 0:\r
+            return\r
+        for Item in DataClass.MODEL_LIST:\r
+            CrossIndex = Item[1]\r
+            Name = Item[0]\r
+            Description = Item[0]\r
+            self.Insert(CrossIndex, Name, Description)\r
+        EdkLogger.verbose("Initialize table DataModel ... DONE!")\r
+    \r
+    ## Get CrossIndex\r
+    #\r
+    # Get a model's cross index from its name\r
+    #\r
+    # @param ModelName:    Name of the model\r
+    # @retval CrossIndex:  CrossIndex of the model\r
+    #\r
+    def GetCrossIndex(self, ModelName):\r
+        CrossIndex = -1\r
+        SqlCommand = """select CrossIndex from DataModel where name = '""" + ModelName + """'"""\r
+        self.Cur.execute(SqlCommand)\r
+        for Item in self.Cur:\r
+            CrossIndex = Item[0]\r
+        \r
+        return CrossIndex\r
+\r
diff --git a/Source/Python/Workspace/MetaFileParser.py b/Source/Python/Workspace/MetaFileParser.py
new file mode 100644 (file)
index 0000000..5927846
--- /dev/null
@@ -0,0 +1,655 @@
+## @file\r
+# This file is used to create a database used by ECC tool\r
+#\r
+# Copyright (c) 2007 ~ 2008, Intel Corporation\r
+# All rights reserved. This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+##\r
+# Import Modules\r
+#\r
+import sqlite3\r
+import os\r
+import time\r
+\r
+import Common.EdkLogger as EdkLogger\r
+from CommonDataClass.DataClass import *\r
+from Common.DataType import *\r
+from Common.String import *\r
+\r
+class MetaFileParser(object):\r
+    _DataType = {}\r
+    def __init__(self, FilePath, FileType, Table, Macros={}, Owner=-1, From=-1):\r
+        self._Table = Table\r
+        self._FileType = FileType\r
+        self._FilePath = FilePath\r
+        self._FileDir = os.path.dirname(self._FilePath)\r
+        self._Macros = Macros\r
+        # for recursive parsing \r
+        self._Owner = Owner\r
+        self._From = From\r
+\r
+        # for parsing\r
+        self._Content = None\r
+        self._ValueList = ['', '', '', '', '']\r
+        self._Scope = []\r
+        self._LineIndex = 0\r
+        self._CurrentLine = ''\r
+        self._SectionType = MODEL_UNKNOWN\r
+        self._SectionName = ''\r
+        self._InSubsection = False\r
+        self._SubsectionType = MODEL_UNKNOWN\r
+        self._SubsectionName = ''\r
+        self._LastItem = -1\r
+\r
+    def _Store(self, *Args):\r
+        return self._Table.Insert(*Args)\r
+\r
+    def Start(self):\r
+        raise NotImplementedError \r
+\r
+    def _Done(self):\r
+        self._Table.SetEndFlag()\r
+\r
+    def _CommonParser(self):\r
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)\r
+        self._ValueList[0:len(TokenList)] = TokenList\r
+\r
+    def _PathParser(self):\r
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)\r
+        self._ValueList[0:len(TokenList)] = TokenList\r
+        if len(self._Macros) > 0:\r
+            for Index in range(0, len(self._ValueList)):\r
+                Value = self._ValueList[Index]\r
+                if Value == None or Value == '':\r
+                    continue\r
+                self._ValueList[Index] = NormPath(Value, self._Macros)\r
+\r
+    def _Skip(self):\r
+        self._ValueList[0:1] = [self._CurrentLine]\r
+\r
+    def _SectionHeaderParser(self):\r
+        self._Scope = []\r
+        for Item in GetSplitValueList(self._CurrentLine[1:-1], TAB_COMMA_SPLIT):\r
+            ItemList = GetSplitValueList(Item, TAB_SPLIT)\r
+            self._SectionName = ItemList[0].upper()\r
+            if self._SectionName in self._DataType:\r
+                self._SectionType = self._DataType[self._SectionName]\r
+            else:\r
+                self._SectionType = MODEL_UNKNOWN\r
+            # S1 is always Arch\r
+            if len(ItemList) > 1:\r
+                S1 = ItemList[1].upper()\r
+            else:\r
+                S1 = 'COMMON'\r
+            # S2 may be Platform or ModuleType\r
+            if len(ItemList) > 2:\r
+                S2 = ItemList[2].upper()\r
+            else:\r
+                S2 = 'COMMON'\r
+            self._Scope.append([S1, S2])\r
+\r
+    def _DefineParser(self):\r
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
+        self._ValueList[0:len(TokenList)] = TokenList\r
+\r
+    def _MacroParser(self):\r
+        TokenList = GetSplitValueList(self._CurrentLine, ' ', 1)\r
+        if len(TokenList) <= 1:\r
+            return\r
+        TokenList = GetSplitValueList(TokenList[1], TAB_EQUAL_SPLIT, 1)\r
+        if len(TokenList) < 1:\r
+            return\r
+        if self._Macros == None:\r
+            self._Macros = {}\r
+        self._Macros[TokenList[0]] = TokenList[1]\r
+\r
+    _SectionParser = {}\r
+\r
+class InfParser(MetaFileParser):\r
+    _DataType = {\r
+        TAB_UNKNOWN.upper() : MODEL_UNKNOWN,\r
+        TAB_INF_DEFINES.upper() : MODEL_META_DATA_HEADER,\r
+        TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION,\r
+        TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,\r
+        TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE,\r
+        TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,\r
+        TAB_PACKAGES.upper() : MODEL_META_DATA_PACKAGE,\r
+        TAB_NMAKE.upper() : MODEL_META_DATA_NMAKE,\r
+        TAB_INF_FIXED_PCD.upper() : MODEL_PCD_FIXED_AT_BUILD,\r
+        TAB_INF_PATCH_PCD.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,\r
+        TAB_INF_FEATURE_PCD.upper() : MODEL_PCD_FEATURE_FLAG,\r
+        TAB_INF_PCD_EX.upper() : MODEL_PCD_DYNAMIC_EX,\r
+        TAB_INF_PCD.upper() : MODEL_PCD_DYNAMIC,\r
+        TAB_SOURCES.upper() : MODEL_EFI_SOURCE_FILE,\r
+        TAB_GUIDS.upper() : MODEL_EFI_GUID,\r
+        TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,\r
+        TAB_PPIS.upper() : MODEL_EFI_PPI,\r
+        TAB_DEPEX.upper() : MODEL_EFI_DEPEX,\r
+        TAB_BINARIES.upper() : MODEL_EFI_BINARY_FILE,\r
+        TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION\r
+    }\r
+\r
+    def __init__(self, FilePath, FileId, FileType, Table, Macros={}):\r
+        MetaFileParser.__init__(self, FilePath, FileType, Table, Macros)\r
+\r
+    def Start(self):\r
+        try:\r
+            self._Content = open(self._FilePath, 'r').readlines()\r
+        except:\r
+            EdkLogger.error("InfParser", FILE_READ_FAILURE, ExtraData=self._FilePath)\r
+\r
+        for Index in range(0, len(self._Content)):\r
+            Line = CleanString(self._Content[Index])\r
+            if Line == '':\r
+                continue\r
+            self._CurrentLine = Line\r
+            self._LineIndex = Index\r
+\r
+            # section header\r
+            if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:\r
+                self._SectionHeaderParser()\r
+                continue\r
+            elif Line.startswith('DEFINE '):\r
+                self._MacroParser()\r
+                continue\r
+\r
+            # section content\r
+            self._ValueList = ['','','']\r
+            self._SectionParser[self._SectionType](self)\r
+            EdkLogger.debug(EdkLogger.DEBUG_8, "Define: %s" % self._ValueList)\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
+            # Enabled=-1\r
+            # \r
+            for Arch, Platform in self._Scope:\r
+                self._Store(self._SectionType,\r
+                            self._ValueList[0],\r
+                            self._ValueList[1],\r
+                            self._ValueList[2],\r
+                            Arch,\r
+                            Platform,\r
+                            self._Owner,\r
+                            self._LineIndex+1,\r
+                            -1,\r
+                            self._LineIndex+1,\r
+                            -1,\r
+                            0\r
+                            )\r
+        self._Done()\r
+            \r
+    #def _DefineParser(self):\r
+    #    TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
+    #    self._ValueList[0] = TokenList[0]\r
+    #    if len(TokenList) == 2:\r
+    #        MoreValues = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT)\r
+    #        self._ValueList[1:1+len(MoreValues)] = MoreValues\r
+\r
+    def _BuildOptionParser(self):\r
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
+        TokenList2 = GetSplitValueList(TokenList[0], ':', 1)\r
+        if len(TokenList2) == 2:\r
+            self._ValueList[0] = TokenList2[0]\r
+            self._ValueList[1] = TokenList2[1]\r
+        else:\r
+            self._ValueList[1] = TokenList[0]\r
+        self._ValueList[2] = TokenList[1]\r
+\r
+    def _NmakeParser(self):\r
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
+        if len(TokenList) == 2:\r
+            self._ValueList[0] = TokenList[0]\r
+            TokenList = GetSplitValueList(TokenList[1], TAB_EQUAL_SPLIT, 1)\r
+        else:\r
+            TokenList = GetSplitValueList(TokenList[0], TAB_EQUAL_SPLIT, 1)\r
+        self._ValueList[1:1+len(TokenList)] = TokenList\r
+\r
+    def _PcdParser(self):\r
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
+        self._ValueList[0:2] = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
+        if len(TokenList) > 1:\r
+            self._ValueList[2] = TokenList[1]\r
+\r
+    def _DepexParser(self):\r
+        self._ValueList[0:1] = [self._CurrentLine]\r
+\r
+    _SectionParser = {\r
+        MODEL_UNKNOWN                   :   MetaFileParser._Skip,\r
+        MODEL_META_DATA_HEADER          :   MetaFileParser._DefineParser,\r
+        MODEL_META_DATA_BUILD_OPTION    :   _BuildOptionParser,\r
+        MODEL_EFI_INCLUDE               :   MetaFileParser._PathParser,\r
+        MODEL_EFI_LIBRARY_INSTANCE      :   MetaFileParser._PathParser,\r
+        MODEL_EFI_LIBRARY_CLASS         :   MetaFileParser._PathParser,\r
+        MODEL_META_DATA_PACKAGE         :   MetaFileParser._PathParser,\r
+        MODEL_META_DATA_NMAKE           :   _NmakeParser,\r
+        MODEL_PCD_FIXED_AT_BUILD        :   _PcdParser,\r
+        MODEL_PCD_PATCHABLE_IN_MODULE   :   _PcdParser,\r
+        MODEL_PCD_FEATURE_FLAG          :   _PcdParser,\r
+        MODEL_PCD_DYNAMIC_EX            :   _PcdParser,\r
+        MODEL_PCD_DYNAMIC               :   _PcdParser,\r
+        MODEL_EFI_SOURCE_FILE           :   MetaFileParser._PathParser,\r
+        MODEL_EFI_GUID                  :   MetaFileParser._CommonParser,\r
+        MODEL_EFI_PROTOCOL              :   MetaFileParser._CommonParser,\r
+        MODEL_EFI_PPI                   :   MetaFileParser._CommonParser,\r
+        MODEL_EFI_DEPEX                 :   _DepexParser,\r
+        MODEL_EFI_BINARY_FILE           :   MetaFileParser._PathParser,\r
+        MODEL_META_DATA_USER_EXTENSION  :   MetaFileParser._Skip,\r
+    }    \r
+\r
+class DscParser(MetaFileParser):\r
+    _DataType = {\r
+        TAB_SKUIDS.upper()                          :   MODEL_EFI_SKU_ID,\r
+        TAB_LIBRARIES.upper()                       :   MODEL_EFI_LIBRARY_INSTANCE,\r
+        TAB_LIBRARY_CLASSES.upper()                 :   MODEL_EFI_LIBRARY_CLASS,\r
+        TAB_BUILD_OPTIONS.upper()                   :   MODEL_META_DATA_BUILD_OPTION,\r
+        TAB_PCDS_FIXED_AT_BUILD_NULL.upper()        :   MODEL_PCD_FIXED_AT_BUILD,\r
+        TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper()   :   MODEL_PCD_PATCHABLE_IN_MODULE,\r
+        TAB_PCDS_FEATURE_FLAG_NULL.upper()          :   MODEL_PCD_FEATURE_FLAG,\r
+        TAB_PCDS_DYNAMIC_DEFAULT_NULL.upper()       :   MODEL_PCD_DYNAMIC_DEFAULT,\r
+        TAB_PCDS_DYNAMIC_HII_NULL.upper()           :   MODEL_PCD_DYNAMIC_HII,\r
+        TAB_PCDS_DYNAMIC_VPD_NULL.upper()           :   MODEL_PCD_DYNAMIC_VPD,\r
+        TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL.upper()    :   MODEL_PCD_DYNAMIC_EX_DEFAULT,\r
+        TAB_PCDS_DYNAMIC_EX_HII_NULL.upper()        :   MODEL_PCD_DYNAMIC_EX_HII,\r
+        TAB_PCDS_DYNAMIC_EX_VPD_NULL.upper()        :   MODEL_PCD_DYNAMIC_EX_VPD,\r
+        TAB_COMPONENTS.upper()                      :   MODEL_META_DATA_COMPONENT,\r
+        TAB_DSC_DEFINES.upper()                     :   MODEL_META_DATA_HEADER,\r
+        TAB_INCLUDE.upper()                         :   MODEL_META_DATA_INCLUDE,\r
+        TAB_IF.upper()                              :   MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,\r
+        TAB_IF_DEF.upper()                          :   MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,\r
+        TAB_IF_N_DEF.upper()                        :   MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF,\r
+        TAB_ELSE_IF.upper()                         :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF,\r
+        TAB_ELSE.upper()                            :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE,\r
+        TAB_END_IF.upper()                          :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF,\r
+    }\r
+\r
+    _IncludeAllowedSection = [\r
+        TAB_LIBRARIES.upper(), \r
+        TAB_LIBRARY_CLASSES.upper(), \r
+        TAB_SKUIDS.upper(),\r
+        TAB_COMPONENTS.upper(),\r
+        TAB_BUILD_OPTIONS.upper(),\r
+        TAB_PCDS_FIXED_AT_BUILD_NULL.upper(),\r
+        TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper(),\r
+        TAB_PCDS_FEATURE_FLAG_NULL.upper(),\r
+        TAB_PCDS_DYNAMIC_DEFAULT_NULL.upper(),\r
+        TAB_PCDS_DYNAMIC_HII_NULL.upper(),\r
+        TAB_PCDS_DYNAMIC_VPD_NULL.upper(),\r
+        TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL.upper(),\r
+        TAB_PCDS_DYNAMIC_EX_HII_NULL.upper(),\r
+        TAB_PCDS_DYNAMIC_EX_VPD_NULL.upper(),\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
+\r
+    def Start(self):\r
+        try:\r
+            if self._Content == None:\r
+                self._Content = open(self._FilePath, 'r').readlines()\r
+        except:\r
+            EdkLogger.error("DscParser", FILE_READ_FAILURE, ExtraData=self._FilePath)\r
+\r
+        for Index in range(0, len(self._Content)):\r
+            Line = CleanString(self._Content[Index])\r
+            # skip empty line\r
+            if Line == '':\r
+                self._LineIndex += 1\r
+                continue\r
+            self._CurrentLine = Line\r
+            self._LineIndex = Index\r
+\r
+            # section header\r
+            if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:\r
+                self._SectionHeaderParser()\r
+                continue\r
+            elif Line[0] == '}':\r
+                self._InSubsection = False\r
+                self._Owner = -1\r
+                continue\r
+            elif Line[0] == TAB_OPTION_START and Line[-1] == TAB_OPTION_END:\r
+                self._SubsectionHeaderParser()\r
+                continue\r
+            # directive line\r
+            elif Line[0] == '!':\r
+                self._DirectiveParser()\r
+                continue\r
+            elif Line.startswith('DEFINE '):\r
+                self._MacroParser()\r
+                continue\r
+\r
+            # section content\r
+            if self._InSubsection:\r
+                SectionType = self._SubsectionType\r
+                SectionName = self._SubsectionName\r
+                if self._Owner == -1:\r
+                    self._Owner = self._LastItem\r
+            else:\r
+                SectionType = self._SectionType\r
+                SectionName = self._SectionName\r
+            self._ValueList = ['','','']\r
+            self._SectionParser[SectionType](self)\r
+            EdkLogger.debug(EdkLogger.DEBUG_8, "Define: %s" % self._ValueList)\r
+            if self._ValueList == None:\r
+                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
+            # Enabled=-1\r
+            # \r
+            for Arch, ModuleType in self._Scope:\r
+                self._LastItem = self._Store(\r
+                    SectionType,\r
+                    self._ValueList[0],\r
+                    self._ValueList[1],\r
+                    self._ValueList[2],\r
+                    Arch,\r
+                    ModuleType,\r
+                    self._Owner,\r
+                    self._From,\r
+                    self._LineIndex+1,\r
+                    -1,\r
+                    self._LineIndex+1,\r
+                    -1,\r
+                    0\r
+                    )\r
+        self._Done()\r
+\r
+    def _DefineParser(self):\r
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
+        if len(TokenList) > 1:\r
+            if TokenList[0] in ['FLASH_DEFINITION', 'OUTPUT_DIRECTORY']:\r
+                TokenList[1] = NormPath(TokenList[1], self._Macros)\r
+        self._ValueList[0:len(TokenList)] = TokenList\r
+    \r
+            \r
+    def _SubsectionHeaderParser(self):\r
+        self._SubsectionName = self._CurrentLine[1:-1].upper()\r
+        if self._SubsectionName in self._DataType:\r
+            self._SubsectionType = self._DataType[self._SubsectionName]\r
+        else:\r
+            self._SubsectionType = MODEL_UNKNOWN\r
+\r
+    def _DirectiveParser(self):\r
+        self._ValueList = ['','','']\r
+        TokenList = GetSplitValueList(self._CurrentLine, ' ', 1)\r
+        self._ValueList[0:len(TokenList)] = TokenList\r
+        print self._ValueList\r
+        DirectiveName = self._ValueList[0].upper()\r
+        self._LastItem = self._Store(\r
+            self._DataType[DirectiveName],\r
+            self._ValueList[0],\r
+            self._ValueList[1],\r
+            self._ValueList[2],\r
+            'COMMON',\r
+            'COMMON',\r
+            self._Owner,\r
+            self._LineIndex + 1,\r
+            -1,\r
+            self._LineIndex + 1,\r
+            -1,\r
+            0\r
+            )\r
+        if DirectiveName == "!INCLUDE":\r
+            if not self._SectionName in self._IncludeAllowedSection:\r
+                EdkLogger.error("DscParser", FORMAT_INVALID, File=self._FilePath, Line=self._LineIndex+1,\r
+                                ExtraData="'!include' is not allowed in section %s" % self._SectionName)\r
+            # the included file must be relative to the parsing file\r
+            IncludedFile = os.path.join(self._FileDir, self._ValueList[1])\r
+            Parser = DscParser(IncludedFile, self._FileType, self._Table, self._Macros, From=self._LastItem)\r
+            Parser._SectionName = self._SectionName\r
+            Parser._SectionType = self._SectionType\r
+            Parser._Scope = self._Scope\r
+            try:\r
+                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
+            self._SectionName = Parser._SectionName\r
+            self._SectionType = Parser._SectionType\r
+            self._Scope       = Parser._Scope\r
+\r
+    def _BuildOptionParser(self):\r
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
+        TokenList2 = GetSplitValueList(TokenList[0], ':', 1)\r
+        if len(TokenList2) == 2:\r
+            self._ValueList[0] = TokenList2[0]\r
+            self._ValueList[1] = TokenList2[1]\r
+        else:\r
+            self._ValueList[1] = TokenList[0]\r
+        self._ValueList[2] = TokenList[1]\r
+\r
+    def _PcdParser(self):\r
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
+        self._ValueList[0:2] = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
+        self._ValueList[2] = TokenList[1]\r
+\r
+    def _ComponentParser(self):        \r
+        if self._CurrentLine[-1] == '{':\r
+            self._InSubsection = True\r
+            self._ValueList[0] = self._CurrentLine[0:-1].strip()\r
+        else:\r
+            self._ValueList[0] = self._CurrentLine\r
+        if len(self._Macros) > 0:\r
+            self._ValueList[0] = NormPath(self._ValueList[0], self._Macros)\r
+\r
+    _SectionParser = {\r
+        MODEL_META_DATA_HEADER          :   MetaFileParser._DefineParser,\r
+        MODEL_EFI_SKU_ID                :   MetaFileParser._CommonParser,\r
+        MODEL_EFI_LIBRARY_INSTANCE      :   MetaFileParser._PathParser,\r
+        MODEL_EFI_LIBRARY_CLASS         :   MetaFileParser._PathParser,\r
+        MODEL_PCD_FIXED_AT_BUILD        :   _PcdParser,\r
+        MODEL_PCD_PATCHABLE_IN_MODULE   :   _PcdParser,\r
+        MODEL_PCD_FEATURE_FLAG          :   _PcdParser,\r
+        MODEL_PCD_DYNAMIC_DEFAULT       :   _PcdParser,\r
+        MODEL_PCD_DYNAMIC_HII           :   _PcdParser,\r
+        MODEL_PCD_DYNAMIC_VPD           :   _PcdParser,\r
+        MODEL_PCD_DYNAMIC_EX_DEFAULT    :   _PcdParser,\r
+        MODEL_PCD_DYNAMIC_EX_HII        :   _PcdParser,\r
+        MODEL_PCD_DYNAMIC_EX_VPD        :   _PcdParser,\r
+        MODEL_META_DATA_COMPONENT       :   _ComponentParser,\r
+        MODEL_META_DATA_BUILD_OPTION    :   _BuildOptionParser,\r
+        MODEL_UNKNOWN                   :   MetaFileParser._Skip,\r
+        MODEL_META_DATA_USER_EXTENSION  :   MetaFileParser._Skip,\r
+    }\r
+\r
+class DecParser(MetaFileParser):\r
+    _DataType = {\r
+        TAB_DEC_DEFINES.upper()                     :   MODEL_META_DATA_HEADER,\r
+        TAB_INCLUDES.upper()                        :   MODEL_EFI_INCLUDE,\r
+        TAB_LIBRARY_CLASSES.upper()                 :   MODEL_EFI_LIBRARY_CLASS,\r
+        TAB_GUIDS.upper()                           :   MODEL_EFI_GUID,\r
+        TAB_PPIS.upper()                            :   MODEL_EFI_PPI,\r
+        TAB_PROTOCOLS.upper()                       :   MODEL_EFI_PROTOCOL,\r
+        TAB_PCDS_FIXED_AT_BUILD_NULL.upper()        :   MODEL_PCD_FIXED_AT_BUILD,\r
+        TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper()   :   MODEL_PCD_PATCHABLE_IN_MODULE,\r
+        TAB_PCDS_FEATURE_FLAG_NULL.upper()          :   MODEL_PCD_FEATURE_FLAG,\r
+        TAB_PCDS_DYNAMIC_NULL.upper()               :   MODEL_PCD_DYNAMIC,\r
+        TAB_PCDS_DYNAMIC_EX_NULL.upper()            :   MODEL_PCD_DYNAMIC_EX,\r
+    }\r
+\r
+    def __init__(self, FilePath, FileId, FileType, Table, Macro={}):\r
+        MetaFileParser.__init__(self, FilePath, FileType, Table, Macro, -1)\r
+\r
+    def Start(self):\r
+        try:\r
+            if self._Content == None:\r
+                self._Content = open(self._FilePath, 'r').readlines()\r
+        except:\r
+            EdkLogger.error("DecParser", FILE_READ_FAILURE, ExtraData=self._FilePath)\r
+\r
+        for Index in range(0, len(self._Content)):\r
+            Line = CleanString(self._Content[Index])\r
+            # skip empty line\r
+            if Line == '':\r
+                continue\r
+            self._CurrentLine = Line\r
+            self._LineIndex = Index\r
+\r
+            # section header\r
+            if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:\r
+                self._SectionHeaderParser()\r
+                continue\r
+            elif Line.startswith('DEFINE '):\r
+                self._MacroParser()\r
+                continue\r
+\r
+            # section content\r
+            self._ValueList = ['','','']\r
+            self._SectionParser[self._SectionType](self)\r
+            EdkLogger.debug(EdkLogger.DEBUG_8, "Define: %s" % self._ValueList)\r
+            if self._ValueList == None:\r
+                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
+            # Enabled=-1\r
+            # \r
+            for Arch, ModuleType in self._Scope:\r
+                self._LastItem = self._Store(\r
+                    self._SectionType,\r
+                    self._ValueList[0],\r
+                    self._ValueList[1],\r
+                    self._ValueList[2],\r
+                    Arch,\r
+                    ModuleType,\r
+                    self._Owner,\r
+                    self._LineIndex+1,\r
+                    -1,\r
+                    self._LineIndex+1,\r
+                    -1,\r
+                    0\r
+                    )\r
+        self._Done()\r
+            \r
+    #def _DefineParser(self):\r
+    #    TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
+    #    self._ValueList[0] = TokenList[0]\r
+    #    if len(TokenList) == 2:\r
+    #        MoreValues = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT)\r
+    #        self._ValueList[1:1+len(MoreValues)] = MoreValues\r
+\r
+    def _GuidParser(self):\r
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
+        self._ValueList[0] = TokenList[0]\r
+        self._ValueList[1] = TokenList[1]\r
+\r
+    def _PcdParser(self):\r
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
+        self._ValueList[0:2] = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
+        self._ValueList[2] = TokenList[1]\r
+\r
+    _SectionParser = {\r
+        MODEL_META_DATA_HEADER          :   MetaFileParser._DefineParser,\r
+        MODEL_EFI_INCLUDE               :   MetaFileParser._PathParser,\r
+        MODEL_EFI_LIBRARY_CLASS         :   MetaFileParser._PathParser,\r
+        MODEL_EFI_GUID                  :   _GuidParser,\r
+        MODEL_EFI_PPI                   :   _GuidParser,\r
+        MODEL_EFI_PROTOCOL              :   _GuidParser,\r
+        MODEL_PCD_FIXED_AT_BUILD        :   _PcdParser,\r
+        MODEL_PCD_PATCHABLE_IN_MODULE   :   _PcdParser,\r
+        MODEL_PCD_FEATURE_FLAG          :   _PcdParser,\r
+        MODEL_PCD_DYNAMIC               :   _PcdParser,\r
+        MODEL_PCD_DYNAMIC_EX            :   _PcdParser,\r
+        MODEL_UNKNOWN                   :   MetaFileParser._Skip,\r
+        MODEL_META_DATA_USER_EXTENSION  :   MetaFileParser._Skip,\r
+    }\r
+\r
+class Timer(object):\r
+    def __init__(self):\r
+        self.StartTime = 0\r
+        self.EndTime = 0\r
+\r
+    def __str__(self):\r
+        if self.EndTime != 0:\r
+            return str(self.EndTime - self.StartTime)\r
+        return time.clock() - self.StartTime\r
+\r
+    def Start(self):\r
+        self.StartTime = time.clock()\r
+\r
+    def Stop(self):\r
+        self.EndTime = time.clock()\r
+\r
+##\r
+#\r
+# This acts like the main() function for the script, unless it is 'import'ed into another\r
+# script.\r
+#\r
+if __name__ == '__main__':\r
+    from WorkspaceDatabase import WorkspaceDatabase as DB\r
+\r
+    try:\r
+        import psyco\r
+        #psyco.profile()\r
+        #psyco.log()\r
+    except:\r
+        pass\r
+    timer = Timer()\r
+    timer.Start()\r
+\r
+    EdkLogger.Initialize()\r
+    if os.path.exists("test.db"):\r
+        os.remove("test.db")\r
+    Wks = DB("test.db")\r
+    Wks.InitDatabase()\r
+\r
+    os.chdir(r"H:\dev\AllPackagesDev")\r
+\r
+    #Gf = r"H:\dev\AllPackagesDev\LakeportX64Pkg\LakeportX64Pkg.dec"\r
+    ##Gf = r"H:\dev\AllPackagesDev\Nt32Pkg\Nt32Pkg.dec"\r
+    #Gb32 = Wks.BuildObject[Gf, MODEL_FILE_DEC, 'IA32']\r
+    #print repr(Gb32)\r
+\r
+    Pf = r"H:\dev\AllPackagesDev\LakeportX64Pkg\LakeportX64Pkg.dsc"\r
+    #Pf = r"H:\dev\AllPackagesDev\Nt32Pkg\Nt32Pkg.dsc"\r
+    Pb32 = Wks.BuildObject[Pf, MODEL_FILE_DSC, 'IA32']\r
+\r
+    print repr(Pb32)\r
+    for Mb in Pb32.Modules:\r
+        print repr(Mb)\r
+\r
+    Pb64 = Wks.BuildObject[Pf, MODEL_FILE_DSC, 'X64']\r
+\r
+    print repr(Pb64)\r
+    for Mb in Pb64.Modules:\r
+        print repr(Mb)\r
+\r
+    #LibList = []\r
+    #for Key in Pb32.LibraryClasses:\r
+    #    Inf = Pb32.LibraryClasses[Key]\r
+    #    if Inf  in LibList:\r
+    #        continue \r
+    #    Wks[Inf] = MODEL_FILE_INF\r
+    #    Mb = Module(Inf, Wks[Inf], 'IA32')\r
+    #    print repr(Mb)\r
+    #    LibList.append(Inf)\r
+    #\r
+    #Pb64 = Platform(Pf, Dsc, 'X64')\r
+    #print repr(Pb64)\r
+    #for Inf in Pb64.Modules:\r
+    #    Wks[Inf] = MODEL_FILE_INF\r
+    #    Mb = Module(Inf, Wks[Inf], 'X64')\r
+    #    print repr(Mb)\r
+    #LibList = []\r
+    #for Key in Pb64.LibraryClasses:\r
+    #    Inf = Pb64.LibraryClasses[Key]\r
+    #    if Inf in LibList:\r
+    #        continue \r
+    #    Wks[Inf] = MODEL_FILE_INF\r
+    #    Mb = Module(Inf, Wks[Inf], 'X64')\r
+    #    print repr(Mb)\r
+    #    LibList.append(Inf)\r
+\r
+    Wks.Close()\r
+    timer.Stop()\r
+    print "DONE [%s]" % str(timer)\r
diff --git a/Source/Python/Workspace/MetaFileTable.py b/Source/Python/Workspace/MetaFileTable.py
new file mode 100644 (file)
index 0000000..2ef280d
--- /dev/null
@@ -0,0 +1,272 @@
+## @file\r
+# This file is used to create/update/query/erase a common table\r
+#\r
+# Copyright (c) 2008, Intel Corporation\r
+# All rights reserved. This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+##\r
+# Import Modules\r
+#\r
+import Common.EdkLogger as EdkLogger\r
+from MetaDataTable import Table\r
+from Common.String import ConvertToSqlString\r
+\r
+class ModuleTable(Table):\r
+    _ID_STEP_ = 0.00000001\r
+    _ID_MAX_  = 0.99999999\r
+    _COLUMN_ = '''\r
+        ID REAL PRIMARY KEY,\r
+        Model INTEGER NOT NULL,\r
+        Value1 TEXT NOT NULL,\r
+        Value2 TEXT,\r
+        Value3 TEXT,\r
+        Scope1 TEXT,\r
+        Scope2 TEXT,\r
+        BelongsToItem REAL NOT NULL,\r
+        StartLine INTEGER NOT NULL,\r
+        StartColumn INTEGER NOT NULL,\r
+        EndLine INTEGER NOT NULL,\r
+        EndColumn INTEGER NOT NULL,\r
+        Enabled INTEGER DEFAULT 0\r
+        '''\r
+    _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1"\r
+\r
+    def __init__(self, Cursor, Name='Inf', IdBase=0, Temporary=False):\r
+        Table.__init__(self, Cursor, Name, IdBase, Temporary)\r
+\r
+    #\r
+    # Insert a record into table Inf\r
+    #\r
+    # @param Model:          Model of a Inf item\r
+    # @param Value1:         Value1 of a Inf item\r
+    # @param Value2:         Value2 of a Inf item\r
+    # @param Value3:         Value3 of a Inf item\r
+    # @param Value4:         Value4 of a Inf item\r
+    # @param Value5:         Value5 of a Inf item\r
+    # @param Arch:           Arch of a Inf item\r
+    # @param BelongsToItem:  The item belongs to which another item\r
+    # @param BelongsToFile:  The item belongs to which dsc file\r
+    # @param StartLine:      StartLine of a Inf item\r
+    # @param StartColumn:    StartColumn of a Inf item\r
+    # @param EndLine:        EndLine of a Inf item\r
+    # @param EndColumn:      EndColumn of a Inf item\r
+    # @param Enabled:        If this item enabled\r
+    #\r
+    def Insert(self, Model, Value1, Value2, Value3, Scope1='COMMON', Scope2='COMMON',\r
+               BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):\r
+        (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2))\r
+        return Table.Insert(\r
+                        self, \r
+                        Model, \r
+                        Value1, \r
+                        Value2, \r
+                        Value3, \r
+                        Scope1, \r
+                        Scope2,\r
+                        BelongsToItem, \r
+                        StartLine, \r
+                        StartColumn, \r
+                        EndLine, \r
+                        EndColumn, \r
+                        Enabled\r
+                        )\r
+\r
+    ## Query table\r
+    #\r
+    # @param Model:  The Model of Record \r
+    #\r
+    # @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
+        if Value1 == None:\r
+            ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"\r
+        else:\r
+            ValueString = "Value2,Value3,Scope1,Scope2,ID,StartLine"\r
+            ConditionString = "Value1='%s'" % Value1\r
+\r
+        if Arch != None and Arch != 'COMMON':\r
+            ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch\r
+        if Platform != None and Platform != 'COMMON':\r
+            ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT')" % Platform\r
+\r
+        SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)\r
+        return self.Exec(SqlCommand)\r
+\r
+class PackageTable(Table):\r
+    _ID_STEP_ = 0.00000001\r
+    _ID_MAX_ = 1\r
+    _COLUMN_ = '''\r
+        ID REAL PRIMARY KEY,\r
+        Model INTEGER NOT NULL,\r
+        Value1 TEXT NOT NULL,\r
+        Value2 TEXT,\r
+        Value3 TEXT,\r
+        Scope1 TEXT,\r
+        Scope2 TEXT,\r
+        BelongsToItem REAL NOT NULL,\r
+        StartLine INTEGER NOT NULL,\r
+        StartColumn INTEGER NOT NULL,\r
+        EndLine INTEGER NOT NULL,\r
+        EndColumn INTEGER NOT NULL,\r
+        Enabled INTEGER DEFAULT 0\r
+        '''\r
+    _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1"\r
+    def __init__(self, Cursor, Name='Dec', IdBase=0, Temporary=False):\r
+        Table.__init__(self, Cursor, Name, IdBase, Temporary)\r
+\r
+    ## Insert table\r
+    #\r
+    # Insert a record into table Dec\r
+    #\r
+    # @param Model:          Model of a Dec item\r
+    # @param Value1:         Value1 of a Dec item\r
+    # @param Value2:         Value2 of a Dec item\r
+    # @param Value3:         Value3 of a Dec item\r
+    # @param Arch:           Arch of a Dec item\r
+    # @param BelongsToItem:  The item belongs to which another item\r
+    # @param BelongsToFile:  The item belongs to which dsc file\r
+    # @param StartLine:      StartLine of a Dec item\r
+    # @param StartColumn:    StartColumn of a Dec item\r
+    # @param EndLine:        EndLine of a Dec item\r
+    # @param EndColumn:      EndColumn of a Dec item\r
+    # @param Enabled:        If this item enabled\r
+    #\r
+    def Insert(self, Model, Value1, Value2, Value3, Scope1='COMMON', Scope2='COMMON',\r
+               BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):\r
+        (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2))\r
+        return Table.Insert(\r
+                        self, \r
+                        Model, \r
+                        Value1, \r
+                        Value2, \r
+                        Value3, \r
+                        Scope1, \r
+                        Scope2,\r
+                        BelongsToItem, \r
+                        StartLine, \r
+                        StartColumn, \r
+                        EndLine, \r
+                        EndColumn, \r
+                        Enabled\r
+                        )\r
+\r
+    ## Query table\r
+    #\r
+    # @param Model:  The Model of Record \r
+    #\r
+    # @retval:       A recordSet of all found records \r
+    #\r
+    def Query(self, Model, Value1=None, Arch=None):\r
+        ConditionString = "Model=%s" % Model\r
+        if Value1 == None:\r
+            ValueString = "Value1,Value2,Value3,Scope1,ID,StartLine"\r
+        else:\r
+            ValueString = "Value2,Value3,Scope1,ID,StartLine"\r
+            ConditionString = "Value1='%s'" % Value1\r
+\r
+        if Arch != None and Arch != 'COMMON':\r
+            ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch\r
+\r
+        SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)\r
+        return self.Exec(SqlCommand)\r
+\r
+class PlatformTable(Table):\r
+    _ID_STEP_ = 0.00000001\r
+    _ID_MAX_ = 1\r
+    _COLUMN_ = '''\r
+        ID REAL PRIMARY KEY,\r
+        Model INTEGER NOT NULL,\r
+        Value1 TEXT NOT NULL,\r
+        Value2 TEXT,\r
+        Value3 TEXT,\r
+        Scope1 TEXT,\r
+        Scope2 TEXT,\r
+        BelongsToItem REAL NOT NULL,\r
+        FromItem REAL NOT NULL,\r
+        StartLine INTEGER NOT NULL,\r
+        StartColumn INTEGER NOT NULL,\r
+        EndLine INTEGER NOT NULL,\r
+        EndColumn INTEGER NOT NULL,\r
+        Enabled INTEGER DEFAULT 0\r
+        '''\r
+    _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1, -1"\r
+    def __init__(self, Cursor, Name='Dsc', IdBase=0, Temporary=False):\r
+        Table.__init__(self, Cursor, Name, IdBase, Temporary)\r
+\r
+    ## Insert table\r
+    #\r
+    # Insert a record into table Dsc\r
+    #\r
+    # @param Model:          Model of a Dsc item\r
+    # @param Value1:         Value1 of a Dsc item\r
+    # @param Value2:         Value2 of a Dsc item\r
+    # @param Value3:         Value3 of a Dsc item\r
+    # @param Arch:           Arch of a Dsc item\r
+    # @param BelongsToItem:  The item belongs to which another item\r
+    # @param BelongsToFile:  The item belongs to which dsc file\r
+    # @param StartLine:      StartLine of a Dsc item\r
+    # @param StartColumn:    StartColumn of a Dsc item\r
+    # @param EndLine:        EndLine of a Dsc item\r
+    # @param EndColumn:      EndColumn of a Dsc item\r
+    # @param Enabled:        If this item enabled\r
+    #\r
+    def Insert(self, Model, Value1, Value2, Value3, Scope1='COMMON', Scope2='COMMON', BelongsToItem=-1, \r
+               FromItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=1):\r
+        (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2))\r
+        return Table.Insert(\r
+                        self, \r
+                        Model, \r
+                        Value1, \r
+                        Value2, \r
+                        Value3, \r
+                        Scope1, \r
+                        Scope2,\r
+                        BelongsToItem, \r
+                        FromItem,\r
+                        StartLine, \r
+                        StartColumn, \r
+                        EndLine, \r
+                        EndColumn, \r
+                        Enabled\r
+                        )\r
+\r
+    ## Query table\r
+    #\r
+    # @param Model:  The Model of Record \r
+    #\r
+    # @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
+        if Value1 == None:\r
+            ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"\r
+        else:\r
+            ValueString = "Value2,Value3,Scope1,Scope2,ID,StartLine"\r
+            ConditionString = "Value1='%s'" % Value1\r
+\r
+        if Scope1 != None and Scope1 != 'COMMON':\r
+            ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Scope1\r
+        if Scope2 != None and Scope2 != 'COMMON':\r
+            ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT')" % Scope2\r
+\r
+        if BelongsToItem != None:\r
+            ConditionString += " AND BelongsToItem=%s" % BelongsToItem\r
+        else:\r
+            ConditionString += " AND BelongsToItem<0"\r
+\r
+        if FromItem != None:\r
+            ConditionString += " AND FromItem=%s" % FromItem\r
+\r
+        SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)\r
+        #print SqlCommand\r
+        return self.Exec(SqlCommand)\r
+\r
+\r
diff --git a/Source/Python/Workspace/WorkspaceBuild.py b/Source/Python/Workspace/WorkspaceBuild.py
new file mode 100644 (file)
index 0000000..ab8c2f1
--- /dev/null
@@ -0,0 +1,145 @@
+## @file\r
+# This file is used to create a database used by ECC tool\r
+#\r
+# Copyright (c) 2007 ~ 2008, Intel Corporation\r
+# All rights reserved. This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+##\r
+# Import Modules\r
+#\r
+##\r
+# Import Modules\r
+#\r
+import os\r
+\r
+from CommonDataClass.DataClass import *\r
+from WorkspaceDatabase import *\r
+from Common import EdkLogger as EdkLogger\r
+from Common import DataType\r
+from Common.String import *\r
+from Common.BuildToolError import *\r
+from Common.Misc import sdict\r
+from Common import GlobalData\r
+\r
+## ItemBuild\r
+#\r
+# This Class defines Module/Platform/Package databases for build system\r
+#\r
+# @param object:          Inherited from object class\r
+# @param Arch:            Build arch\r
+# @param Platform:        Build Platform\r
+# @param Package:         Build Package\r
+# @param Module:          Build Module\r
+#\r
+# @var Arch:              To store value for Build Arch\r
+# @var PlatformDatabase:  To store value for PlatformDatabase, it is a set structure as\r
+#                         { [DscFileName] : PlatformBuildClassObject, ...}\r
+# @var PackageDatabase:   To store value for PackageDatabase, it is a set structure as\r
+#                         { [DecFileName] : PacakgeBuildClassObject, ...}\r
+# @var ModuleDatabase:    To store value for ModuleDatabase, it is a list structure as\r
+#                         { [InfFileName] : ModuleBuildClassObject, ...}\r
+#\r
+class ItemBuild(object):\r
+    def __init__(self, Arch, Platform = None, Package = None, Module = None):\r
+        self.Arch                    = Arch\r
+        self.PlatformDatabase        = {}\r
+        self.PackageDatabase         = {}\r
+        self.ModuleDatabase          = {}\r
+\r
+class WorkspaceBuild(object):\r
+    def __init__(self, ActivePlatform, WorkspaceDir):\r
+        self.WorkspaceDir            = NormPath(WorkspaceDir)\r
+        self.SupArchList             = []\r
+        self.BuildTarget             = []\r
+        self.SkuId                   = ''\r
+        self.Fdf                     = ''\r
+        self.FdTargetList            = []\r
+        self.FvTargetList            = []\r
+        self.TargetTxt               = None\r
+        self.ToolDef                 = None\r
+\r
+        self.InfDatabase             = {}\r
+        self.DecDatabase             = {}\r
+        self.DscDatabase             = {}\r
+        \r
+        self.UnFoundPcdInDsc         = {}\r
+\r
+        os.chdir(self.WorkspaceDir)\r
+        #\r
+        # Init build for all arches\r
+        #\r
+        self.Build                   = {}\r
+        for Arch in DataType.ARCH_LIST:\r
+            self.Build[Arch] = ItemBuild(Arch)\r
+\r
+        #\r
+        # Init build database\r
+        #\r
+        self.Db = WorkspaceDatabase(DATABASE_PATH, GlobalData.gGlobalDefines)\r
+        self.Db.InitDatabase()\r
+        \r
+        #\r
+        # Get active platform\r
+        #\r
+        self.DscFileName = NormPath(ActivePlatform)\r
+        File = os.path.join(self.WorkspaceDir, self.DscFileName)\r
+        if not (os.path.exists(File) and os.path.isfile(File)):\r
+            EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData = File)\r
+\r
+        #\r
+        # Parse platform to get module\r
+        #\r
+        Platform = self.Db.BuildObject[self.DscFileName, MODEL_FILE_DSC, 'COMMON']\r
+        self.SupArchList = Platform.SupArchList\r
+        self.BuildTarget = Platform.BuildTargets\r
+        self.SkuId = Platform.SkuName\r
+        self.Fdf = Platform.FlashDefinition\r
+        for Arch in self.SupArchList:\r
+            self.Build[Arch].PlatformDatabase[self.DscFileName] = self.Db.BuildObject[self.DscFileName, MODEL_FILE_DSC, Arch]\r
+    \r
+    ## GenBuildDatabase\r
+    #\r
+    # Generate build database for all arches\r
+    #\r
+    # @param PcdsSet: Pcd list for override from Fdf parse result\r
+    # @param InfList: Inf list for override from Fdf parse result\r
+    #\r
+    def GenBuildDatabase(self, PcdsSet = {}, InfList = []):\r
+        for Arch in self.SupArchList:\r
+            Platform = self.Build[Arch].PlatformDatabase[self.DscFileName]\r
+\r
+            for Name,Guid in PcdsSet:\r
+                Platform.AddPcd(Name, Guid, PcdsSet[Name, Guid])\r
+\r
+            for Inf in InfList:\r
+                Platform.AddModule(Inf)\r
+\r
+            #\r
+            # Get all inf files\r
+            #\r
+            for Module in Platform.Modules:\r
+                ModulePath = str(Module)\r
+                if ModulePath in self.Build[Arch].ModuleDatabase:\r
+                    continue \r
+                self.Build[Arch].ModuleDatabase[ModulePath] = Module\r
+\r
+                for Key in Module.LibraryClasses:\r
+                    ModulePath = Module.LibraryClasses[Key]\r
+                    self.Build[Arch].ModuleDatabase[ModulePath] = self.Db.BuildObject[ModulePath, MODEL_FILE_INF, Arch]\r
+\r
+                for Package in Module.Packages:\r
+                    PackagePath = str(Package)\r
+                    if PackagePath in self.Build[Arch].PackageDatabase:\r
+                        continue\r
+                    self.Build[Arch].PackageDatabase[PackagePath] = Package\r
+\r
+    def WorkspaceFile(self, Filename):\r
+        return os.path.join(self.WorkspaceDir, Filename)\r
+\r
diff --git a/Source/Python/Workspace/WorkspaceDatabase.py b/Source/Python/Workspace/WorkspaceDatabase.py
new file mode 100644 (file)
index 0000000..58e221a
--- /dev/null
@@ -0,0 +1,1809 @@
+## @file\r
+# This file is used to create a database used by ECC tool\r
+#\r
+# Copyright (c) 2007 ~ 2008, Intel Corporation\r
+# All rights reserved. This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+##\r
+# Import Modules\r
+#\r
+import sqlite3\r
+import os\r
+\r
+import Common.EdkLogger as EdkLogger\r
+from CommonDataClass.DataClass import *\r
+from CommonDataClass.ModuleClass import *\r
+from Common.String import *\r
+from Common.DataType import *\r
+from Common.Misc import tdict\r
+from Common.Misc import sdict\r
+\r
+from MetaDataTable import *\r
+from MetaFileTable import *\r
+from MetaFileParser import *\r
+from BuildClassObject import *\r
+\r
+def ValidFile(File, Dir='.'):\r
+    Wd = os.getcwd()\r
+    os.chdir(Dir)\r
+    if not os.path.exists(File):\r
+        os.chdir(Wd)\r
+        return False\r
+    os.chdir(Wd)\r
+    return True\r
+\r
+class DscBuildData(PlatformBuildClassObject):\r
+    #_PROPERTY_ = {\r
+    #    TAB_DSC_DEFINES_PLATFORM_NAME           : '_PlatformName'\r
+    #    TAB_DSC_DEFINES_PLATFORM_GUID           : '_Guid'\r
+    #    TAB_DSC_DEFINES_PLATFORM_VERSION        : '_Version'\r
+    #    TAB_DSC_DEFINES_DSC_SPECIFICATION       : '_DscSpecification'\r
+    #    TAB_DSC_DEFINES_OUTPUT_DIRECTORY        : '_OutputDirectory'\r
+    #    TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : '_SupArchList'\r
+    #    TAB_DSC_DEFINES_BUILD_TARGETS           : '_BuildTargets'\r
+    #    TAB_DSC_DEFINES_SKUID_IDENTIFIER        : '_SkuId'\r
+    #    TAB_DSC_DEFINES_FLASH_DEFINITION        : '_FlashDefinition'\r
+    #    TAB_DSC_DEFINES_BUILD_NUMBER            : '_BuildNumber'\r
+    #    TAB_DSC_DEFINES_MAKEFILE_NAME           : '_MakefileName'\r
+    #    TAB_DSC_DEFINES_BS_BASE_ADDRESS         : '_BsBaseAddress'\r
+    #    TAB_DSC_DEFINES_RT_BASE_ADDRESS         : '_RtBaseAddress'\r
+    #}\r
+    _PCD_TYPE_STRING_ = {\r
+        MODEL_PCD_FIXED_AT_BUILD        :   "FixedAtBuild",\r
+        MODEL_PCD_PATCHABLE_IN_MODULE   :   "PatchableInModule",\r
+        MODEL_PCD_FEATURE_FLAG          :   "FeatureFlag",\r
+        MODEL_PCD_DYNAMIC               :   "Dynamic",\r
+        MODEL_PCD_DYNAMIC_DEFAULT       :   "Dynamic",\r
+        MODEL_PCD_DYNAMIC_HII           :   "DynamicHii",\r
+        MODEL_PCD_DYNAMIC_VPD           :   "DynamicVpd",\r
+        MODEL_PCD_DYNAMIC_EX            :   "DynamicEx",\r
+        MODEL_PCD_DYNAMIC_EX_DEFAULT    :   "DynamicEx",\r
+        MODEL_PCD_DYNAMIC_EX_HII        :   "DynamicExHii",\r
+        MODEL_PCD_DYNAMIC_EX_VPD        :   "DynamicExVpd",\r
+    }\r
+\r
+    _NullLibraryNumber = 0\r
+\r
+    def __init__(self, FilePath, Table, Db, Arch='COMMON', Macros={}):\r
+        self.DescFilePath = FilePath\r
+        self._Table = Table\r
+        self._Db = Db\r
+        self._Arch = Arch\r
+        self._Macros = Macros\r
+        self._Clear()\r
+\r
+    def __repr__(self):\r
+        S = '[Platform.%s]\n' % self.Arch\r
+        S += "\tName = %s\n" % self.PlatformName\r
+        S += "\tGuid = %s\n" % self.Guid\r
+        S += "\tVer = %s\n" % self.Version\r
+        S += "\n"\r
+        S += "\tSpecification = %s\n" % self.DscSpecification\r
+        S += "\tOutputDirectory = %s\n" % self.OutputDirectory \r
+        S += "\tSupArchList = %s\n" % self.SupArchList     \r
+        S += "\tBuildTargets = %s\n" % self.BuildTargets    \r
+        S += "\tSkuName = %s\n" % self.SkuName           \r
+        S += "\tFlashDefinition = %s\n" % self.FlashDefinition \r
+        S += "\tBuildNumber = %s\n" % self.BuildNumber     \r
+        S += "\tMakefileName = %s\n" % self.MakefileName    \r
+        S += "\tBsBaseAddress = %s\n" % self.BsBaseAddress   \r
+        S += "\tRtBaseAddress = %s\n" % self.RtBaseAddress   \r
+\r
+        S += '  <SkuId>\n'\r
+        for SkuName in self.SkuIds:\r
+            S += "\t%s = %s\n" % (SkuName, self.SkuIds[SkuName])\r
+\r
+        #S += '  <LibraryClass>\n'\r
+        #ModuleTypeList = set()\r
+        #LibraryClassList = set()\r
+        #for LibraryClass,ModuleType in self.LibraryClasses:\r
+        #    LibraryClassList.add(LibraryClass)\r
+        #    ModuleTypeList.add(ModuleType)\r
+        #LibraryClassList = list(LibraryClassList)\r
+        #ModuleTypeList = list(ModuleTypeList)\r
+        #LibraryClassList.sort()\r
+        #ModuleTypeList.sort()\r
+        #for LibraryClass in LibraryClassList:\r
+        #    for ModuleType in ModuleTypeList:\r
+        #        if not (LibraryClass,ModuleType) in self.LibraryClasses:\r
+        #            continue \r
+        #        S += "\t%32s, %-24s = %s\n" % (LibraryClass, ModuleType, self.LibraryClasses[LibraryClass,ModuleType])\r
+        \r
+        S += '  <PCD>\n'\r
+        for Name, Guid in self.Pcds:\r
+            S += "\t%s.%s\n\t\t%s\n" % (Guid, Name, str(self.Pcds[Name, Guid]))\r
+        \r
+        S += '  <BuildOption>\n'\r
+        for ToolChainFamily,ToolChain in self.BuildOptions:\r
+            S += "\t%s:%s = %s\n" % (ToolChainFamily, ToolChain, self.BuildOptions[ToolChainFamily, ToolChain])\r
+\r
+        S += '  <Module>\n'\r
+        S += "\t" + "\n\t".join([str(M) for M in self.Modules]) + '\n'\r
+        return S\r
+\r
+    ## XXX[key] = value\r
+    #def __setitem__(self, key, value):\r
+    #    self.__dict__[self._PROPERTY_[key]] = value\r
+    #\r
+    ### variable = XXX[key]\r
+    #def __getitem__(self, key):\r
+    #    return self.__dict__[self._PROPERTY_[key]]\r
+    #\r
+    ### "in" test support\r
+    #def __contains__(self, key):\r
+    #    return key in self._PROPERTY_\r
+\r
+    def _Clear(self):\r
+        self._PlatformName      = None\r
+        self._Guid              = None\r
+        self._Version           = None\r
+        self._DscSpecification  = None\r
+        self._OutputDirectory   = None\r
+        self._SupArchList       = None\r
+        self._BuildTargets      = None\r
+        self._SkuName           = None\r
+        self._FlashDefinition   = None\r
+        self._BuildNumber       = None\r
+        self._MakefileName      = None\r
+        self._BsBaseAddress     = None\r
+        self._RtBaseAddress     = None\r
+        self._SkuIds            = None\r
+        self._Modules           = None\r
+        self._LibraryInstances  = None\r
+        self._LibraryClasses    = None\r
+        self._Libraries         = None\r
+        self._Pcds              = None\r
+        self._BuildOptions      = None\r
+\r
+    def _GetArch(self):\r
+        return self._Arch\r
+\r
+    def _SetArch(self, Value):\r
+        if self._Arch == Value:\r
+            return\r
+        self._Arch = Value\r
+        self._Clear()\r
+\r
+    def _GetPlatformName(self):\r
+        if self._PlatformName == None:\r
+            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_PLATFORM_NAME, self.Arch)\r
+            self._PlatformName = RecordList[0][0]\r
+        return self._PlatformName\r
+\r
+    def _GetFileGuid(self):\r
+        if self._Guid == None:\r
+            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_PLATFORM_GUID, self.Arch)\r
+            self._Guid = RecordList[0][0]\r
+        return self._Guid\r
+\r
+    def _GetVersion(self):\r
+        if self._Version == None:\r
+            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_PLATFORM_VERSION, self.Arch)\r
+            self._Version = RecordList[0][0]\r
+        return self._Version\r
+\r
+    def _GetDscSpec(self):\r
+        if self._DscSpecification == None:\r
+            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_DSC_SPECIFICATION, self.Arch)\r
+            self._DscSpecification = RecordList[0][0]\r
+        return self._DscSpecification\r
+\r
+    def _GetOutpuDir(self):\r
+        if self._OutputDirectory == None:\r
+            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_OUTPUT_DIRECTORY, self.Arch)\r
+            File = NormPath(RecordList[0][0], self._Macros)\r
+            LineNo = RecordList[0][-1]\r
+            self._OutputDirectory = File\r
+        return self._OutputDirectory\r
+\r
+    def _GetSupArch(self):\r
+        if self._SupArchList == None:\r
+            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES, self.Arch)\r
+            self._SupArchList = GetSplitValueList(RecordList[0][0], TAB_VALUE_SPLIT)\r
+        return self._SupArchList\r
+\r
+    def _GetBuildTarget(self):\r
+        if self._BuildTargets == None:\r
+            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_BUILD_TARGETS, self.Arch)\r
+            self._BuildTargets = GetSplitValueList(RecordList[0][0])\r
+        return self._BuildTargets\r
+\r
+    def _GetSkuName(self):\r
+        if self._SkuName == None:\r
+            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_SKUID_IDENTIFIER, self.Arch)\r
+            if len(RecordList) > 0:\r
+                self._SkuName = RecordList[0][0]\r
+                if self._SkuName not in self.SkuIds:\r
+                    self._SkuName = 'DEFAULT'\r
+            else:\r
+                self._SkuName = 'DEFAULT'\r
+        return self._SkuName\r
+\r
+    def _GetFdfFile(self):\r
+        if self._FlashDefinition == None:\r
+            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_FLASH_DEFINITION, self.Arch)\r
+            self._FlashDefinition = NormPath(RecordList[0][0])\r
+        return self._FlashDefinition\r
+\r
+    def _GetBuildNumber(self):\r
+        if self._BuildNumber == None:\r
+            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_BUILD_NUMBER, self.Arch)\r
+            if len(RecordList) > 0:\r
+                self._BuildNumber = RecordList[0][0]\r
+        return self._BuildNumber\r
+\r
+    def _GetMakefileName(self):\r
+        if self._MakefileName == None:\r
+            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_MAKEFILE_NAME, self.Arch)\r
+            if len(RecordList):\r
+                self._MakefileName = RecordList[0][0]\r
+        return self._MakefileName\r
+\r
+    def _GetBsBaseAddress(self):\r
+        if self._BsBaseAddress == None:\r
+            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_BS_BASE_ADDRESS, self.Arch)\r
+            if len(RecordList) != 0:\r
+                self._BsBaseAddress = RecordList[0][0]\r
+        return self._BsBaseAddress\r
+\r
+    def _GetRtBaseAddress(self):\r
+        if self._RtBaseAddress == None:\r
+            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_RT_BASE_ADDRESS, self.Arch)\r
+            if len(RecordList):\r
+                self._RtBaseAddress = RecordList[0][0]\r
+        return self._RtBaseAddress\r
+\r
+    def _GetSkuIds(self):\r
+        if self._SkuIds == None:\r
+            self._SkuIds = {}\r
+            RecordList = self._Table.Query(MODEL_EFI_SKU_ID)\r
+            for Record in RecordList:\r
+                self._SkuIds[Record[1]] = Record[0]\r
+        return self._SkuIds\r
+\r
+    def _GetModules(self):\r
+        if self._Modules == None:\r
+            self._Modules = []\r
+            RecordList = self._Table.Query(MODEL_META_DATA_COMPONENT, Scope1=self.Arch)\r
+            for Record in RecordList:\r
+                ModuleFile = NormPath(Record[0], self._Macros)\r
+                ModuleId = Record[5]\r
+                LineNo = Record[6]\r
+                if not ValidFile(ModuleFile):\r
+                    EdkLogger.error('build', FILE_NOT_FOUND, File=self.DescFilePath, \r
+                                    ExtraData=ModuleFile, Line=LineNo)\r
+                if ModuleFile in self._Modules:\r
+                    continue\r
+                Module = self._Db.BuildObject[ModuleFile, MODEL_FILE_INF, self._Arch]\r
+                self._MergeModuleInfo(Module, ModuleId)\r
+                self._Modules.append(Module)\r
+        return self._Modules\r
+\r
+    def _MergeModuleInfo(self, Module, ModuleId):\r
+        ModuleType = Module.ModuleType\r
+        # merge library class/instance information\r
+        for LibraryClass in Module.LibraryClasses:\r
+            if self.LibraryClasses[LibraryClass, ModuleType] == None: continue\r
+            Module.LibraryClasses[LibraryClass] = self.LibraryClasses[LibraryClass, ModuleType]\r
+        RecordList = self._Table.Query(MODEL_EFI_LIBRARY_CLASS, Scope1=self.Arch, BelongsToItem=ModuleId)\r
+        for Record in RecordList:\r
+            LibraryClass = Record[0]\r
+            LibraryPath = NormPath(Record[1], self._Macros)\r
+            LineNo = Record[-1]\r
+            if not ValidFile(LibraryPath):\r
+                EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=LibraryPath,\r
+                                File=self.DescFilePath, Line=LineNo)\r
+            if LibraryClass == '' or LibraryClass == 'NULL':\r
+                LibraryClass = 'NULL%d' % (self._NullLibraryNumber + 1)\r
+                LibraryInstance = self._Db.BuildObject[LibraryPath, MODEL_FILE_INF, self._Arch]\r
+                LibraryInstance.LibraryClass.append(LibraryClassObject(LibraryClass, [ModuleType]))\r
+            Module.LibraryClasses[LibraryClass] = LibraryPath\r
+\r
+        # R9 module\r
+        LibraryConsumerList = [Module]\r
+        Constructor         = []\r
+        ConsumedByList      = sdict()\r
+        LibraryInstance     = sdict()\r
+\r
+        EdkLogger.verbose("")\r
+        EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))\r
+        while len(LibraryConsumerList) > 0:\r
+            M = LibraryConsumerList.pop()\r
+            for LibraryClassName in M.LibraryClasses:\r
+                LibraryPath = M.LibraryClasses[LibraryClassName]\r
+                if LibraryPath == None or LibraryPath == "":\r
+                    LibraryPath = self.LibraryClasses[LibraryClassName, ModuleType]\r
+                    if LibraryPath == None and LibraryClassName not in LibraryInstance:\r
+                        LibraryInstance[LibraryClassName] = None\r
+                        continue\r
+                if LibraryClassName not in LibraryInstance:\r
+                    LibraryModule = self._Db.BuildObject[LibraryPath, MODEL_FILE_INF, self._Arch]\r
+                    LibraryInstance[LibraryClassName] = LibraryModule\r
+                    LibraryConsumerList.append(LibraryModule)\r
+                    EdkLogger.verbose("\t" + LibraryClassName + " : " + str(LibraryModule))\r
+                else:\r
+                    LibraryModule = LibraryInstance[LibraryClassName]\r
+\r
+                if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:\r
+                    Constructor.append(LibraryModule)\r
+\r
+                if LibraryModule not in ConsumedByList:\r
+                    ConsumedByList[LibraryModule] = []\r
+                if M != Module:\r
+                    if M in ConsumedByList[LibraryModule]:\r
+                        continue\r
+                    ConsumedByList[LibraryModule].append(M)\r
+        #\r
+        # Initialize the sorted output list to the empty set\r
+        #\r
+        SortedLibraryList = []\r
+        #\r
+        # Q <- Set of all nodes with no incoming edges\r
+        #\r
+        LibraryList = [] #LibraryInstance.values()\r
+        Q = []\r
+        for LibraryClassName in LibraryInstance:\r
+            M = LibraryInstance[LibraryClassName]\r
+            if M == None:\r
+                EdkLogger.error("AutoGen", AUTOGEN_ERROR,\r
+                                "Library instance for library class [%s] is not found" % LibraryClassName,\r
+                                ExtraData="\t%s [%s]" % (str(Module), self.Arch))\r
+            LibraryList.append(M)\r
+            #\r
+            # check if there're duplicate library classes\r
+            #\r
+            for Lc in M.LibraryClass:\r
+                if Lc.SupModList != None and ModuleType not in Lc.SupModList:\r
+                    EdkLogger.error("AutoGen", AUTOGEN_ERROR,\r
+                                    "Module type [%s] is not supported by library instance [%s]" % (ModuleType, str(M)),\r
+                                    ExtraData="\t%s" % str(Module))\r
+\r
+                if Lc.LibraryClass in LibraryInstance and str(M) != str(LibraryInstance[Lc.LibraryClass]):\r
+                    EdkLogger.error("AutoGen", AUTOGEN_ERROR,\r
+                                    "More than one library instance found for library class [%s] in module [%s]" % (Lc.LibraryClass, Module),\r
+                                    ExtraData="\t%s\n\t%s" % (LibraryInstance[Lc.LibraryClass], str(M))\r
+                                    )\r
+            if ConsumedByList[M] == []:\r
+                Q.insert(0, M)\r
+        #\r
+        # while Q is not empty do\r
+        #\r
+        while Q != []:\r
+            #\r
+            # remove node from Q\r
+            #\r
+            Node = Q.pop()\r
+            #\r
+            # output Node\r
+            #\r
+            SortedLibraryList.append(Node)\r
+            #\r
+            # for each node Item with an edge e from Node to Item do\r
+            #\r
+            for Item in LibraryList:\r
+                if Node not in ConsumedByList[Item]:\r
+                    continue\r
+                #\r
+                # remove edge e from the graph\r
+                #\r
+                ConsumedByList[Item].remove(Node)\r
+                #\r
+                # If Item has no other incoming edges then\r
+                #\r
+                if ConsumedByList[Item] == []:\r
+                    #\r
+                    # insert Item into Q\r
+                    #\r
+                    Q.insert(0, Item)\r
+\r
+            EdgeRemoved = True\r
+            while Q == [] and EdgeRemoved:\r
+                EdgeRemoved = False\r
+                #\r
+                # for each node Item with a Constructor\r
+                #\r
+                for Item in LibraryList:\r
+                    if Item in Constructor:\r
+                        #\r
+                        # for each Node without a constructor with an edge e from Item to Node\r
+                        #\r
+                        for Node in ConsumedByList[Item]:\r
+                            if Node not in Constructor:\r
+                                #\r
+                                # remove edge e from the graph\r
+                                #\r
+                                ConsumedByList[Item].remove(Node)\r
+                                EdgeRemoved = True\r
+                                if ConsumedByList[Item] == []:\r
+                                    #\r
+                                    # insert Item into Q\r
+                                    #\r
+                                    Q.insert(0, Item)\r
+                                    break\r
+                    if Q != []:\r
+                        break\r
+\r
+        #\r
+        # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle\r
+        #\r
+        for Item in LibraryList:\r
+            if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:\r
+                ErrorMessage = 'Library [%s] with constructors has a cycle' % str(Item)\r
+                EdkLogger.error("AutoGen", AUTOGEN_ERROR, ErrorMessage,\r
+                                "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]]))\r
+            if Item not in SortedLibraryList:\r
+                SortedLibraryList.append(Item)\r
+\r
+        #\r
+        # Build the list of constructor and destructir names\r
+        # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order\r
+        #\r
+        SortedLibraryList.reverse()\r
+        Module.LibraryClasses = sdict()\r
+        for L in SortedLibraryList:\r
+            Module.LibraryClasses[L.LibraryClass[0].LibraryClass, ModuleType] = L\r
+            #\r
+            # Merge PCDs from library instance\r
+            #\r
+            for Key in L.Pcds:\r
+                if Key not in Module.Pcds:\r
+                    Module.Pcds[Key] = L.Pcds[Key]\r
+            #\r
+            # Merge GUIDs from library instance\r
+            #\r
+            for CName in L.Guids:\r
+                if CName not in Module.Guids:\r
+                    Module.Guids.append(CName)\r
+            #\r
+            # Merge Protocols from library instance\r
+            #\r
+            for CName in L.Protocols:\r
+                if CName not in Module.Protocols:\r
+                    Module.Protocols.append(CName)\r
+            #\r
+            # Merge Ppis from library instance\r
+            #\r
+            for CName in L.Ppis:\r
+                if CName not in Module.Ppis:\r
+                    Module.Ppis.append(CName)\r
+\r
+        self._UpdateModulePcd(Module, ModuleId)\r
+        self._MergeModuleBuildOption(Module, ModuleId)\r
+\r
+    def _UpdateModulePcd(self, Module, ModuleId):\r
+        for Name,Guid in Module.Pcds:\r
+            PcdInModule = Module.Pcds[Name,Guid]\r
+            if (Name,Guid) in self.Pcds:\r
+                PcdInPlatform = self.Pcds[Name,Guid]\r
+                # \r
+                # in case there's PCDs coming from FDF file, which have no type given.\r
+                # at this point, PcdInModule.Type has the type found from dependent\r
+                # package\r
+                # \r
+                if PcdInPlatform.Type != None and PcdInPlatform.Type != '':\r
+                    PcdInModule.Type = PcdInPlatform.Type\r
+                PcdInModule.MaxDatumSize = PcdInPlatform.MaxDatumSize\r
+                PcdInModule.SkuInfoList = PcdInPlatform.SkuInfoList\r
+                if PcdInPlatform.DefaultValue not in [None, '']:\r
+                    PcdInModule.DefaultValue = PcdInPlatform.DefaultValue\r
+                if PcdInPlatform.TokenValue not in [None, '']:\r
+                    PcdInModule.TokenValue = PcdInPlatform.TokenValue\r
+                if PcdInPlatform.MaxDatumSize not in [None, '']:\r
+                    PcdInModule.MaxDatumSize = PcdInPlatform.MaxDatumSize\r
+                if PcdInPlatform.DatumType not in [None, '']:\r
+                    PcdInModule.DatumType = PcdInPlatform.DatumType\r
+\r
+            if PcdInModule.DatumType == "VOID*" and PcdInModule.MaxDatumSize in ['', None]:\r
+                EdkLogger.verbose("No MaxDatumSize specified for PCD %s.%s in module [%s]" % (Guid, Name, str(Module)))\r
+                Value = PcdInModule.DefaultValue\r
+                if Value[0] == 'L':\r
+                    PcdInModule.MaxDatumSize = str(len(Value) * 2)\r
+                elif Value[0] == '{':\r
+                    PcdInModule.MaxDatumSize = str(len(Value.split(',')))\r
+                else:\r
+                    PcdInModule.MaxDatumSize = str(len(Value))\r
+\r
+        RecordList = self._Table.Query(MODEL_PCD_FIXED_AT_BUILD, Scope1=self.Arch, BelongsToItem=ModuleId)\r
+        for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
+            if (PcdCName, TokenSpaceGuid) not in Module.Pcds:\r
+                continue\r
+            TokenList = GetSplitValueList(Setting)\r
+            Pcd = Module.Pcds[PcdCName, TokenSpaceGuid]\r
+            Pcd.DefaultValue = TokenList[0]\r
+            if len(TokenList) > 1:\r
+                Pcd.MaxDatumSize = TokenList[1]\r
+            Pcd.Type = self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD]\r
+\r
+        RecordList = self._Table.Query(MODEL_PCD_PATCHABLE_IN_MODULE, Scope1=self.Arch, BelongsToItem=ModuleId)\r
+        for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
+            if (PcdCName, TokenSpaceGuid) not in Module.Pcds:\r
+                continue\r
+            TokenList = GetSplitValueList(Setting)\r
+            Pcd = Module.Pcds[PcdCName, TokenSpaceGuid]\r
+            Pcd.DefaultValue = TokenList[0]\r
+            if len(TokenList) > 1:\r
+                Pcd.MaxDatumSize = TokenList[1]\r
+            Pcd.Type = self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]\r
+\r
+        RecordList = self._Table.Query(MODEL_PCD_FEATURE_FLAG, Scope1=self.Arch, BelongsToItem=ModuleId)\r
+        for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
+            if (PcdCName, TokenSpaceGuid) not in Module.Pcds:\r
+                continue\r
+            TokenList = GetSplitValueList(Setting)\r
+            Pcd = Module.Pcds[PcdCName, TokenSpaceGuid]\r
+            Pcd.DefaultValue = TokenList[0]\r
+            if len(TokenList) > 1:\r
+                Pcd.MaxDatumSize = TokenList[1]\r
+            Pcd.Type = self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG]\r
+\r
+        RecordList = self._Table.Query(MODEL_PCD_DYNAMIC, Scope1=self.Arch, BelongsToItem=ModuleId)\r
+        for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
+            if (PcdCName, TokenSpaceGuid) not in Module.Pcds:\r
+                continue\r
+            Pcd.DefaultValue = Setting\r
+            Pcd.Type = self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC]\r
+\r
+        RecordList = self._Table.Query(MODEL_PCD_DYNAMIC_EX, Scope1=self.Arch, BelongsToItem=ModuleId)\r
+        for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
+            if (PcdCName, TokenSpaceGuid) not in Module.Pcds:\r
+                continue\r
+            Pcd.DefaultValue = Setting\r
+            Pcd.Type = self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX]\r
+\r
+    def _MergeModuleBuildOption(self, Module, ModuleId):\r
+        RecordList = self._Table.Query(MODEL_META_DATA_BUILD_OPTION, Scope1=self.Arch, BelongsToItem=ModuleId)\r
+        for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
+            if (ToolChainFamily, ToolChain) not in Module.BuildOptions:\r
+                Module.BuildOptions[ToolChainFamily, ToolChain] = Option\r
+            else:\r
+                OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]\r
+                Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
+\r
+    def _GetLibraryInstances(self):\r
+        if self._LibraryInstances == None:\r
+            self._LibraryInstances = []\r
+            for Module in self.Modules:\r
+                for Key in Module.LibraryClasses:\r
+                    Lib = Module.LibraryClasses[Key]\r
+                    if Lib in self._LibraryInstances:\r
+                        continue\r
+                    self._LibraryInstances.append(Lib)\r
+        return self._LibraryInstances\r
+\r
+    def _GetLibraryClasses(self):\r
+        if self._LibraryClasses == None:\r
+            LibraryClassDict = tdict(True, 3)\r
+            LibraryClassSet = set()\r
+            ModuleTypeSet = set()\r
+            RecordList = self._Table.Query(MODEL_EFI_LIBRARY_CLASS, Scope1=self.Arch)\r
+            for LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, LineNo in RecordList:\r
+                LibraryClassSet.add(LibraryClass)\r
+                ModuleTypeSet.add(ModuleType)\r
+                LibraryInstance = NormPath(LibraryInstance, self._Macros)\r
+                if not ValidFile(LibraryInstance):\r
+                    EdkLogger.error('build', FILE_NOT_FOUND, File=self.DescFilePath, \r
+                                    ExtraData=LibraryInstance, Line=LineNo)\r
+                LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance\r
+\r
+            self._LibraryClasses = tdict(True)\r
+            for LibraryClass in LibraryClassSet:\r
+                for ModuleType in ModuleTypeSet:\r
+                    LibraryInstance = LibraryClassDict[self.Arch, ModuleType, LibraryClass]\r
+                    if LibraryInstance == None:\r
+                        continue\r
+                    self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance\r
+        return self._LibraryClasses\r
+\r
+    def _GetLibraries(self):\r
+        if self._Libraries == None:\r
+            self._Libraries = []\r
+            RecordList = self._Table.Query(MODEL_EFI_LIBRARY_INSTANCE, Scope1=self.Arch)\r
+            for Record in RecordList:\r
+                File = NormPath(Record[0], self._Macros)\r
+                LineNo = Record[-1]\r
+                if not ValidFile(File):\r
+                    EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
+                                    File=self.DescFilePath, Line=LineNo)\r
+                self._Libraries.append(File)\r
+        return self._Libraries\r
+\r
+    def _GetPcds(self):\r
+        if self._Pcds == None:\r
+            self._Pcds = {}\r
+            self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
+            self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
+            self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
+            self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))\r
+            self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))\r
+            self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))\r
+            self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))\r
+            self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))\r
+            self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))\r
+        return self._Pcds\r
+\r
+    def _GetBuildOptions(self):\r
+        if self._BuildOptions == None:\r
+            self._BuildOptions = {}\r
+            RecordList = self._Table.Query(MODEL_META_DATA_BUILD_OPTION)\r
+            for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
+                self._BuildOptions[ToolChainFamily, ToolChain] = Option\r
+        return self._BuildOptions\r
+\r
+    def _GetPcd(self, Type):\r
+        Pcds = {}\r
+        PcdDict = tdict(True, 3)\r
+        PcdSet = set()\r
+        # Find out all possible PCD candidates for self.Arch\r
+        RecordList = self._Table.Query(Type, Scope1=self.Arch)\r
+        for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
+            PcdSet.add((PcdCName, TokenSpaceGuid))\r
+            PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting\r
+        # Remove redundant PCD candidates\r
+        for PcdCName, TokenSpaceGuid in PcdSet:\r
+            ValueList = ['', '', '']\r
+            Setting = PcdDict[self.Arch, PcdCName, TokenSpaceGuid]\r
+            if Setting == None:\r
+                continue\r
+            TokenList = Setting.split(TAB_VALUE_SPLIT)\r
+            ValueList[0:len(TokenList)] = TokenList\r
+            PcdValue, DatumType, MaxDatumSize = ValueList\r
+            Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
+                                                PcdCName,\r
+                                                TokenSpaceGuid,\r
+                                                self._PCD_TYPE_STRING_[Type],\r
+                                                DatumType,\r
+                                                PcdValue,\r
+                                                '',\r
+                                                MaxDatumSize,\r
+                                                {},\r
+                                                True\r
+                                                )\r
+        return Pcds\r
+\r
+    def _GetDynamicPcd(self, Type):\r
+        Pcds = {}\r
+        PcdDict = tdict(True, 4)\r
+        PcdSet = set()\r
+        RecordList = self._Table.Query(Type, Scope1=self.Arch)\r
+        for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
+            PcdSet.add((PcdCName, TokenSpaceGuid))\r
+            PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
+\r
+        for PcdCName, TokenSpaceGuid in PcdSet:\r
+            ValueList = ['', '', '']\r
+            Setting = PcdDict[self.Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
+            if Setting == None:\r
+                continue\r
+            TokenList = Setting.split(TAB_VALUE_SPLIT)\r
+            ValueList[0:len(TokenList)] = TokenList\r
+            PcdValue, DatumType, MaxDatumSize = ValueList\r
+\r
+            SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', '', PcdValue)\r
+            Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
+                                                PcdCName,\r
+                                                TokenSpaceGuid,\r
+                                                self._PCD_TYPE_STRING_[Type],\r
+                                                DatumType,\r
+                                                PcdValue,\r
+                                                '',\r
+                                                MaxDatumSize,\r
+                                                {self.SkuName : SkuInfo},\r
+                                                True\r
+                                                )\r
+        return Pcds\r
+\r
+    def _GetDynamicHiiPcd(self, Type):\r
+        Pcds = {}\r
+        PcdDict = tdict(True, 4)\r
+        PcdSet = set()\r
+        RecordList = self._Table.Query(Type, Scope1=self.Arch)\r
+        for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
+            PcdSet.add((PcdCName, TokenSpaceGuid))\r
+            PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
+\r
+        for PcdCName, TokenSpaceGuid in PcdSet:\r
+            ValueList = ['', '', '', '']\r
+            Setting = PcdDict[self.Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
+            if Setting == None:\r
+                continue\r
+            TokenList = Setting.split(TAB_VALUE_SPLIT)\r
+            ValueList[0:len(TokenList)] = TokenList\r
+            VariableName, VariableGuid, VariableOffset, DefaultValue = ValueList\r
+            SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue)\r
+            Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
+                                                PcdCName,\r
+                                                TokenSpaceGuid,\r
+                                                self._PCD_TYPE_STRING_[Type],\r
+                                                '',\r
+                                                DefaultValue,\r
+                                                '',\r
+                                                '',\r
+                                                {self.SkuName : SkuInfo},\r
+                                                True\r
+                                                )\r
+        return Pcds\r
+\r
+    def _GetDynamicVpdPcd(self, Type):\r
+        Pcds = {}\r
+        PcdDict = tdict(True, 4)\r
+        PcdSet = set()\r
+        RecordList = self._Table.Query(Type, Scope1=self.Arch)\r
+        for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
+            PcdSet.add((PcdCName, TokenSpaceGuid))\r
+            PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
+\r
+        for PcdCName, TokenSpaceGuid in PcdSet:\r
+            ValueList = ['', '']\r
+            Setting = PcdDict[self.Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
+            if Setting == None:\r
+                continue\r
+            TokenList = Setting.split(TAB_VALUE_SPLIT)\r
+            ValueList[0:len(TokenList)] = TokenList\r
+            VpdOffset, MaxDatumSize = ValueList\r
+\r
+            SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', VpdOffset)\r
+            Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
+                                                PcdCName,\r
+                                                TokenSpaceGuid,\r
+                                                self._PCD_TYPE_STRING_[Type],\r
+                                                '',\r
+                                                '',\r
+                                                '',\r
+                                                MaxDatumSize,\r
+                                                {self.SkuName : SkuInfo},\r
+                                                True\r
+                                                )\r
+        return Pcds\r
+\r
+    def AddModule(self, FilePath):\r
+        Module = self._Db.BuildObject[FilePath, MODEL_FILE_INF, self._Arch]\r
+        self._Modules.append(NormPath(Module))\r
+\r
+    def AddPcd(self, Name, Guid, Value):\r
+        if (Name, Guid) not in self.Pcds:\r
+            self.Pcds[Name, Guid] = PcdClassObject(\r
+                                        Name,\r
+                                        Guid,\r
+                                        '',\r
+                                        '',\r
+                                        '',\r
+                                        '',\r
+                                        '',\r
+                                        {},\r
+                                        True\r
+                                        )\r
+        self.Pcds[Name, Guid].DefaultValue = Value\r
+\r
+    Arch                = property(_GetArch, _SetArch)\r
+    Platform            = property(_GetPlatformName)\r
+    PlatformName        = property(_GetPlatformName)\r
+    Guid                = property(_GetFileGuid)\r
+    Version             = property(_GetVersion)\r
+    DscSpecification    = property(_GetDscSpec)\r
+    OutputDirectory     = property(_GetOutpuDir)\r
+    SupArchList         = property(_GetSupArch)\r
+    BuildTargets        = property(_GetBuildTarget)\r
+    SkuName             = property(_GetSkuName)\r
+    FlashDefinition     = property(_GetFdfFile)\r
+    BuildNumber         = property(_GetBuildNumber)\r
+    MakefileName        = property(_GetMakefileName)\r
+    BsBaseAddress       = property(_GetBsBaseAddress)\r
+    RtBaseAddress       = property(_GetRtBaseAddress)\r
+\r
+    SkuIds              = property(_GetSkuIds)\r
+    Modules             = property(_GetModules)\r
+    LibraryInstances    = property(_GetLibraryInstances)\r
+    LibraryClasses      = property(_GetLibraryClasses)\r
+    Libraries           = property(_GetLibraries)\r
+    Pcds                = property(_GetPcds)\r
+    BuildOptions        = property(_GetBuildOptions)\r
+\r
+class DecBuildData(PackageBuildClassObject):\r
+    _PCD_TYPE_STRING_ = {\r
+        MODEL_PCD_FIXED_AT_BUILD        :   "FixedAtBuild",\r
+        MODEL_PCD_PATCHABLE_IN_MODULE   :   "PatchableInModule",\r
+        MODEL_PCD_FEATURE_FLAG          :   "FeatureFlag",\r
+        MODEL_PCD_DYNAMIC               :   "Dynamic",\r
+        MODEL_PCD_DYNAMIC_DEFAULT       :   "Dynamic",\r
+        MODEL_PCD_DYNAMIC_HII           :   "DynamicHii",\r
+        MODEL_PCD_DYNAMIC_VPD           :   "DynamicVpd",\r
+        MODEL_PCD_DYNAMIC_EX            :   "DynamicEx",\r
+        MODEL_PCD_DYNAMIC_EX_DEFAULT    :   "DynamicEx",\r
+        MODEL_PCD_DYNAMIC_EX_HII        :   "DynamicExHii",\r
+        MODEL_PCD_DYNAMIC_EX_VPD        :   "DynamicExVpd",\r
+    }\r
+\r
+    def __init__(self, FilePath, Table, Db, Arch='COMMON', Macros={}):\r
+        self.DescFilePath = FilePath\r
+        self._PackageDir = os.path.dirname(FilePath)\r
+        self._Table = Table\r
+        self._Arch = Arch\r
+        self._Macros = Macros\r
+        self._Clear()\r
+\r
+    def __repr__(self):\r
+        S = "[Package]\n"\r
+        S += "\tNAME = %s\n" % self.PackageName\r
+        S += "\tGUID = %s\n" % self.Guid\r
+        S += "\tVER  = %s\n" % self.Version\r
+\r
+        S += '  <Protocol>\n'\r
+        for Name in self.Protocols:\r
+            S += "\t%s = %s\n" % (Name, self.Protocols[Name])\r
+\r
+        S += '  <Ppi>\n'\r
+        for Name in self.Ppis:\r
+            S += "\t%s = %s\n" % (Name, self.Ppis[Name])\r
+\r
+        S += '  <Guid>\n'\r
+        for Name in self.Guids:\r
+            S += "\t%s = %s\n" % (Name, self.Guids[Name])\r
+\r
+        S += '  <Include>\n\t'\r
+        S += "\n\t".join(self.Includes) + '\n'\r
+\r
+        S += '  <LibraryClass>\n'\r
+        for LibraryClass in self.LibraryClasses:\r
+            S += "\t%s = %s\n" % (LibraryClass, self.LibraryClasses[LibraryClass])\r
+\r
+        S += '  <PCD>\n'\r
+        for Name,Guid,Type in self.Pcds:\r
+            S += "\t%s.%s-%s\n\t\t%s\n" % (Guid, Name, Type, str(self.Pcds[Name, Guid, Type]))\r
+        return S\r
+\r
+    def _Clear(self):\r
+        self._PackageName       = None\r
+        self._Guid              = None\r
+        self._Version           = None\r
+        self._Protocols         = None\r
+        self._Ppis              = None\r
+        self._Guids             = None\r
+        self._Includes          = None\r
+        self._LibraryClasses    = None\r
+        self._Pcds              = None\r
+\r
+    def _GetArch(self):\r
+        return self._Arch\r
+\r
+    def _SetArch(self, Value):\r
+        if self._Arch == Value:\r
+            return\r
+        self._Arch = Value\r
+        self._Clear()\r
+\r
+    def _GetPackageName(self):\r
+        if self._PackageName == None:\r
+            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DEC_DEFINES_PACKAGE_NAME)\r
+            if len(RecordList) == 0:\r
+                EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", ExtraData=self.DescFilePath)\r
+            self._PackageName = RecordList[0][0]\r
+        return self._PackageName\r
+\r
+    def _GetFileGuid(self):\r
+        if self._Guid == None:\r
+            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DEC_DEFINES_PACKAGE_GUID)\r
+            if len(RecordList) == 0:\r
+                EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", ExtraData=self.DescFilePath)\r
+            self._Guid = RecordList[0][0]\r
+        return self._Guid\r
+\r
+    def _GetVersion(self):\r
+        if self._Version == None:\r
+            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DEC_DEFINES_PACKAGE_VERSION)\r
+            if len(RecordList) == 0:\r
+                self._Version = ''\r
+            self._Version = RecordList[0][0]\r
+        return self._Version\r
+\r
+    def _GetProtocol(self):\r
+        if self._Protocols == None:\r
+            ProtocolDict = tdict(True)\r
+            NameSet = set()\r
+            RecordList = self._Table.Query(MODEL_EFI_PROTOCOL, Arch=self.Arch)\r
+            for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
+                NameSet.add(Name)\r
+                ProtocolDict[Arch, Name] = Guid\r
+            self._Protocols = sdict()\r
+            for Name in NameSet:\r
+                self._Protocols[Name] = ProtocolDict[self.Arch, Name]\r
+        return self._Protocols\r
+\r
+    def _GetPpi(self):\r
+        if self._Ppis == None:\r
+            PpiDict = tdict(True)\r
+            NameSet = set()\r
+            RecordList = self._Table.Query(MODEL_EFI_PPI, Arch=self.Arch)\r
+            for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
+                NameSet.add(Name)\r
+                PpiDict[Arch, Name] = Guid\r
+            self._Ppis = sdict()\r
+            for Name in NameSet:\r
+                self._Ppis[Name] = PpiDict[self.Arch, Name]\r
+        return self._Ppis\r
+\r
+    def _GetGuid(self):\r
+        if self._Guids == None:\r
+            GuidDict = tdict(True)\r
+            NameSet = set()\r
+            RecordList = self._Table.Query(MODEL_EFI_GUID, Arch=self.Arch)\r
+            for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
+                NameSet.add(Name)\r
+                GuidDict[Arch, Name] = Guid\r
+            self._Guids = sdict()\r
+            for Name in NameSet:\r
+                self._Guids[Name] = GuidDict[self.Arch, Name]\r
+        return self._Guids\r
+\r
+    def _GetInclude(self):\r
+        if self._Includes == None:\r
+            self._Includes = []\r
+            RecordList = self._Table.Query(MODEL_EFI_INCLUDE, Arch=self.Arch)\r
+            for Record in RecordList:\r
+                File = NormPath(Record[0], self._Macros)\r
+                LineNo = Record[-1]\r
+                if not ValidFile(File, self._PackageDir):\r
+                    EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
+                                    File=self.DescFilePath, Line=LineNo)\r
+                self._Includes.append(File)\r
+        return self._Includes\r
+\r
+    def _GetLibraryClass(self):\r
+        if self._LibraryClasses == None:\r
+            LibraryClassDict = tdict(True)\r
+            LibraryClassSet = set()\r
+            RecordList = self._Table.Query(MODEL_EFI_LIBRARY_CLASS, Arch=self.Arch)\r
+            for LibraryClass, File, Dummy, Arch, ID, LineNo in RecordList:\r
+                File = NormPath(File, self._Macros)\r
+                if not ValidFile(File, self._PackageDir):\r
+                    EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
+                                    File=self.DescFilePath, Line=LineNo)\r
+                LibraryClassSet.add(LibraryClass)\r
+                LibraryClassDict[Arch, LibraryClass] = File\r
+            self._LibraryClasses = sdict()\r
+            for LibraryClass in LibraryClassSet:\r
+                self._LibraryClasses[LibraryClass] = LibraryClassDict[self.Arch, LibraryClass]\r
+        return self._LibraryClasses\r
+\r
+    def _GetPcds(self):\r
+        if self._Pcds == None:\r
+            self._Pcds = {}\r
+            self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
+            self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
+            self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
+            self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))\r
+            self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
+        return self._Pcds\r
+\r
+    def _GetPcd(self, Type):\r
+        Pcds = {}\r
+        PcdDict = tdict(True, 3)\r
+        PcdSet = set()\r
+        RecordList = self._Table.Query(Type, Arch=self._Arch)\r
+        for TokenSpaceGuid, PcdCName, Setting, Arch, Dummy1, Dummy2 in RecordList:\r
+            PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting\r
+            PcdSet.add((PcdCName, TokenSpaceGuid))\r
+\r
+        for PcdCName, TokenSpaceGuid in PcdSet:\r
+            ValueList = ['', '', '']\r
+            Setting = PcdDict[self.Arch, PcdCName, TokenSpaceGuid]\r
+            if Setting == None:\r
+                continue\r
+            TokenList = Setting.split(TAB_VALUE_SPLIT)\r
+            ValueList[0:len(TokenList)] = TokenList\r
+            DefaultValue, DatumType, TokenNumber = ValueList\r
+            Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject(\r
+                                                                            PcdCName,\r
+                                                                            TokenSpaceGuid,\r
+                                                                            self._PCD_TYPE_STRING_[Type],\r
+                                                                            DatumType,\r
+                                                                            DefaultValue,\r
+                                                                            TokenNumber,\r
+                                                                            '',\r
+                                                                            {},\r
+                                                                            True\r
+                                                                            )\r
+        return Pcds\r
+\r
+\r
+    Arch            = property(_GetArch, _SetArch)\r
+    PackageName     = property(_GetPackageName)\r
+    Guid            = property(_GetFileGuid)\r
+    Version         = property(_GetVersion)\r
+\r
+    Protocols       = property(_GetProtocol)\r
+    Ppis            = property(_GetPpi)\r
+    Guids           = property(_GetGuid)\r
+    Includes        = property(_GetInclude)\r
+    LibraryClasses  = property(_GetLibraryClass)\r
+    Pcds            = property(_GetPcds)\r
+\r
+class InfBuildData(ModuleBuildClassObject):\r
+    _PCD_TYPE_STRING_ = {\r
+        MODEL_PCD_FIXED_AT_BUILD        :   "FixedAtBuild",\r
+        MODEL_PCD_PATCHABLE_IN_MODULE   :   "PatchableInModule",\r
+        MODEL_PCD_FEATURE_FLAG          :   "FeatureFlag",\r
+        MODEL_PCD_DYNAMIC               :   "Dynamic",\r
+        MODEL_PCD_DYNAMIC_DEFAULT       :   "Dynamic",\r
+        MODEL_PCD_DYNAMIC_HII           :   "DynamicHii",\r
+        MODEL_PCD_DYNAMIC_VPD           :   "DynamicVpd",\r
+        MODEL_PCD_DYNAMIC_EX            :   "DynamicEx",\r
+        MODEL_PCD_DYNAMIC_EX_DEFAULT    :   "DynamicEx",\r
+        MODEL_PCD_DYNAMIC_EX_HII        :   "DynamicExHii",\r
+        MODEL_PCD_DYNAMIC_EX_VPD        :   "DynamicExVpd",\r
+    }\r
+\r
+    _PROPERTY_ = {\r
+        #\r
+        # Required Fields\r
+        #\r
+        TAB_INF_DEFINES_BASE_NAME                   : "_BaseName",\r
+        TAB_INF_DEFINES_FILE_GUID                   : "_Guid",\r
+        TAB_INF_DEFINES_MODULE_TYPE                 : "_ModuleType",\r
+        #\r
+        # Optional Fields\r
+        #\r
+        TAB_INF_DEFINES_INF_VERSION                 : "_AutoGenVersion",\r
+        TAB_INF_DEFINES_COMPONENT_TYPE              : "_ComponentType",\r
+        TAB_INF_DEFINES_MAKEFILE_NAME               : "_CustomMakefile",\r
+        TAB_INF_DEFINES_VERSION_NUMBER              : "_Version",\r
+        TAB_INF_DEFINES_VERSION_STRING              : "_Version",\r
+        TAB_INF_DEFINES_VERSION                     : "_Version",\r
+        TAB_INF_DEFINES_PCD_IS_DRIVER               : "_PcdIsDriver",\r
+        TAB_INF_DEFINES_SHADOW                      : "_Shadow",\r
+        TAB_INF_DEFINES_CUSTOM_MAKEFILE             : "_CustomMakefile",\r
+    }\r
+\r
+    def __init__(self, FilePath, Table, Db, Arch='COMMON', Macros={}):\r
+        self.DescFilePath = FilePath\r
+        self._ModuleDir = os.path.dirname(FilePath)\r
+        self._Table = Table\r
+        self._Db = Db\r
+        self._Arch = Arch\r
+        self._Platform = 'COMMON'\r
+        self._Macros = Macros\r
+        self._Clear()\r
+\r
+    def Print(self):\r
+        S = '[%s.%s]\n' % (self.DescFilePath, self.Arch)\r
+        S += '\tName = ' + self.BaseName + '\n'\r
+        S += '\tGuid = ' + self.Guid + '\n'\r
+        S += '\tVer  = ' + self.Version + '\n'\r
+        S += '\tInfVersion = ' + self.AutoGenVersion + '\n'\r
+        S += '\tModuleType = ' + self.ModuleType + '\n'\r
+        S += '\tComponentType = ' + self.ComponentType + '\n'\r
+        S += '\tPcdIsDriver = ' + str(self.PcdIsDriver) + '\n'\r
+        S += '\tCustomMakefile = ' + self.CustomMakefile + '\n'\r
+        S += '\tSpecification = ' + str(self.Specification) + '\n'\r
+        S += '\tShadow = ' + str(self.Shadow) + '\n'\r
+        S += '\tPcdIsDriver = ' + str(self.PcdIsDriver) + '\n'\r
+        for Lib in self.LibraryClass:\r
+            S += '\tLibraryClassDefinition = ' + str(Lib.LibraryClass) + ' SupModList = ' + str(Lib.SupModList) + '\n'\r
+        S += '\tModuleEntryPointList = ' + str(self.ModuleEntryPointList) + '\n'\r
+        S += '\tModuleUnloadImageList = ' + str(self.ModuleUnloadImageList) + '\n'\r
+        S += '\tConstructorList = ' + str(self.ConstructorList) + '\n'\r
+        S += '\tDestructorList = ' + str(self.DestructorList) + '\n'\r
+\r
+        S += '  <Binaries>\n'\r
+        for item in self.Binaries:\r
+            S += "\t" + item.BinaryFile + item.FeatureFlag + item.SupArchList + '\n'\r
+\r
+        S += '  <Sources>\n'\r
+        for item in self.Sources:\r
+            S += "\t" + item.SourceFile + '\n'\r
+\r
+        S += '  <LibraryClasses>\n'\r
+        S += '\t' + '\n\t'.join([Key for Key in self.LibraryClasses]) + '\n'\r
+\r
+        S += '  <Protocols>\n'\r
+        S += '\t' + '\n\t'.join(self.Protocols) + '\n'\r
+\r
+        S += '  <Ppis>\n'\r
+        S += '\t' + '\n\t'.join(self.Ppis) + '\n'\r
+\r
+        S += '  <Guids>\n'\r
+        S += '\t' + '\n\t'.join(self.Guids) + '\n'\r
+\r
+        S += '  <Includes>\n'\r
+        S += '\t' + '\n\t'.join(self.Includes) + '\n'\r
+\r
+        S += '  <Packages>\n'\r
+        S += '\t' + '\n\t'.join([str(P) for P in self.Packages]) + '\n'\r
+\r
+        S += '  <Pcds>\n'\r
+        for Name,Guid in self.Pcds.keys():\r
+            S += "\t%s.%s\n\t\t%s\n" % (Guid, Name, str(self.Pcds[Name,Guid]))\r
+\r
+        S += '  <BuildOptions\n'\r
+        S += '\t' + '\n\t'.join(self.BuildOptions.values()) + '\n'\r
+\r
+        S += '  <Depex>\n'\r
+        S += '\t' + str(self.Depex) + '\n'\r
+\r
+        S += '\n'\r
+        return S\r
+\r
+    ## XXX[key] = value\r
+    def __setitem__(self, key, value):\r
+        self.__dict__[self._PROPERTY_[key]] = value\r
+    ## value = XXX[key]\r
+    def __getitem__(self, key):\r
+        return self.__dict__[self._PROPERTY_[key]]\r
+    ## "in" test support\r
+    def __contains__(self, key):\r
+        return key in self._PROPERTY_\r
+\r
+    def _Clear(self):\r
+        self._Header_               = None\r
+        self._AutoGenVersion        = None\r
+        self._DescFilePath          = None\r
+        self._BaseName              = None\r
+        self._ModuleType            = None\r
+        self._ComponentType         = None\r
+        self._Guid                  = None\r
+        self._Version               = None\r
+        self._PcdIsDriver           = None\r
+        self._BinaryModule          = None\r
+        self._Shadow                = None\r
+        self._CustomMakefile        = None\r
+        self._Specification         = None\r
+        self._LibraryClass          = None\r
+        self._ModuleEntryPointList  = None\r
+        self._ModuleUnloadImageList = None\r
+        self._ConstructorList       = None\r
+        self._DestructorList        = None\r
+        self._Binaries              = None\r
+        self._Sources               = None\r
+        self._LibraryClasses        = None\r
+        self._Libraries             = None\r
+        self._Protocols             = None\r
+        self._Ppis                  = None\r
+        self._Guids                 = None\r
+        self._Includes              = None\r
+        self._Packages              = None\r
+        self._Pcds                  = None\r
+        self._BuildOptions          = None\r
+        self._Depex                 = None\r
+\r
+    def _GetArch(self):\r
+        return self._Arch\r
+\r
+    def _SetArch(self, Value):\r
+        if self._Arch == Value:\r
+            return\r
+        self._Arch = Value\r
+        self._Clear()\r
+\r
+    def _GetPlatform(self):\r
+        return self._Platform\r
+\r
+    def _SetPlatform(self, Value):\r
+        self._Platform = Value\r
+\r
+    def _GetHeaderInfo(self):\r
+        RecordList = self._Table.Query(MODEL_META_DATA_HEADER, Arch=self._Arch, Platform=self._Platform)\r
+        for Record in RecordList:\r
+            Name = Record[0]\r
+            if Name in self:\r
+                self[Name] = Record[1]\r
+            elif Name == 'EFI_SPECIFICATION_VERSION':\r
+                if self._Specification == None:\r
+                    self._Specification = sdict()\r
+                self._Specification[Name] = Record[1]\r
+            elif Name == 'EDK_RELEASE_VERSION':\r
+                if self._Specification == None:\r
+                    self._Specification = sdict()\r
+                self._Specification[Name] = Record[1]\r
+            elif Name == 'LIBRARY_CLASS':\r
+                if self._LibraryClass == None:\r
+                    self._LibraryClass = []\r
+                ValueList = GetSplitValueList(Record[1])\r
+                LibraryClass = ValueList[0]\r
+                if len(ValueList) > 1:\r
+                    SupModuleList = GetSplitValueList(ValueList[1], ' ')\r
+                else:\r
+                    SupModuleList = SUP_MODULE_LIST\r
+                self._LibraryClass.append(LibraryClassObject(LibraryClass, SupModuleList))\r
+            elif Name == 'ENTRY_POINT':\r
+                if self._ModuleEntryPointList == None:\r
+                    self._ModuleEntryPointList = []\r
+                self._ModuleEntryPointList.append(Record[1])\r
+            elif Name == 'UNLOAD_IMAGE':\r
+                if self._ModuleUnloadImageList == None:\r
+                    self._ModuleUnloadImageList = []\r
+                if Record[1] == '':\r
+                    continue\r
+                self._ModuleUnloadImageList.append(Record[1])\r
+            elif Name == 'CONSTRUCTOR':\r
+                if self._ConstructorList == None:\r
+                    self._ConstructorList = []\r
+                if Record[1] == '':\r
+                    continue\r
+                self._ConstructorList.append(Record[1])\r
+            elif Name == 'DESTRUCTOR':\r
+                if self._DestructorList == None:\r
+                    self._DestructorList = []\r
+                if Record[1] == '':\r
+                    continue\r
+                self._DestructorList.append(Record[1])\r
+        self._Header_ = 'DUMMY'\r
+\r
+    def _GetInfVersion(self):\r
+        if self._AutoGenVersion == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._AutoGenVersion == None:\r
+                self._AutoGenVersion = 0x00010000\r
+        return self._AutoGenVersion\r
+\r
+    def _GetBaseName(self):\r
+        if self._BaseName == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._BaseName == None:\r
+                self._BaseName = ''\r
+        return self._BaseName\r
+\r
+    def _GetModuleType(self):\r
+        if self._ModuleType == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._ModuleType == None:\r
+                self._ModuleType = 'BASE'\r
+        return self._ModuleType\r
+\r
+    def _GetComponentType(self):\r
+        if self._ComponentType == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._ComponentType == None:\r
+                self._ComponentType = ''\r
+        return self._ComponentType\r
+\r
+    def _GetFileGuid(self):\r
+        if self._Guid == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._Guid == None:\r
+                self._Guid = '00000000-0000-0000-000000000000'\r
+        return self._Guid\r
+\r
+    def _GetVersion(self):\r
+        if self._Version == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._Version == None:\r
+                self._Version = '0.0'\r
+        return self._Version\r
+\r
+    def _GetPcdIsDriver(self):\r
+        if self._PcdIsDriver == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._PcdIsDriver == None:\r
+                self._PcdIsDriver = ''\r
+        return self._PcdIsDriver\r
+\r
+    def _GetShadow(self):\r
+        if self._Shadow == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._Shadow != None and self._Shadow.upper() == 'TRUE':\r
+                self._Shadow = True\r
+            else:\r
+                self._Shadow = False\r
+        return self._Shadow\r
+\r
+    def _GetMakefile(self):\r
+        if self._CustomMakefile == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._CustomMakefile == None:\r
+                self._CustomMakefile = ''\r
+        return self._CustomMakefile\r
+\r
+    def _GetSpec(self):\r
+        if self._Specification == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._Specification == None:\r
+                self._Specification = {}\r
+        return self._Specification\r
+\r
+    def _GetLibraryClass(self):\r
+        if self._LibraryClass == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._LibraryClass == None:\r
+                self._LibraryClass = []\r
+        return self._LibraryClass\r
+\r
+    def _GetEntryPoint(self):\r
+        if self._ModuleEntryPointList == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._ModuleEntryPointList == None:\r
+                self._ModuleEntryPointList = []\r
+        return self._ModuleEntryPointList\r
+\r
+    def _GetUnloadImage(self):\r
+        if self._ModuleUnloadImageList == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._ModuleUnloadImageList == None:\r
+                self._ModuleUnloadImageList = []\r
+        return self._ModuleUnloadImageList\r
+\r
+    def _GetConstructor(self):\r
+        if self._ConstructorList == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._ConstructorList == None:\r
+                self._ConstructorList = []\r
+        return self._ConstructorList\r
+\r
+    def _GetDestructor(self):\r
+        if self._DestructorList == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._DestructorList == None:\r
+                self._DestructorList = []\r
+        return self._DestructorList\r
+                        \r
+    def _GetBinaryFiles(self):\r
+        if self._Binaries == None:\r
+            self._Binaries = []\r
+            RecordList = self._Table.Query(MODEL_EFI_BINARY_FILE, Arch=self._Arch, Platform=self._Platform)\r
+            for Record in RecordList:\r
+                FileType = Record[0]\r
+                File = NormPath(Record[1], self._Macros)\r
+                LineNo = Record[-1]\r
+                if not ValidFile(File, self._ModuleDir):\r
+                    EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
+                                    File=self.DescFilePath, Line=LineNo)\r
+                Target = Record[2]\r
+                FeatureFlag = Record[3]\r
+                self._Binaries.append(ModuleBinaryFileClass(File, FileType, Target, FeatureFlag, self._Arch))\r
+        return self._Binaries\r
+\r
+    def _GetSourceFiles(self):\r
+        if self._Sources == None:\r
+            self._Sources = []\r
+            RecordList = self._Table.Query(MODEL_EFI_SOURCE_FILE, Arch=self._Arch, Platform=self._Platform)\r
+            for Record in RecordList:\r
+                File = NormPath(Record[0], self._Macros)\r
+                LineNo = Record[-1]\r
+                if not ValidFile(File, self._ModuleDir):\r
+                    EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
+                                    File=self.DescFilePath, Line=LineNo)\r
+                ToolChainFamily = Record[1]\r
+                TagName = Record[2]\r
+                ToolCode = Record[3]\r
+                FeatureFlag = Record[4]\r
+                self._Sources.append(ModuleSourceFileClass(File, TagName, ToolCode, ToolChainFamily, FeatureFlag))\r
+        return self._Sources\r
+\r
+    def _GetLibraryClassUses(self):\r
+        if self._LibraryClasses == None:\r
+            self._LibraryClasses = sdict()\r
+            RecordList = self._Table.Query(MODEL_EFI_LIBRARY_CLASS, Arch=self._Arch, Platform=self._Platform)\r
+            for Record in RecordList:\r
+                Lib = Record[0]\r
+                Instance = Record[1]\r
+                if Instance != None and Instance != '':\r
+                    Instance = NormPath(Instance, self._Macros)\r
+                self._LibraryClasses[Lib] = Instance\r
+        return self._LibraryClasses\r
+\r
+    def _SetLibraryClassUses(self, Value):\r
+        self._LibraryClasses = Value\r
+\r
+    def _GetLibraryInstances(self):\r
+        if self._Libraries == None:\r
+            self._Libraries = []\r
+            RecordList = self._Table.Query(MODEL_EFI_LIBRARY_INSTANCE, Arch=self._Arch, Platform=self._Platform)\r
+            for Record in RecordList:\r
+                self._Libraries.append(Record[0])\r
+        return self._Libraries\r
+\r
+    def _GetProtocols(self):\r
+        if self._Protocols == None:\r
+            self._Protocols = []\r
+            RecordList = self._Table.Query(MODEL_EFI_PROTOCOL, Arch=self._Arch, Platform=self._Platform)\r
+            for Record in RecordList:\r
+                self._Protocols.append(Record[0])\r
+        return self._Protocols\r
+\r
+    def _GetPpis(self):\r
+        if self._Ppis == None:\r
+            self._Ppis = []\r
+            RecordList = self._Table.Query(MODEL_EFI_PPI, Arch=self._Arch, Platform=self._Platform)\r
+            for Record in RecordList:\r
+                self._Ppis.append(Record[0])\r
+        return self._Ppis\r
+\r
+    def _GetGuids(self):\r
+        if self._Guids == None:\r
+            self._Guids = []\r
+            RecordList = self._Table.Query(MODEL_EFI_GUID, Arch=self._Arch, Platform=self._Platform)\r
+            for Record in RecordList:\r
+                self._Guids.append(Record[0])\r
+        return self._Guids\r
+\r
+    def _GetIncludes(self):\r
+        if self._Includes == None:\r
+            self._Includes = []\r
+            RecordList = self._Table.Query(MODEL_EFI_INCLUDE, Arch=self._Arch, Platform=self._Platform)\r
+            for Record in RecordList:\r
+                File = NormPath(Record[0], self._Macros)\r
+                LineNo = Record[-1]\r
+                if not ValidFile(File, self._ModuleDir):\r
+                    EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
+                                    File=self.DescFilePath, Line=LineNo)\r
+                self._Includes.append(File)\r
+        return self._Includes\r
+\r
+    def _GetPackages(self):\r
+        if self._Packages == None:\r
+            self._Packages = []\r
+            RecordList = self._Table.Query(MODEL_META_DATA_PACKAGE, Arch=self._Arch, Platform=self._Platform)\r
+            for Record in RecordList:\r
+                File = NormPath(Record[0], self._Macros)\r
+                LineNo = Record[-1]\r
+                if not ValidFile(File):\r
+                    EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
+                                    File=self.DescFilePath, Line=LineNo)\r
+                Package = self._Db.BuildObject[File, MODEL_FILE_DEC, self._Arch]\r
+                self._Packages.append(Package)\r
+        return self._Packages\r
+\r
+    def _GetPcds(self):\r
+        if self._Pcds == None:\r
+            self._Pcds = {}\r
+            self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
+            self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
+            self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
+            self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))\r
+            self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
+        return self._Pcds\r
+\r
+    def _GetBuildOptions(self):\r
+        if self._BuildOptions == None:\r
+            self._BuildOptions = sdict()\r
+            RecordList = self._Table.Query(MODEL_META_DATA_BUILD_OPTION, Arch=self._Arch, Platform=self._Platform)\r
+            for Record in RecordList:\r
+                ToolChainFamily = Record[0]\r
+                ToolChain = Record[1]\r
+                Option = Record[2]\r
+                if (ToolChainFamily, ToolChain) not in self._BuildOptions:\r
+                    self._BuildOptions[ToolChainFamily, ToolChain] = Option\r
+                else:\r
+                    OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
+                    self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
+        return self._BuildOptions\r
+\r
+    def _GetDepex(self):\r
+        if self._Depex == None:\r
+            self._Depex = ''\r
+            RecordList = self._Table.Query(MODEL_EFI_DEPEX, Arch=self._Arch, Platform=self._Platform)\r
+            for Record in RecordList:\r
+                self._Depex += ' ' + Record[0]\r
+        return self._Depex\r
+\r
+    def _GetPcd(self, Type):\r
+        Pcds = {}\r
+        PcdDict = tdict(True, 4)\r
+        PcdSet = set()\r
+        RecordList = self._Table.Query(Type, Arch=self.Arch, Platform=self.Platform)\r
+        for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Dummy1, Dummy2 in RecordList:\r
+            PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = Setting\r
+            PcdSet.add((PcdCName, TokenSpaceGuid))\r
+\r
+        for PcdCName, TokenSpaceGuid in PcdSet:\r
+            ValueList = ['', '']\r
+            Setting = PcdDict[self.Arch, self.Platform, PcdCName, TokenSpaceGuid]\r
+            if Setting == None:\r
+                continue\r
+            TokenList = Setting.split(TAB_VALUE_SPLIT)\r
+            ValueList[0:len(TokenList)] = TokenList\r
+            DefaultValue = ValueList[0]\r
+            Pcd = PcdClassObject(\r
+                    PcdCName,\r
+                    TokenSpaceGuid,\r
+                    '',\r
+                    '',\r
+                    DefaultValue,\r
+                    '',\r
+                    '',\r
+                    {},\r
+                    True\r
+                    )\r
+            # get necessary info from package declaring this PCD\r
+            for Package in self.Packages:\r
+                # \r
+                # 'dynamic' in INF means its type is determined by platform;\r
+                # if platform doesn't give its type, use 'lowest' one in the \r
+                # following order, if any\r
+                # \r
+                #   "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"\r
+                # \r
+                PcdType = self._PCD_TYPE_STRING_[Type]\r
+                if Type in [MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:\r
+                    for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:\r
+                        if (PcdCName, TokenSpaceGuid, T) in Package.Pcds:\r
+                            PcdType = T\r
+                            break\r
+\r
+                if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds:\r
+                    PcdInPackage = Package.Pcds[PcdCName, TokenSpaceGuid, PcdType]\r
+                    Pcd.Type = PcdType\r
+                    Pcd.TokenValue = PcdInPackage.TokenValue\r
+                    Pcd.DatumType = PcdInPackage.DatumType\r
+                    Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize\r
+                    if Pcd.DefaultValue in [None, '']:\r
+                        Pcd.DefaultValue = PcdInPackage.DefaultValue\r
+                    break\r
+            else:\r
+                EdkLogger.error(\r
+                            'build', \r
+                            PARSER_ERROR,\r
+                            "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdCName, self.DescFilePath),\r
+                            ExtraData="\t%s" % '\n\t'.join([str(P) for P in self.Packages])\r
+                            )\r
+            Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
+        return Pcds\r
+\r
+    Arch                    = property(_GetArch, _SetArch)\r
+    Platform                = property(_GetPlatform, _SetPlatform)\r
+\r
+    AutoGenVersion          = property(_GetInfVersion)\r
+    BaseName                = property(_GetBaseName)\r
+    ModuleType              = property(_GetModuleType)\r
+    ComponentType           = property(_GetComponentType)\r
+    Guid                    = property(_GetFileGuid)\r
+    Version                 = property(_GetVersion)\r
+    PcdIsDriver             = property(_GetPcdIsDriver)\r
+    Shadow                  = property(_GetShadow)\r
+    CustomMakefile          = property(_GetMakefile)\r
+    Specification           = property(_GetSpec)\r
+    LibraryClass            = property(_GetLibraryClass)\r
+    ModuleEntryPointList    = property(_GetEntryPoint)\r
+    ModuleUnloadImageList   = property(_GetUnloadImage)\r
+    ConstructorList         = property(_GetConstructor)\r
+    DestructorList          = property(_GetDestructor)\r
+\r
+    Binaries                = property(_GetBinaryFiles)\r
+    Sources                 = property(_GetSourceFiles)\r
+    LibraryClasses          = property(_GetLibraryClassUses, _SetLibraryClassUses)\r
+    Libraries               = property(_GetLibraryInstances)\r
+    Protocols               = property(_GetProtocols)\r
+    Ppis                    = property(_GetPpis)\r
+    Guids                   = property(_GetGuids)\r
+    Includes                = property(_GetIncludes)\r
+    Packages                = property(_GetPackages)\r
+    Pcds                    = property(_GetPcds)\r
+    BuildOptions            = property(_GetBuildOptions)\r
+    Depex                   = property(_GetDepex)\r
+\r
+\r
+## Database\r
+#\r
+# This class defined the build databse\r
+# During the phase of initialization, the database will create all tables and\r
+# insert all records of table DataModel\r
+# \r
+# @param object:      Inherited from object class\r
+# @param DbPath:      A string for the path of the ECC database\r
+#\r
+# @var Conn:          Connection of the ECC database\r
+# @var Cur:           Cursor of the connection\r
+# @var TblDataModel:  Local instance for TableDataModel\r
+#\r
+class WorkspaceDatabase(object):\r
+    _FILE_TYPE_ = {\r
+        ".INF"  : MODEL_FILE_INF,\r
+        ".DEC"  : MODEL_FILE_DEC,\r
+        ".DSC"  : MODEL_FILE_DSC,\r
+        ".FDF"  : MODEL_FILE_FDF,\r
+    }\r
+\r
+    _FILE_PARSER_ = {\r
+        MODEL_FILE_INF  :   InfParser,\r
+        MODEL_FILE_DEC  :   DecParser,\r
+        MODEL_FILE_DSC  :   DscParser,\r
+        MODEL_FILE_FDF  :   None, #FdfParser,\r
+    }\r
+\r
+    _FILE_TABLE_ = {\r
+        MODEL_FILE_INF  :   ModuleTable,\r
+        MODEL_FILE_DEC  :   PackageTable,\r
+        MODEL_FILE_DSC  :   PlatformTable,\r
+    }\r
+\r
+    class BuildObjectFactory(object):\r
+        _GENERATOR_ = {\r
+            MODEL_FILE_INF  :   InfBuildData,\r
+            MODEL_FILE_DEC  :   DecBuildData,\r
+            MODEL_FILE_DSC  :   DscBuildData,\r
+            MODEL_FILE_FDF  :   None #FlashDefTable,\r
+        }\r
+\r
+        _CACHE_ = {}    # FilePath  : <object>\r
+\r
+        def __init__(self, WorkspaceDb):\r
+            self.WorkspaceDb = WorkspaceDb\r
+\r
+        # key = (FilePath, FileType, Arch='COMMON', Platform='COMMON')\r
+        def __getitem__(self, Key):\r
+            FilePath = Key[0]\r
+            FileType = Key[1]\r
+            if len(Key) > 2:\r
+                Arch = Key[2]\r
+            else:\r
+                Arch = 'COMMON'\r
+            Key = (FilePath, Arch)\r
+            if Key in self._CACHE_:\r
+                return self._CACHE_[Key]\r
+\r
+            self.WorkspaceDb[FilePath] = FileType\r
+            if FileType not in self._GENERATOR_:\r
+                return None\r
+\r
+            # create temp table for current file\r
+            Table = self.WorkspaceDb[FilePath]\r
+            BuildObject = self._GENERATOR_[FileType](\r
+                                    FilePath, \r
+                                    Table, \r
+                                    self.WorkspaceDb, \r
+                                    Arch, \r
+                                    self.WorkspaceDb._GlobalMacros\r
+                                    )\r
+            self._CACHE_[Key] = BuildObject\r
+            return BuildObject\r
+\r
+    class TransformObjectFactory:\r
+        def __init__(self, WorkspaceDb):\r
+            self.WorkspaceDb = WorkspaceDb\r
+\r
+        # key = FilePath\r
+        def __getitem__(self, Key):\r
+            pass\r
+\r
+    def __init__(self, DbPath, GlobalMacros={}):\r
+        self._GlobalMacros = GlobalMacros\r
+        self.Conn = sqlite3.connect(DbPath, isolation_level='DEFERRED')\r
+        self.Conn.execute("PRAGMA synchronous=OFF")\r
+        self.Conn.execute("PRAGMA temp_store=MEMORY")\r
+        self.Conn.execute("PRAGMA count_changes=OFF")\r
+        self.Conn.execute("PRAGMA cache_size=8192")\r
+        #self.Conn.execute("PRAGMA page_size=8192")\r
+\r
+        # to avoid non-ascii character conversion issue\r
+        self.Conn.text_factory = str\r
+        self.Cur = self.Conn.cursor()\r
+\r
+        self.TblDataModel = TableDataModel(self.Cur)\r
+        self.TblFile = TableFile(self.Cur)\r
+\r
+        self.BuildObject = WorkspaceDatabase.BuildObjectFactory(self)\r
+        self.TransformObject = WorkspaceDatabase.TransformObjectFactory(self)\r
+    \r
+    ## Initialize build database\r
+    #\r
+    # 1. Delete all old existing tables\r
+    # 2. Create new tables\r
+    # 3. Initialize table DataModel\r
+    #\r
+    def InitDatabase(self):\r
+        EdkLogger.verbose("\nInitialize ECC database started ...")\r
+        \r
+        #\r
+        # Create new tables\r
+        #\r
+        self.TblDataModel.Create(False)\r
+        self.TblFile.Create(False)\r
+        \r
+        #\r
+        # Initialize table DataModel\r
+        #\r
+        self.TblDataModel.InitTable()\r
+        EdkLogger.verbose("Initialize build database ... DONE!")\r
+\r
+    ## Query a table\r
+    #\r
+    # @param Table:  The instance of the table to be queried\r
+    #\r
+    def QueryTable(self, Table):\r
+        Table.Query()\r
+    \r
+    ## Close entire database\r
+    #\r
+    # Commit all first \r
+    # Close the connection and cursor\r
+    #\r
+    def Close(self):\r
+        self.Conn.commit()\r
+        self.Cur.close()\r
+        self.Conn.close()\r
+\r
+    def GetFileId(self, FilePath):\r
+        return self.TblFile.GetFileId(FilePath)\r
+\r
+    def GetFileType(self, FileId):\r
+        return self.TblFile.GetFileType(FileId)\r
+\r
+    def GetTimeStamp(self, FileId):\r
+        return self.TblFile.GetFileTimeStamp(FileId)\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
+            return False\r
+        return True\r
+\r
+    def GetTableName(self, FileType, FileId):\r
+        return "_%s_%s" % (FileType, FileId)\r
+\r
+    ## TRICK: \r
+    # Key = FilePath\r
+    # Value = FileType\r
+    def __setitem__(self, FilePath, FileType):\r
+        FileId = self.GetFileId(FilePath)\r
+        if FileId != None:\r
+            TableName = self.GetTableName(FileType, FileId)\r
+            if self.CheckIntegrity(TableName):\r
+                TimeStamp = os.stat(FilePath)[8]\r
+                if TimeStamp == self.GetTimeStamp(FileId):\r
+                    return\r
+        else:\r
+            FileId = self.TblFile.InsertFile(FilePath, FileType)\r
+            TableName = self.GetTableName(FileType, FileId)\r
+\r
+        FileTable = self._FILE_TABLE_[FileType](self.Cur, TableName, FileId)\r
+        FileTable.Create()\r
+        Parser = self._FILE_PARSER_[FileType](FilePath, FileId, FileType, FileTable)\r
+        Parser.Start()\r
+\r
+    ## Return a temp table containing all content of the given file\r
+    # \r
+    def __getitem__(self, FileInfo):\r
+        if type(FileInfo) == type(''):\r
+            FileId = self.GetFileId(FileInfo)\r
+        else:\r
+            FileId = FileInfo\r
+        if FileId == None:\r
+            return None\r
+        FileType = self.GetFileType(FileId)\r
+        if FileType not in self._FILE_TABLE_:\r
+            return None\r
+\r
+        TableName = "_%s_%s" % (FileType, FileId)\r
+        FileTable = self._FILE_TABLE_[FileType](self.Cur, TableName, FileId)\r
+        return FileTable\r
+\r
+    ## Resolve cross-references between platfor, packages and modules\r
+    def _PostFix(self):\r
+        pass\r
+\r
+##\r
+#\r
+# This acts like the main() function for the script, unless it is 'import'ed into another\r
+# script.\r
+#\r
+if __name__ == '__main__':\r
+    EdkLogger.Initialize()\r
+    EdkLogger.SetLevel(EdkLogger.DEBUG_0)\r
+    \r
+    Db = WorkspaceDatabase(DATABASE_PATH)\r
+    Db.InitDatabase()\r
+    Db.QueryTable(Db.TblDataModel)   \r
+    Db.QueryTable(Db.TblFile)\r
+    Db.QueryTable(Db.TblDsc)\r
+    Db.Close()\r
+    
\ No newline at end of file
diff --git a/Source/Python/Workspace/__init__.py b/Source/Python/Workspace/__init__.py
new file mode 100644 (file)
index 0000000..e69de29