1. Add -m and -s to support only scanning meta-data files or source code files
[people/mcb30/basetools.git] / Source / Python / Common / DecClassObject.py
index 4337f78..b95ff62 100644 (file)
@@ -20,7 +20,32 @@ from DataType import *
 from Identification import *\r
 from Dictionary import *\r
 from CommonDataClass.PackageClass import *\r
+from CommonDataClass.CommonClass import PcdClass\r
 from BuildToolError import *\r
+from Table.TableDec import TableDec\r
+import Database\r
+from Parsing import *\r
+import GlobalData\r
+\r
+#\r
+# Global variable\r
+#\r
+Section = {TAB_UNKNOWN.upper() : MODEL_UNKNOWN,\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_COMPONENTS.upper() : MODEL_META_DATA_COMPONENT,\r
+           TAB_GUIDS.upper() : MODEL_EFI_GUID,\r
+           TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,\r
+           TAB_PPIS.upper() : MODEL_EFI_PPI,\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_EX_NULL.upper() : MODEL_PCD_DYNAMIC_EX,\r
+           TAB_PCDS_DYNAMIC_NULL.upper() : MODEL_PCD_DYNAMIC,\r
+           TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION\r
+           }\r
+\r
 \r
 ## DecObject\r
 #\r
@@ -32,56 +57,6 @@ class DecObject(object):
     def __init__(self):\r
         object.__init__()\r
 \r
-## DecDefines\r
-#\r
-# This class defined basic Defines used in Dec object\r
-# \r
-# @param DecObject:        Inherited from DecObject class\r
-#\r
-# @var DefinesDictionary:  To store value for DefinesDictionary \r
-#\r
-class DecDefines(DecObject):\r
-    def __init__(self):\r
-        self.DefinesDictionary = {\r
-            #\r
-            # Required Fields\r
-            #\r
-            TAB_DEC_DEFINES_DEC_SPECIFICATION           : [''],\r
-            TAB_DEC_DEFINES_PACKAGE_NAME                : [''],\r
-            TAB_DEC_DEFINES_PACKAGE_GUID                : [''],\r
-            TAB_DEC_DEFINES_PACKAGE_VERSION             : ['']\r
-        }\r
-\r
-## DecContents\r
-#\r
-# This class defined basic Contents used in Dec object\r
-# \r
-# @param DecObject:            Inherited from DecObject class\r
-#\r
-# @var Includes:               To store value for Includes\r
-# @var Guids:                  To store value for Guids\r
-# @var Protocols:              To store value for Protocols\r
-# @var Ppis:                   To store value for Ppis\r
-# @var LibraryClasses:         To store value for LibraryClasses\r
-# @var PcdsFixedAtBuild:       To store value for PcdsFixedAtBuild\r
-# @var PcdsPatchableInModule:  To store value for PcdsPatchableInModule\r
-# @var PcdsFeatureFlag:        To store value for PcdsFeatureFlag\r
-# @var PcdsDynamic:            To store value for PcdsDynamic\r
-# @var PcdsDynamicEx:          To store value for PcdsDynamicEx\r
-#\r
-class DecContents(DecObject):\r
-    def __init__(self):\r
-        self.Includes = []\r
-        self.Guids = []\r
-        self.Protocols = []\r
-        self.Ppis = []\r
-        self.LibraryClasses = []\r
-        self.PcdsFixedAtBuild = []\r
-        self.PcdsPatchableInModule = []\r
-        self.PcdsFeatureFlag = []\r
-        self.PcdsDynamic = []\r
-        self.PcdsDynamicEx = []\r
-\r
 ## Dec\r
 #\r
 # This class defined the structure used in Dec object\r
@@ -107,34 +82,41 @@ class DecContents(DecObject):
 # @var KeyList:             To store value for KeyList, a list for all Keys used in Dec\r
 #\r
 class Dec(DecObject):\r
-    def __init__(self, Filename = None, IsMergeAllArches = False, IsToPackage = False, WorkspaceDir = None):\r
+    def __init__(self, Filename = None, IsToDatabase = False, IsToPackage = False, WorkspaceDir = None, Database = None, SupArchList = DataType.ARCH_LIST):\r
         self.Identification = Identification()\r
-        self.Defines = DecDefines()\r
-        self.UserExtensions = ''\r
         self.Package = PackageClass()\r
+        self.UserExtensions = ''\r
         self.WorkspaceDir = WorkspaceDir\r
+        self.SupArchList = SupArchList\r
+        self.IsToDatabase = IsToDatabase\r
         \r
-        self.Contents = {}\r
-        for Arch in DataType.ARCH_LIST_FULL:\r
-            self.Contents[Arch] = DecContents()\r
-        \r
+        self.Cur = Database.Cur\r
+        self.TblFile = Database.TblFile\r
+        self.TblDec = Database.TblDec\r
+        self.FileID = -1\r
+\r
         self.KeyList = [\r
             TAB_INCLUDES, TAB_GUIDS, TAB_PROTOCOLS, TAB_PPIS, TAB_LIBRARY_CLASSES, \\r
             TAB_PCDS_FIXED_AT_BUILD_NULL, TAB_PCDS_PATCHABLE_IN_MODULE_NULL, TAB_PCDS_FEATURE_FLAG_NULL, \\r
-            TAB_PCDS_DYNAMIC_NULL, TAB_PCDS_DYNAMIC_EX_NULL\r
+            TAB_PCDS_DYNAMIC_NULL, TAB_PCDS_DYNAMIC_EX_NULL, TAB_DEC_DEFINES\r
         ]\r
-    \r
         #\r
-        # Load Dec file if filename is not None\r
+        # Upper all KEYs to ignore case sensitive when parsing\r
         #\r
-        if Filename != None:\r
-            self.LoadDecFile(Filename)\r
+        self.KeyList = map(lambda c: c.upper(), self.KeyList)\r
+        \r
+        #\r
+        # Init RecordSet\r
+        #\r
+        self.RecordSet = {}        \r
+        for Key in self.KeyList:\r
+            self.RecordSet[Section[Key]] = []\r
         \r
         #\r
-        # Merge contents of Dec from all arches if IsMergeAllArches is True\r
+        # Load Dec file if filename is not None\r
         #\r
-        if IsMergeAllArches:\r
-            self.MergeAllArches()\r
+        if Filename != None:\r
+            self.LoadDecFile(Filename)\r
         \r
         #\r
         # Transfer to Package Object if IsToPackage is True\r
@@ -142,32 +124,6 @@ class Dec(DecObject):
         if IsToPackage:\r
             self.DecToPackage()\r
     \r
-    ## Parse Dec file\r
-    #\r
-    # Go through input lines one by one to find the value defined in Key section.\r
-    # Save them to KeyField\r
-    #\r
-    # @param Lines:     Lines need to be parsed\r
-    # @param Key:       The key value of the section to be located\r
-    # @param KeyField:  To save the found contents\r
-    #\r
-    def ParseDec(self, Lines, Key, KeyField):\r
-        newKey = SplitModuleType(Key)\r
-        if newKey[0].upper().find(DataType.TAB_LIBRARY_CLASSES.upper()) != -1:\r
-            GetLibraryClassesWithModuleType(Lines, Key, KeyField, TAB_COMMENT_SPLIT)\r
-        else:\r
-            GetMultipleValuesOfKeyFromLines(Lines, Key, KeyField, TAB_COMMENT_SPLIT)\r
-\r
-    ## Merge contents of Dec from all arches\r
-    #\r
-    # Find the contents defined in all arches and merge them to all\r
-    #   \r
-    def MergeAllArches(self):\r
-        for Key in self.KeyList:\r
-            for Arch in DataType.ARCH_LIST:\r
-                Command = "self.Contents[Arch]." + Key + ".extend(" + "self.Contents['" + DataType.TAB_ARCH_COMMON + "']." + Key + ")"\r
-                eval(Command)\r
-\r
     ## Load Dec file\r
     #\r
     # Load the file if it exists\r
@@ -175,36 +131,120 @@ class Dec(DecObject):
     # @param Filename:  Input value for filename of Dec file\r
     #\r
     def LoadDecFile(self, Filename):\r
-        (Filepath, Name) = os.path.split(Filename)\r
-        self.Identification.FileName = Name\r
+        #\r
+        # Insert a record for file\r
+        #\r
+        Filename = NormPath(Filename)\r
         self.Identification.FileFullPath = Filename\r
-        self.Identification.FileRelativePath = Filepath\r
+        (self.Identification.FileRelativePath, self.Identification.FileName) = os.path.split(Filename)\r
+        self.FileID = self.TblFile.InsertFile(Filename, MODEL_FILE_DEC)\r
+        \r
+        #\r
+        # Init DecTable\r
+        #\r
+        #self.TblDec.Table = "Dec%s" % self.FileID\r
+        #self.TblDec.Create()\r
+        \r
+        #\r
+        # Init common datas\r
+        #\r
+        IfDefList, SectionItemList, CurrentSection, ArchList, ThirdList, IncludeFiles = \\r
+        [], [], TAB_UNKNOWN, [], [], []\r
+        LineNo = 0\r
+        \r
+        #\r
+        # Parse file content\r
+        #\r
+        IsFindBlockComment = False\r
+        ReservedLine = ''\r
+        for Line in open(Filename, 'r'):\r
+            LineNo = LineNo + 1\r
+            #\r
+            # Remove comment block\r
+            #\r
+            if Line.find(TAB_COMMENT_R8_START) > -1:\r
+                ReservedLine = GetSplitValueList(Line, TAB_COMMENT_R8_START, 1)[0]\r
+                IsFindBlockComment = True\r
+            if Line.find(TAB_COMMENT_R8_END) > -1:\r
+                Line = ReservedLine + GetSplitValueList(Line, TAB_COMMENT_R8_END, 1)[1]\r
+                ReservedLine = ''\r
+                IsFindBlockComment = False\r
+            if IsFindBlockComment:\r
+                continue\r
+\r
+            #\r
+            # Remove comments at tail and remove spaces again\r
+            #\r
+            Line = CleanString(Line)\r
+            if Line == '':\r
+                continue\r
+            \r
+            #\r
+            # Find a new section tab\r
+            # First insert previous section items\r
+            # And then parse the content of the new section\r
+            #\r
+            if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END):\r
+                #\r
+                # Insert items data of previous section\r
+                #\r
+                Model = Section[CurrentSection.upper()]\r
+                InsertSectionItemsIntoDatabase(self.TblDec, self.FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, self.RecordSet)\r
+\r
+                #\r
+                # Parse the new section\r
+                #\r
+                SectionItemList = []\r
+                ArchList = []\r
+                ThirdList = []\r
+                \r
+                CurrentSection = ''\r
+                LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT)\r
+                for Item in LineList:\r
+                    ItemList = GetSplitValueList(Item, TAB_SPLIT)\r
+                    if CurrentSection == '':\r
+                        CurrentSection = ItemList[0]\r
+                    else:\r
+                        if CurrentSection != ItemList[0]:\r
+                            EdkLogger.error("Parser", PARSER_ERROR, "Different section names '%s' and '%s' are found in one section definition, this is not allowed." % (CurrentSection, ItemList[0]), File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError)\r
+                    if CurrentSection.upper() not in self.KeyList:\r
+                        RaiseParserError(Line, CurrentSection, Filename, '', LineNo)\r
+                    ItemList.append('')\r
+                    ItemList.append('')\r
+                    if len(ItemList) > 5:\r
+                        RaiseParserError(Line, CurrentSection, Filename, '', LineNo)\r
+                    else:\r
+                        if ItemList[1] != '' and ItemList[1].upper() not in ARCH_LIST_FULL:\r
+                            EdkLogger.error("Parser", PARSER_ERROR, "Invalid Arch definition '%s' found" % ItemList[1], File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError)\r
+                        ArchList.append(ItemList[1].upper())\r
+                        ThirdList.append(ItemList[2])\r
+\r
+                continue\r
+            \r
+            #\r
+            # Not in any defined section\r
+            #\r
+            if CurrentSection == TAB_UNKNOWN:\r
+                ErrorMsg = "%s is not in any defined section" % Line\r
+                EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError)\r
+\r
+            #\r
+            # Add a section item\r
+            #\r
+            SectionItemList.append([Line, LineNo])\r
+            # End of parse\r
+        #End of For\r
+        \r
+        #\r
+        # Insert items data of last section\r
+        #\r
+        Model = Section[CurrentSection.upper()]\r
+        InsertSectionItemsIntoDatabase(self.TblDec, self.FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, self.RecordSet)\r
         \r
-        F = open(Filename, 'r').read()\r
-        PreCheck(Filename, F, self.KeyList)\r
-        Sects = F.split(DataType.TAB_SECTION_START)\r
-        for Sect in Sects:\r
-            TabList = GetSplitValueList(Sect.split(TAB_SECTION_END, 1)[0], DataType.TAB_COMMA_SPLIT)\r
-            for Tab in TabList:\r
-                if Tab.upper() == TAB_INF_DEFINES.upper():\r
-                    GetSingleValueOfKeyFromLines(Sect, self.Defines.DefinesDictionary, TAB_COMMENT_SPLIT, TAB_EQUAL_SPLIT, True, TAB_VALUE_SPLIT)\r
-                    continue\r
-                for Arch in DataType.ARCH_LIST_FULL + [DataType.TAB_ARCH_NULL]:\r
-                    for Key in self.KeyList:\r
-                        if Arch != DataType.TAB_ARCH_NULL:\r
-                            Target = (Key + DataType.TAB_SPLIT + Arch).upper()\r
-                        else:\r
-                            Target = Key.upper()\r
-                        if Tab.upper() == Target:\r
-                            if Arch != DataType.TAB_ARCH_NULL:\r
-                                Command = 'self.ParseDec(Sect, Tab, self.Contents[Arch].' + Key + ')'\r
-                                eval(Command)\r
-                                continue\r
-                            else:\r
-                                Command = "self.ParseDec(Sect, Tab, self.Contents['" + DataType.TAB_ARCH_COMMON + "']." + Key + ')'\r
-                                eval(Command)\r
-                                continue\r
-        #EndFor\r
+        #\r
+        # Replace all DEFINE macros with its actual values\r
+        #\r
+        ParseDefineMacro2(self.TblDec, self.RecordSet, GlobalData.gGlobalDefines)\r
 \r
     ## Transfer to Package Object\r
     # \r
@@ -212,130 +252,251 @@ class Dec(DecObject):
     #\r
     def DecToPackage(self):\r
         #\r
-        # Get value for Header\r
+        # Init global information for the file\r
+        #\r
+        ContainerFile = self.Identification.FileFullPath\r
+        \r
+        #\r
+        # Generate Package Header\r
         #\r
-        self.Package.Header.Name = self.Defines.DefinesDictionary[TAB_DEC_DEFINES_PACKAGE_NAME][0]\r
-        self.Package.Header.Guid = self.Defines.DefinesDictionary[TAB_DEC_DEFINES_PACKAGE_GUID][0]\r
-        self.Package.Header.Version = self.Defines.DefinesDictionary[TAB_DEC_DEFINES_PACKAGE_VERSION][0]\r
-        self.Package.Header.FileName = self.Identification.FileName\r
-        self.Package.Header.FullPath = self.Identification.FileFullPath\r
-        self.Package.Header.DecSpecification = self.Defines.DefinesDictionary[TAB_DEC_DEFINES_DEC_SPECIFICATION][0]\r
-        File = self.Package.Header.FullPath\r
+        self.GenPackageHeader(ContainerFile)\r
         \r
         #\r
-        # Includes\r
-        # <IncludeDirectory>\r
+        # Generate Includes\r
+        #\r
+        self.GenIncludes(ContainerFile)\r
+\r
+        #\r
+        # Generate Guids\r
+        #\r
+        self.GenGuidProtocolPpis(DataType.TAB_GUIDS, ContainerFile)\r
+\r
         #\r
+        # Generate Protocols\r
+        #\r
+        self.GenGuidProtocolPpis(DataType.TAB_PROTOCOLS, ContainerFile)\r
+\r
+        #\r
+        # Generate Ppis\r
+        #\r
+        self.GenGuidProtocolPpis(DataType.TAB_PPIS, ContainerFile)\r
+        \r
+        #\r
+        # Generate LibraryClasses\r
+        #\r
+        self.GenLibraryClasses(ContainerFile)\r
+        \r
+        #\r
+        # Generate Pcds\r
+        #\r
+        self.GenPcds(ContainerFile)\r
+    \r
+    ## Get Package Header\r
+    #\r
+    # Gen Package Header of Dec as <Key> = <Value>\r
+    #\r
+    # @param ContainerFile: The Dec file full path \r
+    #\r
+    def GenPackageHeader(self, ContainerFile):\r
+        EdkLogger.debug(2, "Generate PackageHeader ...")\r
+        #\r
+        # Update all defines item in database\r
+        #\r
+        RecordSet = self.RecordSet[MODEL_META_DATA_HEADER]\r
+        for Record in RecordSet:\r
+            ValueList = GetSplitValueList(Record[0], TAB_EQUAL_SPLIT)\r
+            if len(ValueList) != 2:\r
+                RaiseParserError(Record[0], 'Defines', ContainerFile, '<Key> = <Value>', Record[2])\r
+            ID, Value1, Value2, Arch, LineNo = Record[3], ValueList[0], ValueList[1], Record[1], Record[2]\r
+            SqlCommand = """update %s set Value1 = '%s', Value2 = '%s'\r
+                            where ID = %s""" % (self.TblDec.Table, ConvertToSqlString2(Value1), ConvertToSqlString2(Value2), ID)\r
+            self.TblDec.Exec(SqlCommand)\r
+        \r
+        #\r
+        # Get detailed information\r
+        #\r
+        for Arch in self.SupArchList:\r
+            PackageHeader = PackageHeaderClass()\r
+            \r
+            PackageHeader.Name = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_PACKAGE_NAME, Arch, self.FileID)[0]\r
+            PackageHeader.Guid = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_PACKAGE_GUID, Arch, self.FileID)[0]\r
+            PackageHeader.Version = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_PACKAGE_VERSION, Arch, self.FileID)[0]\r
+            PackageHeader.FileName = self.Identification.FileName\r
+            PackageHeader.FullPath = self.Identification.FileFullPath\r
+            PackageHeader.DecSpecification = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_DEC_SPECIFICATION, Arch, self.FileID)[0]\r
+            \r
+            self.Package.Header[Arch] = PackageHeader\r
+    \r
+    ## GenIncludes\r
+    #\r
+    # Gen Includes of Dec\r
+    # \r
+    #\r
+    # @param ContainerFile: The Dec file full path \r
+    #\r
+    def GenIncludes(self, ContainerFile):\r
+        EdkLogger.debug(2, "Generate %s ..." % TAB_INCLUDES)\r
         Includes = {}\r
-        for Arch in DataType.ARCH_LIST:\r
-            for Item in self.Contents[Arch].Includes:\r
-                MergeArches(Includes, Item, Arch)\r
+        #\r
+        # Get all Includes\r
+        #\r
+        RecordSet = self.RecordSet[MODEL_EFI_INCLUDE]\r
+        \r
+        #\r
+        # Go through each arch\r
+        #\r
+        for Arch in self.SupArchList:\r
+            for Record in RecordSet:\r
+                if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:\r
+                    MergeArches(Includes, Record[0], Arch)\r
+\r
         for Key in Includes.keys():\r
             Include = IncludeClass()\r
-            Include.FilePath = Key\r
+            Include.FilePath = NormPath(Key)\r
             Include.SupArchList = Includes[Key]\r
             self.Package.Includes.append(Include)\r
-            \r
+    \r
+    ## GenPpis\r
+    #\r
+    # Gen Ppis of Dec\r
+    # <CName>=<GuidValue>\r
+    #\r
+    # @param ContainerFile: The Dec file full path \r
+    #\r
+    def GenGuidProtocolPpis(self, Type, ContainerFile):\r
+        EdkLogger.debug(2, "Generate %s ..." % Type)\r
+        Lists = {}\r
         #\r
-        # Guids\r
-        # <CName>=<GuidValue>\r
-        #\r
-        Guids = {}\r
-        for Arch in DataType.ARCH_LIST:\r
-            for Item in self.Contents[Arch].Guids:\r
-                List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT)\r
-                if len(List) != 2:\r
-                    RaiseParserError(Item, 'Guids', File, '<CName>=<GuidValue>')\r
-                else:\r
-                    MergeArches(Guids, (List[0], List[1]), Arch)\r
-        for Key in Guids.keys():\r
-            Guid = GuidClass()\r
-            Guid.CName = Key[0]\r
-            Guid.Guid = Key[1]\r
-            Guid.SupArchList = Guids[Key]\r
-            self.Package.GuidDeclarations.append(Guid)\r
-\r
-        # \r
-        # Protocols\r
-        # <CName>=<GuidValue>\r
-        #\r
-        Protocols = {}\r
-        for Arch in DataType.ARCH_LIST:\r
-            for Item in self.Contents[Arch].Protocols:\r
-                List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT)\r
-                if len(List) != 2:\r
-                    RaiseParserError(Item, 'Protocols', File, '<CName>=<GuidValue>')\r
-                else:\r
-                    MergeArches(Protocols, (List[0], List[1]), Arch)\r
-        for Key in Protocols.keys():\r
-            Protocol = ProtocolClass()\r
-            Protocol.CName = Key[0]\r
-            Protocol.Guid = Key[1]\r
-            Protocol.SupArchList = Protocols[Key]\r
-            self.Package.ProtocolDeclarations.append(Protocol)\r
+        # Get all Items\r
+        #\r
+        RecordSet = self.RecordSet[Section[Type.upper()]]\r
         \r
         #\r
-        # Ppis\r
-        # <CName>=<GuidValue>\r
-        #\r
-        Ppis = {}\r
-        for Arch in DataType.ARCH_LIST:\r
-            for Item in self.Contents[Arch].Ppis:\r
-                List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT)\r
-                if len(List) != 2:\r
-                    RaiseParserError(Item, 'Ppis', File, '<CName>=<GuidValue>')\r
-                else:\r
-                    MergeArches(Ppis, (List[0], List[1]), Arch)\r
-        for Key in Ppis.keys():\r
-            Ppi = PpiClass()\r
-            Ppi.CName = Key[0]\r
-            Ppi.Guid = Key[1]\r
-            Ppi.SupArchList = Ppis[Key]\r
-            self.Package.PpiDeclarations.append(Ppi)\r
+        # Go through each arch\r
+        #\r
+        for Arch in self.SupArchList:\r
+            for Record in RecordSet:\r
+                if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:\r
+                    (Name, Value) = GetGuidsProtocolsPpisOfDec(Record[0], Type, ContainerFile, Record[2])\r
+                    MergeArches(Lists, (Name, Value), Arch)\r
+                    if self.IsToDatabase:\r
+                        SqlCommand = """update %s set Value1 = '%s', Value2 = '%s'\r
+                                        where ID = %s""" % (self.TblDec.Table, ConvertToSqlString2(Name), ConvertToSqlString2(Value), Record[3])\r
+                        self.TblDec.Exec(SqlCommand)\r
+        \r
+        ListMember = None\r
+        if Type == TAB_GUIDS:\r
+            ListMember = self.Package.GuidDeclarations\r
+        elif Type == TAB_PROTOCOLS:\r
+            ListMember = self.Package.ProtocolDeclarations\r
+        elif Type == TAB_PPIS:\r
+            ListMember = self.Package.PpiDeclarations\r
+        \r
+        for Key in Lists.keys():\r
+            ListClass = GuidProtocolPpiCommonClass()\r
+            ListClass.CName = Key[0]\r
+            ListClass.Guid = Key[1]\r
+            ListClass.SupArchList = Lists[Key]\r
+            ListMember.append(ListClass)\r
             \r
+    \r
+    ## GenLibraryClasses\r
+    #\r
+    # Gen LibraryClasses of Dec\r
+    # <CName>=<GuidValue>\r
+    #\r
+    # @param ContainerFile: The Dec file full path \r
+    #\r
+    def GenLibraryClasses(self, ContainerFile):\r
+        EdkLogger.debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES)\r
+        LibraryClasses = {}\r
         #\r
-        # LibraryClasses\r
-        # <LibraryClassName>|<LibraryClassInstance>\r
+        # Get all Guids\r
         #\r
-        LibraryClasses = {}\r
-        for Arch in DataType.ARCH_LIST:\r
-            for Item in self.Contents[Arch].LibraryClasses:\r
-                List = GetSplitValueList(Item[0], DataType.TAB_VALUE_SPLIT)\r
-                if len(List) != 2:\r
-                    RaiseParserError(Item[0], 'LibraryClasses', File, '<LibraryClassName>|<LibraryClassInstanceFilename>')\r
-                else:\r
-                    CheckFileExist(self.WorkspaceDir, os.path.join(self.Identification.FileRelativePath, List[1]), File, 'LibraryClasses', Item[0])\r
-                    if Item[1] == ['']:\r
-                            Item[1] = DataType.SUP_MODULE_LIST\r
-                    MergeArches(LibraryClasses, (List[0], List[1]) + tuple(Item[1]), Arch)\r
+        RecordSet = self.RecordSet[MODEL_EFI_LIBRARY_CLASS]\r
+        \r
+        #\r
+        # Go through each arch\r
+        #\r
+        for Arch in self.SupArchList:\r
+            for Record in RecordSet:\r
+                if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:\r
+                    List = GetSplitValueList(Record[0], DataType.TAB_VALUE_SPLIT)\r
+                    if len(List) != 2:\r
+                        RaiseParserError(Record[0], 'LibraryClasses', ContainerFile, '<LibraryClassName>|<LibraryClassInstanceFilename>', Record[2])\r
+                    else:\r
+                        CheckFileExist(self.Identification.FileRelativePath, List[1], ContainerFile, 'LibraryClasses', Record[0])\r
+                    MergeArches(LibraryClasses, (List[0], List[1]), Arch)\r
+                    if self.IsToDatabase:\r
+                        SqlCommand = """update %s set Value1 = '%s', Value2 = '%s', Value3 = '%s'\r
+                                        where ID = %s""" % (self.TblDec.Table, ConvertToSqlString2(List[0]), ConvertToSqlString2(List[1]), SUP_MODULE_LIST_STRING, Record[3])\r
+                        self.TblDec.Exec(SqlCommand)\r
+\r
+        \r
         for Key in LibraryClasses.keys():\r
             LibraryClass = LibraryClassClass()\r
             LibraryClass.LibraryClass = Key[0]\r
-            LibraryClass.RecommendedInstance = Key[1]\r
-            LibraryClass.SupModuleList = list(Key[2:])\r
+            LibraryClass.RecommendedInstance = NormPath(Key[1])\r
+            LibraryClass.SupModuleList = SUP_MODULE_LIST\r
             LibraryClass.SupArchList = LibraryClasses[Key]\r
             self.Package.LibraryClassDeclarations.append(LibraryClass)\r
+    \r
+    ## GenPcds\r
+    #\r
+    # Gen Pcds of Dec\r
+    # <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>\r
+    #\r
+    # @param ContainerFile: The Dec file full path \r
+    #\r
+    def GenPcds(self, ContainerFile):\r
+        EdkLogger.debug(2, "Generate %s ..." % TAB_PCDS)\r
+        Pcds = {}\r
+        PcdToken = {}\r
+        #\r
+        # Get all Guids\r
+        #\r
+        RecordSet1 = self.RecordSet[MODEL_PCD_FIXED_AT_BUILD]\r
+        RecordSet2 = self.RecordSet[MODEL_PCD_PATCHABLE_IN_MODULE]\r
+        RecordSet3 = self.RecordSet[MODEL_PCD_FEATURE_FLAG]\r
+        RecordSet4 = self.RecordSet[MODEL_PCD_DYNAMIC_EX]\r
+        RecordSet5 = self.RecordSet[MODEL_PCD_DYNAMIC]\r
         \r
         #\r
-        # Pcds\r
-        # <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>\r
+        # Go through each arch\r
         #\r
-        Pcds = {}\r
-        for Arch in DataType.ARCH_LIST:\r
-            for Item in self.Contents[Arch].PcdsFixedAtBuild:\r
-                MergeArches(Pcds, self.GetPcdOfDec(Item, TAB_PCDS_FIXED_AT_BUILD, File), Arch)\r
-            \r
-            for Item in self.Contents[Arch].PcdsPatchableInModule:\r
-                MergeArches(Pcds, self.GetPcdOfDec(Item, TAB_PCDS_PATCHABLE_IN_MODULE, File), Arch)\r
-            \r
-            for Item in self.Contents[Arch].PcdsFeatureFlag:\r
-                MergeArches(Pcds, self.GetPcdOfDec(Item, TAB_PCDS_FEATURE_FLAG, File), Arch)\r
-            \r
-            for Item in self.Contents[Arch].PcdsDynamicEx:\r
-                MergeArches(Pcds, self.GetPcdOfDec(Item, TAB_PCDS_DYNAMIC_EX, File), Arch)\r
-            \r
-            for Item in self.Contents[Arch].PcdsDynamic:\r
-                MergeArches(Pcds, self.GetPcdOfDec(Item, TAB_PCDS_DYNAMIC, File), Arch)\r
+        for Arch in self.SupArchList:\r
+            for Record in RecordSet1:\r
+                if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:\r
+                    (TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_FIXED_AT_BUILD, ContainerFile, Record[2])\r
+                    MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch)\r
+                    PcdToken[Record[3]] = (TokenGuidCName, TokenName)\r
+            for Record in RecordSet2:\r
+                if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:\r
+                    (TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_PATCHABLE_IN_MODULE, ContainerFile, Record[2])\r
+                    MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch)\r
+                    PcdToken[Record[3]] = (TokenGuidCName, TokenName)\r
+            for Record in RecordSet3:\r
+                if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:\r
+                    (TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_FEATURE_FLAG, ContainerFile, Record[2])\r
+                    MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch)\r
+                    PcdToken[Record[3]] = (TokenGuidCName, TokenName)\r
+            for Record in RecordSet4:\r
+                if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:\r
+                    (TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_DYNAMIC_EX, ContainerFile, Record[2])\r
+                    MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch)\r
+                    PcdToken[Record[3]] = (TokenGuidCName, TokenName)\r
+            for Record in RecordSet5:\r
+                if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:\r
+                    (TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_DYNAMIC, ContainerFile, Record[2])\r
+                    MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch)\r
+                    PcdToken[Record[3]] = (TokenGuidCName, TokenName)\r
+        #\r
+        # Update to database\r
+        #\r
+        if self.IsToDatabase:\r
+            for Key in PcdToken.keys():\r
+                SqlCommand = """update %s set Value2 = '%s' where ID = %s""" % (self.TblDec.Table, ".".join((PcdToken[Key][0], PcdToken[Key][1])), Key)\r
+                self.TblDec.Exec(SqlCommand)\r
 \r
         for Key in Pcds.keys():\r
             Pcd = PcdClass()\r
@@ -348,49 +509,20 @@ class Dec(DecObject):
             Pcd.SupArchList = Pcds[Key]\r
             self.Package.PcdDeclarations.append(Pcd)\r
     \r
-    ## Get Pcd Values of Dec\r
-    #\r
-    # Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>\r
-    # @retval (TokenSpcCName, TokenCName, Value, DatumType, Token, ItemType) Formatted Pcd Item\r
-    #\r
-    def GetPcdOfDec(self, Item, Type, File):\r
-        Format = '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>'\r
-        List = GetSplitValueList(Item)\r
-        if len(List) != 4:\r
-            RaiseParserError(Item, 'Pcds' + Type, File, Format)\r
-        TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
-        if len(TokenInfo) != 2:\r
-            RaiseParserError(Item, 'Pcds' + Type, File, Format)\r
-        \r
-        return (TokenInfo[0], TokenInfo[1], List[1], List[2], List[3], Type)\r
-    \r
-    ## Show detailed information of Dec\r
-    #\r
-    # Print all members and their values of Dec class\r
-    #\r
-    def ShowDec(self):\r
-        print TAB_SECTION_START + TAB_INF_DEFINES + TAB_SECTION_END\r
-        printDict(self.Defines.DefinesDictionary)\r
-\r
-        for key in self.KeyList:\r
-            for arch in DataType.ARCH_LIST_FULL:\r
-                Command = "printList(TAB_SECTION_START + '" + \\r
-                                    key + DataType.TAB_SPLIT + arch + \\r
-                                    "' + TAB_SECTION_END, self.Contents[arch]." + key + ')'\r
-                eval(Command)\r
-    \r
     ## Show detailed information of Package\r
     #\r
     # Print all members and their values of Package class\r
     #\r
     def ShowPackage(self):\r
         M = self.Package\r
-        print 'Filename =', M.Header.FileName\r
-        print 'FullPath =', M.Header.FullPath\r
-        print 'BaseName =', M.Header.Name\r
-        print 'Guid =', M.Header.Guid\r
-        print 'Version =', M.Header.Version\r
-        print 'DecSpecification =', M.Header.DecSpecification\r
+        for Arch in M.Header.keys():\r
+            print '\nArch =', Arch\r
+            print 'Filename =', M.Header[Arch].FileName\r
+            print 'FullPath =', M.Header[Arch].FullPath\r
+            print 'BaseName =', M.Header[Arch].Name\r
+            print 'Guid =', M.Header[Arch].Guid\r
+            print 'Version =', M.Header[Arch].Version\r
+            print 'DecSpecification =', M.Header[Arch].DecSpecification\r
         print '\nIncludes =', M.Includes\r
         for Item in M.Includes:\r
             print Item.FilePath, Item.SupArchList\r
@@ -416,7 +548,16 @@ class Dec(DecObject):
 # script.\r
 #\r
 if __name__ == '__main__':\r
+    EdkLogger.Initialize()\r
+    EdkLogger.SetLevel(EdkLogger.DEBUG_0)\r
+    \r
     W = os.getenv('WORKSPACE')\r
     F = os.path.join(W, 'Nt32Pkg/Nt32Pkg.dec')\r
-    P = Dec(os.path.normpath(F), True, True, W)\r
+\r
+    Db = Database.Database('Dec.db')\r
+    Db.InitDatabase()\r
+    \r
+    P = Dec(os.path.normpath(F), True, True, W, Db)\r
     P.ShowPackage()\r
+    \r
+    Db.Close()\r