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