diff options
Diffstat (limited to 'BaseTools/Source/Python/UPT/Library/Parsing.py')
| -rw-r--r-- | BaseTools/Source/Python/UPT/Library/Parsing.py | 2030 |
1 files changed, 1015 insertions, 1015 deletions
diff --git a/BaseTools/Source/Python/UPT/Library/Parsing.py b/BaseTools/Source/Python/UPT/Library/Parsing.py index 6fb133745e..802f81e65c 100644 --- a/BaseTools/Source/Python/UPT/Library/Parsing.py +++ b/BaseTools/Source/Python/UPT/Library/Parsing.py @@ -1,1015 +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.<BR>
-#
-# 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 "[<Family>:]<ToolFlag>=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, \
- '[<Family>:]<ToolFlag>=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 <LibraryClassKeyWord>|<LibraryInstance>
-#
-# @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
-# @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, \
- '<LibraryClassKeyWord>|<LibraryInstance>')
- 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 <LibraryClassKeyWord>[|<LibraryInstance>]
-# [|<TokenSpaceGuidCName>.<PcdCName>]
-#
-# @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
-# @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, \
- '<LibraryClassKeyWord>[|<LibraryInstance>]\
- [|<TokenSpaceGuidCName>.<PcdCName>]')
- 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 <TokenSpaceGuidCName>.<PcdCName>
-#
-# @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 = '<TokenSpaceGuidCName>.<PcdCName>'
- 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 <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>
-# [|<Type>|<MaximumDatumSize>]
-#
-# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|
-# <Value>[|<Type>|<MaximumDatumSize>]
-# @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, \
- '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>\
- [|<Type>|<MaximumDatumSize>]', 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 <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
-#
-# @param Item: String as <PcdTokenSpaceGuidCName>
-# .<TokenCName>|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, \
- '<PcdTokenSpaceGuidCName>.<TokenCName>|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 <PcdTokenSpaceGuidCName>.<TokenCName>
-# |<Value>[|<DatumTyp>[|<MaxDatumSize>]]
-#
-# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|
-# 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, \
- '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>\
- [|<DatumTyp>[|<MaxDatumSize>]]', 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 <PcdTokenSpaceGuidCName>.<TokenCName>|<String>|
-# <VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]
-#
-# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|
-# 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, \
- '<PcdTokenSpaceGuidCName>.<TokenCName>|<String>|\
- <VariableGuidCName>|<VariableOffset>[|<DefaultValue>\
- [|<MaximumDatumSize>]]', 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 <PcdTokenSpaceGuidCName>.<TokenCName>|
-# <VpdOffset>[|<MaximumDatumSize>]
-#
-# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>
-# |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, \
- '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>\
- [|<MaximumDatumSize>]', 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('<LibraryClasses>') != -1:
- (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
- FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
- FindPcdsDynamic, FindPcdsDynamicEx) = \
- (True, False, False, False, False, False, False)
- continue
- if Line.find('<BuildOptions>') != -1:
- (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
- FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
- FindPcdsDynamic, FindPcdsDynamicEx) = \
- (False, True, False, False, False, False, False)
- continue
- if Line.find('<PcdsFeatureFlag>') != -1:
- (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
- FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
- FindPcdsDynamic, FindPcdsDynamicEx) = \
- (False, False, True, False, False, False, False)
- continue
- if Line.find('<PcdsPatchableInModule>') != -1:
- (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
- FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
- FindPcdsDynamic, FindPcdsDynamicEx) = \
- (False, False, False, True, False, False, False)
- continue
- if Line.find('<PcdsFixedAtBuild>') != -1:
- (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
- FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
- FindPcdsDynamic, FindPcdsDynamicEx) = \
- (False, False, False, False, True, False, False)
- continue
- if Line.find('<PcdsDynamic>') != -1:
- (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
- FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
- FindPcdsDynamic, FindPcdsDynamicEx) = \
- (False, False, False, False, False, True, False)
- continue
- if Line.find('<PcdsDynamicEx>') != -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('<LibraryClasses>') != -1:
- (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
- FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
- FindPcdsDynamic, FindPcdsDynamicEx) = \
- (True, False, False, False, False, False, False)
- continue
- if Line.find('<BuildOptions>') != -1:
- (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
- FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
- FindPcdsDynamic, FindPcdsDynamicEx) = \
- (False, True, False, False, False, False, False)
- continue
- if Line.find('<PcdsFeatureFlag>') != -1:
- (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
- FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
- FindPcdsDynamic, FindPcdsDynamicEx) = \
- (False, False, True, False, False, False, False)
- continue
- if Line.find('<PcdsPatchableInModule>') != -1:
- (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
- FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
- FindPcdsDynamic, FindPcdsDynamicEx) = \
- (False, False, False, True, False, False, False)
- continue
- if Line.find('<PcdsFixedAtBuild>') != -1:
- (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
- FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
- FindPcdsDynamic, FindPcdsDynamicEx) = \
- (False, False, False, False, True, False, False)
- continue
- if Line.find('<PcdsDynamic>') != -1:
- (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
- FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
- FindPcdsDynamic, FindPcdsDynamicEx) = \
- (False, False, False, False, False, True, False)
- continue
- if Line.find('<PcdsDynamicEx>') != -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 <Filename>[|<Family>[|<TagName>[|<ToolCode>
-# [|<PcdFeatureFlag>]]]]
-#
-# @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>
-# [|<PcdFeatureFlag>]]]]
-# @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, \
- '<Filename>[|<Family>[|<TagName>[|<ToolCode>\
- [|<PcdFeatureFlag>]]]]', 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 <Filename>[|<Family>[|<TagName>[|<ToolCode>
-# [|<PcdFeatureFlag>]]]]
-#
-# @param Item: String as <Filename>[|<Family>[|<TagName>
-# [|<ToolCode>[|<PcdFeatureFlag>]]]]
-# @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, \
- "<FileType>|<Filename>[|<Target>\
- [|<TokenSpaceGuidCName>.<PcdCName>]]", 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 <GuidCName>[|<PcdFeatureFlag>]
-#
-# @param Item: String as <GuidCName>[|<PcdFeatureFlag>]
-# @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 <GuidCName>=<GuidValue>
-#
-# @param Item: String as <GuidCName>=<GuidValue>
-# @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, '<CName>=<GuidValue>', \
- 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 <PackagePath>[|<PcdFeatureFlag>]
-#
-# @param Item: String as <PackagePath>[|<PcdFeatureFlag>]
-# @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 <TokenSpaceGuidCName>.<PcdCName>[|<Value>]
-#
-# @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 = '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]'
- 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 <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
-# @param Item: Pcd item
-# @param Type: Pcd type
-# @param File: Dec file
-# @param LineNo: Line number
-#
-def GetPcdOfDec(Item, Type, File, LineNo= -1):
- Format = '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>'
- 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
- #
- # <MacroDefinition> ::= [<Comments>]{0,}
- # "DEFINE" <MACRO> "=" [{<PATH>} {<VALUE>}] <EOL>
- # <Value> ::= {<NumVal>} {<Boolean>} {<AsciiString>} {<GUID>}
- # {<CString>} {<UnicodeString>} {<CArray>}
- #
- # The definition of <NumVal>, <PATH>, <Boolean>, <GUID>, <CString>,
- # <UnicodeString>, <CArray> are subset of <AsciiString>.
- #
- 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
+## @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.<BR> +# +# 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 "[<Family>:]<ToolFlag>=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, \ + '[<Family>:]<ToolFlag>=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 <LibraryClassKeyWord>|<LibraryInstance> +# +# @param Item: String as <LibraryClassKeyWord>|<LibraryInstance> +# @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, \ + '<LibraryClassKeyWord>|<LibraryInstance>') + 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 <LibraryClassKeyWord>[|<LibraryInstance>] +# [|<TokenSpaceGuidCName>.<PcdCName>] +# +# @param Item: String as <LibraryClassKeyWord>|<LibraryInstance> +# @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, \ + '<LibraryClassKeyWord>[|<LibraryInstance>]\ + [|<TokenSpaceGuidCName>.<PcdCName>]') + 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 <TokenSpaceGuidCName>.<PcdCName> +# +# @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 = '<TokenSpaceGuidCName>.<PcdCName>' + 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 <PcdTokenSpaceGuidCName>.<TokenCName>|<Value> +# [|<Type>|<MaximumDatumSize>] +# +# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>| +# <Value>[|<Type>|<MaximumDatumSize>] +# @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, \ + '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>\ + [|<Type>|<MaximumDatumSize>]', 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 <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE +# +# @param Item: String as <PcdTokenSpaceGuidCName> +# .<TokenCName>|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, \ + '<PcdTokenSpaceGuidCName>.<TokenCName>|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 <PcdTokenSpaceGuidCName>.<TokenCName> +# |<Value>[|<DatumTyp>[|<MaxDatumSize>]] +# +# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>| +# 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, \ + '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>\ + [|<DatumTyp>[|<MaxDatumSize>]]', 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 <PcdTokenSpaceGuidCName>.<TokenCName>|<String>| +# <VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]] +# +# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>| +# 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, \ + '<PcdTokenSpaceGuidCName>.<TokenCName>|<String>|\ + <VariableGuidCName>|<VariableOffset>[|<DefaultValue>\ + [|<MaximumDatumSize>]]', 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 <PcdTokenSpaceGuidCName>.<TokenCName>| +# <VpdOffset>[|<MaximumDatumSize>] +# +# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName> +# |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, \ + '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>\ + [|<MaximumDatumSize>]', 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('<LibraryClasses>') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (True, False, False, False, False, False, False) + continue + if Line.find('<BuildOptions>') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, True, False, False, False, False, False) + continue + if Line.find('<PcdsFeatureFlag>') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, True, False, False, False, False) + continue + if Line.find('<PcdsPatchableInModule>') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, False, True, False, False, False) + continue + if Line.find('<PcdsFixedAtBuild>') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, False, False, True, False, False) + continue + if Line.find('<PcdsDynamic>') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, False, False, False, True, False) + continue + if Line.find('<PcdsDynamicEx>') != -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('<LibraryClasses>') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (True, False, False, False, False, False, False) + continue + if Line.find('<BuildOptions>') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, True, False, False, False, False, False) + continue + if Line.find('<PcdsFeatureFlag>') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, True, False, False, False, False) + continue + if Line.find('<PcdsPatchableInModule>') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, False, True, False, False, False) + continue + if Line.find('<PcdsFixedAtBuild>') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, False, False, True, False, False) + continue + if Line.find('<PcdsDynamic>') != -1: + (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \ + FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \ + FindPcdsDynamic, FindPcdsDynamicEx) = \ + (False, False, False, False, False, True, False) + continue + if Line.find('<PcdsDynamicEx>') != -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 <Filename>[|<Family>[|<TagName>[|<ToolCode> +# [|<PcdFeatureFlag>]]]] +# +# @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode> +# [|<PcdFeatureFlag>]]]] +# @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, \ + '<Filename>[|<Family>[|<TagName>[|<ToolCode>\ + [|<PcdFeatureFlag>]]]]', 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 <Filename>[|<Family>[|<TagName>[|<ToolCode> +# [|<PcdFeatureFlag>]]]] +# +# @param Item: String as <Filename>[|<Family>[|<TagName> +# [|<ToolCode>[|<PcdFeatureFlag>]]]] +# @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, \ + "<FileType>|<Filename>[|<Target>\ + [|<TokenSpaceGuidCName>.<PcdCName>]]", 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 <GuidCName>[|<PcdFeatureFlag>] +# +# @param Item: String as <GuidCName>[|<PcdFeatureFlag>] +# @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 <GuidCName>=<GuidValue> +# +# @param Item: String as <GuidCName>=<GuidValue> +# @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, '<CName>=<GuidValue>', \ + 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 <PackagePath>[|<PcdFeatureFlag>] +# +# @param Item: String as <PackagePath>[|<PcdFeatureFlag>] +# @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 <TokenSpaceGuidCName>.<PcdCName>[|<Value>] +# +# @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 = '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]' + 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 <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token> +# @param Item: Pcd item +# @param Type: Pcd type +# @param File: Dec file +# @param LineNo: Line number +# +def GetPcdOfDec(Item, Type, File, LineNo= -1): + Format = '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>' + 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 + # + # <MacroDefinition> ::= [<Comments>]{0,} + # "DEFINE" <MACRO> "=" [{<PATH>} {<VALUE>}] <EOL> + # <Value> ::= {<NumVal>} {<Boolean>} {<AsciiString>} {<GUID>} + # {<CString>} {<UnicodeString>} {<CArray>} + # + # The definition of <NumVal>, <PATH>, <Boolean>, <GUID>, <CString>, + # <UnicodeString>, <CArray> are subset of <AsciiString>. + # + 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 |
