1## @file 2# This file is used to define common parsing related functions used in parsing 3# INF/DEC/DSC process 4# 5# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR> 6# 7# This program and the accompanying materials are licensed and made available 8# under the terms and conditions of the BSD License which accompanies this 9# distribution. The full text of the license may be found at 10# http://opensource.org/licenses/bsd-license.php 11# 12# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 13# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 14# 15 16''' 17Parsing 18''' 19 20## 21# Import Modules 22# 23import os.path 24import re 25 26from Library.String import RaiseParserError 27from Library.String import GetSplitValueList 28from Library.String import CheckFileType 29from Library.String import CheckFileExist 30from Library.String import CleanString 31from Library.String import NormPath 32 33from Logger.ToolError import FILE_NOT_FOUND 34from Logger.ToolError import FatalError 35from Logger.ToolError import FORMAT_INVALID 36 37from Library import DataType 38 39from Library.Misc import GuidStructureStringToGuidString 40from Library.Misc import CheckGuidRegFormat 41from Logger import StringTable as ST 42import Logger.Log as Logger 43 44from Parser.DecParser import Dec 45import GlobalData 46 47gPKG_INFO_DICT = {} 48 49## GetBuildOption 50# 51# Parse a string with format "[<Family>:]<ToolFlag>=Flag" 52# Return (Family, ToolFlag, Flag) 53# 54# @param String: String with BuildOption statement 55# @param File: The file which defines build option, used in error report 56# 57def GetBuildOption(String, File, LineNo= -1): 58 (Family, ToolChain, Flag) = ('', '', '') 59 if String.find(DataType.TAB_EQUAL_SPLIT) < 0: 60 RaiseParserError(String, 'BuildOptions', File, \ 61 '[<Family>:]<ToolFlag>=Flag', LineNo) 62 else: 63 List = GetSplitValueList(String, DataType.TAB_EQUAL_SPLIT, MaxSplit=1) 64 if List[0].find(':') > -1: 65 Family = List[0][ : List[0].find(':')].strip() 66 ToolChain = List[0][List[0].find(':') + 1 : ].strip() 67 else: 68 ToolChain = List[0].strip() 69 Flag = List[1].strip() 70 return (Family, ToolChain, Flag) 71 72## Get Library Class 73# 74# Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance> 75# 76# @param Item: String as <LibraryClassKeyWord>|<LibraryInstance> 77# @param ContainerFile: The file which describes the library class, used for 78# error report 79# 80def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo= -1): 81 List = GetSplitValueList(Item[0]) 82 SupMod = DataType.SUP_MODULE_LIST_STRING 83 if len(List) != 2: 84 RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, \ 85 '<LibraryClassKeyWord>|<LibraryInstance>') 86 else: 87 CheckFileType(List[1], '.Inf', ContainerFile, \ 88 'library class instance', Item[0], LineNo) 89 CheckFileExist(WorkspaceDir, List[1], ContainerFile, \ 90 'LibraryClasses', Item[0], LineNo) 91 if Item[1] != '': 92 SupMod = Item[1] 93 94 return (List[0], List[1], SupMod) 95 96## Get Library Class 97# 98# Get Library of Dsc as <LibraryClassKeyWord>[|<LibraryInstance>] 99# [|<TokenSpaceGuidCName>.<PcdCName>] 100# 101# @param Item: String as <LibraryClassKeyWord>|<LibraryInstance> 102# @param ContainerFile: The file which describes the library class, used for 103# error report 104# 105def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo= -1): 106 ItemList = GetSplitValueList((Item[0] + DataType.TAB_VALUE_SPLIT * 2)) 107 SupMod = DataType.SUP_MODULE_LIST_STRING 108 109 if len(ItemList) > 5: 110 RaiseParserError\ 111 (Item[0], 'LibraryClasses', ContainerFile, \ 112 '<LibraryClassKeyWord>[|<LibraryInstance>]\ 113 [|<TokenSpaceGuidCName>.<PcdCName>]') 114 else: 115 CheckFileType(ItemList[1], '.Inf', ContainerFile, 'LibraryClasses', \ 116 Item[0], LineNo) 117 CheckFileExist(WorkspaceDir, ItemList[1], ContainerFile, \ 118 'LibraryClasses', Item[0], LineNo) 119 if ItemList[2] != '': 120 CheckPcdTokenInfo(ItemList[2], 'LibraryClasses', \ 121 ContainerFile, LineNo) 122 if Item[1] != '': 123 SupMod = Item[1] 124 125 return (ItemList[0], ItemList[1], ItemList[2], SupMod) 126 127## CheckPcdTokenInfo 128# 129# Check if PcdTokenInfo is following <TokenSpaceGuidCName>.<PcdCName> 130# 131# @param TokenInfoString: String to be checked 132# @param Section: Used for error report 133# @param File: Used for error report 134# 135def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo= -1): 136 Format = '<TokenSpaceGuidCName>.<PcdCName>' 137 if TokenInfoString != '' and TokenInfoString != None: 138 TokenInfoList = GetSplitValueList(TokenInfoString, DataType.TAB_SPLIT) 139 if len(TokenInfoList) == 2: 140 return True 141 142 RaiseParserError(TokenInfoString, Section, File, Format, LineNo) 143 144## Get Pcd 145# 146# Get Pcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value> 147# [|<Type>|<MaximumDatumSize>] 148# 149# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>| 150# <Value>[|<Type>|<MaximumDatumSize>] 151# @param ContainerFile: The file which describes the pcd, used for error 152# report 153 154# 155def GetPcd(Item, Type, ContainerFile, LineNo= -1): 156 TokenGuid, TokenName, Value, MaximumDatumSize, Token = '', '', '', '', '' 157 List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2) 158 159 if len(List) < 4 or len(List) > 6: 160 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \ 161 '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>\ 162 [|<Type>|<MaximumDatumSize>]', LineNo) 163 else: 164 Value = List[1] 165 MaximumDatumSize = List[2] 166 Token = List[3] 167 168 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): 169 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT) 170 171 return (TokenName, TokenGuid, Value, MaximumDatumSize, Token, Type) 172 173## Get FeatureFlagPcd 174# 175# Get FeatureFlagPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE 176# 177# @param Item: String as <PcdTokenSpaceGuidCName> 178# .<TokenCName>|TRUE/FALSE 179# @param ContainerFile: The file which describes the pcd, used for error 180# report 181# 182def GetFeatureFlagPcd(Item, Type, ContainerFile, LineNo= -1): 183 TokenGuid, TokenName, Value = '', '', '' 184 List = GetSplitValueList(Item) 185 if len(List) != 2: 186 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \ 187 '<PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE', \ 188 LineNo) 189 else: 190 Value = List[1] 191 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): 192 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT) 193 194 return (TokenName, TokenGuid, Value, Type) 195 196## Get DynamicDefaultPcd 197# 198# Get DynamicDefaultPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName> 199# |<Value>[|<DatumTyp>[|<MaxDatumSize>]] 200# 201# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>| 202# TRUE/FALSE 203# @param ContainerFile: The file which describes the pcd, used for error 204# report 205# 206def GetDynamicDefaultPcd(Item, Type, ContainerFile, LineNo= -1): 207 TokenGuid, TokenName, Value, DatumTyp, MaxDatumSize = '', '', '', '', '' 208 List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2) 209 if len(List) < 4 or len(List) > 8: 210 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \ 211 '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>\ 212 [|<DatumTyp>[|<MaxDatumSize>]]', LineNo) 213 else: 214 Value = List[1] 215 DatumTyp = List[2] 216 MaxDatumSize = List[3] 217 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): 218 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT) 219 220 return (TokenName, TokenGuid, Value, DatumTyp, MaxDatumSize, Type) 221 222## Get DynamicHiiPcd 223# 224# Get DynamicHiiPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<String>| 225# <VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]] 226# 227# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>| 228# TRUE/FALSE 229# @param ContainerFile: The file which describes the pcd, used for error 230# report 231# 232def GetDynamicHiiPcd(Item, Type, ContainerFile, LineNo= -1): 233 TokenGuid, TokenName, List1, List2, List3, List4, List5 = \ 234 '', '', '', '', '', '', '' 235 List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2) 236 if len(List) < 6 or len(List) > 8: 237 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \ 238 '<PcdTokenSpaceGuidCName>.<TokenCName>|<String>|\ 239 <VariableGuidCName>|<VariableOffset>[|<DefaultValue>\ 240 [|<MaximumDatumSize>]]', LineNo) 241 else: 242 List1, List2, List3, List4, List5 = \ 243 List[1], List[2], List[3], List[4], List[5] 244 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): 245 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT) 246 247 return (TokenName, TokenGuid, List1, List2, List3, List4, List5, Type) 248 249## Get DynamicVpdPcd 250# 251# Get DynamicVpdPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>| 252# <VpdOffset>[|<MaximumDatumSize>] 253# 254# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName> 255# |TRUE/FALSE 256# @param ContainerFile: The file which describes the pcd, used for error 257# report 258# 259def GetDynamicVpdPcd(Item, Type, ContainerFile, LineNo= -1): 260 TokenGuid, TokenName, List1, List2 = '', '', '', '' 261 List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT) 262 if len(List) < 3 or len(List) > 4: 263 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \ 264 '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>\ 265 [|<MaximumDatumSize>]', LineNo) 266 else: 267 List1, List2 = List[1], List[2] 268 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): 269 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT) 270 271 return (TokenName, TokenGuid, List1, List2, Type) 272 273## GetComponent 274# 275# Parse block of the components defined in dsc file 276# Set KeyValues as [ ['component name', [lib1, lib2, lib3], 277# [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...] 278# 279# @param Lines: The content to be parsed 280# @param KeyValues: To store data after parsing 281# 282def GetComponent(Lines, KeyValues): 283 (FindBlock, FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ 284 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, FindPcdsDynamic, \ 285 FindPcdsDynamicEx) = (False, False, False, False, False, False, False, \ 286 False) 287 ListItem = None 288 LibraryClassItem = [] 289 BuildOption = [] 290 Pcd = [] 291 292 for Line in Lines: 293 Line = Line[0] 294 # 295 # Ignore !include statement 296 # 297 if Line.upper().find(DataType.TAB_INCLUDE.upper() + ' ') > -1 or \ 298 Line.upper().find(DataType.TAB_DEFINE + ' ') > -1: 299 continue 300 301 if FindBlock == False: 302 ListItem = Line 303 # 304 # find '{' at line tail 305 # 306 if Line.endswith('{'): 307 FindBlock = True 308 ListItem = CleanString(Line.rsplit('{', 1)[0], \ 309 DataType.TAB_COMMENT_SPLIT) 310 311 # 312 # Parse a block content 313 # 314 if FindBlock: 315 if Line.find('<LibraryClasses>') != -1: 316 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ 317 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ 318 FindPcdsDynamic, FindPcdsDynamicEx) = \ 319 (True, False, False, False, False, False, False) 320 continue 321 if Line.find('<BuildOptions>') != -1: 322 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ 323 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ 324 FindPcdsDynamic, FindPcdsDynamicEx) = \ 325 (False, True, False, False, False, False, False) 326 continue 327 if Line.find('<PcdsFeatureFlag>') != -1: 328 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ 329 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ 330 FindPcdsDynamic, FindPcdsDynamicEx) = \ 331 (False, False, True, False, False, False, False) 332 continue 333 if Line.find('<PcdsPatchableInModule>') != -1: 334 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ 335 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ 336 FindPcdsDynamic, FindPcdsDynamicEx) = \ 337 (False, False, False, True, False, False, False) 338 continue 339 if Line.find('<PcdsFixedAtBuild>') != -1: 340 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ 341 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ 342 FindPcdsDynamic, FindPcdsDynamicEx) = \ 343 (False, False, False, False, True, False, False) 344 continue 345 if Line.find('<PcdsDynamic>') != -1: 346 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ 347 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ 348 FindPcdsDynamic, FindPcdsDynamicEx) = \ 349 (False, False, False, False, False, True, False) 350 continue 351 if Line.find('<PcdsDynamicEx>') != -1: 352 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ 353 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ 354 FindPcdsDynamic, FindPcdsDynamicEx) = \ 355 (False, False, False, False, False, False, True) 356 continue 357 if Line.endswith('}'): 358 # 359 # find '}' at line tail 360 # 361 KeyValues.append([ListItem, LibraryClassItem, \ 362 BuildOption, Pcd]) 363 (FindBlock, FindLibraryClass, FindBuildOption, \ 364 FindPcdsFeatureFlag, FindPcdsPatchableInModule, \ 365 FindPcdsFixedAtBuild, FindPcdsDynamic, FindPcdsDynamicEx) = \ 366 (False, False, False, False, False, False, False, False) 367 LibraryClassItem, BuildOption, Pcd = [], [], [] 368 continue 369 370 if FindBlock: 371 if FindLibraryClass: 372 LibraryClassItem.append(Line) 373 elif FindBuildOption: 374 BuildOption.append(Line) 375 elif FindPcdsFeatureFlag: 376 Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG_NULL, Line)) 377 elif FindPcdsPatchableInModule: 378 Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE_NULL, Line)) 379 elif FindPcdsFixedAtBuild: 380 Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD_NULL, Line)) 381 elif FindPcdsDynamic: 382 Pcd.append((DataType.TAB_PCDS_DYNAMIC_DEFAULT_NULL, Line)) 383 elif FindPcdsDynamicEx: 384 Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL, Line)) 385 else: 386 KeyValues.append([ListItem, [], [], []]) 387 388 return True 389 390## GetExec 391# 392# Parse a string with format "InfFilename [EXEC = ExecFilename]" 393# Return (InfFilename, ExecFilename) 394# 395# @param String: String with EXEC statement 396# 397def GetExec(String): 398 InfFilename = '' 399 ExecFilename = '' 400 if String.find('EXEC') > -1: 401 InfFilename = String[ : String.find('EXEC')].strip() 402 ExecFilename = String[String.find('EXEC') + len('EXEC') : ].strip() 403 else: 404 InfFilename = String.strip() 405 406 return (InfFilename, ExecFilename) 407 408## GetComponents 409# 410# Parse block of the components defined in dsc file 411# Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], 412# [pcd1, pcd2, pcd3]], ...] 413# 414# @param Lines: The content to be parsed 415# @param Key: Reserved 416# @param KeyValues: To store data after parsing 417# @param CommentCharacter: Comment char, used to ignore comment content 418# 419# @retval True Get component successfully 420# 421def GetComponents(Lines, KeyValues, CommentCharacter): 422 if Lines.find(DataType.TAB_SECTION_END) > -1: 423 Lines = Lines.split(DataType.TAB_SECTION_END, 1)[1] 424 (FindBlock, FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ 425 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, FindPcdsDynamic, \ 426 FindPcdsDynamicEx) = \ 427 (False, False, False, False, False, False, False, False) 428 ListItem = None 429 LibraryClassItem = [] 430 BuildOption = [] 431 Pcd = [] 432 433 LineList = Lines.split('\n') 434 for Line in LineList: 435 Line = CleanString(Line, CommentCharacter) 436 if Line == None or Line == '': 437 continue 438 439 if FindBlock == False: 440 ListItem = Line 441 # 442 # find '{' at line tail 443 # 444 if Line.endswith('{'): 445 FindBlock = True 446 ListItem = CleanString(Line.rsplit('{', 1)[0], CommentCharacter) 447 448 # 449 # Parse a block content 450 # 451 if FindBlock: 452 if Line.find('<LibraryClasses>') != -1: 453 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ 454 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ 455 FindPcdsDynamic, FindPcdsDynamicEx) = \ 456 (True, False, False, False, False, False, False) 457 continue 458 if Line.find('<BuildOptions>') != -1: 459 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ 460 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ 461 FindPcdsDynamic, FindPcdsDynamicEx) = \ 462 (False, True, False, False, False, False, False) 463 continue 464 if Line.find('<PcdsFeatureFlag>') != -1: 465 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ 466 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ 467 FindPcdsDynamic, FindPcdsDynamicEx) = \ 468 (False, False, True, False, False, False, False) 469 continue 470 if Line.find('<PcdsPatchableInModule>') != -1: 471 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ 472 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ 473 FindPcdsDynamic, FindPcdsDynamicEx) = \ 474 (False, False, False, True, False, False, False) 475 continue 476 if Line.find('<PcdsFixedAtBuild>') != -1: 477 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ 478 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ 479 FindPcdsDynamic, FindPcdsDynamicEx) = \ 480 (False, False, False, False, True, False, False) 481 continue 482 if Line.find('<PcdsDynamic>') != -1: 483 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ 484 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ 485 FindPcdsDynamic, FindPcdsDynamicEx) = \ 486 (False, False, False, False, False, True, False) 487 continue 488 if Line.find('<PcdsDynamicEx>') != -1: 489 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ 490 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ 491 FindPcdsDynamic, FindPcdsDynamicEx) = \ 492 (False, False, False, False, False, False, True) 493 continue 494 if Line.endswith('}'): 495 # 496 # find '}' at line tail 497 # 498 KeyValues.append([ListItem, LibraryClassItem, BuildOption, \ 499 Pcd]) 500 (FindBlock, FindLibraryClass, FindBuildOption, \ 501 FindPcdsFeatureFlag, FindPcdsPatchableInModule, \ 502 FindPcdsFixedAtBuild, FindPcdsDynamic, FindPcdsDynamicEx) = \ 503 (False, False, False, False, False, False, False, False) 504 LibraryClassItem, BuildOption, Pcd = [], [], [] 505 continue 506 507 if FindBlock: 508 if FindLibraryClass: 509 LibraryClassItem.append(Line) 510 elif FindBuildOption: 511 BuildOption.append(Line) 512 elif FindPcdsFeatureFlag: 513 Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG, Line)) 514 elif FindPcdsPatchableInModule: 515 Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE, Line)) 516 elif FindPcdsFixedAtBuild: 517 Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD, Line)) 518 elif FindPcdsDynamic: 519 Pcd.append((DataType.TAB_PCDS_DYNAMIC, Line)) 520 elif FindPcdsDynamicEx: 521 Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX, Line)) 522 else: 523 KeyValues.append([ListItem, [], [], []]) 524 525 return True 526 527## Get Source 528# 529# Get Source of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode> 530# [|<PcdFeatureFlag>]]]] 531# 532# @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode> 533# [|<PcdFeatureFlag>]]]] 534# @param ContainerFile: The file which describes the library class, used 535# for error report 536# 537def GetSource(Item, ContainerFile, FileRelativePath, LineNo= -1): 538 ItemNew = Item + DataType.TAB_VALUE_SPLIT * 4 539 List = GetSplitValueList(ItemNew) 540 if len(List) < 5 or len(List) > 9: 541 RaiseParserError(Item, 'Sources', ContainerFile, \ 542 '<Filename>[|<Family>[|<TagName>[|<ToolCode>\ 543 [|<PcdFeatureFlag>]]]]', LineNo) 544 List[0] = NormPath(List[0]) 545 CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Sources', \ 546 Item, LineNo) 547 if List[4] != '': 548 CheckPcdTokenInfo(List[4], 'Sources', ContainerFile, LineNo) 549 550 return (List[0], List[1], List[2], List[3], List[4]) 551 552## Get Binary 553# 554# Get Binary of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode> 555# [|<PcdFeatureFlag>]]]] 556# 557# @param Item: String as <Filename>[|<Family>[|<TagName> 558# [|<ToolCode>[|<PcdFeatureFlag>]]]] 559# @param ContainerFile: The file which describes the library class, 560# used for error report 561# 562def GetBinary(Item, ContainerFile, LineNo= -1): 563 ItemNew = Item + DataType.TAB_VALUE_SPLIT 564 List = GetSplitValueList(ItemNew) 565 if len(List) < 3 or len(List) > 5: 566 RaiseParserError(Item, 'Binaries', ContainerFile, \ 567 "<FileType>|<Filename>[|<Target>\ 568 [|<TokenSpaceGuidCName>.<PcdCName>]]", LineNo) 569 570 if len(List) >= 4: 571 if List[3] != '': 572 CheckPcdTokenInfo(List[3], 'Binaries', ContainerFile, LineNo) 573 return (List[0], List[1], List[2], List[3]) 574 elif len(List) == 3: 575 return (List[0], List[1], List[2], '') 576 577## Get Guids/Protocols/Ppis 578# 579# Get Guids/Protocols/Ppis of Inf as <GuidCName>[|<PcdFeatureFlag>] 580# 581# @param Item: String as <GuidCName>[|<PcdFeatureFlag>] 582# @param Type: Type of parsing string 583# @param ContainerFile: The file which describes the library class, 584# used for error report 585# 586def GetGuidsProtocolsPpisOfInf(Item): 587 ItemNew = Item + DataType.TAB_VALUE_SPLIT 588 List = GetSplitValueList(ItemNew) 589 return (List[0], List[1]) 590 591## Get Guids/Protocols/Ppis 592# 593# Get Guids/Protocols/Ppis of Dec as <GuidCName>=<GuidValue> 594# 595# @param Item: String as <GuidCName>=<GuidValue> 596# @param Type: Type of parsing string 597# @param ContainerFile: The file which describes the library class, 598# used for error report 599# 600def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo= -1): 601 List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT) 602 if len(List) != 2: 603 RaiseParserError(Item, Type, ContainerFile, '<CName>=<GuidValue>', \ 604 LineNo) 605 # 606 #convert C-Format Guid to Register Format 607 # 608 if List[1][0] == '{' and List[1][-1] == '}': 609 RegisterFormatGuid = GuidStructureStringToGuidString(List[1]) 610 if RegisterFormatGuid == '': 611 RaiseParserError(Item, Type, ContainerFile, \ 612 'CFormat or RegisterFormat', LineNo) 613 else: 614 if CheckGuidRegFormat(List[1]): 615 RegisterFormatGuid = List[1] 616 else: 617 RaiseParserError(Item, Type, ContainerFile, \ 618 'CFormat or RegisterFormat', LineNo) 619 620 return (List[0], RegisterFormatGuid) 621 622## GetPackage 623# 624# Get Package of Inf as <PackagePath>[|<PcdFeatureFlag>] 625# 626# @param Item: String as <PackagePath>[|<PcdFeatureFlag>] 627# @param Type: Type of parsing string 628# @param ContainerFile: The file which describes the library class, 629# used for error report 630# 631def GetPackage(Item, ContainerFile, FileRelativePath, LineNo= -1): 632 ItemNew = Item + DataType.TAB_VALUE_SPLIT 633 List = GetSplitValueList(ItemNew) 634 CheckFileType(List[0], '.Dec', ContainerFile, 'package', List[0], LineNo) 635 CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Packages', \ 636 List[0], LineNo) 637 if List[1] != '': 638 CheckPcdTokenInfo(List[1], 'Packages', ContainerFile, LineNo) 639 640 return (List[0], List[1]) 641 642## Get Pcd Values of Inf 643# 644# Get Pcd of Inf as <TokenSpaceGuidCName>.<PcdCName>[|<Value>] 645# 646# @param Item: The string describes pcd 647# @param Type: The type of Pcd 648# @param File: The file which describes the pcd, used for error report 649# 650def GetPcdOfInf(Item, Type, File, LineNo): 651 Format = '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]' 652 TokenGuid, TokenName, Value, InfType = '', '', '', '' 653 654 if Type == DataType.TAB_PCDS_FIXED_AT_BUILD: 655 InfType = DataType.TAB_INF_FIXED_PCD 656 elif Type == DataType.TAB_PCDS_PATCHABLE_IN_MODULE: 657 InfType = DataType.TAB_INF_PATCH_PCD 658 elif Type == DataType.TAB_PCDS_FEATURE_FLAG: 659 InfType = DataType.TAB_INF_FEATURE_PCD 660 elif Type == DataType.TAB_PCDS_DYNAMIC_EX: 661 InfType = DataType.TAB_INF_PCD_EX 662 elif Type == DataType.TAB_PCDS_DYNAMIC: 663 InfType = DataType.TAB_INF_PCD 664 List = GetSplitValueList(Item, DataType.TAB_VALUE_SPLIT, 1) 665 TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT) 666 if len(TokenInfo) != 2: 667 RaiseParserError(Item, InfType, File, Format, LineNo) 668 else: 669 TokenGuid = TokenInfo[0] 670 TokenName = TokenInfo[1] 671 672 if len(List) > 1: 673 Value = List[1] 674 else: 675 Value = None 676 return (TokenGuid, TokenName, Value, InfType) 677 678 679## Get Pcd Values of Dec 680# 681# Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token> 682# @param Item: Pcd item 683# @param Type: Pcd type 684# @param File: Dec file 685# @param LineNo: Line number 686# 687def GetPcdOfDec(Item, Type, File, LineNo= -1): 688 Format = '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>' 689 TokenGuid, TokenName, Value, DatumType, Token = '', '', '', '', '' 690 List = GetSplitValueList(Item) 691 if len(List) != 4: 692 RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo) 693 else: 694 Value = List[1] 695 DatumType = List[2] 696 Token = List[3] 697 TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT) 698 if len(TokenInfo) != 2: 699 RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo) 700 else: 701 TokenGuid = TokenInfo[0] 702 TokenName = TokenInfo[1] 703 704 return (TokenGuid, TokenName, Value, DatumType, Token, Type) 705 706## Parse DEFINE statement 707# 708# Get DEFINE macros 709# 710# @param LineValue: A DEFINE line value 711# @param StartLine: A DEFINE start line 712# @param Table: A table 713# @param FileID: File ID 714# @param Filename: File name 715# @param SectionName: DEFINE section name 716# @param SectionModel: DEFINE section model 717# @param Arch: DEFINE arch 718# 719def ParseDefine(LineValue, StartLine, Table, FileID, SectionName, \ 720 SectionModel, Arch): 721 Logger.Debug(Logger.DEBUG_2, ST.MSG_DEFINE_STATEMENT_FOUND % (LineValue, \ 722 SectionName)) 723 Define = \ 724 GetSplitValueList(CleanString\ 725 (LineValue[LineValue.upper().\ 726 find(DataType.TAB_DEFINE.upper() + ' ') + \ 727 len(DataType.TAB_DEFINE + ' ') : ]), \ 728 DataType.TAB_EQUAL_SPLIT, 1) 729 Table.Insert(DataType.MODEL_META_DATA_DEFINE, Define[0], Define[1], '', \ 730 '', '', Arch, SectionModel, FileID, StartLine, -1, \ 731 StartLine, -1, 0) 732 733## InsertSectionItems 734# 735# Insert item data of a section to a dict 736# 737# @param Model: A model 738# @param CurrentSection: Current section 739# @param SectionItemList: Section item list 740# @param ArchList: Arch list 741# @param ThirdList: Third list 742# @param RecordSet: Record set 743# 744def InsertSectionItems(Model, SectionItemList, ArchList, \ 745 ThirdList, RecordSet): 746 # 747 # Insert each item data of a section 748 # 749 for Index in range(0, len(ArchList)): 750 Arch = ArchList[Index] 751 Third = ThirdList[Index] 752 if Arch == '': 753 Arch = DataType.TAB_ARCH_COMMON 754 755 Records = RecordSet[Model] 756 for SectionItem in SectionItemList: 757 LineValue, StartLine, Comment = SectionItem[0], \ 758 SectionItem[1], SectionItem[2] 759 760 Logger.Debug(4, ST.MSG_PARSING % LineValue) 761 # 762 # And then parse DEFINE statement 763 # 764 if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1: 765 continue 766 # 767 # At last parse other sections 768 # 769 IdNum = -1 770 Records.append([LineValue, Arch, StartLine, IdNum, Third, Comment]) 771 772 if RecordSet != {}: 773 RecordSet[Model] = Records 774 775## GenMetaDatSectionItem 776# 777# @param Key: A key 778# @param Value: A value 779# @param List: A list 780# 781def GenMetaDatSectionItem(Key, Value, List): 782 if Key not in List: 783 List[Key] = [Value] 784 else: 785 List[Key].append(Value) 786 787## GetPkgInfoFromDec 788# 789# get package name, guid, version info from dec files 790# 791# @param Path: File path 792# 793def GetPkgInfoFromDec(Path): 794 PkgName = None 795 PkgGuid = None 796 PkgVersion = None 797 798 Path = Path.replace('\\', '/') 799 800 if not os.path.exists(Path): 801 Logger.Error("\nUPT", FILE_NOT_FOUND, File=Path) 802 803 if Path in gPKG_INFO_DICT: 804 return gPKG_INFO_DICT[Path] 805 806 try: 807 DecParser = None 808 if Path not in GlobalData.gPackageDict: 809 DecParser = Dec(Path) 810 GlobalData.gPackageDict[Path] = DecParser 811 else: 812 DecParser = GlobalData.gPackageDict[Path] 813 814 PkgName = DecParser.GetPackageName() 815 PkgGuid = DecParser.GetPackageGuid() 816 PkgVersion = DecParser.GetPackageVersion() 817 gPKG_INFO_DICT[Path] = (PkgName, PkgGuid, PkgVersion) 818 return PkgName, PkgGuid, PkgVersion 819 except FatalError: 820 return None, None, None 821 822 823## GetWorkspacePackage 824# 825# Get a list of workspace package information. 826# 827def GetWorkspacePackage(): 828 DecFileList = [] 829 WorkspaceDir = GlobalData.gWORKSPACE 830 PackageDir = GlobalData.gPACKAGE_PATH 831 for PkgRoot in [WorkspaceDir] + PackageDir: 832 for Root, Dirs, Files in os.walk(PkgRoot): 833 if 'CVS' in Dirs: 834 Dirs.remove('CVS') 835 if '.svn' in Dirs: 836 Dirs.remove('.svn') 837 for Dir in Dirs: 838 if Dir.startswith('.'): 839 Dirs.remove(Dir) 840 for FileSp in Files: 841 if FileSp.startswith('.'): 842 continue 843 Ext = os.path.splitext(FileSp)[1] 844 if Ext.lower() in ['.dec']: 845 DecFileList.append\ 846 (os.path.normpath(os.path.join(Root, FileSp))) 847 # 848 # abstract package guid, version info from DecFile List 849 # 850 PkgList = [] 851 for DecFile in DecFileList: 852 (PkgName, PkgGuid, PkgVersion) = GetPkgInfoFromDec(DecFile) 853 if PkgName and PkgGuid and PkgVersion: 854 PkgList.append((PkgName, PkgGuid, PkgVersion, DecFile)) 855 856 return PkgList 857 858## GetWorkspaceModule 859# 860# Get a list of workspace modules. 861# 862def GetWorkspaceModule(): 863 InfFileList = [] 864 WorkspaceDir = GlobalData.gWORKSPACE 865 for Root, Dirs, Files in os.walk(WorkspaceDir): 866 if 'CVS' in Dirs: 867 Dirs.remove('CVS') 868 if '.svn' in Dirs: 869 Dirs.remove('.svn') 870 if 'Build' in Dirs: 871 Dirs.remove('Build') 872 for Dir in Dirs: 873 if Dir.startswith('.'): 874 Dirs.remove(Dir) 875 for FileSp in Files: 876 if FileSp.startswith('.'): 877 continue 878 Ext = os.path.splitext(FileSp)[1] 879 if Ext.lower() in ['.inf']: 880 InfFileList.append\ 881 (os.path.normpath(os.path.join(Root, FileSp))) 882 883 return InfFileList 884 885## MacroParser used to parse macro definition 886# 887# @param Line: The content contain linestring and line number 888# @param FileName: The meta-file file name 889# @param SectionType: Section for the Line belong to 890# @param FileLocalMacros: A list contain Macro defined in [Defines] section. 891# 892def MacroParser(Line, FileName, SectionType, FileLocalMacros): 893 MacroDefPattern = re.compile("^(DEFINE)[ \t]+") 894 LineContent = Line[0] 895 LineNo = Line[1] 896 Match = MacroDefPattern.match(LineContent) 897 if not Match: 898 # 899 # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method 900 # 901 return None, None 902 903 TokenList = GetSplitValueList(LineContent[Match.end(1):], \ 904 DataType.TAB_EQUAL_SPLIT, 1) 905 # 906 # Syntax check 907 # 908 if not TokenList[0]: 909 Logger.Error('Parser', FORMAT_INVALID, ST.ERR_MACRONAME_NOGIVEN, 910 ExtraData=LineContent, File=FileName, Line=LineNo) 911 if len(TokenList) < 2: 912 Logger.Error('Parser', FORMAT_INVALID, ST.ERR_MACROVALUE_NOGIVEN, 913 ExtraData=LineContent, File=FileName, Line=LineNo) 914 915 Name, Value = TokenList 916 917 # 918 # DEFINE defined macros 919 # 920 if SectionType == DataType.MODEL_META_DATA_HEADER: 921 FileLocalMacros[Name] = Value 922 923 ReIsValidMacroName = re.compile(r"^[A-Z][A-Z0-9_]*$", re.DOTALL) 924 if ReIsValidMacroName.match(Name) == None: 925 Logger.Error('Parser', 926 FORMAT_INVALID, 927 ST.ERR_MACRONAME_INVALID % (Name), 928 ExtraData=LineContent, 929 File=FileName, 930 Line=LineNo) 931 932 # Validate MACRO Value 933 # 934 # <MacroDefinition> ::= [<Comments>]{0,} 935 # "DEFINE" <MACRO> "=" [{<PATH>} {<VALUE>}] <EOL> 936 # <Value> ::= {<NumVal>} {<Boolean>} {<AsciiString>} {<GUID>} 937 # {<CString>} {<UnicodeString>} {<CArray>} 938 # 939 # The definition of <NumVal>, <PATH>, <Boolean>, <GUID>, <CString>, 940 # <UnicodeString>, <CArray> are subset of <AsciiString>. 941 # 942 ReIsValidMacroValue = re.compile(r"^[\x20-\x7e]*$", re.DOTALL) 943 if ReIsValidMacroValue.match(Value) == None: 944 Logger.Error('Parser', 945 FORMAT_INVALID, 946 ST.ERR_MACROVALUE_INVALID % (Value), 947 ExtraData=LineContent, 948 File=FileName, 949 Line=LineNo) 950 951 return Name, Value 952 953## GenSection 954# 955# generate section contents 956# 957# @param SectionName: indicate the name of the section, details refer to 958# INF, DEC specs 959# @param SectionDict: section statement dict, key is SectionAttrs(arch, 960# moduletype or platform may exist as needed) list 961# seperated by space, 962# value is statement 963# 964def GenSection(SectionName, SectionDict, SplitArch=True, NeedBlankLine=False): 965 Content = '' 966 for SectionAttrs in SectionDict: 967 StatementList = SectionDict[SectionAttrs] 968 if SectionAttrs and SectionName != 'Defines' and SectionAttrs.strip().upper() != DataType.TAB_ARCH_COMMON: 969 if SplitArch: 970 ArchList = GetSplitValueList(SectionAttrs, DataType.TAB_SPACE_SPLIT) 971 else: 972 if SectionName != 'UserExtensions': 973 ArchList = GetSplitValueList(SectionAttrs, DataType.TAB_COMMENT_SPLIT) 974 else: 975 ArchList = [SectionAttrs] 976 for Index in xrange(0, len(ArchList)): 977 ArchList[Index] = ConvertArchForInstall(ArchList[Index]) 978 Section = '[' + SectionName + '.' + (', ' + SectionName + '.').join(ArchList) + ']' 979 else: 980 Section = '[' + SectionName + ']' 981 Content += '\n' + Section + '\n' 982 if StatementList != None: 983 for Statement in StatementList: 984 LineList = Statement.split('\n') 985 NewStatement = "" 986 for Line in LineList: 987 # ignore blank comment 988 if not Line.replace("#", '').strip() and SectionName not in ('Defines', 'Hob', 'Event', 'BootMode'): 989 continue 990 # add two space before non-comments line except the comments in Defines section 991 if Line.strip().startswith('#') and SectionName == 'Defines': 992 NewStatement += "%s\n" % Line 993 continue 994 NewStatement += " %s\n" % Line 995 if NeedBlankLine: 996 Content += NewStatement + '\n' 997 else: 998 Content += NewStatement 999 1000 if NeedBlankLine: 1001 Content = Content[:-1] 1002 if not Content.replace('\\n', '').strip(): 1003 return '' 1004 return Content 1005 1006## ConvertArchForInstall 1007# if Arch.upper() is in "IA32", "X64", "IPF", and "EBC", it must be upper case. "common" must be lower case. 1008# Anything else, the case must be preserved 1009# 1010# @param Arch: the arch string that need to be converted, it should be stripped before pass in 1011# @return: the arch string that get converted 1012# 1013def ConvertArchForInstall(Arch): 1014 if Arch.upper() in [DataType.TAB_ARCH_IA32, DataType.TAB_ARCH_X64, 1015 DataType.TAB_ARCH_IPF, DataType.TAB_ARCH_EBC]: 1016 Arch = Arch.upper() 1017 elif Arch.upper() == DataType.TAB_ARCH_COMMON: 1018 Arch = Arch.lower() 1019 1020 return Arch 1021