From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001 From: Angelos Mouzakitis Date: Tue, 10 Oct 2023 14:33:42 +0000 Subject: Add submodule dependency files Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec --- .../BaseTools/Source/Python/UPT/Library/Parsing.py | 1015 ++++++++++++++++++++ 1 file changed, 1015 insertions(+) create mode 100644 roms/edk2/BaseTools/Source/Python/UPT/Library/Parsing.py (limited to 'roms/edk2/BaseTools/Source/Python/UPT/Library/Parsing.py') diff --git a/roms/edk2/BaseTools/Source/Python/UPT/Library/Parsing.py b/roms/edk2/BaseTools/Source/Python/UPT/Library/Parsing.py new file mode 100644 index 000000000..6fb133745 --- /dev/null +++ b/roms/edk2/BaseTools/Source/Python/UPT/Library/Parsing.py @@ -0,0 +1,1015 @@ +## @file +# This file is used to define common parsing related functions used in parsing +# INF/DEC/DSC process +# +# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +''' +Parsing +''' +from __future__ import absolute_import + +## +# Import Modules +# +import os.path +import re + +from Library.StringUtils import RaiseParserError +from Library.StringUtils import GetSplitValueList +from Library.StringUtils import CheckFileType +from Library.StringUtils import CheckFileExist +from Library.StringUtils import CleanString +from Library.StringUtils import NormPath + +from Logger.ToolError import FILE_NOT_FOUND +from Logger.ToolError import FatalError +from Logger.ToolError import FORMAT_INVALID + +from Library import DataType + +from Library.Misc import GuidStructureStringToGuidString +from Library.Misc import CheckGuidRegFormat +from Logger import StringTable as ST +import Logger.Log as Logger + +from Parser.DecParser import Dec +from . import GlobalData + +gPKG_INFO_DICT = {} + +## GetBuildOption +# +# Parse a string with format "[:]=Flag" +# Return (Family, ToolFlag, Flag) +# +# @param String: String with BuildOption statement +# @param File: The file which defines build option, used in error report +# +def GetBuildOption(String, File, LineNo= -1): + (Family, ToolChain, Flag) = ('', '', '') + if String.find(DataType.TAB_EQUAL_SPLIT) < 0: + RaiseParserError(String, 'BuildOptions', File, \ + '[:]=Flag', LineNo) + else: + List = GetSplitValueList(String, DataType.TAB_EQUAL_SPLIT, MaxSplit=1) + if List[0].find(':') > -1: + Family = List[0][ : List[0].find(':')].strip() + ToolChain = List[0][List[0].find(':') + 1 : ].strip() + else: + ToolChain = List[0].strip() + Flag = List[1].strip() + return (Family, ToolChain, Flag) + +## Get Library Class +# +# Get Library of Dsc as | +# +# @param Item: String as | +# @param ContainerFile: The file which describes the library class, used for +# error report +# +def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo= -1): + List = GetSplitValueList(Item[0]) + SupMod = DataType.SUP_MODULE_LIST_STRING + if len(List) != 2: + RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, \ + '|') + else: + CheckFileType(List[1], '.Inf', ContainerFile, \ + 'library class instance', Item[0], LineNo) + CheckFileExist(WorkspaceDir, List[1], ContainerFile, \ + 'LibraryClasses', Item[0], LineNo) + if Item[1] != '': + SupMod = Item[1] + + return (List[0], List[1], SupMod) + +## Get Library Class +# +# Get Library of Dsc as [|] +# [|.] +# +# @param Item: String as | +# @param ContainerFile: The file which describes the library class, used for +# error report +# +def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo= -1): + ItemList = GetSplitValueList((Item[0] + DataType.TAB_VALUE_SPLIT * 2)) + SupMod = DataType.SUP_MODULE_LIST_STRING + + if len(ItemList) > 5: + RaiseParserError\ + (Item[0], 'LibraryClasses', ContainerFile, \ + '[|]\ + [|.]') + else: + CheckFileType(ItemList[1], '.Inf', ContainerFile, 'LibraryClasses', \ + Item[0], LineNo) + CheckFileExist(WorkspaceDir, ItemList[1], ContainerFile, \ + 'LibraryClasses', Item[0], LineNo) + if ItemList[2] != '': + CheckPcdTokenInfo(ItemList[2], 'LibraryClasses', \ + ContainerFile, LineNo) + if Item[1] != '': + SupMod = Item[1] + + return (ItemList[0], ItemList[1], ItemList[2], SupMod) + +## CheckPcdTokenInfo +# +# Check if PcdTokenInfo is following . +# +# @param TokenInfoString: String to be checked +# @param Section: Used for error report +# @param File: Used for error report +# +def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo= -1): + Format = '.' + if TokenInfoString != '' and TokenInfoString is not None: + TokenInfoList = GetSplitValueList(TokenInfoString, DataType.TAB_SPLIT) + if len(TokenInfoList) == 2: + return True + + RaiseParserError(TokenInfoString, Section, File, Format, LineNo) + +## Get Pcd +# +# Get Pcd of Dsc as .| +# [||] +# +# @param Item: String as .| +# [||] +# @param ContainerFile: The file which describes the pcd, used for error +# report + +# +def GetPcd(Item, Type, ContainerFile, LineNo= -1): + TokenGuid, TokenName, Value, MaximumDatumSize, Token = '', '', '', '', '' + List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2) + + if len(List) < 4 or len(List) > 6: + RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \ + '.|\ + [||]', LineNo) + else: + Value = List[1] + MaximumDatumSize = List[2] + Token = List[3] + + if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): + (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT) + + return (TokenName, TokenGuid, Value, MaximumDatumSize, Token, Type) + +## Get FeatureFlagPcd +# +# Get FeatureFlagPcd of Dsc as .|TRUE/FALSE +# +# @param Item: String as +# .|TRUE/FALSE +# @param ContainerFile: The file which describes the pcd, used for error +# report +# +def GetFeatureFlagPcd(Item, Type, ContainerFile, LineNo= -1): + TokenGuid, TokenName, Value = '', '', '' + List = GetSplitValueList(Item) + if len(List) != 2: + RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \ + '.|TRUE/FALSE', \ + LineNo) + else: + Value = List[1] + if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): + (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT) + + return (TokenName, TokenGuid, Value, Type) + +## Get DynamicDefaultPcd +# +# Get DynamicDefaultPcd of Dsc as . +# |[|[|]] +# +# @param Item: String as .| +# TRUE/FALSE +# @param ContainerFile: The file which describes the pcd, used for error +# report +# +def GetDynamicDefaultPcd(Item, Type, ContainerFile, LineNo= -1): + TokenGuid, TokenName, Value, DatumTyp, MaxDatumSize = '', '', '', '', '' + List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2) + if len(List) < 4 or len(List) > 8: + RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \ + '.|\ + [|[|]]', LineNo) + else: + Value = List[1] + DatumTyp = List[2] + MaxDatumSize = List[3] + if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): + (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT) + + return (TokenName, TokenGuid, Value, DatumTyp, MaxDatumSize, Type) + +## Get DynamicHiiPcd +# +# Get DynamicHiiPcd of Dsc as .|| +# |[|[|]] +# +# @param Item: String as .| +# TRUE/FALSE +# @param ContainerFile: The file which describes the pcd, used for error +# report +# +def GetDynamicHiiPcd(Item, Type, ContainerFile, LineNo= -1): + TokenGuid, TokenName, List1, List2, List3, List4, List5 = \ + '', '', '', '', '', '', '' + List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2) + if len(List) < 6 or len(List) > 8: + RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \ + '.||\ + |[|\ + [|]]', LineNo) + else: + List1, List2, List3, List4, List5 = \ + List[1], List[2], List[3], List[4], List[5] + if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): + (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT) + + return (TokenName, TokenGuid, List1, List2, List3, List4, List5, Type) + +## Get DynamicVpdPcd +# +# Get DynamicVpdPcd of Dsc as .| +# [|] +# +# @param Item: String as . +# |TRUE/FALSE +# @param ContainerFile: The file which describes the pcd, used for error +# report +# +def GetDynamicVpdPcd(Item, Type, ContainerFile, LineNo= -1): + TokenGuid, TokenName, List1, List2 = '', '', '', '' + List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT) + if len(List) < 3 or len(List) > 4: + RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \ + '.|\ + [|]', LineNo) + else: + List1, List2 = List[1], List[2] + if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): + (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT) + + return (TokenName, TokenGuid, List1, List2, Type) + +## GetComponent +# +# Parse block of the components defined in dsc file +# Set KeyValues as [ ['component name', [lib1, lib2, lib3], +# [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...] +# +# @param Lines: The content to be parsed +# @param KeyValues: To store data after parsing +# +def GetComponent(Lines, KeyValues): + (FindBlock, FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, FindPcdsDynamic, \ + FindPcdsDynamicEx) = (False, False, False, False, False, False, False, \ + False) + ListItem = None + LibraryClassItem = [] + BuildOption = [] + Pcd = [] + + for Line in Lines: + Line = Line[0] + # + # Ignore !include statement + # + if Line.upper().find(DataType.TAB_INCLUDE.upper() + ' ') > -1 or \ + Line.upper().find(DataType.TAB_DEFINE + ' ') > -1: + continue + + if FindBlock == False: + ListItem = Line + # + # find '{' at line tail + # + if Line.endswith('{'): + FindBlock = True + ListItem = CleanString(Line.rsplit('{', 1)[0], \ + DataType.TAB_COMMENT_SPLIT) + + # + # Parse a block content + # + if FindBlock: + if Line.find('') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (True, False, False, False, False, False, False) + continue + if Line.find('') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, True, False, False, False, False, False) + continue + if Line.find('') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, True, False, False, False, False) + continue + if Line.find('') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, False, True, False, False, False) + continue + if Line.find('') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, False, False, True, False, False) + continue + if Line.find('') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, False, False, False, True, False) + continue + if Line.find('') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, False, False, False, False, True) + continue + if Line.endswith('}'): + # + # find '}' at line tail + # + KeyValues.append([ListItem, LibraryClassItem, \ + BuildOption, Pcd]) + (FindBlock, FindLibraryClass, FindBuildOption, \ + FindPcdsFeatureFlag, FindPcdsPatchableInModule, \ + FindPcdsFixedAtBuild, FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, False, False, False, False, False, False) + LibraryClassItem, BuildOption, Pcd = [], [], [] + continue + + if FindBlock: + if FindLibraryClass: + LibraryClassItem.append(Line) + elif FindBuildOption: + BuildOption.append(Line) + elif FindPcdsFeatureFlag: + Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG_NULL, Line)) + elif FindPcdsPatchableInModule: + Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE_NULL, Line)) + elif FindPcdsFixedAtBuild: + Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD_NULL, Line)) + elif FindPcdsDynamic: + Pcd.append((DataType.TAB_PCDS_DYNAMIC_DEFAULT_NULL, Line)) + elif FindPcdsDynamicEx: + Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL, Line)) + else: + KeyValues.append([ListItem, [], [], []]) + + return True + +## GetExec +# +# Parse a string with format "InfFilename [EXEC = ExecFilename]" +# Return (InfFilename, ExecFilename) +# +# @param String: String with EXEC statement +# +def GetExec(String): + InfFilename = '' + ExecFilename = '' + if String.find('EXEC') > -1: + InfFilename = String[ : String.find('EXEC')].strip() + ExecFilename = String[String.find('EXEC') + len('EXEC') : ].strip() + else: + InfFilename = String.strip() + + return (InfFilename, ExecFilename) + +## GetComponents +# +# Parse block of the components defined in dsc file +# Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], +# [pcd1, pcd2, pcd3]], ...] +# +# @param Lines: The content to be parsed +# @param Key: Reserved +# @param KeyValues: To store data after parsing +# @param CommentCharacter: Comment char, used to ignore comment content +# +# @retval True Get component successfully +# +def GetComponents(Lines, KeyValues, CommentCharacter): + if Lines.find(DataType.TAB_SECTION_END) > -1: + Lines = Lines.split(DataType.TAB_SECTION_END, 1)[1] + (FindBlock, FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, FindPcdsDynamic, \ + FindPcdsDynamicEx) = \ + (False, False, False, False, False, False, False, False) + ListItem = None + LibraryClassItem = [] + BuildOption = [] + Pcd = [] + + LineList = Lines.split('\n') + for Line in LineList: + Line = CleanString(Line, CommentCharacter) + if Line is None or Line == '': + continue + + if FindBlock == False: + ListItem = Line + # + # find '{' at line tail + # + if Line.endswith('{'): + FindBlock = True + ListItem = CleanString(Line.rsplit('{', 1)[0], CommentCharacter) + + # + # Parse a block content + # + if FindBlock: + if Line.find('') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (True, False, False, False, False, False, False) + continue + if Line.find('') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, True, False, False, False, False, False) + continue + if Line.find('') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, True, False, False, False, False) + continue + if Line.find('') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, False, True, False, False, False) + continue + if Line.find('') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, False, False, True, False, False) + continue + if Line.find('') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, False, False, False, True, False) + continue + if Line.find('') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, False, False, False, False, True) + continue + if Line.endswith('}'): + # + # find '}' at line tail + # + KeyValues.append([ListItem, LibraryClassItem, BuildOption, \ + Pcd]) + (FindBlock, FindLibraryClass, FindBuildOption, \ + FindPcdsFeatureFlag, FindPcdsPatchableInModule, \ + FindPcdsFixedAtBuild, FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, False, False, False, False, False, False) + LibraryClassItem, BuildOption, Pcd = [], [], [] + continue + + if FindBlock: + if FindLibraryClass: + LibraryClassItem.append(Line) + elif FindBuildOption: + BuildOption.append(Line) + elif FindPcdsFeatureFlag: + Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG, Line)) + elif FindPcdsPatchableInModule: + Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE, Line)) + elif FindPcdsFixedAtBuild: + Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD, Line)) + elif FindPcdsDynamic: + Pcd.append((DataType.TAB_PCDS_DYNAMIC, Line)) + elif FindPcdsDynamicEx: + Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX, Line)) + else: + KeyValues.append([ListItem, [], [], []]) + + return True + +## Get Source +# +# Get Source of Inf as [|[|[| +# [|]]]] +# +# @param Item: String as [|[|[| +# [|]]]] +# @param ContainerFile: The file which describes the library class, used +# for error report +# +def GetSource(Item, ContainerFile, FileRelativePath, LineNo= -1): + ItemNew = Item + DataType.TAB_VALUE_SPLIT * 4 + List = GetSplitValueList(ItemNew) + if len(List) < 5 or len(List) > 9: + RaiseParserError(Item, 'Sources', ContainerFile, \ + '[|[|[|\ + [|]]]]', LineNo) + List[0] = NormPath(List[0]) + CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Sources', \ + Item, LineNo) + if List[4] != '': + CheckPcdTokenInfo(List[4], 'Sources', ContainerFile, LineNo) + + return (List[0], List[1], List[2], List[3], List[4]) + +## Get Binary +# +# Get Binary of Inf as [|[|[| +# [|]]]] +# +# @param Item: String as [|[| +# [|[|]]]] +# @param ContainerFile: The file which describes the library class, +# used for error report +# +def GetBinary(Item, ContainerFile, LineNo= -1): + ItemNew = Item + DataType.TAB_VALUE_SPLIT + List = GetSplitValueList(ItemNew) + if len(List) < 3 or len(List) > 5: + RaiseParserError(Item, 'Binaries', ContainerFile, \ + "|[|\ + [|.]]", LineNo) + + if len(List) >= 4: + if List[3] != '': + CheckPcdTokenInfo(List[3], 'Binaries', ContainerFile, LineNo) + return (List[0], List[1], List[2], List[3]) + elif len(List) == 3: + return (List[0], List[1], List[2], '') + +## Get Guids/Protocols/Ppis +# +# Get Guids/Protocols/Ppis of Inf as [|] +# +# @param Item: String as [|] +# @param Type: Type of parsing string +# @param ContainerFile: The file which describes the library class, +# used for error report +# +def GetGuidsProtocolsPpisOfInf(Item): + ItemNew = Item + DataType.TAB_VALUE_SPLIT + List = GetSplitValueList(ItemNew) + return (List[0], List[1]) + +## Get Guids/Protocols/Ppis +# +# Get Guids/Protocols/Ppis of Dec as = +# +# @param Item: String as = +# @param Type: Type of parsing string +# @param ContainerFile: The file which describes the library class, +# used for error report +# +def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo= -1): + List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT) + if len(List) != 2: + RaiseParserError(Item, Type, ContainerFile, '=', \ + LineNo) + # + #convert C-Format Guid to Register Format + # + if List[1][0] == '{' and List[1][-1] == '}': + RegisterFormatGuid = GuidStructureStringToGuidString(List[1]) + if RegisterFormatGuid == '': + RaiseParserError(Item, Type, ContainerFile, \ + 'CFormat or RegisterFormat', LineNo) + else: + if CheckGuidRegFormat(List[1]): + RegisterFormatGuid = List[1] + else: + RaiseParserError(Item, Type, ContainerFile, \ + 'CFormat or RegisterFormat', LineNo) + + return (List[0], RegisterFormatGuid) + +## GetPackage +# +# Get Package of Inf as [|] +# +# @param Item: String as [|] +# @param Type: Type of parsing string +# @param ContainerFile: The file which describes the library class, +# used for error report +# +def GetPackage(Item, ContainerFile, FileRelativePath, LineNo= -1): + ItemNew = Item + DataType.TAB_VALUE_SPLIT + List = GetSplitValueList(ItemNew) + CheckFileType(List[0], '.Dec', ContainerFile, 'package', List[0], LineNo) + CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Packages', \ + List[0], LineNo) + if List[1] != '': + CheckPcdTokenInfo(List[1], 'Packages', ContainerFile, LineNo) + + return (List[0], List[1]) + +## Get Pcd Values of Inf +# +# Get Pcd of Inf as .[|] +# +# @param Item: The string describes pcd +# @param Type: The type of Pcd +# @param File: The file which describes the pcd, used for error report +# +def GetPcdOfInf(Item, Type, File, LineNo): + Format = '.[|]' + TokenGuid, TokenName, Value, InfType = '', '', '', '' + + if Type == DataType.TAB_PCDS_FIXED_AT_BUILD: + InfType = DataType.TAB_INF_FIXED_PCD + elif Type == DataType.TAB_PCDS_PATCHABLE_IN_MODULE: + InfType = DataType.TAB_INF_PATCH_PCD + elif Type == DataType.TAB_PCDS_FEATURE_FLAG: + InfType = DataType.TAB_INF_FEATURE_PCD + elif Type == DataType.TAB_PCDS_DYNAMIC_EX: + InfType = DataType.TAB_INF_PCD_EX + elif Type == DataType.TAB_PCDS_DYNAMIC: + InfType = DataType.TAB_INF_PCD + List = GetSplitValueList(Item, DataType.TAB_VALUE_SPLIT, 1) + TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT) + if len(TokenInfo) != 2: + RaiseParserError(Item, InfType, File, Format, LineNo) + else: + TokenGuid = TokenInfo[0] + TokenName = TokenInfo[1] + + if len(List) > 1: + Value = List[1] + else: + Value = None + return (TokenGuid, TokenName, Value, InfType) + + +## Get Pcd Values of Dec +# +# Get Pcd of Dec as .||| +# @param Item: Pcd item +# @param Type: Pcd type +# @param File: Dec file +# @param LineNo: Line number +# +def GetPcdOfDec(Item, Type, File, LineNo= -1): + Format = '.|||' + TokenGuid, TokenName, Value, DatumType, Token = '', '', '', '', '' + List = GetSplitValueList(Item) + if len(List) != 4: + RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo) + else: + Value = List[1] + DatumType = List[2] + Token = List[3] + TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT) + if len(TokenInfo) != 2: + RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo) + else: + TokenGuid = TokenInfo[0] + TokenName = TokenInfo[1] + + return (TokenGuid, TokenName, Value, DatumType, Token, Type) + +## Parse DEFINE statement +# +# Get DEFINE macros +# +# @param LineValue: A DEFINE line value +# @param StartLine: A DEFINE start line +# @param Table: A table +# @param FileID: File ID +# @param Filename: File name +# @param SectionName: DEFINE section name +# @param SectionModel: DEFINE section model +# @param Arch: DEFINE arch +# +def ParseDefine(LineValue, StartLine, Table, FileID, SectionName, \ + SectionModel, Arch): + Logger.Debug(Logger.DEBUG_2, ST.MSG_DEFINE_STATEMENT_FOUND % (LineValue, \ + SectionName)) + Define = \ + GetSplitValueList(CleanString\ + (LineValue[LineValue.upper().\ + find(DataType.TAB_DEFINE.upper() + ' ') + \ + len(DataType.TAB_DEFINE + ' ') : ]), \ + DataType.TAB_EQUAL_SPLIT, 1) + Table.Insert(DataType.MODEL_META_DATA_DEFINE, Define[0], Define[1], '', \ + '', '', Arch, SectionModel, FileID, StartLine, -1, \ + StartLine, -1, 0) + +## InsertSectionItems +# +# Insert item data of a section to a dict +# +# @param Model: A model +# @param CurrentSection: Current section +# @param SectionItemList: Section item list +# @param ArchList: Arch list +# @param ThirdList: Third list +# @param RecordSet: Record set +# +def InsertSectionItems(Model, SectionItemList, ArchList, \ + ThirdList, RecordSet): + # + # Insert each item data of a section + # + for Index in range(0, len(ArchList)): + Arch = ArchList[Index] + Third = ThirdList[Index] + if Arch == '': + Arch = DataType.TAB_ARCH_COMMON + + Records = RecordSet[Model] + for SectionItem in SectionItemList: + LineValue, StartLine, Comment = SectionItem[0], \ + SectionItem[1], SectionItem[2] + + Logger.Debug(4, ST.MSG_PARSING % LineValue) + # + # And then parse DEFINE statement + # + if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1: + continue + # + # At last parse other sections + # + IdNum = -1 + Records.append([LineValue, Arch, StartLine, IdNum, Third, Comment]) + + if RecordSet != {}: + RecordSet[Model] = Records + +## GenMetaDatSectionItem +# +# @param Key: A key +# @param Value: A value +# @param List: A list +# +def GenMetaDatSectionItem(Key, Value, List): + if Key not in List: + List[Key] = [Value] + else: + List[Key].append(Value) + +## GetPkgInfoFromDec +# +# get package name, guid, version info from dec files +# +# @param Path: File path +# +def GetPkgInfoFromDec(Path): + PkgName = None + PkgGuid = None + PkgVersion = None + + Path = Path.replace('\\', '/') + + if not os.path.exists(Path): + Logger.Error("\nUPT", FILE_NOT_FOUND, File=Path) + + if Path in gPKG_INFO_DICT: + return gPKG_INFO_DICT[Path] + + try: + DecParser = None + if Path not in GlobalData.gPackageDict: + DecParser = Dec(Path) + GlobalData.gPackageDict[Path] = DecParser + else: + DecParser = GlobalData.gPackageDict[Path] + + PkgName = DecParser.GetPackageName() + PkgGuid = DecParser.GetPackageGuid() + PkgVersion = DecParser.GetPackageVersion() + gPKG_INFO_DICT[Path] = (PkgName, PkgGuid, PkgVersion) + return PkgName, PkgGuid, PkgVersion + except FatalError: + return None, None, None + + +## GetWorkspacePackage +# +# Get a list of workspace package information. +# +def GetWorkspacePackage(): + DecFileList = [] + WorkspaceDir = GlobalData.gWORKSPACE + PackageDir = GlobalData.gPACKAGE_PATH + for PkgRoot in [WorkspaceDir] + PackageDir: + for Root, Dirs, Files in os.walk(PkgRoot): + if 'CVS' in Dirs: + Dirs.remove('CVS') + if '.svn' in Dirs: + Dirs.remove('.svn') + for Dir in Dirs: + if Dir.startswith('.'): + Dirs.remove(Dir) + for FileSp in Files: + if FileSp.startswith('.'): + continue + Ext = os.path.splitext(FileSp)[1] + if Ext.lower() in ['.dec']: + DecFileList.append\ + (os.path.normpath(os.path.join(Root, FileSp))) + # + # abstract package guid, version info from DecFile List + # + PkgList = [] + for DecFile in DecFileList: + (PkgName, PkgGuid, PkgVersion) = GetPkgInfoFromDec(DecFile) + if PkgName and PkgGuid and PkgVersion: + PkgList.append((PkgName, PkgGuid, PkgVersion, DecFile)) + + return PkgList + +## GetWorkspaceModule +# +# Get a list of workspace modules. +# +def GetWorkspaceModule(): + InfFileList = [] + WorkspaceDir = GlobalData.gWORKSPACE + for Root, Dirs, Files in os.walk(WorkspaceDir): + if 'CVS' in Dirs: + Dirs.remove('CVS') + if '.svn' in Dirs: + Dirs.remove('.svn') + if 'Build' in Dirs: + Dirs.remove('Build') + for Dir in Dirs: + if Dir.startswith('.'): + Dirs.remove(Dir) + for FileSp in Files: + if FileSp.startswith('.'): + continue + Ext = os.path.splitext(FileSp)[1] + if Ext.lower() in ['.inf']: + InfFileList.append\ + (os.path.normpath(os.path.join(Root, FileSp))) + + return InfFileList + +## MacroParser used to parse macro definition +# +# @param Line: The content contain linestring and line number +# @param FileName: The meta-file file name +# @param SectionType: Section for the Line belong to +# @param FileLocalMacros: A list contain Macro defined in [Defines] section. +# +def MacroParser(Line, FileName, SectionType, FileLocalMacros): + MacroDefPattern = re.compile("^(DEFINE)[ \t]+") + LineContent = Line[0] + LineNo = Line[1] + Match = MacroDefPattern.match(LineContent) + if not Match: + # + # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method + # + return None, None + + TokenList = GetSplitValueList(LineContent[Match.end(1):], \ + DataType.TAB_EQUAL_SPLIT, 1) + # + # Syntax check + # + if not TokenList[0]: + Logger.Error('Parser', FORMAT_INVALID, ST.ERR_MACRONAME_NOGIVEN, + ExtraData=LineContent, File=FileName, Line=LineNo) + if len(TokenList) < 2: + Logger.Error('Parser', FORMAT_INVALID, ST.ERR_MACROVALUE_NOGIVEN, + ExtraData=LineContent, File=FileName, Line=LineNo) + + Name, Value = TokenList + + # + # DEFINE defined macros + # + if SectionType == DataType.MODEL_META_DATA_HEADER: + FileLocalMacros[Name] = Value + + ReIsValidMacroName = re.compile(r"^[A-Z][A-Z0-9_]*$", re.DOTALL) + if ReIsValidMacroName.match(Name) is None: + Logger.Error('Parser', + FORMAT_INVALID, + ST.ERR_MACRONAME_INVALID % (Name), + ExtraData=LineContent, + File=FileName, + Line=LineNo) + + # Validate MACRO Value + # + # ::= []{0,} + # "DEFINE" "=" [{} {}] + # ::= {} {} {} {} + # {} {} {} + # + # The definition of , , , , , + # , are subset of . + # + ReIsValidMacroValue = re.compile(r"^[\x20-\x7e]*$", re.DOTALL) + if ReIsValidMacroValue.match(Value) is None: + Logger.Error('Parser', + FORMAT_INVALID, + ST.ERR_MACROVALUE_INVALID % (Value), + ExtraData=LineContent, + File=FileName, + Line=LineNo) + + return Name, Value + +## GenSection +# +# generate section contents +# +# @param SectionName: indicate the name of the section, details refer to +# INF, DEC specs +# @param SectionDict: section statement dict, key is SectionAttrs(arch, +# moduletype or platform may exist as needed) list +# separated by space, +# value is statement +# +def GenSection(SectionName, SectionDict, SplitArch=True, NeedBlankLine=False): + Content = '' + for SectionAttrs in SectionDict: + StatementList = SectionDict[SectionAttrs] + if SectionAttrs and SectionName != 'Defines' and SectionAttrs.strip().upper() != DataType.TAB_ARCH_COMMON: + if SplitArch: + ArchList = GetSplitValueList(SectionAttrs, DataType.TAB_SPACE_SPLIT) + else: + if SectionName != 'UserExtensions': + ArchList = GetSplitValueList(SectionAttrs, DataType.TAB_COMMENT_SPLIT) + else: + ArchList = [SectionAttrs] + for Index in range(0, len(ArchList)): + ArchList[Index] = ConvertArchForInstall(ArchList[Index]) + Section = '[' + SectionName + '.' + (', ' + SectionName + '.').join(ArchList) + ']' + else: + Section = '[' + SectionName + ']' + Content += '\n' + Section + '\n' + if StatementList is not None: + for Statement in StatementList: + LineList = Statement.split('\n') + NewStatement = "" + for Line in LineList: + # ignore blank comment + if not Line.replace("#", '').strip() and SectionName not in ('Defines', 'Hob', 'Event', 'BootMode'): + continue + # add two space before non-comments line except the comments in Defines section + if Line.strip().startswith('#') and SectionName == 'Defines': + NewStatement += "%s\n" % Line + continue + NewStatement += " %s\n" % Line + if NeedBlankLine: + Content += NewStatement + '\n' + else: + Content += NewStatement + + if NeedBlankLine: + Content = Content[:-1] + if not Content.replace('\\n', '').strip(): + return '' + return Content + +## ConvertArchForInstall +# if Arch.upper() is in "IA32", "X64", "IPF", and "EBC", it must be upper case. "common" must be lower case. +# Anything else, the case must be preserved +# +# @param Arch: the arch string that need to be converted, it should be stripped before pass in +# @return: the arch string that get converted +# +def ConvertArchForInstall(Arch): + if Arch.upper() in [DataType.TAB_ARCH_IA32, DataType.TAB_ARCH_X64, + DataType.TAB_ARCH_IPF, DataType.TAB_ARCH_EBC]: + Arch = Arch.upper() + elif Arch.upper() == DataType.TAB_ARCH_COMMON: + Arch = Arch.lower() + + return Arch -- cgit