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# 17from String import * 18from CommonDataClass.DataClass import * 19from DataType import * 20 21## ParseDefineMacro 22# 23# Search whole table to find all defined Macro and replaced them with the real values 24# 25def 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# 55def 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# 109def 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# 153def 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# 179def 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# 196def 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# 212def 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# 229def 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# 252def 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# 274def 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# 300def 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# 318def 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# 343def 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# 364def 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# 387def 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# 408def 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# 430def 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# 518def 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# 541def 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# 628def 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# 650def 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# 678def 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# 696def 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# 713def 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# 734def 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# 768def 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# 795def 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# 804def 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# 842def 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 875def 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# 891def 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