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 - 2018, Intel Corporation. All rights reserved.<BR> 5# SPDX-License-Identifier: BSD-2-Clause-Patent 6# 7 8## 9# Import Modules 10# 11from __future__ import absolute_import 12from .StringUtils import * 13from CommonDataClass.DataClass import * 14from .DataType import * 15 16## ParseDefineMacro 17# 18# Search whole table to find all defined Macro and replaced them with the real values 19# 20def ParseDefineMacro2(Table, RecordSets, GlobalMacro): 21 Macros = {} 22 # 23 # Find all DEFINE macros in section [Header] and its section 24 # 25 SqlCommand = """select Value1, Value2, BelongsToItem, StartLine, Arch from %s 26 where Model = %s 27 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE) 28 RecordSet = Table.Exec(SqlCommand) 29 for Record in RecordSet: 30 Macros[Record[0]] = Record[1] 31 32 # 33 # Overridden by Global Macros 34 # 35 Macros.update(GlobalMacro) 36 37 # 38 # Replace the Macros 39 # 40 for Value in (v for v in RecordSets.values() if v): 41 for Item in Value: 42 Item[0] = ReplaceMacro(Item[0], Macros) 43 44## ParseDefineMacro 45# 46# Search whole table to find all defined Macro and replaced them with the real values 47# 48def ParseDefineMacro(Table, GlobalMacro): 49 Macros = {} 50 # 51 # Find all DEFINE macros 52 # 53 SqlCommand = """select Value1, Value2, BelongsToItem, StartLine, Arch from %s 54 where Model = %s 55 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE) 56 RecordSet = Table.Exec(SqlCommand) 57 for Record in RecordSet: 58#*************************************************************************************************************************************************** 59# The follow SqlCommand (expr replace) is not supported in Sqlite 3.3.4 which is used in Python 2.5 * 60# Reserved Only * 61# SqlCommand = """update %s set Value1 = replace(Value1, '%s', '%s') * 62# where ID in (select ID from %s * 63# where Model = %s * 64# and Value1 like '%%%s%%' * 65# and StartLine > %s * 66# and Enabled > -1 * 67# and Arch = '%s')""" % \ * 68# (self.TblDsc.Table, Record[0], Record[1], self.TblDsc.Table, Record[2], Record[1], Record[3], Record[4]) * 69#*************************************************************************************************************************************************** 70 Macros[Record[0]] = Record[1] 71 72 # 73 # Overridden by Global Macros 74 # 75 Macros.update(GlobalMacro) 76 77 # 78 # Found all defined macro and replaced 79 # 80 SqlCommand = """select ID, Value1 from %s 81 where Model != %s 82 and Value1 like '%%$(%%' and Value1 like '%%)%%' 83 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE) 84 FoundRecords = Table.Exec(SqlCommand) 85 for FoundRecord in FoundRecords: 86 NewValue = ReplaceMacro(FoundRecord[1], Macros) 87 SqlCommand = """update %s set Value1 = '%s' 88 where ID = %s""" % (Table.Table, ConvertToSqlString2(NewValue), FoundRecord[0]) 89 Table.Exec(SqlCommand) 90 91##QueryDefinesItem 92# 93# Search item of section [Defines] by name, return its values 94# 95# @param Table: The Table to be executed 96# @param Name: The Name of item of section [Defines] 97# @param Arch: The Arch of item of section [Defines] 98# 99# @retval RecordSet: A list of all matched records 100# 101def QueryDefinesItem(Table, Name, Arch, BelongsToFile): 102 SqlCommand = """select Value2 from %s 103 where Model = %s 104 and Value1 = '%s' 105 and Arch = '%s' 106 and BelongsToFile = %s 107 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Name), ConvertToSqlString2(Arch), BelongsToFile) 108 RecordSet = Table.Exec(SqlCommand) 109 if len(RecordSet) < 1: 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(TAB_ARCH_COMMON.upper()), BelongsToFile) 116 RecordSet = Table.Exec(SqlCommand) 117 if len(RecordSet) == 1: 118 if Name == TAB_INF_DEFINES_LIBRARY_CLASS: 119 return [RecordSet[0][0]] 120 else: 121 return GetSplitValueList(RecordSet[0][0]) 122 elif len(RecordSet) < 1: 123 return [''] 124 elif len(RecordSet) > 1: 125 RetVal = [] 126 for Record in RecordSet: 127 if Name == TAB_INF_DEFINES_LIBRARY_CLASS: 128 RetVal.append(Record[0]) 129 else: 130 Items = GetSplitValueList(Record[0]) 131 for Item in Items: 132 RetVal.append(Item) 133 return RetVal 134 135##QueryDefinesItem 136# 137# Search item of section [Defines] by name, return its values 138# 139# @param Table: The Table to be executed 140# @param Name: The Name of item of section [Defines] 141# @param Arch: The Arch of item of section [Defines] 142# 143# @retval RecordSet: A list of all matched records 144# 145def QueryDefinesItem2(Table, Arch, BelongsToFile): 146 SqlCommand = """select Value1, Value2, StartLine from %s 147 where Model = %s 148 and Arch = '%s' 149 and BelongsToFile = %s 150 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Arch), BelongsToFile) 151 RecordSet = Table.Exec(SqlCommand) 152 if len(RecordSet) < 1: 153 SqlCommand = """select Value1, Value2, StartLine from %s 154 where Model = %s 155 and Arch = '%s' 156 and BelongsToFile = %s 157 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(TAB_ARCH_COMMON), BelongsToFile) 158 RecordSet = Table.Exec(SqlCommand) 159 160 return RecordSet 161 162##QueryDscItem 163# 164# Search all dsc item for a specific section 165# 166# @param Table: The Table to be executed 167# @param Model: The type of section 168# 169# @retval RecordSet: A list of all matched records 170# 171def QueryDscItem(Table, Model, BelongsToItem, BelongsToFile): 172 SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s 173 where Model = %s 174 and BelongsToItem = %s 175 and BelongsToFile = %s 176 and Enabled > -1""" % (Table.Table, Model, BelongsToItem, BelongsToFile) 177 return Table.Exec(SqlCommand) 178 179##QueryDecItem 180# 181# Search all dec item for a specific section 182# 183# @param Table: The Table to be executed 184# @param Model: The type of section 185# 186# @retval RecordSet: A list of all matched records 187# 188def QueryDecItem(Table, Model, BelongsToItem): 189 SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s 190 where Model = %s 191 and BelongsToItem = %s 192 and Enabled > -1""" % (Table.Table, Model, BelongsToItem) 193 return Table.Exec(SqlCommand) 194 195##QueryInfItem 196# 197# Search all dec item for a specific section 198# 199# @param Table: The Table to be executed 200# @param Model: The type of section 201# 202# @retval RecordSet: A list of all matched records 203# 204def QueryInfItem(Table, Model, BelongsToItem): 205 SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s 206 where Model = %s 207 and BelongsToItem = %s 208 and Enabled > -1""" % (Table.Table, Model, BelongsToItem) 209 return Table.Exec(SqlCommand) 210 211## GetBuildOption 212# 213# Parse a string with format "[<Family>:]<ToolFlag>=Flag" 214# Return (Family, ToolFlag, Flag) 215# 216# @param String: String with BuildOption statement 217# @param File: The file which defines build option, used in error report 218# 219# @retval truple() A truple structure as (Family, ToolChain, Flag) 220# 221def GetBuildOption(String, File, LineNo = -1): 222 (Family, ToolChain, Flag) = ('', '', '') 223 if String.find(TAB_EQUAL_SPLIT) < 0: 224 RaiseParserError(String, 'BuildOptions', File, '[<Family>:]<ToolFlag>=Flag', LineNo) 225 else: 226 List = GetSplitValueList(String, TAB_EQUAL_SPLIT, MaxSplit = 1) 227 if List[0].find(':') > -1: 228 Family = List[0][ : List[0].find(':')].strip() 229 ToolChain = List[0][List[0].find(':') + 1 : ].strip() 230 else: 231 ToolChain = List[0].strip() 232 Flag = List[1].strip() 233 return (Family, ToolChain, Flag) 234 235## Get Library Class 236# 237# Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance> 238# 239# @param Item: String as <LibraryClassKeyWord>|<LibraryInstance> 240# @param ContainerFile: The file which describes the library class, used for error report 241# 242# @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item 243# 244def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo = -1): 245 List = GetSplitValueList(Item[0]) 246 SupMod = SUP_MODULE_LIST_STRING 247 if len(List) != 2: 248 RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, '<LibraryClassKeyWord>|<LibraryInstance>') 249 else: 250 CheckFileType(List[1], '.Inf', ContainerFile, 'library class instance', Item[0], LineNo) 251 CheckFileExist(WorkspaceDir, List[1], ContainerFile, 'LibraryClasses', Item[0], LineNo) 252 if Item[1] != '': 253 SupMod = Item[1] 254 255 return (List[0], List[1], SupMod) 256 257## Get Library Class 258# 259# Get Library of Dsc as <LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>] 260# 261# @param Item: String as <LibraryClassKeyWord>|<LibraryInstance> 262# @param ContainerFile: The file which describes the library class, used for error report 263# 264# @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item 265# 266def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo = -1): 267 ItemList = GetSplitValueList((Item[0] + DataType.TAB_VALUE_SPLIT * 2)) 268 SupMod = SUP_MODULE_LIST_STRING 269 270 if len(ItemList) > 5: 271 RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, '<LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]') 272 else: 273 CheckFileType(ItemList[1], '.Inf', ContainerFile, 'LibraryClasses', Item[0], LineNo) 274 CheckFileExist(WorkspaceDir, ItemList[1], ContainerFile, 'LibraryClasses', Item[0], LineNo) 275 if ItemList[2] != '': 276 CheckPcdTokenInfo(ItemList[2], 'LibraryClasses', ContainerFile, LineNo) 277 if Item[1] != '': 278 SupMod = Item[1] 279 280 return (ItemList[0], ItemList[1], ItemList[2], SupMod) 281 282## CheckPcdTokenInfo 283# 284# Check if PcdTokenInfo is following <TokenSpaceGuidCName>.<PcdCName> 285# 286# @param TokenInfoString: String to be checked 287# @param Section: Used for error report 288# @param File: Used for error report 289# 290# @retval True PcdTokenInfo is in correct format 291# 292def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo = -1): 293 Format = '<TokenSpaceGuidCName>.<PcdCName>' 294 if TokenInfoString != '' and TokenInfoString is not None: 295 TokenInfoList = GetSplitValueList(TokenInfoString, TAB_SPLIT) 296 if len(TokenInfoList) == 2: 297 return True 298 299 RaiseParserError(TokenInfoString, Section, File, Format, LineNo) 300 301## Get Pcd 302# 303# Get Pcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>] 304# 305# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>] 306# @param ContainerFile: The file which describes the pcd, used for error report 307# 308# @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type) 309# 310def GetPcd(Item, Type, ContainerFile, LineNo = -1): 311 TokenGuid, TokenName, Value, MaximumDatumSize, Token = '', '', '', '', '' 312 List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2) 313 314 if len(List) < 4 or len(List) > 6: 315 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]', LineNo) 316 else: 317 Value = List[1] 318 MaximumDatumSize = List[2] 319 Token = List[3] 320 321 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): 322 (TokenGuid, TokenName) = GetSplitValueList(List[0], TAB_SPLIT) 323 324 return (TokenName, TokenGuid, Value, MaximumDatumSize, Token, Type) 325 326## Get FeatureFlagPcd 327# 328# Get FeatureFlagPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE 329# 330# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE 331# @param ContainerFile: The file which describes the pcd, used for error report 332# 333# @retval (TokenInfo[1], TokenInfo[0], List[1], Type) 334# 335def GetFeatureFlagPcd(Item, Type, ContainerFile, LineNo = -1): 336 TokenGuid, TokenName, Value = '', '', '' 337 List = GetSplitValueList(Item) 338 if len(List) != 2: 339 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE', LineNo) 340 else: 341 Value = List[1] 342 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): 343 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT) 344 345 return (TokenName, TokenGuid, Value, Type) 346 347## Get DynamicDefaultPcd 348# 349# Get DynamicDefaultPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]] 350# 351# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE 352# @param ContainerFile: The file which describes the pcd, used for error report 353# 354# @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type) 355# 356def GetDynamicDefaultPcd(Item, Type, ContainerFile, LineNo = -1): 357 TokenGuid, TokenName, Value, DatumTyp, MaxDatumSize = '', '', '', '', '' 358 List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2) 359 if len(List) < 4 or len(List) > 8: 360 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]', LineNo) 361 else: 362 Value = List[1] 363 DatumTyp = List[2] 364 MaxDatumSize = List[3] 365 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): 366 (TokenGuid, TokenName) = GetSplitValueList(List[0], TAB_SPLIT) 367 368 return (TokenName, TokenGuid, Value, DatumTyp, MaxDatumSize, Type) 369 370## Get DynamicHiiPcd 371# 372# Get DynamicHiiPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]] 373# 374# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE 375# @param ContainerFile: The file which describes the pcd, used for error report 376# 377# @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], List[4], List[5], Type) 378# 379def GetDynamicHiiPcd(Item, Type, ContainerFile, LineNo = -1): 380 TokenGuid, TokenName, L1, L2, L3, L4, L5 = '', '', '', '', '', '', '' 381 List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2) 382 if len(List) < 6 or len(List) > 8: 383 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]', LineNo) 384 else: 385 L1, L2, L3, L4, L5 = List[1], List[2], List[3], List[4], List[5] 386 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): 387 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT) 388 389 return (TokenName, TokenGuid, L1, L2, L3, L4, L5, Type) 390 391## Get DynamicVpdPcd 392# 393# Get DynamicVpdPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>] 394# 395# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE 396# @param ContainerFile: The file which describes the pcd, used for error report 397# 398# @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], Type) 399# 400def GetDynamicVpdPcd(Item, Type, ContainerFile, LineNo = -1): 401 TokenGuid, TokenName, L1, L2 = '', '', '', '' 402 List = GetSplitValueList(Item + TAB_VALUE_SPLIT) 403 if len(List) < 3 or len(List) > 4: 404 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]', LineNo) 405 else: 406 L1, L2 = List[1], List[2] 407 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): 408 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT) 409 410 return (TokenName, TokenGuid, L1, L2, Type) 411 412## GetComponent 413# 414# Parse block of the components defined in dsc file 415# Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...] 416# 417# @param Lines: The content to be parsed 418# @param KeyValues: To store data after parsing 419# 420# @retval True Get component successfully 421# 422def GetComponent(Lines, KeyValues): 423 (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False) 424 ListItem = None 425 LibraryClassItem = [] 426 BuildOption = [] 427 Pcd = [] 428 429 for Line in Lines: 430 Line = Line[0] 431 432 # 433 # Ignore !include statement 434 # 435 if Line.upper().find(TAB_INCLUDE.upper() + ' ') > -1 or Line.upper().find(TAB_DEFINE + ' ') > -1: 436 continue 437 438 if findBlock == False: 439 ListItem = Line 440 # 441 # find '{' at line tail 442 # 443 if Line.endswith('{'): 444 findBlock = True 445 ListItem = CleanString(Line.rsplit('{', 1)[0], DataType.TAB_COMMENT_SPLIT) 446 447 # 448 # Parse a block content 449 # 450 if findBlock: 451 if Line.find('<LibraryClasses>') != -1: 452 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (True, False, False, False, False, False, False) 453 continue 454 if Line.find('<BuildOptions>') != -1: 455 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, True, False, False, False, False, False) 456 continue 457 if Line.find('<PcdsFeatureFlag>') != -1: 458 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, True, False, False, False, False) 459 continue 460 if Line.find('<PcdsPatchableInModule>') != -1: 461 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, True, False, False, False) 462 continue 463 if Line.find('<PcdsFixedAtBuild>') != -1: 464 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, True, False, False) 465 continue 466 if Line.find('<PcdsDynamic>') != -1: 467 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, True, False) 468 continue 469 if Line.find('<PcdsDynamicEx>') != -1: 470 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, True) 471 continue 472 if Line.endswith('}'): 473 # 474 # find '}' at line tail 475 # 476 KeyValues.append([ListItem, LibraryClassItem, BuildOption, Pcd]) 477 (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False) 478 LibraryClassItem, BuildOption, Pcd = [], [], [] 479 continue 480 481 if findBlock: 482 if findLibraryClass: 483 LibraryClassItem.append(Line) 484 elif findBuildOption: 485 BuildOption.append(Line) 486 elif findPcdsFeatureFlag: 487 Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG_NULL, Line)) 488 elif findPcdsPatchableInModule: 489 Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE_NULL, Line)) 490 elif findPcdsFixedAtBuild: 491 Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD_NULL, Line)) 492 elif findPcdsDynamic: 493 Pcd.append((DataType.TAB_PCDS_DYNAMIC_DEFAULT_NULL, Line)) 494 elif findPcdsDynamicEx: 495 Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL, Line)) 496 else: 497 KeyValues.append([ListItem, [], [], []]) 498 499 return True 500 501## GetExec 502# 503# Parse a string with format "InfFilename [EXEC = ExecFilename]" 504# Return (InfFilename, ExecFilename) 505# 506# @param String: String with EXEC statement 507# 508# @retval truple() A pair as (InfFilename, ExecFilename) 509# 510def GetExec(String): 511 InfFilename = '' 512 ExecFilename = '' 513 if String.find('EXEC') > -1: 514 InfFilename = String[ : String.find('EXEC')].strip() 515 ExecFilename = String[String.find('EXEC') + len('EXEC') : ].strip() 516 else: 517 InfFilename = String.strip() 518 519 return (InfFilename, ExecFilename) 520 521## GetComponents 522# 523# Parse block of the components defined in dsc file 524# Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...] 525# 526# @param Lines: The content to be parsed 527# @param Key: Reserved 528# @param KeyValues: To store data after parsing 529# @param CommentCharacter: Comment char, used to ignore comment content 530# 531# @retval True Get component successfully 532# 533def GetComponents(Lines, Key, KeyValues, CommentCharacter): 534 if Lines.find(DataType.TAB_SECTION_END) > -1: 535 Lines = Lines.split(DataType.TAB_SECTION_END, 1)[1] 536 (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False) 537 ListItem = None 538 LibraryClassItem = [] 539 BuildOption = [] 540 Pcd = [] 541 542 LineList = Lines.split('\n') 543 for Line in LineList: 544 Line = CleanString(Line, CommentCharacter) 545 if Line is None or Line == '': 546 continue 547 548 if findBlock == False: 549 ListItem = Line 550 # 551 # find '{' at line tail 552 # 553 if Line.endswith('{'): 554 findBlock = True 555 ListItem = CleanString(Line.rsplit('{', 1)[0], CommentCharacter) 556 557 # 558 # Parse a block content 559 # 560 if findBlock: 561 if Line.find('<LibraryClasses>') != -1: 562 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (True, False, False, False, False, False, False) 563 continue 564 if Line.find('<BuildOptions>') != -1: 565 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, True, False, False, False, False, False) 566 continue 567 if Line.find('<PcdsFeatureFlag>') != -1: 568 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, True, False, False, False, False) 569 continue 570 if Line.find('<PcdsPatchableInModule>') != -1: 571 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, True, False, False, False) 572 continue 573 if Line.find('<PcdsFixedAtBuild>') != -1: 574 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, True, False, False) 575 continue 576 if Line.find('<PcdsDynamic>') != -1: 577 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, True, False) 578 continue 579 if Line.find('<PcdsDynamicEx>') != -1: 580 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, True) 581 continue 582 if Line.endswith('}'): 583 # 584 # find '}' at line tail 585 # 586 KeyValues.append([ListItem, LibraryClassItem, BuildOption, Pcd]) 587 (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False) 588 LibraryClassItem, BuildOption, Pcd = [], [], [] 589 continue 590 591 if findBlock: 592 if findLibraryClass: 593 LibraryClassItem.append(Line) 594 elif findBuildOption: 595 BuildOption.append(Line) 596 elif findPcdsFeatureFlag: 597 Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG, Line)) 598 elif findPcdsPatchableInModule: 599 Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE, Line)) 600 elif findPcdsFixedAtBuild: 601 Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD, Line)) 602 elif findPcdsDynamic: 603 Pcd.append((DataType.TAB_PCDS_DYNAMIC, Line)) 604 elif findPcdsDynamicEx: 605 Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX, Line)) 606 else: 607 KeyValues.append([ListItem, [], [], []]) 608 609 return True 610 611## Get Source 612# 613# Get Source of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]] 614# 615# @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]] 616# @param ContainerFile: The file which describes the library class, used for error report 617# 618# @retval (List[0], List[1], List[2], List[3], List[4]) 619# 620def GetSource(Item, ContainerFile, FileRelativePath, LineNo = -1): 621 ItemNew = Item + DataType.TAB_VALUE_SPLIT * 4 622 List = GetSplitValueList(ItemNew) 623 if len(List) < 5 or len(List) > 9: 624 RaiseParserError(Item, 'Sources', ContainerFile, '<Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]', LineNo) 625 List[0] = NormPath(List[0]) 626 CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Sources', Item, LineNo) 627 if List[4] != '': 628 CheckPcdTokenInfo(List[4], 'Sources', ContainerFile, LineNo) 629 630 return (List[0], List[1], List[2], List[3], List[4]) 631 632## Get Binary 633# 634# Get Binary of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]] 635# 636# @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]] 637# @param ContainerFile: The file which describes the library class, used for error report 638# 639# @retval (List[0], List[1], List[2], List[3]) 640# @retval List 641# 642def GetBinary(Item, ContainerFile, FileRelativePath, LineNo = -1): 643 ItemNew = Item + DataType.TAB_VALUE_SPLIT 644 List = GetSplitValueList(ItemNew) 645 if len(List) != 4 and len(List) != 5: 646 RaiseParserError(Item, 'Binaries', ContainerFile, "<FileType>|<Filename>|<Target>[|<TokenSpaceGuidCName>.<PcdCName>]", LineNo) 647 else: 648 if List[3] != '': 649 CheckPcdTokenInfo(List[3], 'Binaries', ContainerFile, LineNo) 650 651 if len(List) == 4: 652 return (List[0], List[1], List[2], List[3]) 653 elif len(List) == 3: 654 return (List[0], List[1], List[2], '') 655 elif len(List) == 2: 656 return (List[0], List[1], '', '') 657 elif len(List) == 1: 658 return (List[0], '', '', '') 659 660## Get Guids/Protocols/Ppis 661# 662# Get Guids/Protocols/Ppis of Inf as <GuidCName>[|<PcdFeatureFlag>] 663# 664# @param Item: String as <GuidCName>[|<PcdFeatureFlag>] 665# @param Type: Type of parsing string 666# @param ContainerFile: The file which describes the library class, used for error report 667# 668# @retval (List[0], List[1]) 669# 670def GetGuidsProtocolsPpisOfInf(Item, Type, ContainerFile, LineNo = -1): 671 ItemNew = Item + TAB_VALUE_SPLIT 672 List = GetSplitValueList(ItemNew) 673 if List[1] != '': 674 CheckPcdTokenInfo(List[1], Type, ContainerFile, LineNo) 675 676 return (List[0], List[1]) 677 678## Get Guids/Protocols/Ppis 679# 680# Get Guids/Protocols/Ppis of Dec as <GuidCName>=<GuidValue> 681# 682# @param Item: String as <GuidCName>=<GuidValue> 683# @param Type: Type of parsing string 684# @param ContainerFile: The file which describes the library class, used for error report 685# 686# @retval (List[0], List[1]) 687# 688def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo = -1): 689 List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT) 690 if len(List) != 2: 691 RaiseParserError(Item, Type, ContainerFile, '<CName>=<GuidValue>', LineNo) 692 693 return (List[0], List[1]) 694 695## GetPackage 696# 697# Get Package of Inf as <PackagePath>[|<PcdFeatureFlag>] 698# 699# @param Item: String as <PackagePath>[|<PcdFeatureFlag>] 700# @param Type: Type of parsing string 701# @param ContainerFile: The file which describes the library class, used for error report 702# 703# @retval (List[0], List[1]) 704# 705def GetPackage(Item, ContainerFile, FileRelativePath, LineNo = -1): 706 ItemNew = Item + TAB_VALUE_SPLIT 707 List = GetSplitValueList(ItemNew) 708 CheckFileType(List[0], '.Dec', ContainerFile, 'package', List[0], LineNo) 709 CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Packages', List[0], LineNo) 710 711 if List[1] != '': 712 CheckPcdTokenInfo(List[1], 'Packages', ContainerFile, LineNo) 713 714 return (List[0], List[1]) 715 716## Get Pcd Values of Inf 717# 718# Get Pcd of Inf as <TokenSpaceGuidCName>.<PcdCName>[|<Value>] 719# 720# @param Item: The string describes pcd 721# @param Type: The type of Pcd 722# @param File: The file which describes the pcd, used for error report 723# 724# @retval (TokenSpcCName, TokenCName, Value, ItemType) Formatted Pcd Item 725# 726def GetPcdOfInf(Item, Type, File, LineNo): 727 Format = '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]' 728 TokenGuid, TokenName, Value, InfType = '', '', '', '' 729 730 if Type == TAB_PCDS_FIXED_AT_BUILD: 731 InfType = TAB_INF_FIXED_PCD 732 elif Type == TAB_PCDS_PATCHABLE_IN_MODULE: 733 InfType = TAB_INF_PATCH_PCD 734 elif Type == TAB_PCDS_FEATURE_FLAG: 735 InfType = TAB_INF_FEATURE_PCD 736 elif Type == TAB_PCDS_DYNAMIC_EX: 737 InfType = TAB_INF_PCD_EX 738 elif Type == TAB_PCDS_DYNAMIC: 739 InfType = TAB_INF_PCD 740 List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT) 741 if len(List) < 2 or len(List) > 3: 742 RaiseParserError(Item, InfType, File, Format, LineNo) 743 else: 744 Value = List[1] 745 TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT) 746 if len(TokenInfo) != 2: 747 RaiseParserError(Item, InfType, File, Format, LineNo) 748 else: 749 TokenGuid = TokenInfo[0] 750 TokenName = TokenInfo[1] 751 752 return (TokenGuid, TokenName, Value, Type) 753 754 755## Get Pcd Values of Dec 756# 757# Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token> 758# @retval (TokenSpcCName, TokenCName, Value, DatumType, Token, ItemType) Formatted Pcd Item 759# 760def GetPcdOfDec(Item, Type, File, LineNo = -1): 761 Format = '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>' 762 TokenGuid, TokenName, Value, DatumType, Token = '', '', '', '', '' 763 List = GetSplitValueList(Item) 764 if len(List) != 4: 765 RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo) 766 else: 767 Value = List[1] 768 DatumType = List[2] 769 Token = List[3] 770 TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT) 771 if len(TokenInfo) != 2: 772 RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo) 773 else: 774 TokenGuid = TokenInfo[0] 775 TokenName = TokenInfo[1] 776 777 return (TokenGuid, TokenName, Value, DatumType, Token, Type) 778 779## Parse DEFINE statement 780# 781# Get DEFINE macros 782# 783# 1. Insert a record into TblDec 784# Value1: Macro Name 785# Value2: Macro Value 786# 787def ParseDefine(LineValue, StartLine, Table, FileID, Filename, SectionName, SectionModel, Arch): 788 EdkLogger.debug(EdkLogger.DEBUG_2, "DEFINE statement '%s' found in section %s" % (LineValue, SectionName)) 789 Define = GetSplitValueList(CleanString(LineValue[LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') + len(DataType.TAB_DEFINE + ' ') : ]), TAB_EQUAL_SPLIT, 1) 790 Table.Insert(MODEL_META_DATA_DEFINE, Define[0], Define[1], '', '', '', Arch, SectionModel, FileID, StartLine, -1, StartLine, -1, 0) 791 792## InsertSectionItems 793# 794# Insert item data of a section to a dict 795# 796def InsertSectionItems(Model, CurrentSection, SectionItemList, ArchList, ThirdList, RecordSet): 797 # Insert each item data of a section 798 for Index in range(0, len(ArchList)): 799 Arch = ArchList[Index] 800 Third = ThirdList[Index] 801 if Arch == '': 802 Arch = TAB_ARCH_COMMON 803 804 Records = RecordSet[Model] 805 for SectionItem in SectionItemList: 806 BelongsToItem, EndLine, EndColumn = -1, -1, -1 807 LineValue, StartLine, EndLine, Comment = SectionItem[0], SectionItem[1], SectionItem[1], SectionItem[2] 808 809 EdkLogger.debug(4, "Parsing %s ..." %LineValue) 810 # And then parse DEFINE statement 811 if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1: 812 continue 813 814 # At last parse other sections 815 ID = -1 816 Records.append([LineValue, Arch, StartLine, ID, Third, Comment]) 817 818 if RecordSet != {}: 819 RecordSet[Model] = Records 820 821## Insert records to database 822# 823# Insert item data of a section to database 824# @param Table: The Table to be inserted 825# @param FileID: The ID of belonging file 826# @param Filename: The name of belonging file 827# @param CurrentSection: The name of current section 828# @param SectionItemList: A list of items of the section 829# @param ArchList: A list of arches 830# @param ThirdList: A list of third parameters, ModuleType for LibraryClass and SkuId for Dynamic Pcds 831# @param IfDefList: A list of all conditional statements 832# @param RecordSet: A dict of all parsed records 833# 834def InsertSectionItemsIntoDatabase(Table, FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, RecordSet): 835 # 836 # Insert each item data of a section 837 # 838 for Index in range(0, len(ArchList)): 839 Arch = ArchList[Index] 840 Third = ThirdList[Index] 841 if Arch == '': 842 Arch = TAB_ARCH_COMMON 843 844 Records = RecordSet[Model] 845 for SectionItem in SectionItemList: 846 BelongsToItem, EndLine, EndColumn = -1, -1, -1 847 LineValue, StartLine, EndLine = SectionItem[0], SectionItem[1], SectionItem[1] 848 849 EdkLogger.debug(4, "Parsing %s ..." %LineValue) 850 # 851 # And then parse DEFINE statement 852 # 853 if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1: 854 ParseDefine(LineValue, StartLine, Table, FileID, Filename, CurrentSection, Model, Arch) 855 continue 856 857 # 858 # At last parse other sections 859 # 860 ID = Table.Insert(Model, LineValue, Third, Third, '', '', Arch, -1, FileID, StartLine, -1, StartLine, -1, 0) 861 Records.append([LineValue, Arch, StartLine, ID, Third]) 862 863 if RecordSet != {}: 864 RecordSet[Model] = Records 865 866## GenMetaDatSectionItem 867def GenMetaDatSectionItem(Key, Value, List): 868 if Key not in List: 869 List[Key] = [Value] 870 else: 871 List[Key].append(Value) 872 873## IsValidWord 874# 875# Check whether the word is valid. 876# <Word> ::= (a-zA-Z0-9_)(a-zA-Z0-9_-){0,} Alphanumeric characters with 877# optional 878# dash "-" and/or underscore "_" characters. No whitespace 879# characters are permitted. 880# 881# @param Word: The word string need to be checked. 882# 883def IsValidWord(Word): 884 if not Word: 885 return False 886 # 887 # The first char should be alpha, _ or Digit. 888 # 889 if not Word[0].isalnum() and \ 890 not Word[0] == '_' and \ 891 not Word[0].isdigit(): 892 return False 893 894 LastChar = '' 895 for Char in Word[1:]: 896 if (not Char.isalpha()) and \ 897 (not Char.isdigit()) and \ 898 Char != '-' and \ 899 Char != '_' and \ 900 Char != '.': 901 return False 902 if Char == '.' and LastChar == '.': 903 return False 904 LastChar = Char 905 906 return True 907