Home | History | Annotate | Download | only in Parser
      1 ## @file

      2 # This file is used to parse DEC file. It will consumed by DecParser

      3 #

      4 # Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>

      5 #

      6 # This program and the accompanying materials are licensed and made available 

      7 # under the terms and conditions of the BSD License which accompanies this 

      8 # distribution. The full text of the license may be found at 

      9 # http://opensource.org/licenses/bsd-license.php

     10 #

     11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

     12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

     13 '''
     14 DecParser
     15 '''
     16 ## Import modules

     17 #

     18 import Logger.Log as Logger
     19 from Logger.ToolError import FILE_PARSE_FAILURE
     20 from Logger.ToolError import FILE_OPEN_FAILURE
     21 from Logger import StringTable as ST
     22 from Logger.ToolError import FORMAT_INVALID
     23 
     24 import Library.DataType as DT
     25 from Library.ParserValidate import IsValidToken
     26 from Library.ParserValidate import IsValidPath
     27 from Library.ParserValidate import IsValidCFormatGuid
     28 from Library.ParserValidate import IsValidIdString
     29 from Library.ParserValidate import IsValidUserId
     30 from Library.ParserValidate import IsValidArch
     31 from Library.ParserValidate import IsValidWord
     32 from Library.ParserValidate import IsValidDecVersionVal
     33 from Parser.DecParserMisc import TOOL_NAME
     34 from Parser.DecParserMisc import CleanString
     35 from Parser.DecParserMisc import IsValidPcdDatum
     36 from Parser.DecParserMisc import ParserHelper
     37 from Parser.DecParserMisc import StripRoot
     38 from Parser.DecParserMisc import VERSION_PATTERN
     39 from Parser.DecParserMisc import CVAR_PATTERN
     40 from Parser.DecParserMisc import PCD_TOKEN_PATTERN
     41 from Parser.DecParserMisc import MACRO_PATTERN
     42 from Parser.DecParserMisc import FileContent
     43 from Object.Parser.DecObject import _DecComments
     44 from Object.Parser.DecObject import DecDefineObject
     45 from Object.Parser.DecObject import DecDefineItemObject
     46 from Object.Parser.DecObject import DecIncludeObject
     47 from Object.Parser.DecObject import DecIncludeItemObject
     48 from Object.Parser.DecObject import DecLibraryclassObject
     49 from Object.Parser.DecObject import DecLibraryclassItemObject
     50 from Object.Parser.DecObject import DecGuidObject
     51 from Object.Parser.DecObject import DecPpiObject
     52 from Object.Parser.DecObject import DecProtocolObject
     53 from Object.Parser.DecObject import DecGuidItemObject
     54 from Object.Parser.DecObject import DecUserExtensionObject
     55 from Object.Parser.DecObject import DecUserExtensionItemObject
     56 from Object.Parser.DecObject import DecPcdObject
     57 from Object.Parser.DecObject import DecPcdItemObject
     58 from Library.Misc import GuidStructureStringToGuidString
     59 from Library.Misc import CheckGuidRegFormat
     60 from Library.String import ReplaceMacro
     61 from Library.String import GetSplitValueList
     62 from Library.String import gMACRO_PATTERN
     63 from Library.String import ConvertSpecialChar
     64 from Library.CommentParsing import ParsePcdErrorCode
     65 
     66 ##

     67 # _DecBase class for parsing

     68 #

     69 class _DecBase:
     70     def __init__(self, RawData):
     71         self._RawData = RawData
     72         self._ItemDict = {}
     73         self._LocalMacro = {}
     74         #

     75         # Data parsed by 'self' are saved to this object

     76         #

     77         self.ItemObject = None
     78     
     79     def GetDataObject(self):
     80         return self.ItemObject
     81     
     82     def GetLocalMacro(self):
     83         return self._LocalMacro
     84     
     85     ## BlockStart

     86     #

     87     # Called if a new section starts

     88     #

     89     def BlockStart(self):
     90         self._LocalMacro = {}
     91     
     92     ## _CheckReDefine

     93     #

     94     # @param Key: to be checked if multi-defined

     95     # @param Scope: Format: [[SectionName, Arch], ...]. 

     96     #               If scope is none, use global scope

     97     #

     98     def _CheckReDefine(self, Key, Scope = None):
     99         if not Scope:
    100             Scope = self._RawData.CurrentScope
    101             return
    102         
    103         SecArch = []
    104         #

    105         # Copy scope to SecArch, avoid Scope be changed outside

    106         #

    107         SecArch[0:1] = Scope[:]
    108         if Key not in self._ItemDict:
    109             self._ItemDict[Key] = [[SecArch, self._RawData.LineIndex]]
    110             return
    111         
    112         for Value in self._ItemDict[Key]:
    113             for SubValue in Scope:
    114                 #

    115                 # If current is common section

    116                 #

    117                 if SubValue[-1] == 'COMMON':
    118                     for Other in Value[0]:
    119                         # Key in common cannot be redefined in other arches

    120                         # [:-1] means stripping arch info

    121                         if Other[:-1] == SubValue[:-1]:
    122                             self._LoggerError(ST.ERR_DECPARSE_REDEFINE % (Key, Value[1]))
    123                             return
    124                     continue
    125                 CommonScope = []
    126                 CommonScope[0:1] = SubValue
    127                 CommonScope[-1] = 'COMMON'
    128                 #

    129                 # Cannot be redefined if this key already defined in COMMON Or defined in same arch

    130                 #

    131                 if SubValue in Value[0] or CommonScope in Value[0]:
    132                     self._LoggerError(ST.ERR_DECPARSE_REDEFINE % (Key, Value[1]))
    133                     return
    134         self._ItemDict[Key].append([SecArch, self._RawData.LineIndex])
    135     
    136     ## CheckRequiredFields

    137     # Some sections need to check if some fields exist, define section for example

    138     # Derived class can re-implement, top parser will call this function after all parsing done

    139     #  

    140     def CheckRequiredFields(self):
    141         if self._RawData:
    142             pass
    143         return True
    144     
    145     ## IsItemRequired

    146     # In DEC spec, sections must have at least one statement except user 

    147     # extension.

    148     # For example: "[guids" [<attribs>] "]" <EOL> <statements>+

    149     # sub class can override this method to indicate if statement is a must.

    150     #

    151     def _IsStatementRequired(self):
    152         if self._RawData:
    153             pass
    154         return False
    155     
    156     def _LoggerError(self, ErrorString):
    157         Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename, 
    158                      Line = self._RawData.LineIndex,
    159                      ExtraData=ErrorString + ST.ERR_DECPARSE_LINE % self._RawData.CurrentLine)
    160     
    161     def _ReplaceMacro(self, String):
    162         if gMACRO_PATTERN.findall(String):
    163             String = ReplaceMacro(String, self._LocalMacro, False,
    164                                   FileName = self._RawData.Filename,
    165                                   Line = ['', self._RawData.LineIndex])
    166             String = ReplaceMacro(String, self._RawData.Macros, False,
    167                                   FileName = self._RawData.Filename,
    168                                   Line = ['', self._RawData.LineIndex])
    169             MacroUsed = gMACRO_PATTERN.findall(String)
    170             if MacroUsed:
    171                 Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE,
    172                              File=self._RawData.Filename, 
    173                              Line = self._RawData.LineIndex,
    174                              ExtraData = ST.ERR_DECPARSE_MACRO_RESOLVE % (str(MacroUsed), String))
    175         return String
    176     
    177     def _MacroParser(self, String):
    178         TokenList = GetSplitValueList(String, ' ', 1)
    179         if len(TokenList) < 2 or TokenList[1] == '':
    180             self._LoggerError(ST.ERR_DECPARSE_MACRO_PAIR)
    181 
    182         TokenList = GetSplitValueList(TokenList[1], DT.TAB_EQUAL_SPLIT, 1)
    183         if TokenList[0] == '':
    184             self._LoggerError(ST.ERR_DECPARSE_MACRO_NAME)
    185         elif not IsValidToken(MACRO_PATTERN, TokenList[0]):
    186             self._LoggerError(ST.ERR_DECPARSE_MACRO_NAME_UPPER % TokenList[0])
    187         
    188         if len(TokenList) == 1:
    189             self._LocalMacro[TokenList[0]] = ''
    190         else:
    191             self._LocalMacro[TokenList[0]] = self._ReplaceMacro(TokenList[1])
    192 
    193     ## _ParseItem

    194     #

    195     # Parse specified item, this function must be derived by subclass

    196     #

    197     def _ParseItem(self):
    198         if self._RawData:
    199             pass
    200         #

    201         # Should never be called

    202         #

    203         return None
    204 
    205     
    206     ## _TailCommentStrategy

    207     #

    208     # This function can be derived to parse tail comment

    209     # default is it will not consume any lines

    210     #

    211     # @param Comment: Comment of current line

    212     #

    213     def _TailCommentStrategy(self, Comment):
    214         if Comment:
    215             pass
    216         if self._RawData:
    217             pass
    218         return False
    219     
    220     ## _StopCurrentParsing

    221     #

    222     # Called in Parse if current parsing should be stopped when encounter some

    223     # keyword

    224     # Default is section start and end

    225     #

    226     # @param Line: Current line

    227     #

    228     def _StopCurrentParsing(self, Line):
    229         if self._RawData:
    230             pass
    231         return Line[0] == DT.TAB_SECTION_START and Line[-1] == DT.TAB_SECTION_END
    232     
    233     ## _TryBackSlash

    234     #

    235     # Split comment and DEC content, concatenate lines if end of char is '\'

    236     #

    237     # @param ProcessedLine: ProcessedLine line

    238     # @param ProcessedComments: ProcessedComments line

    239     #

    240     def _TryBackSlash(self, ProcessedLine, ProcessedComments):
    241         CatLine = ''
    242         Comment = ''
    243         Line = ProcessedLine
    244         CommentList = ProcessedComments
    245         while not self._RawData.IsEndOfFile():
    246             if Line == '':
    247                 self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)
    248                 break
    249             
    250             if Comment:
    251                 CommentList.append((Comment, self._RawData.LineIndex))
    252             if Line[-1] != DT.TAB_SLASH:
    253                 CatLine += Line
    254                 break
    255             elif len(Line) < 2 or Line[-2] != ' ':
    256                 self._LoggerError(ST.ERR_DECPARSE_BACKSLASH)
    257             else:
    258                 CatLine += Line[:-1]
    259                 Line, Comment = CleanString(self._RawData.GetNextLine())
    260         #

    261         # Reach end of content

    262         #

    263         if self._RawData.IsEndOfFile():
    264             if not CatLine:
    265                 if ProcessedLine[-1] == DT.TAB_SLASH:
    266                     self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)
    267                 CatLine = ProcessedLine
    268             else:
    269                 if not Line or Line[-1] == DT.TAB_SLASH:
    270                     self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)
    271                 CatLine += Line
    272          
    273         #

    274         # All MACRO values defined by the DEFINE statements in any section

    275         # (except [Userextensions] sections for Intel) of the INF or DEC file

    276         # must be expanded before processing of the file.

    277         #

    278         __IsReplaceMacro = True
    279         Header = self._RawData.CurrentScope[0] if self._RawData.CurrentScope else None
    280         if Header and len(Header) > 2:
    281             if Header[0].upper() == 'USEREXTENSIONS' and not (Header[1] == 'TianoCore' and Header[2] == '"ExtraFiles"'):
    282                 __IsReplaceMacro = False
    283         if __IsReplaceMacro:
    284             self._RawData.CurrentLine = self._ReplaceMacro(CatLine)
    285         else:
    286             self._RawData.CurrentLine = CatLine
    287 
    288         return CatLine, CommentList
    289     
    290     ## Parse

    291     # This is a template method in which other member functions which might 

    292     # override by sub class are called. It is responsible for reading file 

    293     # line by line, and call other member functions to parse. This function

    294     # should not be re-implement by sub class.

    295     #

    296     def Parse(self):
    297         HeadComments = []
    298         TailComments = []
    299         
    300         #======================================================================

    301         # CurComments may pointer to HeadComments or TailComments

    302         #======================================================================

    303         CurComments = HeadComments
    304         CurObj = None
    305         ItemNum = 0
    306         FromBuf = False
    307         
    308         #======================================================================

    309         # Used to report error information if empty section found

    310         #======================================================================

    311         Index = self._RawData.LineIndex
    312         LineStr = self._RawData.CurrentLine
    313         while not self._RawData.IsEndOfFile() or self._RawData.NextLine:
    314             if self._RawData.NextLine:
    315                 #==============================================================

    316                 # Have processed line in buffer

    317                 #==============================================================

    318                 Line = self._RawData.NextLine
    319                 HeadComments.extend(self._RawData.HeadComment)
    320                 TailComments.extend(self._RawData.TailComment)
    321                 self._RawData.ResetNext()
    322                 Comment = ''
    323                 FromBuf = True
    324             else:
    325                 #==============================================================

    326                 # No line in buffer, read next line

    327                 #==============================================================

    328                 Line, Comment = CleanString(self._RawData.GetNextLine())
    329                 FromBuf = False
    330             if Line:
    331                 if not FromBuf and CurObj and TailComments:
    332                     #==========================================================

    333                     # Set tail comments to previous statement if not empty.

    334                     #==========================================================

    335                     CurObj.SetTailComment(CurObj.GetTailComment()+TailComments)
    336                 
    337                 if not FromBuf:
    338                     del TailComments[:]
    339                 CurComments = TailComments
    340                 Comments = []
    341                 if Comment:
    342                     Comments = [(Comment, self._RawData.LineIndex)]
    343                 
    344                 #==============================================================

    345                 # Try if last char of line has backslash

    346                 #==============================================================

    347                 Line, Comments = self._TryBackSlash(Line, Comments)
    348                 CurComments.extend(Comments)
    349                 
    350                 #==============================================================

    351                 # Macro found

    352                 #==============================================================

    353                 if Line.startswith('DEFINE '):
    354                     self._MacroParser(Line)
    355                     del HeadComments[:]
    356                     del TailComments[:]
    357                     CurComments = HeadComments
    358                     continue
    359                 
    360                 if self._StopCurrentParsing(Line):
    361                     #==========================================================

    362                     # This line does not belong to this parse,

    363                     # Save it, can be used by next parse

    364                     #==========================================================

    365                     self._RawData.SetNext(Line, HeadComments, TailComments)
    366                     break
    367                 
    368                 Obj = self._ParseItem()
    369                 ItemNum += 1
    370                 if Obj:
    371                     Obj.SetHeadComment(Obj.GetHeadComment()+HeadComments)
    372                     Obj.SetTailComment(Obj.GetTailComment()+TailComments)
    373                     del HeadComments[:]
    374                     del TailComments[:]
    375                     CurObj = Obj
    376                 else:
    377                     CurObj = None
    378             else:
    379                 if id(CurComments) == id(TailComments):
    380                     #==========================================================

    381                     # Check if this comment belongs to tail comment

    382                     #==========================================================

    383                     if not self._TailCommentStrategy(Comment):
    384                         CurComments = HeadComments
    385 
    386                 if Comment:
    387                     CurComments.append(((Comment, self._RawData.LineIndex)))
    388                 else:
    389                     del CurComments[:]
    390         
    391         if self._IsStatementRequired() and ItemNum == 0:
    392             Logger.Error(
    393                     TOOL_NAME, FILE_PARSE_FAILURE,
    394                     File=self._RawData.Filename,
    395                     Line=Index,
    396                     ExtraData=ST.ERR_DECPARSE_STATEMENT_EMPTY % LineStr
    397             )
    398 
    399 ## _DecDefine

    400 # Parse define section

    401 #

    402 class _DecDefine(_DecBase):
    403     def __init__(self, RawData):
    404         _DecBase.__init__(self, RawData)
    405         self.ItemObject = DecDefineObject(RawData.Filename)
    406         self._LocalMacro = self._RawData.Macros
    407         self._DefSecNum = 0
    408         
    409         #

    410         # Each field has a function to validate

    411         #

    412         self.DefineValidation = {
    413             DT.TAB_DEC_DEFINES_DEC_SPECIFICATION   :   self._SetDecSpecification,
    414             DT.TAB_DEC_DEFINES_PACKAGE_NAME        :   self._SetPackageName,
    415             DT.TAB_DEC_DEFINES_PACKAGE_GUID        :   self._SetPackageGuid,
    416             DT.TAB_DEC_DEFINES_PACKAGE_VERSION     :   self._SetPackageVersion,
    417             DT.TAB_DEC_DEFINES_PKG_UNI_FILE        :   self._SetPackageUni,
    418         }
    419     
    420     def BlockStart(self):
    421         self._DefSecNum += 1
    422         if self._DefSecNum > 1:
    423             self._LoggerError(ST.ERR_DECPARSE_DEFINE_MULTISEC)
    424     
    425     ## CheckRequiredFields

    426     #

    427     # Check required fields: DEC_SPECIFICATION, PACKAGE_NAME

    428     #                        PACKAGE_GUID, PACKAGE_VERSION

    429     #

    430     def CheckRequiredFields(self):
    431         Ret = False
    432         if self.ItemObject.GetPackageSpecification() == '':
    433             Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename, 
    434                          ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)
    435         elif self.ItemObject.GetPackageName() == '':
    436             Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename, 
    437                          ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)
    438         elif self.ItemObject.GetPackageGuid() == '':
    439             Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename, 
    440                          ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)
    441         elif self.ItemObject.GetPackageVersion() == '':
    442             Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename, 
    443                          ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)
    444         else:
    445             Ret = True
    446         return Ret
    447     
    448     def _ParseItem(self):
    449         Line = self._RawData.CurrentLine
    450         TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)
    451         if TokenList[0] == DT.TAB_DEC_DEFINES_PKG_UNI_FILE:
    452             self.DefineValidation[TokenList[0]](TokenList[1])
    453         elif len(TokenList) < 2:
    454             self._LoggerError(ST.ERR_DECPARSE_DEFINE_FORMAT)
    455         elif TokenList[0] not in self.DefineValidation:
    456             self._LoggerError(ST.ERR_DECPARSE_DEFINE_UNKNOWKEY % TokenList[0])
    457         else:
    458             self.DefineValidation[TokenList[0]](TokenList[1])
    459         
    460         DefineItem = DecDefineItemObject()
    461         DefineItem.Key   = TokenList[0]
    462         DefineItem.Value = TokenList[1]
    463         self.ItemObject.AddItem(DefineItem, self._RawData.CurrentScope)
    464         return DefineItem
    465     
    466     def _SetDecSpecification(self, Token):
    467         if self.ItemObject.GetPackageSpecification():
    468             self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)
    469         if not IsValidToken('0[xX][0-9a-fA-F]{8}', Token):
    470             if not IsValidDecVersionVal(Token):
    471                 self._LoggerError(ST.ERR_DECPARSE_DEFINE_SPEC)
    472         self.ItemObject.SetPackageSpecification(Token)
    473     
    474     def _SetPackageName(self, Token):
    475         if self.ItemObject.GetPackageName():
    476             self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)
    477         if not IsValidWord(Token):
    478             self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGNAME)
    479         self.ItemObject.SetPackageName(Token)
    480     
    481     def _SetPackageGuid(self, Token):
    482         if self.ItemObject.GetPackageGuid():
    483             self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)
    484         if not CheckGuidRegFormat(Token):
    485             self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGGUID)
    486         self.ItemObject.SetPackageGuid(Token)
    487     
    488     def _SetPackageVersion(self, Token):
    489         if self.ItemObject.GetPackageVersion():
    490             self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)
    491         if not IsValidToken(VERSION_PATTERN, Token):
    492             self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGVERSION)
    493         else:
    494             if not DT.TAB_SPLIT in Token:
    495                 Token = Token + '.0'
    496             self.ItemObject.SetPackageVersion(Token)
    497             
    498     def _SetPackageUni(self, Token):
    499         if self.ItemObject.GetPackageUniFile():
    500             self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PKG_UNI_FILE)
    501         self.ItemObject.SetPackageUniFile(Token)
    502 
    503 ## _DecInclude

    504 #

    505 # Parse include section

    506 #

    507 class _DecInclude(_DecBase):
    508     def __init__(self, RawData):
    509         _DecBase.__init__(self, RawData)
    510         self.ItemObject = DecIncludeObject(RawData.Filename)
    511     
    512     def _ParseItem(self):
    513         Line = self._RawData.CurrentLine
    514         
    515         if not IsValidPath(Line, self._RawData.PackagePath):
    516             self._LoggerError(ST.ERR_DECPARSE_INCLUDE % Line) 
    517         
    518         Item = DecIncludeItemObject(StripRoot(self._RawData.PackagePath, Line), self._RawData.PackagePath)
    519         self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
    520         return Item
    521 
    522 ## _DecLibraryclass

    523 #

    524 # Parse library class section

    525 #

    526 class _DecLibraryclass(_DecBase):
    527     def __init__(self, RawData):
    528         _DecBase.__init__(self, RawData)
    529         self.ItemObject = DecLibraryclassObject(RawData.Filename)
    530     
    531     def _ParseItem(self):
    532         Line = self._RawData.CurrentLine
    533         TokenList = GetSplitValueList(Line, DT.TAB_VALUE_SPLIT)
    534         if len(TokenList) != 2:
    535             self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_SPLIT) 
    536         if TokenList[0] == '' or TokenList[1] == '':
    537             self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_EMPTY)
    538         if not IsValidToken('[A-Z][0-9A-Za-z]*', TokenList[0]):
    539             self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_LIB)
    540         
    541         self._CheckReDefine(TokenList[0])
    542         
    543         Value = TokenList[1]
    544         #

    545         # Must end with .h

    546         #

    547         if not Value.endswith('.h'):
    548             self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_PATH_EXT)
    549         
    550         #

    551         # Path must be existed

    552         #

    553         if not IsValidPath(Value, self._RawData.PackagePath):
    554             self._LoggerError(ST.ERR_DECPARSE_INCLUDE % Value)
    555         
    556         Item = DecLibraryclassItemObject(TokenList[0], StripRoot(self._RawData.PackagePath, Value),
    557                                          self._RawData.PackagePath)
    558         self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
    559         return Item
    560 
    561 ## _DecPcd

    562 #

    563 # Parse PCD section

    564 #

    565 class _DecPcd(_DecBase):
    566     def __init__(self, RawData):
    567         _DecBase.__init__(self, RawData)
    568         self.ItemObject = DecPcdObject(RawData.Filename)
    569         #

    570         # Used to check duplicate token

    571         # Key is token space and token number (integer), value is C name

    572         #

    573         self.TokenMap = {}
    574     
    575     def _ParseItem(self):
    576         Line = self._RawData.CurrentLine
    577         TokenList = Line.split(DT.TAB_VALUE_SPLIT)
    578         if len(TokenList) < 4:
    579             self._LoggerError(ST.ERR_DECPARSE_PCD_SPLIT)
    580         
    581         #

    582         # Token space guid C name

    583         #

    584         PcdName = GetSplitValueList(TokenList[0], DT.TAB_SPLIT)
    585         if len(PcdName) != 2 or PcdName[0] == '' or PcdName[1] == '':
    586             self._LoggerError(ST.ERR_DECPARSE_PCD_NAME)
    587         
    588         Guid = PcdName[0]
    589         if not IsValidToken(CVAR_PATTERN, Guid):
    590             self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_GUID)
    591         
    592         #

    593         # PCD C name

    594         #

    595         CName = PcdName[1]
    596         if not IsValidToken(CVAR_PATTERN, CName):
    597             self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_PCDCNAME)
    598         
    599         self._CheckReDefine(Guid + DT.TAB_SPLIT + CName)
    600         
    601         #

    602         # Default value, may be C array, string or number

    603         #

    604         Data = DT.TAB_VALUE_SPLIT.join(TokenList[1:-2]).strip()
    605         
    606         #

    607         # PCD data type

    608         #

    609         DataType = TokenList[-2].strip()
    610         Valid, Cause = IsValidPcdDatum(DataType, Data)
    611         if not Valid:
    612             self._LoggerError(Cause)
    613         PcdType = self._RawData.CurrentScope[0][0]
    614         if PcdType == DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() and DataType != 'BOOLEAN':
    615             self._LoggerError(ST.ERR_DECPARSE_PCD_FEATUREFLAG)
    616         #

    617         # Token value is the last element in list.

    618         #

    619         Token = TokenList[-1].strip()
    620         if not IsValidToken(PCD_TOKEN_PATTERN, Token):
    621             self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN % Token)
    622         elif not Token.startswith('0x') and not Token.startswith('0X'):
    623             if long(Token) > 4294967295:
    624                 self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_INT % Token)
    625             Token = hex(long(Token))[:-1]
    626         
    627         IntToken = long(Token, 0)
    628         if (Guid, IntToken) in self.TokenMap:
    629             if self.TokenMap[Guid, IntToken] != CName:
    630                 self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_UNIQUE%(Token))
    631         else:
    632             self.TokenMap[Guid, IntToken] = CName
    633         
    634         Item = DecPcdItemObject(Guid, CName, Data, DataType, Token)
    635         self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
    636         return Item
    637         
    638 ## _DecGuid

    639 #

    640 # Parse GUID, PPI, Protocol section

    641 #

    642 class _DecGuid(_DecBase):
    643     def __init__(self, RawData):
    644         _DecBase.__init__(self, RawData)
    645         self.GuidObj = DecGuidObject(RawData.Filename)
    646         self.PpiObj = DecPpiObject(RawData.Filename)
    647         self.ProtocolObj = DecProtocolObject(RawData.Filename)
    648         self.ObjectDict = \
    649         {
    650             DT.TAB_GUIDS.upper()     :   self.GuidObj,
    651             DT.TAB_PPIS.upper()      :   self.PpiObj,
    652             DT.TAB_PROTOCOLS.upper() :   self.ProtocolObj
    653         }
    654     
    655     def GetDataObject(self):
    656         if self._RawData.CurrentScope:
    657             return self.ObjectDict[self._RawData.CurrentScope[0][0]]
    658         return None
    659     
    660     def GetGuidObject(self):
    661         return self.GuidObj
    662     
    663     def GetPpiObject(self):
    664         return self.PpiObj
    665     
    666     def GetProtocolObject(self):
    667         return self.ProtocolObj
    668     
    669     def _ParseItem(self):
    670         Line = self._RawData.CurrentLine
    671         TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)
    672         if len(TokenList) < 2:
    673             self._LoggerError(ST.ERR_DECPARSE_CGUID)
    674         if TokenList[0] == '':
    675             self._LoggerError(ST.ERR_DECPARSE_CGUID_NAME)
    676         if TokenList[1] == '':
    677             self._LoggerError(ST.ERR_DECPARSE_CGUID_GUID)
    678         if not IsValidToken(CVAR_PATTERN, TokenList[0]):
    679             self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_GUID)
    680         
    681         self._CheckReDefine(TokenList[0])
    682         
    683         if TokenList[1][0] != '{':
    684             if not CheckGuidRegFormat(TokenList[1]):
    685                 self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGGUID)
    686             GuidString = TokenList[1]
    687         else:
    688             #

    689             # Convert C format GUID to GUID string and Simple error check

    690             #

    691             GuidString = GuidStructureStringToGuidString(TokenList[1])
    692             if TokenList[1][0] != '{' or TokenList[1][-1] != '}' or GuidString == '':
    693                 self._LoggerError(ST.ERR_DECPARSE_CGUID_GUIDFORMAT)
    694     
    695             #

    696             # Check C format GUID

    697             #

    698             if not IsValidCFormatGuid(TokenList[1]):
    699                 self._LoggerError(ST.ERR_DECPARSE_CGUID_GUIDFORMAT)
    700 
    701         Item = DecGuidItemObject(TokenList[0], TokenList[1], GuidString)
    702         ItemObject = self.ObjectDict[self._RawData.CurrentScope[0][0]]
    703         ItemObject.AddItem(Item, self._RawData.CurrentScope)
    704         return Item
    705 
    706 ## _DecUserExtension

    707 #

    708 # Parse user extention section

    709 #

    710 class _DecUserExtension(_DecBase):
    711     def __init__(self, RawData):
    712         _DecBase.__init__(self, RawData)
    713         self.ItemObject = DecUserExtensionObject(RawData.Filename)
    714         self._Headers = []
    715         self._CurItems = []
    716     
    717     def BlockStart(self):
    718         self._CurItems = []
    719         for Header in self._RawData.CurrentScope:
    720             if Header in self._Headers:
    721                 self._LoggerError(ST.ERR_DECPARSE_UE_DUPLICATE)
    722             else:
    723                 self._Headers.append(Header)
    724             
    725             for Item in self._CurItems:
    726                 if Item.UserId == Header[1] and Item.IdString == Header[2]:
    727                     Item.ArchAndModuleType.append(Header[3])
    728                     break
    729             else:
    730                 Item = DecUserExtensionItemObject()
    731                 Item.UserId = Header[1]
    732                 Item.IdString = Header[2]
    733                 Item.ArchAndModuleType.append(Header[3])
    734                 self._CurItems.append(Item)
    735                 self.ItemObject.AddItem(Item, None)
    736         self._LocalMacro = {}
    737     
    738     def _ParseItem(self):
    739         Line = self._RawData.CurrentLine
    740         Item = None
    741         for Item in self._CurItems:
    742             if Item.UserString:
    743                 Item.UserString = '\n'.join([Item.UserString, Line])
    744             else:
    745                 Item.UserString = Line
    746         return Item
    747 
    748 ## Dec

    749 #

    750 # Top dec parser

    751 #

    752 class Dec(_DecBase, _DecComments):    
    753     def __init__(self, DecFile, Parse = True):        
    754         try:
    755             Content = ConvertSpecialChar(open(DecFile, 'rb').readlines())
    756         except BaseException:
    757             Logger.Error(TOOL_NAME, FILE_OPEN_FAILURE, File=DecFile,
    758                          ExtraData=ST.ERR_DECPARSE_FILEOPEN % DecFile)
    759 
    760         #

    761         # Pre-parser for Private section

    762         #

    763         self._Private = ''
    764         __IsFoundPrivate = False
    765         NewContent = []
    766         for Line in Content:
    767             Line = Line.strip()
    768             if Line.startswith(DT.TAB_SECTION_START) and Line.endswith(DT.TAB_PRIVATE + DT.TAB_SECTION_END):
    769                 __IsFoundPrivate = True
    770             if Line.startswith(DT.TAB_SECTION_START) and Line.endswith(DT.TAB_SECTION_END)\
    771                and not Line.endswith(DT.TAB_PRIVATE + DT.TAB_SECTION_END):
    772                 __IsFoundPrivate = False
    773             if __IsFoundPrivate:
    774                 self._Private += Line + '\r'
    775             if not __IsFoundPrivate:
    776                 NewContent.append(Line + '\r')
    777 
    778         RawData = FileContent(DecFile, NewContent)
    779         
    780         _DecComments.__init__(self)
    781         _DecBase.__init__(self, RawData)
    782         
    783         self.BinaryHeadComment = []
    784         self.PcdErrorCommentDict = {}
    785         
    786         self._Define    = _DecDefine(RawData)
    787         self._Include   = _DecInclude(RawData)
    788         self._Guid      = _DecGuid(RawData)
    789         self._LibClass  = _DecLibraryclass(RawData)
    790         self._Pcd       = _DecPcd(RawData)
    791         self._UserEx    = _DecUserExtension(RawData)
    792         
    793         #

    794         # DEC file supported data types (one type per section)

    795         #

    796         self._SectionParser = {
    797             DT.TAB_DEC_DEFINES.upper()                     :   self._Define,
    798             DT.TAB_INCLUDES.upper()                        :   self._Include,
    799             DT.TAB_LIBRARY_CLASSES.upper()                 :   self._LibClass,
    800             DT.TAB_GUIDS.upper()                           :   self._Guid,
    801             DT.TAB_PPIS.upper()                            :   self._Guid,
    802             DT.TAB_PROTOCOLS.upper()                       :   self._Guid,
    803             DT.TAB_PCDS_FIXED_AT_BUILD_NULL.upper()        :   self._Pcd,
    804             DT.TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper()   :   self._Pcd,
    805             DT.TAB_PCDS_FEATURE_FLAG_NULL.upper()          :   self._Pcd,
    806             DT.TAB_PCDS_DYNAMIC_NULL.upper()               :   self._Pcd,
    807             DT.TAB_PCDS_DYNAMIC_EX_NULL.upper()            :   self._Pcd,
    808             DT.TAB_USER_EXTENSIONS.upper()                 :   self._UserEx
    809         }
    810 
    811         if Parse:
    812             self.ParseDecComment()
    813             self.Parse()
    814             #

    815             # Parsing done, check required fields

    816             #

    817             self.CheckRequiredFields()
    818     
    819     def CheckRequiredFields(self):
    820         for SectionParser in self._SectionParser.values():
    821             if not SectionParser.CheckRequiredFields():
    822                 return False
    823         return True
    824 
    825     ##

    826     # Parse DEC file

    827     #

    828     def ParseDecComment(self):
    829         IsFileHeader = False
    830         IsBinaryHeader = False
    831         FileHeaderLineIndex = -1
    832         BinaryHeaderLineIndex = -1
    833         TokenSpaceGuidCName = ''
    834         
    835         #

    836         # Parse PCD error comment section

    837         #

    838         while not self._RawData.IsEndOfFile():
    839             self._RawData.CurrentLine = self._RawData.GetNextLine()
    840             if self._RawData.CurrentLine.startswith(DT.TAB_COMMENT_SPLIT) and \
    841                 DT.TAB_SECTION_START in self._RawData.CurrentLine and \
    842                 DT.TAB_SECTION_END in self._RawData.CurrentLine:
    843                 self._RawData.CurrentLine = self._RawData.CurrentLine.replace(DT.TAB_COMMENT_SPLIT, '').strip()
    844 
    845                 if self._RawData.CurrentLine[0] == DT.TAB_SECTION_START and \
    846                     self._RawData.CurrentLine[-1] == DT.TAB_SECTION_END:
    847                     RawSection = self._RawData.CurrentLine[1:-1].strip()
    848                     if RawSection.upper().startswith(DT.TAB_PCD_ERROR.upper()+'.'):
    849                         TokenSpaceGuidCName = RawSection.split(DT.TAB_PCD_ERROR+'.')[1].strip()
    850                         continue
    851 
    852             if TokenSpaceGuidCName and self._RawData.CurrentLine.startswith(DT.TAB_COMMENT_SPLIT):
    853                 self._RawData.CurrentLine = self._RawData.CurrentLine.replace(DT.TAB_COMMENT_SPLIT, '').strip()
    854                 if self._RawData.CurrentLine != '':
    855                     if DT.TAB_VALUE_SPLIT not in self._RawData.CurrentLine:
    856                         self._LoggerError(ST.ERR_DECPARSE_PCDERRORMSG_MISS_VALUE_SPLIT)   
    857                           
    858                     PcdErrorNumber, PcdErrorMsg = GetSplitValueList(self._RawData.CurrentLine, DT.TAB_VALUE_SPLIT, 1)
    859                     PcdErrorNumber = ParsePcdErrorCode(PcdErrorNumber, self._RawData.Filename, self._RawData.LineIndex)
    860                     if not PcdErrorMsg.strip():
    861                         self._LoggerError(ST.ERR_DECPARSE_PCD_MISS_ERRORMSG)
    862                         
    863                     self.PcdErrorCommentDict[(TokenSpaceGuidCName, PcdErrorNumber)] = PcdErrorMsg.strip()
    864             else:
    865                 TokenSpaceGuidCName = ''
    866 
    867         self._RawData.LineIndex = 0
    868         self._RawData.CurrentLine = ''
    869         self._RawData.NextLine = ''
    870 
    871         while not self._RawData.IsEndOfFile():
    872             Line, Comment = CleanString(self._RawData.GetNextLine())
    873             
    874             #

    875             # Header must be pure comment

    876             #

    877             if Line != '':
    878                 self._RawData.UndoNextLine()
    879                 break
    880             
    881             if Comment and Comment.startswith(DT.TAB_SPECIAL_COMMENT) and Comment.find(DT.TAB_HEADER_COMMENT) > 0 \
    882                 and not Comment[2:Comment.find(DT.TAB_HEADER_COMMENT)].strip():
    883                 IsFileHeader = True
    884                 IsBinaryHeader = False
    885                 FileHeaderLineIndex = self._RawData.LineIndex
    886                 
    887             #

    888             # Get license information before '@file' 

    889             #   

    890             if not IsFileHeader and not IsBinaryHeader and Comment and Comment.startswith(DT.TAB_COMMENT_SPLIT) and \
    891             DT.TAB_BINARY_HEADER_COMMENT not in Comment:
    892                 self._HeadComment.append((Comment, self._RawData.LineIndex))
    893             
    894             if Comment and IsFileHeader and \
    895             not(Comment.startswith(DT.TAB_SPECIAL_COMMENT) \
    896             and Comment.find(DT.TAB_BINARY_HEADER_COMMENT) > 0):
    897                 self._HeadComment.append((Comment, self._RawData.LineIndex))
    898             #

    899             # Double '#' indicates end of header comments

    900             #

    901             if (not Comment or Comment == DT.TAB_SPECIAL_COMMENT) and IsFileHeader:
    902                 IsFileHeader = False  
    903                 continue
    904             
    905             if Comment and Comment.startswith(DT.TAB_SPECIAL_COMMENT) \
    906             and Comment.find(DT.TAB_BINARY_HEADER_COMMENT) > 0:
    907                 IsBinaryHeader = True
    908                 IsFileHeader = False
    909                 BinaryHeaderLineIndex = self._RawData.LineIndex
    910                 
    911             if Comment and IsBinaryHeader:
    912                 self.BinaryHeadComment.append((Comment, self._RawData.LineIndex))
    913             #

    914             # Double '#' indicates end of header comments

    915             #

    916             if (not Comment or Comment == DT.TAB_SPECIAL_COMMENT) and IsBinaryHeader:
    917                 IsBinaryHeader = False
    918                 break
    919             
    920             if FileHeaderLineIndex > -1 and not IsFileHeader and not IsBinaryHeader:
    921                 break
    922 
    923         if FileHeaderLineIndex > BinaryHeaderLineIndex and FileHeaderLineIndex > -1 and BinaryHeaderLineIndex > -1:
    924             self._LoggerError(ST.ERR_BINARY_HEADER_ORDER)
    925             
    926         if FileHeaderLineIndex == -1:
    927 #            self._LoggerError(ST.ERR_NO_SOURCE_HEADER)

    928             Logger.Error(TOOL_NAME, FORMAT_INVALID, 
    929                          ST.ERR_NO_SOURCE_HEADER,
    930                          File=self._RawData.Filename)
    931         return
    932     
    933     def _StopCurrentParsing(self, Line):
    934         return False
    935     
    936     def _ParseItem(self):
    937         self._SectionHeaderParser()
    938         if len(self._RawData.CurrentScope) == 0:
    939             self._LoggerError(ST.ERR_DECPARSE_SECTION_EMPTY)
    940         SectionObj = self._SectionParser[self._RawData.CurrentScope[0][0]]
    941         SectionObj.BlockStart()
    942         SectionObj.Parse()
    943         return SectionObj.GetDataObject()
    944 
    945     def _UserExtentionSectionParser(self):
    946         self._RawData.CurrentScope = []
    947         ArchList = set()
    948         Section = self._RawData.CurrentLine[1:-1]
    949         Par = ParserHelper(Section, self._RawData.Filename)
    950         while not Par.End():
    951             #

    952             # User extention

    953             #

    954             Token = Par.GetToken()
    955             if Token.upper() != DT.TAB_USER_EXTENSIONS.upper():
    956                 self._LoggerError(ST.ERR_DECPARSE_SECTION_UE)
    957             UserExtension = Token.upper()
    958             Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)     
    959             
    960             #

    961             # UserID

    962             #

    963             Token = Par.GetToken()
    964             if not IsValidUserId(Token):
    965                 self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_USERID)
    966             UserId = Token
    967             Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)
    968             #

    969             # IdString

    970             #

    971             Token = Par.GetToken()
    972             if not IsValidIdString(Token):
    973                 self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_IDSTRING)
    974             IdString = Token
    975             Arch = 'COMMON'
    976             if Par.Expect(DT.TAB_SPLIT):
    977                 Token = Par.GetToken()
    978                 Arch = Token.upper()
    979                 if not IsValidArch(Arch):
    980                     self._LoggerError(ST.ERR_DECPARSE_ARCH)
    981             ArchList.add(Arch)
    982             if [UserExtension, UserId, IdString, Arch] not in \
    983                 self._RawData.CurrentScope:
    984                 self._RawData.CurrentScope.append(
    985                     [UserExtension, UserId, IdString, Arch]
    986                 )
    987             if not Par.Expect(DT.TAB_COMMA_SPLIT):
    988                 break
    989             elif Par.End():
    990                 self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMA)
    991         Par.AssertEnd(ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)
    992         if 'COMMON' in ArchList and len(ArchList) > 1:
    993             self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON)
    994  
    995     ## Section header parser

    996     #

    997     # The section header is always in following format:

    998     #

    999     # [section_name.arch<.platform|module_type>]

   1000     #

   1001     def _SectionHeaderParser(self):
   1002         if self._RawData.CurrentLine[0] != DT.TAB_SECTION_START or self._RawData.CurrentLine[-1] != DT.TAB_SECTION_END:
   1003             self._LoggerError(ST.ERR_DECPARSE_SECTION_IDENTIFY)
   1004         
   1005         RawSection = self._RawData.CurrentLine[1:-1].strip().upper()
   1006         #

   1007         # Check defines section which is only allowed to occur once and

   1008         # no arch can be followed

   1009         #

   1010         if RawSection.startswith(DT.TAB_DEC_DEFINES.upper()):
   1011             if RawSection != DT.TAB_DEC_DEFINES.upper():
   1012                 self._LoggerError(ST.ERR_DECPARSE_DEFINE_SECNAME)
   1013         #

   1014         # Check user extension section

   1015         #

   1016         if RawSection.startswith(DT.TAB_USER_EXTENSIONS.upper()):
   1017             return self._UserExtentionSectionParser()
   1018         self._RawData.CurrentScope = []
   1019         SectionNames = []
   1020         ArchList = set()
   1021         for Item in GetSplitValueList(RawSection, DT.TAB_COMMA_SPLIT):
   1022             if Item == '':
   1023                 self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)
   1024 
   1025             ItemList = GetSplitValueList(Item, DT.TAB_SPLIT)
   1026             #

   1027             # different types of PCD are permissible in one section

   1028             #

   1029             SectionName = ItemList[0]
   1030             if SectionName not in self._SectionParser:
   1031                 self._LoggerError(ST.ERR_DECPARSE_SECTION_UNKNOW % SectionName)
   1032             if SectionName not in SectionNames:
   1033                 SectionNames.append(SectionName)
   1034             #

   1035             # In DEC specification, all section headers have at most two part:

   1036             # SectionName.Arch except UserExtention

   1037             #

   1038             if len(ItemList) > 2:
   1039                 self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBTOOMANY % Item)
   1040 
   1041             if DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() in SectionNames and len(SectionNames) > 1:
   1042                 self._LoggerError(ST.ERR_DECPARSE_SECTION_FEATUREFLAG % DT.TAB_PCDS_FEATURE_FLAG_NULL) 
   1043             #

   1044             # S1 is always Arch

   1045             #

   1046             if len(ItemList) > 1:
   1047                 Str1 = ItemList[1]
   1048                 if not IsValidArch(Str1):
   1049                     self._LoggerError(ST.ERR_DECPARSE_ARCH)
   1050             else:
   1051                 Str1 = 'COMMON'
   1052             ArchList.add(Str1)
   1053 
   1054             if [SectionName, Str1] not in self._RawData.CurrentScope:
   1055                 self._RawData.CurrentScope.append([SectionName, Str1])
   1056         #

   1057         # 'COMMON' must not be used with specific ARCHs at the same section

   1058         #

   1059         if 'COMMON' in ArchList and len(ArchList) > 1:
   1060             self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON)
   1061         if len(SectionNames) == 0:
   1062             self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)
   1063         if len(SectionNames) != 1:
   1064             for Sec in SectionNames:
   1065                 if not Sec.startswith(DT.TAB_PCDS.upper()):
   1066                     self._LoggerError(ST.ERR_DECPARSE_SECTION_NAME % str(SectionNames))
   1067     
   1068     def GetDefineSectionMacro(self):
   1069         return self._Define.GetLocalMacro()
   1070     def GetDefineSectionObject(self):
   1071         return self._Define.GetDataObject()
   1072     def GetIncludeSectionObject(self):
   1073         return self._Include.GetDataObject()
   1074     def GetGuidSectionObject(self):
   1075         return self._Guid.GetGuidObject()
   1076     def GetProtocolSectionObject(self):
   1077         return self._Guid.GetProtocolObject()
   1078     def GetPpiSectionObject(self):
   1079         return self._Guid.GetPpiObject()
   1080     def GetLibraryClassSectionObject(self):
   1081         return self._LibClass.GetDataObject()
   1082     def GetPcdSectionObject(self):
   1083         return self._Pcd.GetDataObject()
   1084     def GetUserExtensionSectionObject(self):
   1085         return self._UserEx.GetDataObject()
   1086     def GetPackageSpecification(self):
   1087         return self._Define.GetDataObject().GetPackageSpecification()   
   1088     def GetPackageName(self):
   1089         return self._Define.GetDataObject().GetPackageName()   
   1090     def GetPackageGuid(self):
   1091         return self._Define.GetDataObject().GetPackageGuid()    
   1092     def GetPackageVersion(self):
   1093         return self._Define.GetDataObject().GetPackageVersion()
   1094     def GetPackageUniFile(self):
   1095         return self._Define.GetDataObject().GetPackageUniFile()
   1096     def GetPrivateSections(self):
   1097         return self._Private
   1098