Liming Gao 1ccc4d895d Revert BaseTools: PYTHON3 migration
This reverts commit 6693f359b3c213513c5096a06c6f67244a44dc52..
678f85131238622e576705117e299d81cff755c9.

Python3 migration is the fundamental change. It requires every developer
to install Python3. Before this migration, the well communication and wide
verification must be done. But now, most people is not aware of this change,
and not try it. So, Python3 migration is reverted and be moved to edk2-staging
Python3 branch for the edk2 user evaluation.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Liming Gao <liming.gao@intel.com>
2018-10-15 08:29:14 +08:00

913 lines
38 KiB
Python

## @file
# This file is used to define common parsing related functions used in parsing INF/DEC/DSC process
#
# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
# Import Modules
#
from __future__ import absolute_import
from .StringUtils import *
from CommonDataClass.DataClass import *
from .DataType import *
## ParseDefineMacro
#
# Search whole table to find all defined Macro and replaced them with the real values
#
def ParseDefineMacro2(Table, RecordSets, GlobalMacro):
Macros = {}
#
# Find all DEFINE macros in section [Header] and its section
#
SqlCommand = """select Value1, Value2, BelongsToItem, StartLine, Arch from %s
where Model = %s
and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE)
RecordSet = Table.Exec(SqlCommand)
for Record in RecordSet:
Macros[Record[0]] = Record[1]
#
# Overrided by Global Macros
#
Macros.update(GlobalMacro)
#
# Replace the Macros
#
for Value in (v for v in RecordSets.values() if v):
for Item in Value:
Item[0] = ReplaceMacro(Item[0], Macros)
## ParseDefineMacro
#
# Search whole table to find all defined Macro and replaced them with the real values
#
def ParseDefineMacro(Table, GlobalMacro):
Macros = {}
#
# Find all DEFINE macros
#
SqlCommand = """select Value1, Value2, BelongsToItem, StartLine, Arch from %s
where Model = %s
and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE)
RecordSet = Table.Exec(SqlCommand)
for Record in RecordSet:
#***************************************************************************************************************************************************
# The follow SqlCommand (expr replace) is not supported in Sqlite 3.3.4 which is used in Python 2.5 *
# Reserved Only *
# SqlCommand = """update %s set Value1 = replace(Value1, '%s', '%s') *
# where ID in (select ID from %s *
# where Model = %s *
# and Value1 like '%%%s%%' *
# and StartLine > %s *
# and Enabled > -1 *
# and Arch = '%s')""" % \ *
# (self.TblDsc.Table, Record[0], Record[1], self.TblDsc.Table, Record[2], Record[1], Record[3], Record[4]) *
#***************************************************************************************************************************************************
Macros[Record[0]] = Record[1]
#
# Overrided by Global Macros
#
Macros.update(GlobalMacro)
#
# Found all defined macro and replaced
#
SqlCommand = """select ID, Value1 from %s
where Model != %s
and Value1 like '%%$(%%' and Value1 like '%%)%%'
and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE)
FoundRecords = Table.Exec(SqlCommand)
for FoundRecord in FoundRecords:
NewValue = ReplaceMacro(FoundRecord[1], Macros)
SqlCommand = """update %s set Value1 = '%s'
where ID = %s""" % (Table.Table, ConvertToSqlString2(NewValue), FoundRecord[0])
Table.Exec(SqlCommand)
##QueryDefinesItem
#
# Search item of section [Defines] by name, return its values
#
# @param Table: The Table to be executed
# @param Name: The Name of item of section [Defines]
# @param Arch: The Arch of item of section [Defines]
#
# @retval RecordSet: A list of all matched records
#
def QueryDefinesItem(Table, Name, Arch, BelongsToFile):
SqlCommand = """select Value2 from %s
where Model = %s
and Value1 = '%s'
and Arch = '%s'
and BelongsToFile = %s
and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Name), ConvertToSqlString2(Arch), BelongsToFile)
RecordSet = Table.Exec(SqlCommand)
if len(RecordSet) < 1:
SqlCommand = """select Value2 from %s
where Model = %s
and Value1 = '%s'
and Arch = '%s'
and BelongsToFile = %s
and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Name), ConvertToSqlString2(TAB_ARCH_COMMON.upper()), BelongsToFile)
RecordSet = Table.Exec(SqlCommand)
if len(RecordSet) == 1:
if Name == TAB_INF_DEFINES_LIBRARY_CLASS:
return [RecordSet[0][0]]
else:
return GetSplitValueList(RecordSet[0][0])
elif len(RecordSet) < 1:
return ['']
elif len(RecordSet) > 1:
RetVal = []
for Record in RecordSet:
if Name == TAB_INF_DEFINES_LIBRARY_CLASS:
RetVal.append(Record[0])
else:
Items = GetSplitValueList(Record[0])
for Item in Items:
RetVal.append(Item)
return RetVal
##QueryDefinesItem
#
# Search item of section [Defines] by name, return its values
#
# @param Table: The Table to be executed
# @param Name: The Name of item of section [Defines]
# @param Arch: The Arch of item of section [Defines]
#
# @retval RecordSet: A list of all matched records
#
def QueryDefinesItem2(Table, Arch, BelongsToFile):
SqlCommand = """select Value1, Value2, StartLine from %s
where Model = %s
and Arch = '%s'
and BelongsToFile = %s
and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Arch), BelongsToFile)
RecordSet = Table.Exec(SqlCommand)
if len(RecordSet) < 1:
SqlCommand = """select Value1, Value2, StartLine from %s
where Model = %s
and Arch = '%s'
and BelongsToFile = %s
and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(TAB_ARCH_COMMON), BelongsToFile)
RecordSet = Table.Exec(SqlCommand)
return RecordSet
##QueryDscItem
#
# Search all dsc item for a specific section
#
# @param Table: The Table to be executed
# @param Model: The type of section
#
# @retval RecordSet: A list of all matched records
#
def QueryDscItem(Table, Model, BelongsToItem, BelongsToFile):
SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s
where Model = %s
and BelongsToItem = %s
and BelongsToFile = %s
and Enabled > -1""" % (Table.Table, Model, BelongsToItem, BelongsToFile)
return Table.Exec(SqlCommand)
##QueryDecItem
#
# Search all dec item for a specific section
#
# @param Table: The Table to be executed
# @param Model: The type of section
#
# @retval RecordSet: A list of all matched records
#
def QueryDecItem(Table, Model, BelongsToItem):
SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s
where Model = %s
and BelongsToItem = %s
and Enabled > -1""" % (Table.Table, Model, BelongsToItem)
return Table.Exec(SqlCommand)
##QueryInfItem
#
# Search all dec item for a specific section
#
# @param Table: The Table to be executed
# @param Model: The type of section
#
# @retval RecordSet: A list of all matched records
#
def QueryInfItem(Table, Model, BelongsToItem):
SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s
where Model = %s
and BelongsToItem = %s
and Enabled > -1""" % (Table.Table, Model, BelongsToItem)
return Table.Exec(SqlCommand)
## 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
#
# @retval truple() A truple structure as (Family, ToolChain, Flag)
#
def GetBuildOption(String, File, LineNo = -1):
(Family, ToolChain, Flag) = ('', '', '')
if String.find(TAB_EQUAL_SPLIT) < 0:
RaiseParserError(String, 'BuildOptions', File, '[<Family>:]<ToolFlag>=Flag', LineNo)
else:
List = GetSplitValueList(String, 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
#
# @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item
#
def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo = -1):
List = GetSplitValueList(Item[0])
SupMod = 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
#
# @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item
#
def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo = -1):
ItemList = GetSplitValueList((Item[0] + DataType.TAB_VALUE_SPLIT * 2))
SupMod = 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
#
# @retval True PcdTokenInfo is in correct format
#
def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo = -1):
Format = '<TokenSpaceGuidCName>.<PcdCName>'
if TokenInfoString != '' and TokenInfoString is not None:
TokenInfoList = GetSplitValueList(TokenInfoString, 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
#
# @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)
#
def GetPcd(Item, Type, ContainerFile, LineNo = -1):
TokenGuid, TokenName, Value, MaximumDatumSize, Token = '', '', '', '', ''
List = GetSplitValueList(Item + 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], 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
#
# @retval (TokenInfo[1], TokenInfo[0], List[1], Type)
#
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
#
# @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)
#
def GetDynamicDefaultPcd(Item, Type, ContainerFile, LineNo = -1):
TokenGuid, TokenName, Value, DatumTyp, MaxDatumSize = '', '', '', '', ''
List = GetSplitValueList(Item + 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], 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
#
# @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], List[4], List[5], Type)
#
def GetDynamicHiiPcd(Item, Type, ContainerFile, LineNo = -1):
TokenGuid, TokenName, L1, L2, L3, L4, L5 = '', '', '', '', '', '', ''
List = GetSplitValueList(Item + 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:
L1, L2, L3, L4, L5 = 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, L1, L2, L3, L4, L5, 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
#
# @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], Type)
#
def GetDynamicVpdPcd(Item, Type, ContainerFile, LineNo = -1):
TokenGuid, TokenName, L1, L2 = '', '', '', ''
List = GetSplitValueList(Item + TAB_VALUE_SPLIT)
if len(List) < 3 or len(List) > 4:
RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]', LineNo)
else:
L1, L2 = List[1], List[2]
if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
(TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)
return (TokenName, TokenGuid, L1, L2, 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
#
# @retval True Get component successfully
#
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(TAB_INCLUDE.upper() + ' ') > -1 or Line.upper().find(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
#
# @retval truple() A pair as (InfFilename, ExecFilename)
#
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, Key, 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
#
# @retval (List[0], List[1], List[2], List[3], List[4])
#
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
#
# @retval (List[0], List[1], List[2], List[3])
# @retval List
#
def GetBinary(Item, ContainerFile, FileRelativePath, LineNo = -1):
ItemNew = Item + DataType.TAB_VALUE_SPLIT
List = GetSplitValueList(ItemNew)
if len(List) != 4 and len(List) != 5:
RaiseParserError(Item, 'Binaries', ContainerFile, "<FileType>|<Filename>|<Target>[|<TokenSpaceGuidCName>.<PcdCName>]", LineNo)
else:
if List[3] != '':
CheckPcdTokenInfo(List[3], 'Binaries', ContainerFile, LineNo)
if len(List) == 4:
return (List[0], List[1], List[2], List[3])
elif len(List) == 3:
return (List[0], List[1], List[2], '')
elif len(List) == 2:
return (List[0], List[1], '', '')
elif len(List) == 1:
return (List[0], '', '', '')
## 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
#
# @retval (List[0], List[1])
#
def GetGuidsProtocolsPpisOfInf(Item, Type, ContainerFile, LineNo = -1):
ItemNew = Item + TAB_VALUE_SPLIT
List = GetSplitValueList(ItemNew)
if List[1] != '':
CheckPcdTokenInfo(List[1], Type, ContainerFile, LineNo)
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
#
# @retval (List[0], List[1])
#
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)
return (List[0], List[1])
## 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
#
# @retval (List[0], List[1])
#
def GetPackage(Item, ContainerFile, FileRelativePath, LineNo = -1):
ItemNew = Item + 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
#
# @retval (TokenSpcCName, TokenCName, Value, ItemType) Formatted Pcd Item
#
def GetPcdOfInf(Item, Type, File, LineNo):
Format = '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]'
TokenGuid, TokenName, Value, InfType = '', '', '', ''
if Type == TAB_PCDS_FIXED_AT_BUILD:
InfType = TAB_INF_FIXED_PCD
elif Type == TAB_PCDS_PATCHABLE_IN_MODULE:
InfType = TAB_INF_PATCH_PCD
elif Type == TAB_PCDS_FEATURE_FLAG:
InfType = TAB_INF_FEATURE_PCD
elif Type == TAB_PCDS_DYNAMIC_EX:
InfType = TAB_INF_PCD_EX
elif Type == TAB_PCDS_DYNAMIC:
InfType = TAB_INF_PCD
List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT)
if len(List) < 2 or len(List) > 3:
RaiseParserError(Item, InfType, File, Format, LineNo)
else:
Value = List[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]
return (TokenGuid, TokenName, Value, Type)
## Get Pcd Values of Dec
#
# Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
# @retval (TokenSpcCName, TokenCName, Value, DatumType, Token, ItemType) Formatted Pcd Item
#
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
#
# 1. Insert a record into TblDec
# Value1: Macro Name
# Value2: Macro Value
#
def ParseDefine(LineValue, StartLine, Table, FileID, Filename, SectionName, SectionModel, Arch):
EdkLogger.debug(EdkLogger.DEBUG_2, "DEFINE statement '%s' found in section %s" % (LineValue, SectionName))
Define = GetSplitValueList(CleanString(LineValue[LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') + len(DataType.TAB_DEFINE + ' ') : ]), TAB_EQUAL_SPLIT, 1)
Table.Insert(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
#
def InsertSectionItems(Model, CurrentSection, 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 = TAB_ARCH_COMMON
Records = RecordSet[Model]
for SectionItem in SectionItemList:
BelongsToItem, EndLine, EndColumn = -1, -1, -1
LineValue, StartLine, EndLine, Comment = SectionItem[0], SectionItem[1], SectionItem[1], SectionItem[2]
EdkLogger.debug(4, "Parsing %s ..." %LineValue)
# And then parse DEFINE statement
if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1:
continue
# At last parse other sections
ID = -1
Records.append([LineValue, Arch, StartLine, ID, Third, Comment])
if RecordSet != {}:
RecordSet[Model] = Records
## Insert records to database
#
# Insert item data of a section to database
# @param Table: The Table to be inserted
# @param FileID: The ID of belonging file
# @param Filename: The name of belonging file
# @param CurrentSection: The name of currect section
# @param SectionItemList: A list of items of the section
# @param ArchList: A list of arches
# @param ThirdList: A list of third parameters, ModuleType for LibraryClass and SkuId for Dynamic Pcds
# @param IfDefList: A list of all conditional statements
# @param RecordSet: A dict of all parsed records
#
def InsertSectionItemsIntoDatabase(Table, FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, RecordSet):
#
# Insert each item data of a section
#
for Index in range(0, len(ArchList)):
Arch = ArchList[Index]
Third = ThirdList[Index]
if Arch == '':
Arch = TAB_ARCH_COMMON
Records = RecordSet[Model]
for SectionItem in SectionItemList:
BelongsToItem, EndLine, EndColumn = -1, -1, -1
LineValue, StartLine, EndLine = SectionItem[0], SectionItem[1], SectionItem[1]
EdkLogger.debug(4, "Parsing %s ..." %LineValue)
#
# And then parse DEFINE statement
#
if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1:
ParseDefine(LineValue, StartLine, Table, FileID, Filename, CurrentSection, Model, Arch)
continue
#
# At last parse other sections
#
ID = Table.Insert(Model, LineValue, Third, Third, '', '', Arch, -1, FileID, StartLine, -1, StartLine, -1, 0)
Records.append([LineValue, Arch, StartLine, ID, Third])
if RecordSet != {}:
RecordSet[Model] = Records
## GenMetaDatSectionItem
def GenMetaDatSectionItem(Key, Value, List):
if Key not in List:
List[Key] = [Value]
else:
List[Key].append(Value)
## IsValidWord
#
# Check whether the word is valid.
# <Word> ::= (a-zA-Z0-9_)(a-zA-Z0-9_-){0,} Alphanumeric characters with
# optional
# dash "-" and/or underscore "_" characters. No whitespace
# characters are permitted.
#
# @param Word: The word string need to be checked.
#
def IsValidWord(Word):
if not Word:
return False
#
# The first char should be alpha, _ or Digit.
#
if not Word[0].isalnum() and \
not Word[0] == '_' and \
not Word[0].isdigit():
return False
LastChar = ''
for Char in Word[1:]:
if (not Char.isalpha()) and \
(not Char.isdigit()) and \
Char != '-' and \
Char != '_' and \
Char != '.':
return False
if Char == '.' and LastChar == '.':
return False
LastChar = Char
return True