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

      2 # This file contained the parser for INF file

      3 #

      4 # Copyright (c) 2011 - 2014, 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 
     15 '''
     16 InfParser
     17 '''
     18 
     19 ##

     20 # Import Modules

     21 #

     22 import re
     23 import os
     24 from copy import deepcopy
     25 
     26 from Library.String import GetSplitValueList
     27 from Library.String import ConvertSpecialChar
     28 from Library.Misc import ProcessLineExtender
     29 from Library.Misc import ProcessEdkComment
     30 from Library.Parsing import NormPath
     31 from Library.ParserValidate import IsValidInfMoudleTypeList
     32 from Library.ParserValidate import IsValidArch
     33 from Library import DataType as DT
     34 from Library import GlobalData
     35 
     36 import Logger.Log as Logger
     37 from Logger import StringTable as ST
     38 from Logger.ToolError import FORMAT_INVALID
     39 from Logger.ToolError import FILE_READ_FAILURE
     40 from Logger.ToolError import PARSER_ERROR
     41 
     42 from Object.Parser.InfCommonObject import InfSectionCommonDef
     43 from Parser.InfSectionParser import InfSectionParser
     44 from Parser.InfParserMisc import gINF_SECTION_DEF
     45 from Parser.InfParserMisc import IsBinaryInf
     46 
     47 ## OpenInfFile

     48 #

     49 #

     50 def OpenInfFile(Filename):
     51     FileLinesList = []
     52     
     53     try:
     54         FInputfile = open(Filename, "rb", 0)
     55         try:
     56             FileLinesList = FInputfile.readlines()
     57         except BaseException:
     58             Logger.Error("InfParser", 
     59                          FILE_READ_FAILURE, 
     60                          ST.ERR_FILE_OPEN_FAILURE,
     61                          File=Filename)
     62         finally:
     63             FInputfile.close()
     64     except BaseException:
     65         Logger.Error("InfParser", 
     66                      FILE_READ_FAILURE, 
     67                      ST.ERR_FILE_OPEN_FAILURE,
     68                      File=Filename)
     69         
     70     return FileLinesList
     71 
     72 ## InfParser

     73 #

     74 # This class defined the structure used in InfParser object

     75 #

     76 # @param InfObject:         Inherited from InfSectionParser class

     77 # @param Filename:          Input value for Filename of INF file, default is 

     78 #                           None

     79 # @param WorkspaceDir:      Input value for current workspace directory, 

     80 #                           default is None

     81 #

     82 class InfParser(InfSectionParser):
     83 
     84     def __init__(self, Filename = None, WorkspaceDir = None):
     85         
     86         #

     87         # Call parent class construct function

     88         #

     89         super(InfParser, self).__init__()
     90         
     91         self.WorkspaceDir    = WorkspaceDir
     92         self.SupArchList     = DT.ARCH_LIST
     93         self.EventList    = []
     94         self.HobList      = []
     95         self.BootModeList = []
     96 
     97         #

     98         # Load Inf file if filename is not None

     99         #

    100         if Filename != None:
    101             self.ParseInfFile(Filename)
    102 
    103     ## Parse INF file

    104     #

    105     # Parse the file if it exists

    106     #

    107     # @param Filename:  Input value for filename of INF file

    108     #

    109     def ParseInfFile(self, Filename):
    110         
    111         Filename = NormPath(Filename)
    112         (Path, Name) = os.path.split(Filename)
    113         self.FullPath = Filename
    114         self.RelaPath = Path
    115         self.FileName = Name
    116         GlobalData.gINF_MODULE_DIR = Path
    117         GlobalData.gINF_MODULE_NAME = self.FullPath
    118         GlobalData.gIS_BINARY_INF = False
    119         #

    120         # Initialize common data

    121         #

    122         LineNo             = 0
    123         CurrentSection     = DT.MODEL_UNKNOWN 
    124         SectionLines       = []
    125         
    126         #

    127         # Flags

    128         #

    129         HeaderCommentStart = False 
    130         HeaderCommentEnd   = False
    131         HeaderStarLineNo = -1
    132         BinaryHeaderCommentStart = False 
    133         BinaryHeaderCommentEnd   = False
    134         BinaryHeaderStarLineNo = -1
    135         
    136         #

    137         # While Section ends. parse whole section contents.

    138         #

    139         NewSectionStartFlag = False
    140         FirstSectionStartFlag = False
    141         
    142         #

    143         # Parse file content

    144         #

    145         CommentBlock       = []
    146  
    147         #

    148         # Variables for Event/Hob/BootMode

    149         #

    150         self.EventList    = []
    151         self.HobList      = []
    152         self.BootModeList = []
    153         SectionType = ''
    154         
    155         FileLinesList = OpenInfFile (Filename)
    156         
    157         #

    158         # One INF file can only has one [Defines] section.

    159         #

    160         DefineSectionParsedFlag = False
    161         
    162         #

    163         # Convert special characters in lines to space character.

    164         #

    165         FileLinesList = ConvertSpecialChar(FileLinesList)
    166         
    167         #

    168         # Process Line Extender

    169         #

    170         FileLinesList = ProcessLineExtender(FileLinesList)
    171         
    172         #

    173         # Process EdkI INF style comment if found

    174         #

    175         OrigLines = [Line for Line in FileLinesList]
    176         FileLinesList, EdkCommentStartPos = ProcessEdkComment(FileLinesList)
    177         
    178         #

    179         # Judge whether the INF file is Binary INF or not

    180         #

    181         if IsBinaryInf(FileLinesList):
    182             GlobalData.gIS_BINARY_INF = True
    183             
    184         InfSectionCommonDefObj = None
    185         
    186         for Line in FileLinesList:
    187             LineNo   = LineNo + 1
    188             Line     = Line.strip()
    189             if (LineNo < len(FileLinesList) - 1):
    190                 NextLine = FileLinesList[LineNo].strip()
    191             
    192             #

    193             # blank line

    194             #

    195             if (Line == '' or not Line) and LineNo == len(FileLinesList):
    196                 LastSectionFalg = True
    197 
    198             #

    199             # check whether file header comment section started

    200             #

    201             if Line.startswith(DT.TAB_SPECIAL_COMMENT) and \
    202                (Line.find(DT.TAB_HEADER_COMMENT) > -1) and \
    203                not HeaderCommentStart and not HeaderCommentEnd:
    204 
    205                 CurrentSection = DT.MODEL_META_DATA_FILE_HEADER
    206                 #

    207                 # Append the first line to section lines.

    208                 #

    209                 HeaderStarLineNo = LineNo
    210                 SectionLines.append((Line, LineNo))
    211                 HeaderCommentStart = True
    212                 continue        
    213 
    214             #

    215             # Collect Header content.

    216             #

    217             if (Line.startswith(DT.TAB_COMMENT_SPLIT) and CurrentSection == DT.MODEL_META_DATA_FILE_HEADER) and\
    218                 HeaderCommentStart and not Line.startswith(DT.TAB_SPECIAL_COMMENT) and not\
    219                 HeaderCommentEnd and NextLine != '':
    220                 SectionLines.append((Line, LineNo))
    221                 continue
    222             #

    223             # Header content end

    224             #

    225             if (Line.startswith(DT.TAB_SPECIAL_COMMENT) or not Line.strip().startswith("#")) and HeaderCommentStart \
    226                 and not HeaderCommentEnd:
    227                 HeaderCommentEnd = True
    228                 BinaryHeaderCommentStart = False 
    229                 BinaryHeaderCommentEnd   = False
    230                 HeaderCommentStart = False      
    231                 if Line.find(DT.TAB_BINARY_HEADER_COMMENT) > -1:
    232                     self.InfHeaderParser(SectionLines, self.InfHeader, self.FileName) 
    233                     SectionLines = []
    234                 else:
    235                     SectionLines.append((Line, LineNo))
    236                     #

    237                     # Call Header comment parser.

    238                     #

    239                     self.InfHeaderParser(SectionLines, self.InfHeader, self.FileName)
    240                     SectionLines = []
    241                     continue
    242 
    243             #

    244             # check whether binary header comment section started

    245             #

    246             if Line.startswith(DT.TAB_SPECIAL_COMMENT) and \
    247                 (Line.find(DT.TAB_BINARY_HEADER_COMMENT) > -1) and \
    248                 not BinaryHeaderCommentStart:
    249                 SectionLines = []
    250                 CurrentSection = DT.MODEL_META_DATA_FILE_HEADER
    251                 #

    252                 # Append the first line to section lines.

    253                 #

    254                 BinaryHeaderStarLineNo = LineNo
    255                 SectionLines.append((Line, LineNo))
    256                 BinaryHeaderCommentStart = True
    257                 HeaderCommentEnd = True
    258                 continue   
    259             
    260             #

    261             # check whether there are more than one binary header exist

    262             #

    263             if Line.startswith(DT.TAB_SPECIAL_COMMENT) and BinaryHeaderCommentStart and \
    264                 not BinaryHeaderCommentEnd and (Line.find(DT.TAB_BINARY_HEADER_COMMENT) > -1):
    265                 Logger.Error('Parser',
    266                              FORMAT_INVALID,
    267                              ST.ERR_MULTIPLE_BINARYHEADER_EXIST,
    268                              File=Filename)
    269             
    270             #

    271             # Collect Binary Header content.

    272             #

    273             if (Line.startswith(DT.TAB_COMMENT_SPLIT) and CurrentSection == DT.MODEL_META_DATA_FILE_HEADER) and\
    274                 BinaryHeaderCommentStart and not Line.startswith(DT.TAB_SPECIAL_COMMENT) and not\
    275                 BinaryHeaderCommentEnd and NextLine != '':
    276                 SectionLines.append((Line, LineNo))
    277                 continue
    278             #

    279             # Binary Header content end

    280             #

    281             if (Line.startswith(DT.TAB_SPECIAL_COMMENT) or not Line.strip().startswith(DT.TAB_COMMENT_SPLIT)) and \
    282                 BinaryHeaderCommentStart and not BinaryHeaderCommentEnd:
    283                 SectionLines.append((Line, LineNo))
    284                 BinaryHeaderCommentStart = False
    285                 #

    286                 # Call Binary Header comment parser.

    287                 #

    288                 self.InfHeaderParser(SectionLines, self.InfBinaryHeader, self.FileName, True)
    289                 SectionLines = []
    290                 BinaryHeaderCommentEnd   = True               
    291                 continue                   
    292             #

    293             # Find a new section tab

    294             # Or at the last line of INF file, 

    295             # need to process the last section.

    296             #

    297             LastSectionFalg = False
    298             if LineNo == len(FileLinesList):
    299                 LastSectionFalg = True
    300                              
    301             if Line.startswith(DT.TAB_COMMENT_SPLIT) and not Line.startswith(DT.TAB_SPECIAL_COMMENT):
    302                 SectionLines.append((Line, LineNo))
    303                 if not LastSectionFalg:
    304                     continue
    305 
    306             #

    307             # Encountered a section. start with '[' and end with ']'

    308             #

    309             if (Line.startswith(DT.TAB_SECTION_START) and \
    310                Line.find(DT.TAB_SECTION_END) > -1) or LastSectionFalg:   
    311                 
    312                 HeaderCommentEnd = True        
    313                 BinaryHeaderCommentEnd = True       
    314                 
    315                 if not LastSectionFalg:
    316                     #

    317                     # check to prevent '#' inside section header

    318                     #

    319                     HeaderContent = Line[1:Line.find(DT.TAB_SECTION_END)]
    320                     if HeaderContent.find(DT.TAB_COMMENT_SPLIT) != -1:
    321                         Logger.Error("InfParser", 
    322                                      FORMAT_INVALID,
    323                                      ST.ERR_INF_PARSER_DEFINE_SECTION_HEADER_INVALID,
    324                                      File=self.FullPath,
    325                                      Line=LineNo, 
    326                                      ExtraData=Line)                        
    327 
    328                     #

    329                     # Keep last time section header content for section parser

    330                     # usage.

    331                     #

    332                     self.LastSectionHeaderContent = deepcopy(self.SectionHeaderContent)
    333 
    334                     #

    335                     # TailComments in section define.

    336                     #

    337                     TailComments = ''
    338                     CommentIndex = Line.find(DT.TAB_COMMENT_SPLIT)
    339                     if  CommentIndex > -1:
    340                         TailComments = Line[CommentIndex:]
    341                         Line = Line[:CommentIndex]
    342                     
    343                     InfSectionCommonDefObj = InfSectionCommonDef()
    344                     if TailComments != '':
    345                         InfSectionCommonDefObj.SetTailComments(TailComments)
    346                     if CommentBlock != '':
    347                         InfSectionCommonDefObj.SetHeaderComments(CommentBlock)
    348                         CommentBlock = []
    349                     #

    350                     # Call section parser before section header parer to avoid encounter EDKI INF file

    351                     #

    352                     if CurrentSection == DT.MODEL_META_DATA_DEFINE:
    353                         DefineSectionParsedFlag = self._CallSectionParsers(CurrentSection, 
    354                                                                    DefineSectionParsedFlag, SectionLines, 
    355                                                                    InfSectionCommonDefObj, LineNo)
    356                     #

    357                     # Compare the new section name with current

    358                     #

    359                     self.SectionHeaderParser(Line, self.FileName, LineNo)
    360 
    361                     self._CheckSectionHeaders(Line, LineNo)
    362 
    363                     SectionType = _ConvertSecNameToType(self.SectionHeaderContent[0][0])
    364 
    365                 if not FirstSectionStartFlag:
    366                     CurrentSection = SectionType
    367                     FirstSectionStartFlag = True
    368                 else:
    369                     NewSectionStartFlag = True
    370             else:
    371                 SectionLines.append((Line, LineNo))
    372                 continue
    373 
    374             if LastSectionFalg:
    375                 SectionLines, CurrentSection = self._ProcessLastSection(SectionLines, Line, LineNo, CurrentSection)
    376 
    377             #

    378             # End of section content collect.

    379             # Parser the section content collected previously.

    380             #  

    381             if NewSectionStartFlag or LastSectionFalg:
    382                 if CurrentSection != DT.MODEL_META_DATA_DEFINE or \
    383                     (LastSectionFalg and CurrentSection == DT.MODEL_META_DATA_DEFINE):     
    384                     DefineSectionParsedFlag = self._CallSectionParsers(CurrentSection, 
    385                                                                        DefineSectionParsedFlag, SectionLines, 
    386                                                                        InfSectionCommonDefObj, LineNo)
    387                 
    388                 CurrentSection = SectionType
    389                 #

    390                 # Clear section lines

    391                 #

    392                 SectionLines = []                                             
    393         
    394         if HeaderStarLineNo == -1:
    395             Logger.Error("InfParser", 
    396                         FORMAT_INVALID,
    397                         ST.ERR_NO_SOURCE_HEADER,
    398                         File=self.FullPath) 
    399         if BinaryHeaderStarLineNo > -1 and HeaderStarLineNo > -1  and HeaderStarLineNo > BinaryHeaderStarLineNo:
    400             Logger.Error("InfParser", 
    401                         FORMAT_INVALID,
    402                         ST.ERR_BINARY_HEADER_ORDER,
    403                         File=self.FullPath)         
    404         #

    405         # EDKII INF should not have EDKI style comment

    406         #

    407         if EdkCommentStartPos != -1:
    408             Logger.Error("InfParser", 
    409                          FORMAT_INVALID, 
    410                          ST.ERR_INF_PARSER_EDKI_COMMENT_IN_EDKII, 
    411                          File=self.FullPath,
    412                          Line=EdkCommentStartPos + 1,
    413                          ExtraData=OrigLines[EdkCommentStartPos])
    414         
    415         #

    416         # extract [Event] [Hob] [BootMode] sections 

    417         #            

    418         self._ExtractEventHobBootMod(FileLinesList)
    419     
    420     ## _CheckSectionHeaders

    421     #

    422     #

    423     def _CheckSectionHeaders(self, Line, LineNo):
    424         if len(self.SectionHeaderContent) == 0:
    425             Logger.Error("InfParser", 
    426                          FORMAT_INVALID,
    427                          ST.ERR_INF_PARSER_DEFINE_SECTION_HEADER_INVALID,
    428                          File=self.FullPath,
    429                          Line=LineNo, ExtraData=Line)
    430         else:
    431             for SectionItem in self.SectionHeaderContent:
    432                 ArchList = []
    433                 #

    434                 # Not cover Depex/UserExtension section header 

    435                 # check.

    436                 #

    437                 if SectionItem[0].strip().upper() == DT.TAB_INF_FIXED_PCD.upper() or \
    438                     SectionItem[0].strip().upper() == DT.TAB_INF_PATCH_PCD.upper() or \
    439                     SectionItem[0].strip().upper() == DT.TAB_INF_PCD_EX.upper() or \
    440                     SectionItem[0].strip().upper() == DT.TAB_INF_PCD.upper() or \
    441                     SectionItem[0].strip().upper() == DT.TAB_INF_FEATURE_PCD.upper():
    442                     ArchList = GetSplitValueList(SectionItem[1].strip(), ' ')
    443                 else:
    444                     ArchList = [SectionItem[1].strip()]
    445                     
    446                 for Arch in ArchList:
    447                     if (not IsValidArch(Arch)) and \
    448                         (SectionItem[0].strip().upper() != DT.TAB_DEPEX.upper()) and \
    449                         (SectionItem[0].strip().upper() != DT.TAB_USER_EXTENSIONS.upper()) and \
    450                         (SectionItem[0].strip().upper() != DT.TAB_COMMON_DEFINES.upper()):
    451                         Logger.Error("InfParser", 
    452                                      FORMAT_INVALID,
    453                                      ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(SectionItem[1]), 
    454                                      File=self.FullPath,
    455                                      Line=LineNo, ExtraData=Line)
    456                 #

    457                 # Check if the ModuleType is valid

    458                 #

    459                 ChkModSectionList = ['LIBRARYCLASSES']
    460                 if (self.SectionHeaderContent[0][0].upper() in ChkModSectionList):
    461                     if SectionItem[2].strip().upper():
    462                         MoudleTypeList = GetSplitValueList(
    463                                     SectionItem[2].strip().upper())
    464                         if (not IsValidInfMoudleTypeList(MoudleTypeList)):
    465                             Logger.Error("InfParser",
    466                                          FORMAT_INVALID,
    467                                          ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(SectionItem[2]),
    468                                          File=self.FullPath, Line=LineNo,
    469                                          ExtraData=Line)
    470                               
    471     ## _CallSectionParsers

    472     #

    473     #

    474     def _CallSectionParsers(self, CurrentSection, DefineSectionParsedFlag, 
    475                             SectionLines, InfSectionCommonDefObj, LineNo):
    476         if CurrentSection == DT.MODEL_META_DATA_DEFINE:
    477             if not DefineSectionParsedFlag:
    478                 self.InfDefineParser(SectionLines,
    479                                      self.InfDefSection,
    480                                      self.FullPath,
    481                                      InfSectionCommonDefObj)
    482                 DefineSectionParsedFlag = True
    483             else:
    484                 Logger.Error("Parser", 
    485                              PARSER_ERROR, 
    486                              ST.ERR_INF_PARSER_MULTI_DEFINE_SECTION, 
    487                              File=self.FullPath, 
    488                              RaiseError = Logger.IS_RAISE_ERROR)
    489             
    490         elif CurrentSection == DT.MODEL_META_DATA_BUILD_OPTION:
    491             self.InfBuildOptionParser(SectionLines,
    492                                       self.InfBuildOptionSection,
    493                                       self.FullPath)
    494             
    495         elif CurrentSection == DT.MODEL_EFI_LIBRARY_CLASS:
    496             self.InfLibraryParser(SectionLines,
    497                                   self.InfLibraryClassSection,
    498                                   self.FullPath)
    499             
    500         elif CurrentSection == DT.MODEL_META_DATA_PACKAGE:
    501             self.InfPackageParser(SectionLines,
    502                                   self.InfPackageSection,
    503                                   self.FullPath)
    504         #

    505         # [Pcd] Sections, put it together

    506         #

    507         elif CurrentSection == DT.MODEL_PCD_FIXED_AT_BUILD or \
    508              CurrentSection == DT.MODEL_PCD_PATCHABLE_IN_MODULE or \
    509              CurrentSection == DT.MODEL_PCD_FEATURE_FLAG or \
    510              CurrentSection == DT.MODEL_PCD_DYNAMIC_EX or \
    511              CurrentSection == DT.MODEL_PCD_DYNAMIC:
    512             self.InfPcdParser(SectionLines,
    513                               self.InfPcdSection,
    514                               self.FullPath)
    515             
    516         elif CurrentSection == DT.MODEL_EFI_SOURCE_FILE:
    517             self.InfSourceParser(SectionLines,
    518                                  self.InfSourcesSection,
    519                                  self.FullPath)
    520             
    521         elif CurrentSection == DT.MODEL_META_DATA_USER_EXTENSION:
    522             self.InfUserExtensionParser(SectionLines,
    523                                         self.InfUserExtensionSection,
    524                                         self.FullPath)
    525             
    526         elif CurrentSection == DT.MODEL_EFI_PROTOCOL:
    527             self.InfProtocolParser(SectionLines,
    528                                    self.InfProtocolSection,
    529                                    self.FullPath)
    530             
    531         elif CurrentSection == DT.MODEL_EFI_PPI:
    532             self.InfPpiParser(SectionLines,
    533                               self.InfPpiSection,
    534                               self.FullPath)
    535             
    536         elif CurrentSection == DT.MODEL_EFI_GUID:
    537             self.InfGuidParser(SectionLines,
    538                                self.InfGuidSection,
    539                                self.FullPath)
    540             
    541         elif CurrentSection == DT.MODEL_EFI_DEPEX:
    542             self.InfDepexParser(SectionLines,
    543                                 self.InfDepexSection,
    544                                 self.FullPath)
    545             
    546         elif CurrentSection == DT.MODEL_EFI_BINARY_FILE:
    547             self.InfBinaryParser(SectionLines,
    548                                  self.InfBinariesSection,
    549                                  self.FullPath)
    550         #

    551         # Unknown section type found, raise error.

    552         #

    553         else:
    554             if len(self.SectionHeaderContent) >= 1:
    555                 Logger.Error("Parser", 
    556                              PARSER_ERROR, 
    557                              ST.ERR_INF_PARSER_UNKNOWN_SECTION, 
    558                              File=self.FullPath, Line=LineNo, 
    559                              RaiseError = Logger.IS_RAISE_ERROR)
    560             else:
    561                 Logger.Error("Parser", 
    562                              PARSER_ERROR, 
    563                              ST.ERR_INF_PARSER_NO_SECTION_ERROR, 
    564                              File=self.FullPath, Line=LineNo, 
    565                              RaiseError = Logger.IS_RAISE_ERROR)
    566                 
    567         return DefineSectionParsedFlag   
    568         
    569     def _ExtractEventHobBootMod(self, FileLinesList):
    570         SpecialSectionStart = False
    571         CheckLocation = False
    572         GFindSpecialCommentRe = \
    573         re.compile(r"""#(?:\s*)\[(.*?)\](?:.*)""", re.DOTALL)
    574         GFindNewSectionRe2 = \
    575         re.compile(r"""#?(\s*)\[(.*?)\](.*)""", re.DOTALL)
    576         LineNum = 0
    577         Element = []
    578         for Line in FileLinesList:
    579             Line = Line.strip()
    580             LineNum += 1
    581             MatchObject = GFindSpecialCommentRe.search(Line)
    582             if MatchObject:
    583                 SpecialSectionStart = True
    584                 Element = []
    585                 if MatchObject.group(1).upper().startswith("EVENT"):
    586                     List = self.EventList
    587                 elif MatchObject.group(1).upper().startswith("HOB"):
    588                     List = self.HobList
    589                 elif MatchObject.group(1).upper().startswith("BOOTMODE"):
    590                     List = self.BootModeList
    591                 else:
    592                     SpecialSectionStart = False
    593                     CheckLocation = False
    594                 if SpecialSectionStart:
    595                     Element.append([Line, LineNum])
    596                     List.append(Element)
    597             else:
    598                 #

    599                 # if currently in special section, try to detect end of current section

    600                 #

    601                 MatchObject = GFindNewSectionRe2.search(Line)
    602                 if SpecialSectionStart:
    603                     if MatchObject:
    604                         SpecialSectionStart = False
    605                         CheckLocation = False
    606                         Element = []
    607                     elif not Line:
    608                         SpecialSectionStart = False
    609                         CheckLocation = True
    610                         Element = []                        
    611                     else:
    612                         if not Line.startswith(DT.TAB_COMMENT_SPLIT):
    613                             Logger.Warn("Parser", 
    614                                          ST.WARN_SPECIAL_SECTION_LOCATION_WRONG, 
    615                                          File=self.FullPath, Line=LineNum)
    616                             SpecialSectionStart = False
    617                             CheckLocation = False
    618                             Element = []
    619                         else:
    620                             Element.append([Line, LineNum]) 
    621                 else:
    622                     if CheckLocation:
    623                         if MatchObject:
    624                             CheckLocation = False
    625                         elif Line:
    626                             Logger.Warn("Parser", 
    627                                          ST.WARN_SPECIAL_SECTION_LOCATION_WRONG, 
    628                                          File=self.FullPath, Line=LineNum)    
    629                             CheckLocation = False
    630                     
    631         if len(self.BootModeList) >= 1:
    632             self.InfSpecialCommentParser(self.BootModeList, 
    633                                          self.InfSpecialCommentSection, 
    634                                          self.FileName, 
    635                                          DT.TYPE_BOOTMODE_SECTION)
    636         
    637         if len(self.EventList) >= 1:
    638             self.InfSpecialCommentParser(self.EventList, 
    639                                          self.InfSpecialCommentSection,
    640                                          self.FileName, 
    641                                          DT.TYPE_EVENT_SECTION)
    642             
    643         if len(self.HobList) >= 1:
    644             self.InfSpecialCommentParser(self.HobList, 
    645                                          self.InfSpecialCommentSection, 
    646                                          self.FileName, 
    647                                          DT.TYPE_HOB_SECTION)
    648     ## _ProcessLastSection

    649     #

    650     #

    651     def _ProcessLastSection(self, SectionLines, Line, LineNo, CurrentSection):
    652         #

    653         # The last line is a section header. will discard it.

    654         #

    655         if not (Line.startswith(DT.TAB_SECTION_START) and Line.find(DT.TAB_SECTION_END) > -1):                      
    656             SectionLines.append((Line, LineNo))
    657             
    658         if len(self.SectionHeaderContent) >= 1:
    659             TemSectionName = self.SectionHeaderContent[0][0].upper()
    660             if TemSectionName.upper() not in gINF_SECTION_DEF.keys():
    661                 Logger.Error("InfParser", 
    662                              FORMAT_INVALID, 
    663                              ST.ERR_INF_PARSER_UNKNOWN_SECTION, 
    664                              File=self.FullPath, 
    665                              Line=LineNo, 
    666                              ExtraData=Line,
    667                              RaiseError = Logger.IS_RAISE_ERROR
    668                              ) 
    669             else:
    670                 CurrentSection = gINF_SECTION_DEF[TemSectionName]
    671                 self.LastSectionHeaderContent = self.SectionHeaderContent
    672             
    673         return SectionLines, CurrentSection
    674 
    675 ## _ConvertSecNameToType

    676 #

    677 #

    678 def _ConvertSecNameToType(SectionName): 
    679     SectionType = ''
    680     if SectionName.upper() not in gINF_SECTION_DEF.keys():
    681         SectionType = DT.MODEL_UNKNOWN                    
    682     else:
    683         SectionType = gINF_SECTION_DEF[SectionName.upper()]  
    684     
    685     return SectionType      
    686         
    687