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

      2 # This file is used to define common parsing related functions used in parsing INF/DEC/DSC process

      3 #

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

      5 # This program and the accompanying materials

      6 # are licensed and made available under the terms and conditions of the BSD License

      7 # which accompanies this distribution.  The full text of the license may be found at

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

      9 #

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

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

     12 #

     13 
     14 ##

     15 # Import Modules

     16 #

     17 from String import *
     18 from CommonDataClass.DataClass import *
     19 from DataType import *
     20 
     21 ## ParseDefineMacro

     22 #

     23 # Search whole table to find all defined Macro and replaced them with the real values

     24 #

     25 def ParseDefineMacro2(Table, RecordSets, GlobalMacro):
     26     Macros = {}
     27     #

     28     # Find all DEFINE macros in section [Header] and its section

     29     #

     30     SqlCommand = """select Value1, Value2, BelongsToItem, StartLine, Arch from %s
     31                     where Model = %s
     32                     and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE)
     33     RecordSet = Table.Exec(SqlCommand)
     34     for Record in RecordSet:
     35         Macros[Record[0]] = Record[1]
     36 
     37     #

     38     # Overrided by Global Macros

     39     #

     40     for Key in GlobalMacro.keys():
     41         Macros[Key] = GlobalMacro[Key]
     42 
     43     #

     44     # Replace the Macros

     45     #

     46     for Key in RecordSets.keys():
     47         if RecordSets[Key] != []:
     48             for Item in RecordSets[Key]:
     49                 Item[0] = ReplaceMacro(Item[0], Macros)
     50 
     51 ## ParseDefineMacro

     52 #

     53 # Search whole table to find all defined Macro and replaced them with the real values

     54 #

     55 def ParseDefineMacro(Table, GlobalMacro):
     56     Macros = {}
     57     #

     58     # Find all DEFINE macros

     59     #

     60     SqlCommand = """select Value1, Value2, BelongsToItem, StartLine, Arch from %s
     61                     where Model = %s
     62                     and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE)
     63     RecordSet = Table.Exec(SqlCommand)
     64     for Record in RecordSet:
     65 #***************************************************************************************************************************************************

     66 #            The follow SqlCommand (expr replace) is not supported in Sqlite 3.3.4 which is used in Python 2.5                                     *

     67 #            Reserved Only                                                                                                                         *

     68 #            SqlCommand = """update %s set Value1 = replace(Value1, '%s', '%s')                                                                    *

     69 #                            where ID in (select ID from %s                                                                                        *

     70 #                                         where Model = %s                                                                                         *

     71 #                                         and Value1 like '%%%s%%'                                                                                 *

     72 #                                         and StartLine > %s                                                                                       *

     73 #                                         and Enabled > -1                                                                                         *

     74 #                                         and Arch = '%s')""" % \                                                                                  *

     75 #                                         (self.TblDsc.Table, Record[0], Record[1], self.TblDsc.Table, Record[2], Record[1], Record[3], Record[4]) *

     76 #***************************************************************************************************************************************************

     77         Macros[Record[0]] = Record[1]
     78 
     79     #

     80     # Overrided by Global Macros

     81     #

     82     for Key in GlobalMacro.keys():
     83         Macros[Key] = GlobalMacro[Key]
     84 
     85     #

     86     # Found all defined macro and replaced

     87     #

     88     SqlCommand = """select ID, Value1 from %s
     89                     where Model != %s
     90                     and Value1 like '%%$(%%' and Value1 like '%%)%%'
     91                     and Enabled > -1"""  % (Table.Table, MODEL_META_DATA_DEFINE)
     92     FoundRecords = Table.Exec(SqlCommand)
     93     for FoundRecord in FoundRecords:
     94         NewValue = ReplaceMacro(FoundRecord[1], Macros)
     95         SqlCommand = """update %s set Value1 = '%s'
     96                         where ID = %s""" % (Table.Table, ConvertToSqlString2(NewValue), FoundRecord[0])
     97         Table.Exec(SqlCommand)
     98 
     99 ##QueryDefinesItem

    100 #

    101 # Search item of section [Defines] by name, return its values

    102 #

    103 # @param Table: The Table to be executed

    104 # @param Name:  The Name of item of section [Defines]

    105 # @param Arch:  The Arch of item of section [Defines]

    106 #

    107 # @retval RecordSet: A list of all matched records

    108 #

    109 def QueryDefinesItem(Table, Name, Arch, BelongsToFile):
    110     SqlCommand = """select Value2 from %s
    111                     where Model = %s
    112                     and Value1 = '%s'
    113                     and Arch = '%s'
    114                     and BelongsToFile = %s
    115                     and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Name), ConvertToSqlString2(Arch), BelongsToFile)
    116     RecordSet = Table.Exec(SqlCommand)
    117     if len(RecordSet) < 1:
    118         SqlCommand = """select Value2 from %s
    119                     where Model = %s
    120                     and Value1 = '%s'
    121                     and Arch = '%s'
    122                     and BelongsToFile = %s
    123                     and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Name), ConvertToSqlString2(TAB_ARCH_COMMON.upper()), BelongsToFile)
    124         RecordSet = Table.Exec(SqlCommand)
    125     if len(RecordSet) == 1:
    126         if Name == TAB_INF_DEFINES_LIBRARY_CLASS:
    127             return [RecordSet[0][0]]
    128         else:
    129             return GetSplitValueList(RecordSet[0][0])
    130     elif len(RecordSet) < 1:
    131         return ['']
    132     elif len(RecordSet) > 1:
    133         RetVal = []
    134         for Record in RecordSet:
    135             if Name == TAB_INF_DEFINES_LIBRARY_CLASS:
    136                 RetVal.append(Record[0])
    137             else:
    138                 Items = GetSplitValueList(Record[0])
    139                 for Item in Items:
    140                     RetVal.append(Item)
    141         return RetVal
    142 
    143 ##QueryDefinesItem

    144 #

    145 # Search item of section [Defines] by name, return its values

    146 #

    147 # @param Table: The Table to be executed

    148 # @param Name:  The Name of item of section [Defines]

    149 # @param Arch:  The Arch of item of section [Defines]

    150 #

    151 # @retval RecordSet: A list of all matched records

    152 #

    153 def QueryDefinesItem2(Table, Arch, BelongsToFile):
    154     SqlCommand = """select Value1, Value2, StartLine from %s
    155                     where Model = %s
    156                     and Arch = '%s'
    157                     and BelongsToFile = %s
    158                     and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Arch), BelongsToFile)
    159     RecordSet = Table.Exec(SqlCommand)
    160     if len(RecordSet) < 1:
    161         SqlCommand = """select Value1, Value2, StartLine from %s
    162                     where Model = %s
    163                     and Arch = '%s'
    164                     and BelongsToFile = %s
    165                     and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(TAB_ARCH_COMMON), BelongsToFile)
    166         RecordSet = Table.Exec(SqlCommand)
    167 
    168     return RecordSet
    169 
    170 ##QueryDscItem

    171 #

    172 # Search all dsc item for a specific section

    173 #

    174 # @param Table: The Table to be executed

    175 # @param Model:  The type of section

    176 #

    177 # @retval RecordSet: A list of all matched records

    178 #

    179 def QueryDscItem(Table, Model, BelongsToItem, BelongsToFile):
    180     SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s
    181                     where Model = %s
    182                     and BelongsToItem = %s
    183                     and BelongsToFile = %s
    184                     and Enabled > -1""" % (Table.Table, Model, BelongsToItem, BelongsToFile)
    185     return Table.Exec(SqlCommand)
    186 
    187 ##QueryDecItem

    188 #

    189 # Search all dec item for a specific section

    190 #

    191 # @param Table: The Table to be executed

    192 # @param Model:  The type of section

    193 #

    194 # @retval RecordSet: A list of all matched records

    195 #

    196 def QueryDecItem(Table, Model, BelongsToItem):
    197     SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s
    198                     where Model = %s
    199                     and BelongsToItem = %s
    200                     and Enabled > -1""" % (Table.Table, Model, BelongsToItem)
    201     return Table.Exec(SqlCommand)
    202 
    203 ##QueryInfItem

    204 #

    205 # Search all dec item for a specific section

    206 #

    207 # @param Table: The Table to be executed

    208 # @param Model: The type of section

    209 #

    210 # @retval RecordSet: A list of all matched records

    211 #

    212 def QueryInfItem(Table, Model, BelongsToItem):
    213     SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s
    214                     where Model = %s
    215                     and BelongsToItem = %s
    216                     and Enabled > -1""" % (Table.Table, Model, BelongsToItem)
    217     return Table.Exec(SqlCommand)
    218 
    219 ## GetBuildOption

    220 #

    221 # Parse a string with format "[<Family>:]<ToolFlag>=Flag"

    222 # Return (Family, ToolFlag, Flag)

    223 #

    224 # @param String:  String with BuildOption statement

    225 # @param File:    The file which defines build option, used in error report

    226 #

    227 # @retval truple() A truple structure as (Family, ToolChain, Flag)

    228 #

    229 def GetBuildOption(String, File, LineNo = -1):
    230     (Family, ToolChain, Flag) = ('', '', '')
    231     if String.find(TAB_EQUAL_SPLIT) < 0:
    232         RaiseParserError(String, 'BuildOptions', File, '[<Family>:]<ToolFlag>=Flag', LineNo)
    233     else:
    234         List = GetSplitValueList(String, TAB_EQUAL_SPLIT, MaxSplit = 1)
    235         if List[0].find(':') > -1:
    236             Family = List[0][ : List[0].find(':')].strip()
    237             ToolChain = List[0][List[0].find(':') + 1 : ].strip()
    238         else:
    239             ToolChain = List[0].strip()
    240         Flag = List[1].strip()
    241     return (Family, ToolChain, Flag)
    242 
    243 ## Get Library Class

    244 #

    245 # Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance>

    246 #

    247 # @param Item:           String as <LibraryClassKeyWord>|<LibraryInstance>

    248 # @param ContainerFile:  The file which describes the library class, used for error report

    249 #

    250 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item

    251 #

    252 def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo = -1):
    253     List = GetSplitValueList(Item[0])
    254     SupMod = SUP_MODULE_LIST_STRING
    255     if len(List) != 2:
    256         RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, '<LibraryClassKeyWord>|<LibraryInstance>')
    257     else:
    258         CheckFileType(List[1], '.Inf', ContainerFile, 'library class instance', Item[0], LineNo)
    259         CheckFileExist(WorkspaceDir, List[1], ContainerFile, 'LibraryClasses', Item[0], LineNo)
    260         if Item[1] != '':
    261             SupMod = Item[1]
    262 
    263     return (List[0], List[1], SupMod)
    264 
    265 ## Get Library Class

    266 #

    267 # Get Library of Dsc as <LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]

    268 #

    269 # @param Item:           String as <LibraryClassKeyWord>|<LibraryInstance>

    270 # @param ContainerFile:  The file which describes the library class, used for error report

    271 #

    272 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item

    273 #

    274 def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo = -1):
    275     ItemList = GetSplitValueList((Item[0] + DataType.TAB_VALUE_SPLIT * 2))
    276     SupMod = SUP_MODULE_LIST_STRING
    277 
    278     if len(ItemList) > 5:
    279         RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, '<LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]')
    280     else:
    281         CheckFileType(ItemList[1], '.Inf', ContainerFile, 'LibraryClasses', Item[0], LineNo)
    282         CheckFileExist(WorkspaceDir, ItemList[1], ContainerFile, 'LibraryClasses', Item[0], LineNo)
    283         if ItemList[2] != '':
    284             CheckPcdTokenInfo(ItemList[2], 'LibraryClasses', ContainerFile, LineNo)
    285         if Item[1] != '':
    286             SupMod = Item[1]
    287 
    288     return (ItemList[0], ItemList[1], ItemList[2], SupMod)
    289 
    290 ## CheckPcdTokenInfo

    291 #

    292 # Check if PcdTokenInfo is following <TokenSpaceGuidCName>.<PcdCName>

    293 #

    294 # @param TokenInfoString:  String to be checked

    295 # @param Section:          Used for error report

    296 # @param File:             Used for error report

    297 #

    298 # @retval True PcdTokenInfo is in correct format

    299 #

    300 def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo = -1):
    301     Format = '<TokenSpaceGuidCName>.<PcdCName>'
    302     if TokenInfoString != '' and TokenInfoString != None:
    303         TokenInfoList = GetSplitValueList(TokenInfoString, TAB_SPLIT)
    304         if len(TokenInfoList) == 2:
    305             return True
    306 
    307     RaiseParserError(TokenInfoString, Section, File, Format, LineNo)
    308 
    309 ## Get Pcd

    310 #

    311 # Get Pcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]

    312 #

    313 # @param Item:           String as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]

    314 # @param ContainerFile:  The file which describes the pcd, used for error report

    315 #

    316 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)

    317 #

    318 def GetPcd(Item, Type, ContainerFile, LineNo = -1):
    319     TokenGuid, TokenName, Value, MaximumDatumSize, Token = '', '', '', '', ''
    320     List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2)
    321 
    322     if len(List) < 4 or len(List) > 6:
    323         RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]', LineNo)
    324     else:
    325         Value = List[1]
    326         MaximumDatumSize = List[2]
    327         Token = List[3]
    328 
    329     if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
    330         (TokenGuid, TokenName) = GetSplitValueList(List[0], TAB_SPLIT)
    331 
    332     return (TokenName, TokenGuid, Value, MaximumDatumSize, Token, Type)
    333 
    334 ## Get FeatureFlagPcd

    335 #

    336 # Get FeatureFlagPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE

    337 #

    338 # @param Item:           String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE

    339 # @param ContainerFile:  The file which describes the pcd, used for error report

    340 #

    341 # @retval (TokenInfo[1], TokenInfo[0], List[1], Type)

    342 #

    343 def GetFeatureFlagPcd(Item, Type, ContainerFile, LineNo = -1):
    344     TokenGuid, TokenName, Value = '', '', ''
    345     List = GetSplitValueList(Item)
    346     if len(List) != 2:
    347         RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE', LineNo)
    348     else:
    349         Value = List[1]
    350     if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
    351         (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)
    352 
    353     return (TokenName, TokenGuid, Value, Type)
    354 
    355 ## Get DynamicDefaultPcd

    356 #

    357 # Get DynamicDefaultPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]

    358 #

    359 # @param Item:           String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE

    360 # @param ContainerFile:  The file which describes the pcd, used for error report

    361 #

    362 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)

    363 #

    364 def GetDynamicDefaultPcd(Item, Type, ContainerFile, LineNo = -1):
    365     TokenGuid, TokenName, Value, DatumTyp, MaxDatumSize = '', '', '', '', ''
    366     List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2)
    367     if len(List) < 4 or len(List) > 8:
    368         RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]', LineNo)
    369     else:
    370         Value = List[1]
    371         DatumTyp = List[2]
    372         MaxDatumSize = List[3]
    373     if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
    374         (TokenGuid, TokenName) = GetSplitValueList(List[0], TAB_SPLIT)
    375 
    376     return (TokenName, TokenGuid, Value, DatumTyp, MaxDatumSize, Type)
    377 
    378 ## Get DynamicHiiPcd

    379 #

    380 # Get DynamicHiiPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]

    381 #

    382 # @param Item:           String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE

    383 # @param ContainerFile:  The file which describes the pcd, used for error report

    384 #

    385 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], List[4], List[5], Type)

    386 #

    387 def GetDynamicHiiPcd(Item, Type, ContainerFile, LineNo = -1):
    388     TokenGuid, TokenName, L1, L2, L3, L4, L5 = '', '', '', '', '', '', ''
    389     List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2)
    390     if len(List) < 6 or len(List) > 8:
    391         RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]', LineNo)
    392     else:
    393         L1, L2, L3, L4, L5 = List[1], List[2], List[3], List[4], List[5]
    394     if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
    395         (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)
    396 
    397     return (TokenName, TokenGuid, L1, L2, L3, L4, L5, Type)
    398 
    399 ## Get DynamicVpdPcd

    400 #

    401 # Get DynamicVpdPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]

    402 #

    403 # @param Item:           String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE

    404 # @param ContainerFile:  The file which describes the pcd, used for error report

    405 #

    406 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], Type)

    407 #

    408 def GetDynamicVpdPcd(Item, Type, ContainerFile, LineNo = -1):
    409     TokenGuid, TokenName, L1, L2 = '', '', '', ''
    410     List = GetSplitValueList(Item + TAB_VALUE_SPLIT)
    411     if len(List) < 3 or len(List) > 4:
    412         RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]', LineNo)
    413     else:
    414         L1, L2 = List[1], List[2]
    415     if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
    416         (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)
    417 
    418     return (TokenName, TokenGuid, L1, L2, Type)
    419 
    420 ## GetComponent

    421 #

    422 # Parse block of the components defined in dsc file

    423 # Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]

    424 #

    425 # @param Lines:             The content to be parsed

    426 # @param KeyValues:         To store data after parsing

    427 #

    428 # @retval True Get component successfully

    429 #

    430 def GetComponent(Lines, KeyValues):
    431     (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False)
    432     ListItem = None
    433     LibraryClassItem = []
    434     BuildOption = []
    435     Pcd = []
    436 
    437     for Line in Lines:
    438         Line = Line[0]
    439 
    440         #

    441         # Ignore !include statement

    442         #

    443         if Line.upper().find(TAB_INCLUDE.upper() + ' ') > -1 or Line.upper().find(TAB_DEFINE + ' ') > -1:
    444             continue
    445 
    446         if findBlock == False:
    447             ListItem = Line
    448             #

    449             # find '{' at line tail

    450             #

    451             if Line.endswith('{'):
    452                 findBlock = True
    453                 ListItem = CleanString(Line.rsplit('{', 1)[0], DataType.TAB_COMMENT_SPLIT)
    454 
    455         #

    456         # Parse a block content

    457         #

    458         if findBlock:
    459             if Line.find('<LibraryClasses>') != -1:
    460                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (True, False, False, False, False, False, False)
    461                 continue
    462             if Line.find('<BuildOptions>') != -1:
    463                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, True, False, False, False, False, False)
    464                 continue
    465             if Line.find('<PcdsFeatureFlag>') != -1:
    466                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, True, False, False, False, False)
    467                 continue
    468             if Line.find('<PcdsPatchableInModule>') != -1:
    469                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, True, False, False, False)
    470                 continue
    471             if Line.find('<PcdsFixedAtBuild>') != -1:
    472                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, True, False, False)
    473                 continue
    474             if Line.find('<PcdsDynamic>') != -1:
    475                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, True, False)
    476                 continue
    477             if Line.find('<PcdsDynamicEx>') != -1:
    478                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, True)
    479                 continue
    480             if Line.endswith('}'):
    481                 #

    482                 # find '}' at line tail

    483                 #

    484                 KeyValues.append([ListItem, LibraryClassItem, BuildOption, Pcd])
    485                 (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False)
    486                 LibraryClassItem, BuildOption, Pcd = [], [], []
    487                 continue
    488 
    489         if findBlock:
    490             if findLibraryClass:
    491                 LibraryClassItem.append(Line)
    492             elif findBuildOption:
    493                 BuildOption.append(Line)
    494             elif findPcdsFeatureFlag:
    495                 Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG_NULL, Line))
    496             elif findPcdsPatchableInModule:
    497                 Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE_NULL, Line))
    498             elif findPcdsFixedAtBuild:
    499                 Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD_NULL, Line))
    500             elif findPcdsDynamic:
    501                 Pcd.append((DataType.TAB_PCDS_DYNAMIC_DEFAULT_NULL, Line))
    502             elif findPcdsDynamicEx:
    503                 Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL, Line))
    504         else:
    505             KeyValues.append([ListItem, [], [], []])
    506 
    507     return True
    508 
    509 ## GetExec

    510 #

    511 # Parse a string with format "InfFilename [EXEC = ExecFilename]"

    512 # Return (InfFilename, ExecFilename)

    513 #

    514 # @param String:  String with EXEC statement

    515 #

    516 # @retval truple() A pair as (InfFilename, ExecFilename)

    517 #

    518 def GetExec(String):
    519     InfFilename = ''
    520     ExecFilename = ''
    521     if String.find('EXEC') > -1:
    522         InfFilename = String[ : String.find('EXEC')].strip()
    523         ExecFilename = String[String.find('EXEC') + len('EXEC') : ].strip()
    524     else:
    525         InfFilename = String.strip()
    526 
    527     return (InfFilename, ExecFilename)
    528 
    529 ## GetComponents

    530 #

    531 # Parse block of the components defined in dsc file

    532 # Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]

    533 #

    534 # @param Lines:             The content to be parsed

    535 # @param Key:               Reserved

    536 # @param KeyValues:         To store data after parsing

    537 # @param CommentCharacter:  Comment char, used to ignore comment content

    538 #

    539 # @retval True Get component successfully

    540 #

    541 def GetComponents(Lines, Key, KeyValues, CommentCharacter):
    542     if Lines.find(DataType.TAB_SECTION_END) > -1:
    543         Lines = Lines.split(DataType.TAB_SECTION_END, 1)[1]
    544     (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False)
    545     ListItem = None
    546     LibraryClassItem = []
    547     BuildOption = []
    548     Pcd = []
    549 
    550     LineList = Lines.split('\n')
    551     for Line in LineList:
    552         Line = CleanString(Line, CommentCharacter)
    553         if Line == None or Line == '':
    554             continue
    555 
    556         if findBlock == False:
    557             ListItem = Line
    558             #

    559             # find '{' at line tail

    560             #

    561             if Line.endswith('{'):
    562                 findBlock = True
    563                 ListItem = CleanString(Line.rsplit('{', 1)[0], CommentCharacter)
    564 
    565         #

    566         # Parse a block content

    567         #

    568         if findBlock:
    569             if Line.find('<LibraryClasses>') != -1:
    570                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (True, False, False, False, False, False, False)
    571                 continue
    572             if Line.find('<BuildOptions>') != -1:
    573                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, True, False, False, False, False, False)
    574                 continue
    575             if Line.find('<PcdsFeatureFlag>') != -1:
    576                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, True, False, False, False, False)
    577                 continue
    578             if Line.find('<PcdsPatchableInModule>') != -1:
    579                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, True, False, False, False)
    580                 continue
    581             if Line.find('<PcdsFixedAtBuild>') != -1:
    582                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, True, False, False)
    583                 continue
    584             if Line.find('<PcdsDynamic>') != -1:
    585                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, True, False)
    586                 continue
    587             if Line.find('<PcdsDynamicEx>') != -1:
    588                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, True)
    589                 continue
    590             if Line.endswith('}'):
    591                 #

    592                 # find '}' at line tail

    593                 #

    594                 KeyValues.append([ListItem, LibraryClassItem, BuildOption, Pcd])
    595                 (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False)
    596                 LibraryClassItem, BuildOption, Pcd = [], [], []
    597                 continue
    598 
    599         if findBlock:
    600             if findLibraryClass:
    601                 LibraryClassItem.append(Line)
    602             elif findBuildOption:
    603                 BuildOption.append(Line)
    604             elif findPcdsFeatureFlag:
    605                 Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG, Line))
    606             elif findPcdsPatchableInModule:
    607                 Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE, Line))
    608             elif findPcdsFixedAtBuild:
    609                 Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD, Line))
    610             elif findPcdsDynamic:
    611                 Pcd.append((DataType.TAB_PCDS_DYNAMIC, Line))
    612             elif findPcdsDynamicEx:
    613                 Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX, Line))
    614         else:
    615             KeyValues.append([ListItem, [], [], []])
    616 
    617     return True
    618 
    619 ## Get Source

    620 #

    621 # Get Source of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]

    622 #

    623 # @param Item:           String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]

    624 # @param ContainerFile:  The file which describes the library class, used for error report

    625 #

    626 # @retval (List[0], List[1], List[2], List[3], List[4])

    627 #

    628 def GetSource(Item, ContainerFile, FileRelativePath, LineNo = -1):
    629     ItemNew = Item + DataType.TAB_VALUE_SPLIT * 4
    630     List = GetSplitValueList(ItemNew)
    631     if len(List) < 5 or len(List) > 9:
    632         RaiseParserError(Item, 'Sources', ContainerFile, '<Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]', LineNo)
    633     List[0] = NormPath(List[0])
    634     CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Sources', Item, LineNo)
    635     if List[4] != '':
    636         CheckPcdTokenInfo(List[4], 'Sources', ContainerFile, LineNo)
    637 
    638     return (List[0], List[1], List[2], List[3], List[4])
    639 
    640 ## Get Binary

    641 #

    642 # Get Binary of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]

    643 #

    644 # @param Item:           String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]

    645 # @param ContainerFile:  The file which describes the library class, used for error report

    646 #

    647 # @retval (List[0], List[1], List[2], List[3])

    648 # @retval List

    649 #

    650 def GetBinary(Item, ContainerFile, FileRelativePath, LineNo = -1):
    651     ItemNew = Item + DataType.TAB_VALUE_SPLIT
    652     List = GetSplitValueList(ItemNew)
    653     if len(List) != 4 and len(List) != 5:
    654         RaiseParserError(Item, 'Binaries', ContainerFile, "<FileType>|<Filename>|<Target>[|<TokenSpaceGuidCName>.<PcdCName>]", LineNo)
    655     else:
    656         if List[3] != '':
    657             CheckPcdTokenInfo(List[3], 'Binaries', ContainerFile, LineNo)
    658 
    659     if len(List) == 4:
    660         return (List[0], List[1], List[2], List[3])
    661     elif len(List) == 3:
    662         return (List[0], List[1], List[2], '')
    663     elif len(List) == 2:
    664         return (List[0], List[1], '', '')
    665     elif len(List) == 1:
    666         return (List[0], '', '', '')
    667 
    668 ## Get Guids/Protocols/Ppis

    669 #

    670 # Get Guids/Protocols/Ppis of Inf as <GuidCName>[|<PcdFeatureFlag>]

    671 #

    672 # @param Item:           String as <GuidCName>[|<PcdFeatureFlag>]

    673 # @param Type:           Type of parsing string

    674 # @param ContainerFile:  The file which describes the library class, used for error report

    675 #

    676 # @retval (List[0], List[1])

    677 #

    678 def GetGuidsProtocolsPpisOfInf(Item, Type, ContainerFile, LineNo = -1):
    679     ItemNew = Item + TAB_VALUE_SPLIT
    680     List = GetSplitValueList(ItemNew)
    681     if List[1] != '':
    682         CheckPcdTokenInfo(List[1], Type, ContainerFile, LineNo)
    683 
    684     return (List[0], List[1])
    685 
    686 ## Get Guids/Protocols/Ppis

    687 #

    688 # Get Guids/Protocols/Ppis of Dec as <GuidCName>=<GuidValue>

    689 #

    690 # @param Item:           String as <GuidCName>=<GuidValue>

    691 # @param Type:           Type of parsing string

    692 # @param ContainerFile:  The file which describes the library class, used for error report

    693 #

    694 # @retval (List[0], List[1])

    695 #

    696 def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo = -1):
    697     List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT)
    698     if len(List) != 2:
    699         RaiseParserError(Item, Type, ContainerFile, '<CName>=<GuidValue>', LineNo)
    700 
    701     return (List[0], List[1])
    702 
    703 ## GetPackage

    704 #

    705 # Get Package of Inf as <PackagePath>[|<PcdFeatureFlag>]

    706 #

    707 # @param Item:           String as <PackagePath>[|<PcdFeatureFlag>]

    708 # @param Type:           Type of parsing string

    709 # @param ContainerFile:  The file which describes the library class, used for error report

    710 #

    711 # @retval (List[0], List[1])

    712 #

    713 def GetPackage(Item, ContainerFile, FileRelativePath, LineNo = -1):
    714     ItemNew = Item + TAB_VALUE_SPLIT
    715     List = GetSplitValueList(ItemNew)
    716     CheckFileType(List[0], '.Dec', ContainerFile, 'package', List[0], LineNo)
    717     CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Packages', List[0], LineNo)
    718 
    719     if List[1] != '':
    720         CheckPcdTokenInfo(List[1], 'Packages', ContainerFile, LineNo)
    721 
    722     return (List[0], List[1])
    723 
    724 ## Get Pcd Values of Inf

    725 #

    726 # Get Pcd of Inf as <TokenSpaceGuidCName>.<PcdCName>[|<Value>]

    727 #

    728 # @param Item:  The string describes pcd

    729 # @param Type:  The type of Pcd

    730 # @param File:  The file which describes the pcd, used for error report

    731 #

    732 # @retval (TokenSpcCName, TokenCName, Value, ItemType) Formatted Pcd Item

    733 #

    734 def GetPcdOfInf(Item, Type, File, LineNo):
    735     Format = '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]'
    736     TokenGuid, TokenName, Value, InfType = '', '', '', ''
    737 
    738     if Type == TAB_PCDS_FIXED_AT_BUILD:
    739         InfType = TAB_INF_FIXED_PCD
    740     elif Type == TAB_PCDS_PATCHABLE_IN_MODULE:
    741         InfType = TAB_INF_PATCH_PCD
    742     elif Type == TAB_PCDS_FEATURE_FLAG:
    743         InfType = TAB_INF_FEATURE_PCD
    744     elif Type == TAB_PCDS_DYNAMIC_EX:
    745         InfType = TAB_INF_PCD_EX
    746     elif Type == TAB_PCDS_DYNAMIC:
    747         InfType = TAB_INF_PCD
    748     List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT)
    749     if len(List) < 2 or len(List) > 3:
    750         RaiseParserError(Item, InfType, File, Format, LineNo)
    751     else:
    752         Value = List[1]
    753     TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT)
    754     if len(TokenInfo) != 2:
    755         RaiseParserError(Item, InfType, File, Format, LineNo)
    756     else:
    757         TokenGuid = TokenInfo[0]
    758         TokenName = TokenInfo[1]
    759 
    760     return (TokenGuid, TokenName, Value, Type)
    761 
    762 
    763 ## Get Pcd Values of Dec

    764 #

    765 # Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>

    766 # @retval (TokenSpcCName, TokenCName, Value, DatumType, Token, ItemType) Formatted Pcd Item

    767 #

    768 def GetPcdOfDec(Item, Type, File, LineNo = -1):
    769     Format = '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>'
    770     TokenGuid, TokenName, Value, DatumType, Token = '', '', '', '', ''
    771     List = GetSplitValueList(Item)
    772     if len(List) != 4:
    773         RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo)
    774     else:
    775         Value = List[1]
    776         DatumType = List[2]
    777         Token = List[3]
    778     TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT)
    779     if len(TokenInfo) != 2:
    780         RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo)
    781     else:
    782         TokenGuid = TokenInfo[0]
    783         TokenName = TokenInfo[1]
    784 
    785     return (TokenGuid, TokenName, Value, DatumType, Token, Type)
    786 
    787 ## Parse DEFINE statement

    788 #

    789 # Get DEFINE macros

    790 #

    791 # 1. Insert a record into TblDec

    792 # Value1: Macro Name

    793 # Value2: Macro Value

    794 #

    795 def ParseDefine(LineValue, StartLine, Table, FileID, Filename, SectionName, SectionModel, Arch):
    796     EdkLogger.debug(EdkLogger.DEBUG_2, "DEFINE statement '%s' found in section %s" % (LineValue, SectionName))
    797     Define = GetSplitValueList(CleanString(LineValue[LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') + len(DataType.TAB_DEFINE + ' ') : ]), TAB_EQUAL_SPLIT, 1)
    798     Table.Insert(MODEL_META_DATA_DEFINE, Define[0], Define[1], '', '', '', Arch, SectionModel, FileID, StartLine, -1, StartLine, -1, 0)
    799 
    800 ## InsertSectionItems

    801 #

    802 # Insert item data of a section to a dict

    803 #

    804 def InsertSectionItems(Model, CurrentSection, SectionItemList, ArchList, ThirdList, RecordSet):
    805     # Insert each item data of a section

    806     for Index in range(0, len(ArchList)):
    807         Arch = ArchList[Index]
    808         Third = ThirdList[Index]
    809         if Arch == '':
    810             Arch = TAB_ARCH_COMMON
    811 
    812         Records = RecordSet[Model]
    813         for SectionItem in SectionItemList:
    814             BelongsToItem, EndLine, EndColumn = -1, -1, -1
    815             LineValue, StartLine, EndLine, Comment = SectionItem[0], SectionItem[1], SectionItem[1], SectionItem[2]
    816 
    817             EdkLogger.debug(4, "Parsing %s ..." %LineValue)
    818             # And then parse DEFINE statement

    819             if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1:
    820                 continue
    821 
    822             # At last parse other sections

    823             ID = -1
    824             Records.append([LineValue, Arch, StartLine, ID, Third, Comment])
    825 
    826         if RecordSet != {}:
    827             RecordSet[Model] = Records
    828 
    829 ## Insert records to database

    830 #

    831 # Insert item data of a section to database

    832 # @param Table:            The Table to be inserted

    833 # @param FileID:           The ID of belonging file

    834 # @param Filename:         The name of belonging file

    835 # @param CurrentSection:   The name of currect section

    836 # @param SectionItemList:  A list of items of the section

    837 # @param ArchList:         A list of arches

    838 # @param ThirdList:        A list of third parameters, ModuleType for LibraryClass and SkuId for Dynamic Pcds

    839 # @param IfDefList:        A list of all conditional statements

    840 # @param RecordSet:        A dict of all parsed records

    841 #

    842 def InsertSectionItemsIntoDatabase(Table, FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, RecordSet):
    843     #

    844     # Insert each item data of a section

    845     #

    846     for Index in range(0, len(ArchList)):
    847         Arch = ArchList[Index]
    848         Third = ThirdList[Index]
    849         if Arch == '':
    850             Arch = TAB_ARCH_COMMON
    851 
    852         Records = RecordSet[Model]
    853         for SectionItem in SectionItemList:
    854             BelongsToItem, EndLine, EndColumn = -1, -1, -1
    855             LineValue, StartLine, EndLine = SectionItem[0], SectionItem[1], SectionItem[1]
    856 
    857             EdkLogger.debug(4, "Parsing %s ..." %LineValue)
    858             #

    859             # And then parse DEFINE statement

    860             #

    861             if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1:
    862                 ParseDefine(LineValue, StartLine, Table, FileID, Filename, CurrentSection, Model, Arch)
    863                 continue
    864 
    865             #

    866             # At last parse other sections

    867             #

    868             ID = Table.Insert(Model, LineValue, Third, Third, '', '', Arch, -1, FileID, StartLine, -1, StartLine, -1, 0)
    869             Records.append([LineValue, Arch, StartLine, ID, Third])
    870 
    871         if RecordSet != {}:
    872             RecordSet[Model] = Records
    873 
    874 ## GenMetaDatSectionItem

    875 def GenMetaDatSectionItem(Key, Value, List):
    876     if Key not in List:
    877         List[Key] = [Value]
    878     else:
    879         List[Key].append(Value)
    880 
    881 ## IsValidWord

    882 #

    883 # Check whether the word is valid.

    884 # <Word>   ::=  (a-zA-Z0-9_)(a-zA-Z0-9_-){0,} Alphanumeric characters with

    885 #               optional

    886 #               dash "-" and/or underscore "_" characters. No whitespace

    887 #               characters are permitted.

    888 #

    889 # @param Word:  The word string need to be checked.

    890 #

    891 def IsValidWord(Word):
    892     if not Word:
    893         return False
    894     #

    895     # The first char should be alpha, _ or Digit.

    896     #

    897     if not Word[0].isalnum() and \
    898        not Word[0] == '_' and \
    899        not Word[0].isdigit():
    900         return False
    901 
    902     LastChar = ''
    903     for Char in Word[1:]:
    904         if (not Char.isalpha()) and \
    905            (not Char.isdigit()) and \
    906            Char != '-' and \
    907            Char != '_' and \
    908            Char != '.':
    909             return False
    910         if Char == '.' and LastChar == '.':
    911             return False
    912         LastChar = Char
    913 
    914     return True
    915