Check In tool source code based on Build tool project revision r1655.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8964 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
lgao4
2009-07-17 09:10:31 +00:00
parent 577e30cdb4
commit 30fdf1140b
532 changed files with 231447 additions and 32 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,622 @@
## @file
# The engine for building files
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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
#
import os
import re
import copy
import string
from Common.GlobalData import *
from Common.BuildToolError import *
from Common.Misc import tdict, PathClass
from Common.String import NormPath
from Common.DataType import *
import Common.EdkLogger as EdkLogger
## Convert file type to file list macro name
#
# @param FileType The name of file type
#
# @retval string The name of macro
#
def FileListMacro(FileType):
return "%sS" % FileType.replace("-", "_").upper()
## Convert file type to list file macro name
#
# @param FileType The name of file type
#
# @retval string The name of macro
#
def ListFileMacro(FileType):
return "%s_LIST" % FileListMacro(FileType)
class TargetDescBlock(object):
_Cache_ = {} # {TargetFile : TargetDescBlock object}
# Factory method
def __new__(Class, Inputs, Outputs, Commands, Dependencies):
if Outputs[0] in Class._Cache_:
Tdb = Class._Cache_[Outputs[0]]
for File in Inputs:
Tdb.AddInput(File)
else:
Tdb = super(TargetDescBlock, Class).__new__(Class)
Tdb._Init(Inputs, Outputs, Commands, Dependencies)
#Class._Cache_[Outputs[0]] = Tdb
return Tdb
def _Init(self, Inputs, Outputs, Commands, Dependencies):
self.Inputs = Inputs
self.Outputs = Outputs
self.Commands = Commands
self.Dependencies = Dependencies
if self.Outputs:
self.Target = self.Outputs[0]
else:
self.Target = None
def __str__(self):
return self.Target.Path
def __hash__(self):
return hash(self.Target.Path)
def __eq__(self, Other):
if type(Other) == type(self):
return Other.Target.Path == self.Target.Path
else:
return str(Other) == self.Target.Path
def AddInput(self, Input):
if Input not in self.Inputs:
self.Inputs.append(Input)
def IsMultipleInput(self):
return len(self.Inputs) > 1
@staticmethod
def Renew():
TargetDescBlock._Cache_ = {}
## Class for one build rule
#
# This represents a build rule which can give out corresponding command list for
# building the given source file(s). The result can be used for generating the
# target for makefile.
#
class FileBuildRule:
INC_LIST_MACRO = "INC_LIST"
INC_MACRO = "INC"
## constructor
#
# @param Input The dictionary represeting input file(s) for a rule
# @param Output The list represeting output file(s) for a rule
# @param Command The list containing commands to generate the output from input
#
def __init__(self, Type, Input, Output, Command, ExtraDependency=None):
# The Input should not be empty
if not Input:
Input = []
if not Output:
Output = []
if not Command:
Command = []
self.FileListMacro = FileListMacro(Type)
self.ListFileMacro = ListFileMacro(Type)
self.IncListFileMacro = self.INC_LIST_MACRO
self.SourceFileType = Type
# source files listed not in "*" or "?" pattern format
if not ExtraDependency:
self.ExtraSourceFileList = []
else:
self.ExtraSourceFileList = ExtraDependency
#
# Search macros used in command lines for <FILE_TYPE>_LIST and INC_LIST.
# If found, generate a file to keep the input files used to get over the
# limitation of command line length
#
self.MacroList = []
self.CommandList = []
for CmdLine in Command:
self.MacroList.extend(gMacroPattern.findall(CmdLine))
# replace path separator with native one
self.CommandList.append(CmdLine)
# Indicate what should be generated
if self.FileListMacro in self.MacroList:
self.GenFileListMacro = True
else:
self.GenFileListMacro = False
if self.ListFileMacro in self.MacroList:
self.GenListFile = True
self.GenFileListMacro = True
else:
self.GenListFile = False
if self.INC_LIST_MACRO in self.MacroList:
self.GenIncListFile = True
else:
self.GenIncListFile = False
# Check input files
self.IsMultipleInput = False
self.SourceFileExtList = []
for File in Input:
Base, Ext = os.path.splitext(File)
if Base.find("*") >= 0:
# There's "*" in the file name
self.IsMultipleInput = True
self.GenFileListMacro = True
elif Base.find("?") < 0:
# There's no "*" and "?" in file name
self.ExtraSourceFileList.append(File)
continue
if Ext not in self.SourceFileExtList:
self.SourceFileExtList.append(Ext)
# Check output files
self.DestFileList = []
for File in Output:
self.DestFileList.append(File)
# All build targets generated by this rule for a module
self.BuildTargets = {}
## str() function support
#
# @retval string
#
def __str__(self):
SourceString = ""
SourceString += " %s %s %s" % (self.SourceFileType, " ".join(self.SourceFileExtList), self.ExtraSourceFileList)
DestString = ", ".join(self.DestFileList)
CommandString = "\n\t".join(self.CommandList)
return "%s : %s\n\t%s" % (DestString, SourceString, CommandString)
## Check if given file extension is supported by this rule
#
# @param FileExt The extension of a file
#
# @retval True If the extension is supported
# @retval False If the extension is not supported
#
def IsSupported(self, FileExt):
return FileExt in self.SourceFileExtList
def Instantiate(self, Macros={}):
NewRuleObject = copy.copy(self)
NewRuleObject.BuildTargets = {}
NewRuleObject.DestFileList = []
for File in self.DestFileList:
NewRuleObject.DestFileList.append(PathClass(NormPath(File, Macros)))
return NewRuleObject
## Apply the rule to given source file(s)
#
# @param SourceFile One file or a list of files to be built
# @param RelativeToDir The relative path of the source file
# @param PathSeparator Path separator
#
# @retval tuple (Source file in full path, List of individual sourcefiles, Destionation file, List of build commands)
#
def Apply(self, SourceFile):
if not self.CommandList or not self.DestFileList:
return None
# source file
if self.IsMultipleInput:
SrcFileName = ""
SrcFileBase = ""
SrcFileExt = ""
SrcFileDir = ""
SrcPath = ""
# SourceFile must be a list
SrcFile = "$(%s)" % self.FileListMacro
else:
SrcFileName, SrcFileBase, SrcFileExt = SourceFile.Name, SourceFile.BaseName, SourceFile.Ext
if SourceFile.Root:
SrcFileDir = SourceFile.SubDir
if SrcFileDir == "":
SrcFileDir = "."
else:
SrcFileDir = "."
SrcFile = SourceFile.Path
SrcPath = SourceFile.Dir
# destination file (the first one)
if self.DestFileList:
DestFile = self.DestFileList[0].Path
DestPath = self.DestFileList[0].Dir
DestFileName = self.DestFileList[0].Name
DestFileBase, DestFileExt = self.DestFileList[0].BaseName, self.DestFileList[0].Ext
else:
DestFile = ""
DestPath = ""
DestFileName = ""
DestFileBase = ""
DestFileExt = ""
BuildRulePlaceholderDict = {
# source file
"src" : SrcFile,
"s_path" : SrcPath,
"s_dir" : SrcFileDir,
"s_name" : SrcFileName,
"s_base" : SrcFileBase,
"s_ext" : SrcFileExt,
# destination file
"dst" : DestFile,
"d_path" : DestPath,
"d_name" : DestFileName,
"d_base" : DestFileBase,
"d_ext" : DestFileExt,
}
DstFile = []
for File in self.DestFileList:
File = string.Template(str(File)).safe_substitute(BuildRulePlaceholderDict)
File = string.Template(str(File)).safe_substitute(BuildRulePlaceholderDict)
DstFile.append(PathClass(File, IsBinary=True))
if DstFile[0] in self.BuildTargets:
TargetDesc = self.BuildTargets[DstFile[0]]
TargetDesc.AddInput(SourceFile)
else:
CommandList = []
for CommandString in self.CommandList:
CommandString = string.Template(CommandString).safe_substitute(BuildRulePlaceholderDict)
CommandString = string.Template(CommandString).safe_substitute(BuildRulePlaceholderDict)
CommandList.append(CommandString)
TargetDesc = TargetDescBlock([SourceFile], DstFile, CommandList, self.ExtraSourceFileList)
TargetDesc.ListFileMacro = self.ListFileMacro
TargetDesc.FileListMacro = self.FileListMacro
TargetDesc.IncListFileMacro = self.IncListFileMacro
TargetDesc.GenFileListMacro = self.GenFileListMacro
TargetDesc.GenListFile = self.GenListFile
TargetDesc.GenIncListFile = self.GenIncListFile
self.BuildTargets[DstFile[0]] = TargetDesc
return TargetDesc
## Class for build rules
#
# BuildRule class parses rules defined in a file or passed by caller, and converts
# the rule into FileBuildRule object.
#
class BuildRule:
_SectionHeader = "SECTIONHEADER"
_Section = "SECTION"
_SubSectionHeader = "SUBSECTIONHEADER"
_SubSection = "SUBSECTION"
_InputFile = "INPUTFILE"
_OutputFile = "OUTPUTFILE"
_ExtraDependency = "EXTRADEPENDENCY"
_Command = "COMMAND"
_UnknownSection = "UNKNOWNSECTION"
_SubSectionList = [_InputFile, _OutputFile, _Command]
_PATH_SEP = "(+)"
_FileTypePattern = re.compile("^[_a-zA-Z][_\-0-9a-zA-Z]*$")
_BinaryFileRule = FileBuildRule(TAB_DEFAULT_BINARY_FILE, [], [os.path.join("$(OUTPUT_DIR)", "${s_name}")],
["$(CP) ${src} ${dst}"], [])
## Constructor
#
# @param File The file containing build rules in a well defined format
# @param Content The string list of build rules in a well defined format
# @param LineIndex The line number from which the parsing will begin
# @param SupportedFamily The list of supported tool chain families
#
def __init__(self, File=None, Content=None, LineIndex=0, SupportedFamily=["MSFT", "INTEL", "GCC", "RVCT"]):
self.RuleFile = File
# Read build rules from file if it's not none
if File != None:
try:
self.RuleContent = open(File, 'r').readlines()
except:
EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File)
elif Content != None:
self.RuleContent = Content
else:
EdkLogger.error("build", PARAMETER_MISSING, ExtraData="No rule file or string given")
self.SupportedToolChainFamilyList = SupportedFamily
self.RuleDatabase = tdict(True, 4) # {FileExt, ModuleType, Arch, Family : FileBuildRule object}
self.Ext2FileType = {} # {ext : file-type}
self.FileTypeList = set()
self._LineIndex = LineIndex
self._State = ""
self._RuleInfo = tdict(True, 2) # {toolchain family : {"InputFile": {}, "OutputFile" : [], "Command" : []}}
self._FileType = ''
self._BuildTypeList = []
self._ArchList = []
self._FamilyList = []
self._TotalToolChainFamilySet = set()
self._RuleObjectList = [] # FileBuildRule object list
self.Parse()
# some intrinsic rules
self.RuleDatabase[TAB_DEFAULT_BINARY_FILE, "COMMON", "COMMON", "COMMON"] = self._BinaryFileRule
self.FileTypeList.add(TAB_DEFAULT_BINARY_FILE)
## Parse the build rule strings
def Parse(self):
self._State = self._Section
for Index in range(self._LineIndex, len(self.RuleContent)):
# Clean up the line and replace path separator with native one
Line = self.RuleContent[Index].strip().replace(self._PATH_SEP, os.path.sep)
self.RuleContent[Index] = Line
# skip empty or comment line
if Line == "" or Line[0] == "#":
continue
# find out section header, enclosed by []
if Line[0] == '[' and Line[-1] == ']':
# merge last section information into rule database
self.EndOfSection()
self._State = self._SectionHeader
# find out sub-section header, enclosed by <>
elif Line[0] == '<' and Line[-1] == '>':
if self._State != self._UnknownSection:
self._State = self._SubSectionHeader
# call section handler to parse each (sub)section
self._StateHandler[self._State](self, Index)
# merge last section information into rule database
self.EndOfSection()
## Parse definitions under a section
#
# @param LineIndex The line index of build rule text
#
def ParseSection(self, LineIndex):
pass
## Parse definitions under a subsection
#
# @param LineIndex The line index of build rule text
#
def ParseSubSection(self, LineIndex):
# currenly nothing here
pass
## Placeholder for not supported sections
#
# @param LineIndex The line index of build rule text
#
def SkipSection(self, LineIndex):
pass
## Merge section information just got into rule database
def EndOfSection(self):
Database = self.RuleDatabase
# if there's specific toochain family, 'COMMON' doesn't make sense any more
if len(self._TotalToolChainFamilySet) > 1 and 'COMMON' in self._TotalToolChainFamilySet:
self._TotalToolChainFamilySet.remove('COMMON')
for Family in self._TotalToolChainFamilySet:
Input = self._RuleInfo[Family, self._InputFile]
Output = self._RuleInfo[Family, self._OutputFile]
Command = self._RuleInfo[Family, self._Command]
ExtraDependency = self._RuleInfo[Family, self._ExtraDependency]
BuildRule = FileBuildRule(self._FileType, Input, Output, Command, ExtraDependency)
for BuildType in self._BuildTypeList:
for Arch in self._ArchList:
Database[self._FileType, BuildType, Arch, Family] = BuildRule
for FileExt in BuildRule.SourceFileExtList:
self.Ext2FileType[FileExt] = self._FileType
## Parse section header
#
# @param LineIndex The line index of build rule text
#
def ParseSectionHeader(self, LineIndex):
self._RuleInfo = tdict(True, 2)
self._BuildTypeList = []
self._ArchList = []
self._FamilyList = []
self._TotalToolChainFamilySet = set()
FileType = ''
RuleNameList = self.RuleContent[LineIndex][1:-1].split(',')
for RuleName in RuleNameList:
Arch = 'COMMON'
BuildType = 'COMMON'
TokenList = [Token.strip().upper() for Token in RuleName.split('.')]
# old format: Build.File-Type
if TokenList[0] == "BUILD":
if len(TokenList) == 1:
EdkLogger.error("build", FORMAT_INVALID, "Invalid rule section",
File=self.RuleFile, Line=LineIndex+1,
ExtraData=self.RuleContent[LineIndex])
FileType = TokenList[1]
if FileType == '':
EdkLogger.error("build", FORMAT_INVALID, "No file type given",
File=self.RuleFile, Line=LineIndex+1,
ExtraData=self.RuleContent[LineIndex])
if self._FileTypePattern.match(FileType) == None:
EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
ExtraData="Only character, number (non-first character), '_' and '-' are allowed in file type")
# new format: File-Type.Build-Type.Arch
else:
if FileType == '':
FileType = TokenList[0]
elif FileType != TokenList[0]:
EdkLogger.error("build", FORMAT_INVALID,
"Different file types are not allowed in the same rule section",
File=self.RuleFile, Line=LineIndex+1,
ExtraData=self.RuleContent[LineIndex])
if len(TokenList) > 1:
BuildType = TokenList[1]
if len(TokenList) > 2:
Arch = TokenList[2]
if BuildType not in self._BuildTypeList:
self._BuildTypeList.append(BuildType)
if Arch not in self._ArchList:
self._ArchList.append(Arch)
if 'COMMON' in self._BuildTypeList and len(self._BuildTypeList) > 1:
EdkLogger.error("build", FORMAT_INVALID,
"Specific build types must not be mixed with common one",
File=self.RuleFile, Line=LineIndex+1,
ExtraData=self.RuleContent[LineIndex])
if 'COMMON' in self._ArchList and len(self._ArchList) > 1:
EdkLogger.error("build", FORMAT_INVALID,
"Specific ARCH must not be mixed with common one",
File=self.RuleFile, Line=LineIndex+1,
ExtraData=self.RuleContent[LineIndex])
self._FileType = FileType
self._State = self._Section
self.FileTypeList.add(FileType)
## Parse sub-section header
#
# @param LineIndex The line index of build rule text
#
def ParseSubSectionHeader(self, LineIndex):
SectionType = ""
List = self.RuleContent[LineIndex][1:-1].split(',')
FamilyList = []
for Section in List:
TokenList = Section.split('.')
Type = TokenList[0].strip().upper()
if SectionType == "":
SectionType = Type
elif SectionType != Type:
EdkLogger.error("build", FORMAT_INVALID,
"Two different section types are not allowed in the same sub-section",
File=self.RuleFile, Line=LineIndex+1,
ExtraData=self.RuleContent[LineIndex])
if len(TokenList) > 1:
Family = TokenList[1].strip().upper()
else:
Family = "COMMON"
if Family not in FamilyList:
FamilyList.append(Family)
self._FamilyList = FamilyList
self._TotalToolChainFamilySet.update(FamilyList)
self._State = SectionType.upper()
if 'COMMON' in FamilyList and len(FamilyList) > 1:
EdkLogger.error("build", FORMAT_INVALID,
"Specific tool chain family should not be mixed with general one",
File=self.RuleFile, Line=LineIndex+1,
ExtraData=self.RuleContent[LineIndex])
if self._State not in self._StateHandler:
EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
ExtraData="Unknown subsection: %s" % self.RuleContent[LineIndex])
## Parse <InputFile> sub-section
#
# @param LineIndex The line index of build rule text
#
def ParseInputFile(self, LineIndex):
FileList = [File.strip() for File in self.RuleContent[LineIndex].split(",")]
for ToolChainFamily in self._FamilyList:
InputFiles = self._RuleInfo[ToolChainFamily, self._State]
if InputFiles == None:
InputFiles = []
self._RuleInfo[ToolChainFamily, self._State] = InputFiles
InputFiles.extend(FileList)
## Parse <ExtraDependency> sub-section
#
# @param LineIndex The line index of build rule text
#
def ParseCommon(self, LineIndex):
for ToolChainFamily in self._FamilyList:
Items = self._RuleInfo[ToolChainFamily, self._State]
if Items == None:
Items = []
self._RuleInfo[ToolChainFamily, self._State] = Items
Items.append(self.RuleContent[LineIndex])
## Get a build rule via [] operator
#
# @param FileExt The extension of a file
# @param ToolChainFamily The tool chain family name
# @param BuildVersion The build version number. "*" means any rule
# is applicalbe.
#
# @retval FileType The file type string
# @retval FileBuildRule The object of FileBuildRule
#
# Key = (FileExt, ModuleType, Arch, ToolChainFamily)
def __getitem__(self, Key):
if not Key:
return None
if Key[0] in self.Ext2FileType:
Type = self.Ext2FileType[Key[0]]
elif Key[0].upper() in self.FileTypeList:
Type = Key[0].upper()
else:
return None
if len(Key) > 1:
Key = (Type,) + Key[1:]
else:
Key = (Type,)
return self.RuleDatabase[Key]
_StateHandler = {
_SectionHeader : ParseSectionHeader,
_Section : ParseSection,
_SubSectionHeader : ParseSubSectionHeader,
_SubSection : ParseSubSection,
_InputFile : ParseInputFile,
_OutputFile : ParseCommon,
_ExtraDependency : ParseCommon,
_Command : ParseCommon,
_UnknownSection : SkipSection,
}
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
if __name__ == '__main__':
import sys
EdkLogger.Initialize()
if len(sys.argv) > 1:
Br = BuildRule(sys.argv[1])
print str(Br[".c", "DXE_DRIVER", "IA32", "MSFT"][1])
print
print str(Br[".c", "DXE_DRIVER", "IA32", "INTEL"][1])
print
print str(Br[".c", "DXE_DRIVER", "IA32", "GCC"][1])
print
print str(Br[".ac", "ACPI_TABLE", "IA32", "MSFT"][1])
print
print str(Br[".h", "ACPI_TABLE", "IA32", "INTEL"][1])
print
print str(Br[".ac", "ACPI_TABLE", "IA32", "MSFT"][1])
print
print str(Br[".s", "SEC", "IPF", "COMMON"][1])
print
print str(Br[".s", "SEC"][1])

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,441 @@
## @file
# This file is used to generate DEPEX file for module's dependency expression
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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
#
import sys
import os
import re
import traceback
from StringIO import StringIO
from struct import pack
from Common.BuildToolError import *
from Common.Misc import SaveFileOnChange
from Common.Misc import GuidStructureStringToGuidString
from Common import EdkLogger as EdkLogger
## Regular expression for matching "DEPENDENCY_START ... DEPENDENCY_END"
gStartClosePattern = re.compile(".*DEPENDENCY_START(.+)DEPENDENCY_END.*", re.S)
## Mapping between module type and EFI phase
gType2Phase = {
"BASE" : None,
"SEC" : "PEI",
"PEI_CORE" : "PEI",
"PEIM" : "PEI",
"DXE_CORE" : "DXE",
"DXE_DRIVER" : "DXE",
"DXE_SMM_DRIVER" : "DXE",
"DXE_RUNTIME_DRIVER": "DXE",
"DXE_SAL_DRIVER" : "DXE",
"UEFI_DRIVER" : "DXE",
"UEFI_APPLICATION" : "DXE",
"SMM_DRIVER" : "DXE",
}
## Convert dependency expression string into EFI internal representation
#
# DependencyExpression class is used to parse dependency expression string and
# convert it into its binary form.
#
class DependencyExpression:
ArchProtocols = set([
'665e3ff6-46cc-11d4-9a38-0090273fc14d', # 'gEfiBdsArchProtocolGuid'
'26baccb1-6f42-11d4-bce7-0080c73c8881', # 'gEfiCpuArchProtocolGuid'
'26baccb2-6f42-11d4-bce7-0080c73c8881', # 'gEfiMetronomeArchProtocolGuid'
'1da97072-bddc-4b30-99f1-72a0b56fff2a', # 'gEfiMonotonicCounterArchProtocolGuid'
'27cfac87-46cc-11d4-9a38-0090273fc14d', # 'gEfiRealTimeClockArchProtocolGuid'
'27cfac88-46cc-11d4-9a38-0090273fc14d', # 'gEfiResetArchProtocolGuid'
'b7dfb4e1-052f-449f-87be-9818fc91b733', # 'gEfiRuntimeArchProtocolGuid'
'a46423e3-4617-49f1-b9ff-d1bfa9115839', # 'gEfiSecurityArchProtocolGuid'
'26baccb3-6f42-11d4-bce7-0080c73c8881', # 'gEfiTimerArchProtocolGuid'
'6441f818-6362-4e44-b570-7dba31dd2453', # 'gEfiVariableWriteArchProtocolGuid'
'1e5668e2-8481-11d4-bcf1-0080c73c8881', # 'gEfiVariableArchProtocolGuid'
'665e3ff5-46cc-11d4-9a38-0090273fc14d' # 'gEfiWatchdogTimerArchProtocolGuid'
]
)
OpcodePriority = {
"AND" : 1,
"OR" : 1,
"NOT" : 2,
# "SOR" : 9,
# "BEFORE": 9,
# "AFTER" : 9,
}
Opcode = {
"PEI" : {
"PUSH" : 0x02,
"AND" : 0x03,
"OR" : 0x04,
"NOT" : 0x05,
"TRUE" : 0x06,
"FALSE" : 0x07,
"END" : 0x08
},
"DXE" : {
"BEFORE": 0x00,
"AFTER" : 0x01,
"PUSH" : 0x02,
"AND" : 0x03,
"OR" : 0x04,
"NOT" : 0x05,
"TRUE" : 0x06,
"FALSE" : 0x07,
"END" : 0x08,
"SOR" : 0x09
}
}
# all supported op codes and operands
SupportedOpcode = ["BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "END", "SOR"]
SupportedOperand = ["TRUE", "FALSE"]
OpcodeWithSingleOperand = ['NOT', 'BEFORE', 'AFTER']
OpcodeWithTwoOperand = ['AND', 'OR']
# op code that should not be the last one
NonEndingOpcode = ["AND", "OR", "NOT", 'SOR']
# op code must not present at the same time
ExclusiveOpcode = ["BEFORE", "AFTER"]
# op code that should be the first one if it presents
AboveAllOpcode = ["SOR", "BEFORE", "AFTER"]
#
# open and close brace must be taken as individual tokens
#
TokenPattern = re.compile("(\(|\)|\{[^{}]+\{?[^{}]+\}?[ ]*\}|\w+)")
## Constructor
#
# @param Expression The list or string of dependency expression
# @param ModuleType The type of the module using the dependency expression
#
def __init__(self, Expression, ModuleType, Optimize=False):
self.ModuleType = ModuleType
self.Phase = gType2Phase[ModuleType]
if type(Expression) == type([]):
self.ExpressionString = " ".join(Expression)
self.TokenList = Expression
else:
self.ExpressionString = Expression
self.GetExpressionTokenList()
self.PostfixNotation = []
self.OpcodeList = []
self.GetPostfixNotation()
self.ValidateOpcode()
EdkLogger.debug(EdkLogger.DEBUG_8, repr(self))
if Optimize:
self.Optimize()
EdkLogger.debug(EdkLogger.DEBUG_8, "\n Optimized: " + repr(self))
def __str__(self):
return " ".join(self.TokenList)
def __repr__(self):
WellForm = ''
for Token in self.PostfixNotation:
if Token in self.SupportedOpcode:
WellForm += "\n " + Token
else:
WellForm += ' ' + Token
return WellForm
## Split the expression string into token list
def GetExpressionTokenList(self):
self.TokenList = self.TokenPattern.findall(self.ExpressionString)
## Convert token list into postfix notation
def GetPostfixNotation(self):
Stack = []
LastToken = ''
for Token in self.TokenList:
if Token == "(":
if LastToken not in self.SupportedOpcode + ['(', '', None]:
EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operator before open parentheses",
ExtraData="Near %s" % LastToken)
Stack.append(Token)
elif Token == ")":
if '(' not in Stack:
EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: mismatched parentheses",
ExtraData=str(self))
elif LastToken in self.SupportedOpcode + ['', None]:
EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operand before close parentheses",
ExtraData="Near %s" % LastToken)
while len(Stack) > 0:
if Stack[-1] == '(':
Stack.pop()
break
self.PostfixNotation.append(Stack.pop())
elif Token in self.OpcodePriority:
if Token == "NOT":
if LastToken not in self.SupportedOpcode + ['(', '', None]:
EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operator before NOT",
ExtraData="Near %s" % LastToken)
elif LastToken in self.SupportedOpcode + ['(', '', None]:
EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operand before " + Token,
ExtraData="Near %s" % LastToken)
while len(Stack) > 0:
if Stack[-1] == "(" or self.OpcodePriority[Token] >= self.OpcodePriority[Stack[-1]]:
break
self.PostfixNotation.append(Stack.pop())
Stack.append(Token)
self.OpcodeList.append(Token)
else:
if Token not in self.SupportedOpcode:
# not OP, take it as GUID
if LastToken not in self.SupportedOpcode + ['(', '', None]:
EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operator before %s" % Token,
ExtraData="Near %s" % LastToken)
if len(self.OpcodeList) == 0 or self.OpcodeList[-1] not in self.ExclusiveOpcode:
if Token not in self.SupportedOperand:
self.PostfixNotation.append("PUSH")
# check if OP is valid in this phase
elif Token in self.Opcode[self.Phase]:
if Token == "END":
break
self.OpcodeList.append(Token)
else:
EdkLogger.error("GenDepex", PARSER_ERROR,
"Opcode=%s doesn't supported in %s stage " % (Token, self.Phase),
ExtraData=str(self))
self.PostfixNotation.append(Token)
LastToken = Token
# there should not be parentheses in Stack
if '(' in Stack or ')' in Stack:
EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: mismatched parentheses",
ExtraData=str(self))
while len(Stack) > 0:
self.PostfixNotation.append(Stack.pop())
if self.PostfixNotation[-1] != 'END':
self.PostfixNotation.append("END")
## Validate the dependency expression
def ValidateOpcode(self):
for Op in self.AboveAllOpcode:
if Op in self.PostfixNotation:
if Op != self.PostfixNotation[0]:
EdkLogger.error("GenDepex", PARSER_ERROR, "%s should be the first opcode in the expression" % Op,
ExtraData=str(self))
if len(self.PostfixNotation) < 3:
EdkLogger.error("GenDepex", PARSER_ERROR, "Missing operand for %s" % Op,
ExtraData=str(self))
for Op in self.ExclusiveOpcode:
if Op in self.OpcodeList:
if len(self.OpcodeList) > 1:
EdkLogger.error("GenDepex", PARSER_ERROR, "%s should be the only opcode in the expression" % Op,
ExtraData=str(self))
if len(self.PostfixNotation) < 3:
EdkLogger.error("GenDepex", PARSER_ERROR, "Missing operand for %s" % Op,
ExtraData=str(self))
if self.TokenList[-1] != 'END' and self.TokenList[-1] in self.NonEndingOpcode:
EdkLogger.error("GenDepex", PARSER_ERROR, "Extra %s at the end of the dependency expression" % self.TokenList[-1],
ExtraData=str(self))
if self.TokenList[-1] == 'END' and self.TokenList[-2] in self.NonEndingOpcode:
EdkLogger.error("GenDepex", PARSER_ERROR, "Extra %s at the end of the dependency expression" % self.TokenList[-2],
ExtraData=str(self))
if "END" in self.TokenList and "END" != self.TokenList[-1]:
EdkLogger.error("GenDepex", PARSER_ERROR, "Extra expressions after END",
ExtraData=str(self))
## Simply optimize the dependency expression by removing duplicated operands
def Optimize(self):
ValidOpcode = list(set(self.OpcodeList))
if len(ValidOpcode) != 1 or ValidOpcode[0] not in ['AND', 'OR']:
return
Op = ValidOpcode[0]
NewOperand = []
AllOperand = set()
for Token in self.PostfixNotation:
if Token in self.SupportedOpcode or Token in NewOperand:
continue
AllOperand.add(Token)
if Token == 'TRUE':
if Op == 'AND':
continue
else:
NewOperand.append(Token)
break
elif Token == 'FALSE':
if Op == 'OR':
continue
else:
NewOperand.append(Token)
break
NewOperand.append(Token)
# don't generate depex if only TRUE operand left
if self.ModuleType == 'PEIM' and len(NewOperand) == 1 and NewOperand[0] == 'TRUE':
self.PostfixNotation = []
return
# don't generate depex if all operands are architecture protocols
if self.ModuleType in ['UEFI_DRIVER', 'DXE_DRIVER', 'DXE_RUNTIME_DRIVER', 'DXE_SAL_DRIVER', 'DXE_SMM_DRIVER'] and \
Op == 'AND' and \
self.ArchProtocols == set([GuidStructureStringToGuidString(Guid) for Guid in AllOperand]):
self.PostfixNotation = []
return
if len(NewOperand) == 0:
self.TokenList = list(AllOperand)
else:
self.TokenList = []
while True:
self.TokenList.append(NewOperand.pop(0))
if NewOperand == []:
break
self.TokenList.append(Op)
self.PostfixNotation = []
self.GetPostfixNotation()
## Convert a GUID value in C structure format into its binary form
#
# @param Guid The GUID value in C structure format
#
# @retval array The byte array representing the GUID value
#
def GetGuidValue(self, Guid):
GuidValueString = Guid.replace("{", "").replace("}", "").replace(" ", "")
GuidValueList = GuidValueString.split(",")
if len(GuidValueList) != 11:
EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid GUID value string or opcode: %s" % Guid)
return pack("1I2H8B", *(int(value, 16) for value in GuidValueList))
## Save the binary form of dependency expression in file
#
# @param File The path of file. If None is given, put the data on console
#
# @retval True If the file doesn't exist or file is changed
# @retval False If file exists and is not changed.
#
def Generate(self, File=None):
Buffer = StringIO()
if len(self.PostfixNotation) == 0:
return False
for Item in self.PostfixNotation:
if Item in self.Opcode[self.Phase]:
Buffer.write(pack("B", self.Opcode[self.Phase][Item]))
elif Item in self.SupportedOpcode:
EdkLogger.error("GenDepex", FORMAT_INVALID,
"Opcode [%s] is not expected in %s phase" % (Item, self.Phase),
ExtraData=self.ExpressionString)
else:
Buffer.write(self.GetGuidValue(Item))
FilePath = ""
FileChangeFlag = True
if File == None:
sys.stdout.write(Buffer.getvalue())
FilePath = "STDOUT"
else:
FileChangeFlag = SaveFileOnChange(File, Buffer.getvalue(), True)
Buffer.close()
return FileChangeFlag
versionNumber = "0.04"
__version__ = "%prog Version " + versionNumber
__copyright__ = "Copyright (c) 2007-2008, Intel Corporation All rights reserved."
__usage__ = "%prog [options] [dependency_expression_file]"
## Parse command line options
#
# @retval OptionParser
#
def GetOptions():
from optparse import OptionParser
Parser = OptionParser(description=__copyright__, version=__version__, usage=__usage__)
Parser.add_option("-o", "--output", dest="OutputFile", default=None, metavar="FILE",
help="Specify the name of depex file to be generated")
Parser.add_option("-t", "--module-type", dest="ModuleType", default=None,
help="The type of module for which the dependency expression serves")
Parser.add_option("-e", "--dependency-expression", dest="Expression", default="",
help="The string of dependency expression. If this option presents, the input file will be ignored.")
Parser.add_option("-m", "--optimize", dest="Optimize", default=False, action="store_true",
help="Do some simple optimization on the expression.")
Parser.add_option("-v", "--verbose", dest="verbose", default=False, action="store_true",
help="build with verbose information")
Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")
Parser.add_option("-q", "--quiet", dest="quiet", default=False, action="store_true",
help="build with little information")
return Parser.parse_args()
## Entrance method
#
# @retval 0 Tool was successful
# @retval 1 Tool failed
#
def Main():
EdkLogger.Initialize()
Option, Input = GetOptions()
# Set log level
if Option.quiet:
EdkLogger.SetLevel(EdkLogger.QUIET)
elif Option.verbose:
EdkLogger.SetLevel(EdkLogger.VERBOSE)
elif Option.debug != None:
EdkLogger.SetLevel(Option.debug + 1)
else:
EdkLogger.SetLevel(EdkLogger.INFO)
try:
if Option.ModuleType == None or Option.ModuleType not in gType2Phase:
EdkLogger.error("GenDepex", OPTION_MISSING, "Module type is not specified or supported")
DxsFile = ''
if len(Input) > 0 and Option.Expression == "":
DxsFile = Input[0]
DxsString = open(DxsFile, 'r').read().replace("\n", " ").replace("\r", " ")
DxsString = gStartClosePattern.sub("\\1", DxsString)
elif Option.Expression != "":
if Option.Expression[0] == '"':
DxsString = Option.Expression[1:-1]
else:
DxsString = Option.Expression
else:
EdkLogger.error("GenDepex", OPTION_MISSING, "No expression string or file given")
Dpx = DependencyExpression(DxsString, Option.ModuleType, Option.Optimize)
if Option.OutputFile != None:
Dpx.Generate(Option.OutputFile)
else:
Dpx.Generate()
except BaseException, X:
EdkLogger.quiet("")
if Option != None and Option.debug != None:
EdkLogger.quiet(traceback.format_exc())
else:
EdkLogger.quiet(str(X))
return 1
return 0
if __name__ == '__main__':
sys.exit(Main())

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,532 @@
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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.
#
#This file is used to parse a strings file and create or add to a string database file.
#
##
# Import Modules
#
import re
import Common.EdkLogger as EdkLogger
from Common.BuildToolError import *
from UniClassObject import *
##
# Static definitions
#
EFI_HII_SIBT_END = '0x00'
EFI_HII_SIBT_STRING_SCSU = '0x10'
EFI_HII_SIBT_STRING_SCSU_FONT = '0x11'
EFI_HII_SIBT_STRINGS_SCSU = '0x12'
EFI_HII_SIBT_STRINGS_SCSU_FONT = '0x13'
EFI_HII_SIBT_STRING_UCS2 = '0x14'
EFI_HII_SIBT_STRING_UCS2_FONT = '0x15'
EFI_HII_SIBT_STRINGS_UCS2 = '0x16'
EFI_HII_SIBT_STRINGS_UCS2_FONT = '0x17'
EFI_HII_SIBT_DUPLICATE = '0x20'
EFI_HII_SIBT_SKIP2 = '0x21'
EFI_HII_SIBT_SKIP1 = '0x22'
EFI_HII_SIBT_EXT1 = '0x30'
EFI_HII_SIBT_EXT2 = '0x31'
EFI_HII_SIBT_EXT4 = '0x32'
EFI_HII_SIBT_FONT = '0x40'
EFI_HII_PACKAGE_STRINGS = '0x04'
EFI_HII_PACKAGE_FORM = '0x02'
StringPackageType = EFI_HII_PACKAGE_STRINGS
StringPackageForm = EFI_HII_PACKAGE_FORM
StringBlockType = EFI_HII_SIBT_STRING_UCS2
StringSkipType = EFI_HII_SIBT_SKIP2
HexHeader = '0x'
COMMENT = '// '
DEFINE_STR = '#define'
COMMENT_DEFINE_STR = COMMENT + DEFINE_STR
NOT_REFERENCED = 'not referenced'
COMMENT_NOT_REFERENCED = ' ' + COMMENT + NOT_REFERENCED
CHAR_ARRAY_DEFIN = 'unsigned char'
COMMON_FILE_NAME = 'Strings'
OFFSET = 'offset'
STRING = 'string'
TO = 'to'
STRING_TOKEN = re.compile('STRING_TOKEN *\(([A-Z0-9_]+) *\)', re.MULTILINE | re.UNICODE)
EFI_HII_ARRAY_SIZE_LENGTH = 4
EFI_HII_PACKAGE_HEADER_LENGTH = 4
EFI_HII_HDR_SIZE_LENGTH = 4
EFI_HII_STRING_OFFSET_LENGTH = 4
EFI_STRING_ID = 1
EFI_STRING_ID_LENGTH = 2
EFI_HII_LANGUAGE_WINDOW = 0
EFI_HII_LANGUAGE_WINDOW_LENGTH = 2
EFI_HII_LANGUAGE_WINDOW_NUMBER = 16
EFI_HII_STRING_PACKAGE_HDR_LENGTH = EFI_HII_PACKAGE_HEADER_LENGTH + EFI_HII_HDR_SIZE_LENGTH + EFI_HII_STRING_OFFSET_LENGTH + EFI_HII_LANGUAGE_WINDOW_LENGTH * EFI_HII_LANGUAGE_WINDOW_NUMBER + EFI_STRING_ID_LENGTH
H_C_FILE_HEADER = ['//', \
'// DO NOT EDIT -- auto-generated file', \
'//', \
'// This file is generated by the StrGather utility', \
'//']
LANGUAGE_NAME_STRING_NAME = '$LANGUAGE_NAME'
PRINTABLE_LANGUAGE_NAME_STRING_NAME = '$PRINTABLE_LANGUAGE_NAME'
## Convert a dec number to a hex string
#
# Convert a dec number to a formatted hex string in length digit
# The digit is set to default 8
# The hex string starts with "0x"
# DecToHexStr(1000) is '0x000003E8'
# DecToHexStr(1000, 6) is '0x0003E8'
#
# @param Dec: The number in dec format
# @param Digit: The needed digit of hex string
#
# @retval: The formatted hex string
#
def DecToHexStr(Dec, Digit = 8):
return eval("'0x%0" + str(Digit) + "X' % int(Dec)")
## Convert a dec number to a hex list
#
# Convert a dec number to a formatted hex list in size digit
# The digit is set to default 8
# DecToHexList(1000) is ['0xE8', '0x03', '0x00', '0x00']
# DecToHexList(1000, 6) is ['0xE8', '0x03', '0x00']
#
# @param Dec: The number in dec format
# @param Digit: The needed digit of hex list
#
# @retval: A list for formatted hex string
#
def DecToHexList(Dec, Digit = 8):
Hex = eval("'%0" + str(Digit) + "X' % int(Dec)" )
List = []
for Bit in range(Digit - 2, -1, -2):
List.append(HexHeader + Hex[Bit:Bit + 2])
return List
## Convert a acsii string to a hex list
#
# Convert a acsii string to a formatted hex list
# AscToHexList('en-US') is ['0x65', '0x6E', '0x2D', '0x55', '0x53']
#
# @param Ascii: The acsii string
#
# @retval: A list for formatted hex string
#
def AscToHexList(Ascii):
List = []
for Item in Ascii:
List.append('0x%2X' % ord(Item))
return List
## Create header of .h file
#
# Create a header of .h file
#
# @param BaseName: The basename of strings
#
# @retval Str: A string for .h file header
#
def CreateHFileHeader(BaseName):
Str = ''
for Item in H_C_FILE_HEADER:
Str = WriteLine(Str, Item)
Str = WriteLine(Str, '#ifndef _' + BaseName.upper() + '_STRINGS_DEFINE_H_')
Str = WriteLine(Str, '#define _' + BaseName.upper() + '_STRINGS_DEFINE_H_')
return Str
## Create content of .h file
#
# Create content of .h file
#
# @param BaseName: The basename of strings
# @param UniObjectClass: A UniObjectClass instance
#
# @retval Str: A string of .h file content
#
def CreateHFileContent(BaseName, UniObjectClass):
Str = ''
ValueStartPtr = 60
Line = COMMENT_DEFINE_STR + ' ' + LANGUAGE_NAME_STRING_NAME + ' ' * (ValueStartPtr - len(DEFINE_STR + LANGUAGE_NAME_STRING_NAME)) + DecToHexStr(0, 4) + COMMENT_NOT_REFERENCED
Str = WriteLine(Str, Line)
Line = COMMENT_DEFINE_STR + ' ' + PRINTABLE_LANGUAGE_NAME_STRING_NAME + ' ' * (ValueStartPtr - len(DEFINE_STR + PRINTABLE_LANGUAGE_NAME_STRING_NAME)) + DecToHexStr(1, 4) + COMMENT_NOT_REFERENCED
Str = WriteLine(Str, Line)
for Index in range(2, len(UniObjectClass.OrderedStringList[UniObjectClass.LanguageDef[0][0]])):
StringItem = UniObjectClass.OrderedStringList[UniObjectClass.LanguageDef[0][0]][Index]
Name = StringItem.StringName
Token = StringItem.Token
Referenced = StringItem.Referenced
if Name != None:
Line = ''
if Referenced == True:
Line = DEFINE_STR + ' ' + Name + ' ' * (ValueStartPtr - len(DEFINE_STR + Name)) + DecToHexStr(Token, 4)
else:
Line = COMMENT_DEFINE_STR + ' ' + Name + ' ' * (ValueStartPtr - len(DEFINE_STR + Name)) + DecToHexStr(Token, 4) + COMMENT_NOT_REFERENCED
Str = WriteLine(Str, Line)
Str = WriteLine(Str, '')
Str = WriteLine(Str, 'extern unsigned char ' + BaseName + 'Strings[];')
return Str
## Create a complete .h file
#
# Create a complet .h file with file header and file content
#
# @param BaseName: The basename of strings
# @param UniObjectClass: A UniObjectClass instance
#
# @retval Str: A string of complete .h file
#
def CreateHFile(BaseName, UniObjectClass):
HFile = WriteLine('', CreateHFileContent(BaseName, UniObjectClass))
return HFile
## Create header of .c file
#
# Create a header of .c file
#
# @retval Str: A string for .c file header
#
def CreateCFileHeader():
Str = ''
for Item in H_C_FILE_HEADER:
Str = WriteLine(Str, Item)
return Str
## Create a formatted string all items in an array
#
# Use ',' to join each item in an array, and break an new line when reaching the width (default is 16)
#
# @param Array: The array need to be formatted
# @param Width: The line length, the default value is set to 16
#
# @retval ArrayItem: A string for all formatted array items
#
def CreateArrayItem(Array, Width = 16):
MaxLength = Width
Index = 0
Line = ' '
ArrayItem = ''
for Item in Array:
if Index < MaxLength:
Line = Line + Item + ', '
Index = Index + 1
else:
ArrayItem = WriteLine(ArrayItem, Line)
Line = ' ' + Item + ', '
Index = 1
ArrayItem = Write(ArrayItem, Line.rstrip())
return ArrayItem
## CreateCFileStringValue
#
# Create a line with string value
#
# @param Value: Value of the string
#
# @retval Str: A formatted string with string value
#
def CreateCFileStringValue(Value):
Value = [StringBlockType] + Value
Str = WriteLine('', CreateArrayItem(Value))
return Str
## Create content of .c file
#
# Create content of .c file
#
# @param BaseName: The basename of strings
# @param UniObjectClass: A UniObjectClass instance
#
# @retval Str: A string of .c file content
#
def CreateCFileContent(BaseName, UniObjectClass, IsCompatibleMode):
#
# Init array length
#
TotalLength = EFI_HII_ARRAY_SIZE_LENGTH
Str = ''
Offset = 0
#
# Create lines for each language's strings
#
for IndexI in range(len(UniObjectClass.LanguageDef)):
Language = UniObjectClass.LanguageDef[IndexI][0]
LangPrintName = UniObjectClass.LanguageDef[IndexI][1]
StrStringValue = ''
ArrayLength = 0
NumberOfUseOhterLangDef = 0
Index = 0
for IndexJ in range(1, len(UniObjectClass.OrderedStringList[UniObjectClass.LanguageDef[IndexI][0]])):
Item = UniObjectClass.FindByToken(IndexJ, Language)
Name = Item.StringName
Value = Item.StringValueByteList
Referenced = Item.Referenced
Token = Item.Token
Length = Item.Length
UseOtherLangDef = Item.UseOtherLangDef
if UseOtherLangDef != '' and Referenced:
NumberOfUseOhterLangDef = NumberOfUseOhterLangDef + 1
Index = Index + 1
else:
if NumberOfUseOhterLangDef > 0:
StrStringValue = WriteLine(StrStringValue, CreateArrayItem([StringSkipType] + DecToHexList(NumberOfUseOhterLangDef, 4)))
NumberOfUseOhterLangDef = 0
ArrayLength = ArrayLength + 3
if Referenced and Item.Token > 0:
Index = Index + 1
StrStringValue = WriteLine(StrStringValue, "// %s: %s:%s" % (DecToHexStr(Index, 4), Name, DecToHexStr(Token, 4)))
StrStringValue = Write(StrStringValue, CreateCFileStringValue(Value))
Offset = Offset + Length
ArrayLength = ArrayLength + Item.Length + 1 # 1 is for the length of string type
#
# EFI_HII_PACKAGE_HEADER
#
Offset = EFI_HII_STRING_PACKAGE_HDR_LENGTH + len(Language) + 1
ArrayLength = Offset + ArrayLength + 1
#
# Create PACKAGE HEADER
#
Str = WriteLine(Str, '// PACKAGE HEADER\n')
TotalLength = TotalLength + ArrayLength
List = DecToHexList(ArrayLength, 6) + \
[StringPackageType] + \
DecToHexList(Offset) + \
DecToHexList(Offset) + \
DecToHexList(EFI_HII_LANGUAGE_WINDOW, EFI_HII_LANGUAGE_WINDOW_LENGTH * 2) * EFI_HII_LANGUAGE_WINDOW_NUMBER + \
DecToHexList(EFI_STRING_ID, 4) + \
AscToHexList(Language) + \
DecToHexList(0, 2)
Str = WriteLine(Str, CreateArrayItem(List, 16) + '\n')
#
# Create PACKAGE DATA
#
Str = WriteLine(Str, '// PACKAGE DATA\n')
Str = Write(Str, StrStringValue)
#
# Add an EFI_HII_SIBT_END at last
#
Str = WriteLine(Str, ' ' + EFI_HII_SIBT_END + ",")
#
# Create line for string variable name
# "unsigned char $(BaseName)Strings[] = {"
#
AllStr = WriteLine('', CHAR_ARRAY_DEFIN + ' ' + BaseName + COMMON_FILE_NAME + '[] = {\n' )
#
# Create FRAMEWORK_EFI_HII_PACK_HEADER in compatible mode
#
if IsCompatibleMode:
AllStr = WriteLine(AllStr, '// FRAMEWORK PACKAGE HEADER Length')
AllStr = WriteLine(AllStr, CreateArrayItem(DecToHexList(TotalLength + 2)) + '\n')
AllStr = WriteLine(AllStr, '// FRAMEWORK PACKAGE HEADER Type')
AllStr = WriteLine(AllStr, CreateArrayItem(DecToHexList(2, 4)) + '\n')
#
# Create whole array length in UEFI mode
#
if not IsCompatibleMode:
AllStr = WriteLine(AllStr, '// STRGATHER_OUTPUT_HEADER')
AllStr = WriteLine(AllStr, CreateArrayItem(DecToHexList(TotalLength)) + '\n')
#
# Join package data
#
AllStr = Write(AllStr, Str)
return AllStr
## Create end of .c file
#
# Create end of .c file
#
# @retval Str: A string of .h file end
#
def CreateCFileEnd():
Str = Write('', '};')
return Str
## Create a .c file
#
# Create a complete .c file
#
# @param BaseName: The basename of strings
# @param UniObjectClass: A UniObjectClass instance
#
# @retval CFile: A string of complete .c file
#
def CreateCFile(BaseName, UniObjectClass, IsCompatibleMode):
CFile = ''
#CFile = WriteLine(CFile, CreateCFileHeader())
CFile = WriteLine(CFile, CreateCFileContent(BaseName, UniObjectClass, IsCompatibleMode))
CFile = WriteLine(CFile, CreateCFileEnd())
return CFile
## GetFileList
#
# Get a list for all files
#
# @param IncludeList: A list of all path to be searched
# @param SkipList: A list of all types of file could be skipped
#
# @retval FileList: A list of all files found
#
def GetFileList(SourceFileList, IncludeList, SkipList):
if IncludeList == None:
EdkLogger.error("UnicodeStringGather", AUTOGEN_ERROR, "Include path for unicode file is not defined")
FileList = []
if SkipList == None:
SkipList = []
for File in SourceFileList:
for Dir in IncludeList:
if not os.path.exists(Dir):
continue
File = os.path.join(Dir, File.Path)
#
# Ignore Dir
#
if os.path.isfile(File) != True:
continue
#
# Ignore file listed in skip list
#
IsSkip = False
for Skip in SkipList:
if os.path.splitext(File)[1].upper() == Skip.upper():
EdkLogger.verbose("Skipped %s for string token uses search" % File)
IsSkip = True
break
if not IsSkip:
FileList.append(File)
break
return FileList
## SearchString
#
# Search whether all string defined in UniObjectClass are referenced
# All string used should be set to Referenced
#
# @param UniObjectClass: Input UniObjectClass
# @param FileList: Search path list
#
# @retval UniObjectClass: UniObjectClass after searched
#
def SearchString(UniObjectClass, FileList):
if FileList == []:
return UniObjectClass
for File in FileList:
if os.path.isfile(File):
Lines = open(File, 'r')
for Line in Lines:
StringTokenList = STRING_TOKEN.findall(Line)
for StrName in StringTokenList:
EdkLogger.debug(EdkLogger.DEBUG_5, "Found string identifier: " + StrName)
UniObjectClass.SetStringReferenced(StrName)
UniObjectClass.ReToken()
return UniObjectClass
## GetStringFiles
#
# This function is used for UEFI2.1 spec
#
#
def GetStringFiles(UniFilList, SourceFileList, IncludeList, SkipList, BaseName, IsCompatibleMode = False, ShellMode = False):
Status = True
ErrorMessage = ''
if len(UniFilList) > 0:
if ShellMode:
#
# support ISO 639-2 codes in .UNI files of EDK Shell
#
Uni = UniFileClassObject(UniFilList, True)
else:
Uni = UniFileClassObject(UniFilList, IsCompatibleMode)
else:
EdkLogger.error("UnicodeStringGather", AUTOGEN_ERROR, 'No unicode files given')
FileList = GetFileList(SourceFileList, IncludeList, SkipList)
Uni = SearchString(Uni, FileList)
HFile = CreateHFile(BaseName, Uni)
CFile = CreateCFile(BaseName, Uni, IsCompatibleMode)
return HFile, CFile
#
# Write an item
#
def Write(Target, Item):
return Target + Item
#
# Write an item with a break line
#
def WriteLine(Target, Item):
return Target + Item + '\n'
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
if __name__ == '__main__':
EdkLogger.info('start')
UniFileList = [
r'C:\\Edk\\Strings2.uni',
r'C:\\Edk\\Strings.uni'
]
SrcFileList = []
for Root, Dirs, Files in os.walk('C:\\Edk'):
for File in Files:
SrcFileList.append(File)
IncludeList = [
r'C:\\Edk'
]
SkipList = ['.inf', '.uni']
BaseName = 'DriverSample'
(h, c) = GetStringFiles(UniFileList, SrcFileList, IncludeList, SkipList, BaseName, True)
hfile = open('unistring.h', 'w')
cfile = open('unistring.c', 'w')
hfile.write(h)
cfile.write(c)
EdkLogger.info('end')

View File

@@ -0,0 +1,530 @@
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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.
#
#This file is used to collect all defined strings in multiple uni files
#
##
# Import Modules
#
import os, codecs, re
import Common.EdkLogger as EdkLogger
from Common.BuildToolError import *
from Common.String import GetLineNo
from Common.Misc import PathClass
##
# Static definitions
#
UNICODE_WIDE_CHAR = u'\\wide'
UNICODE_NARROW_CHAR = u'\\narrow'
UNICODE_NON_BREAKING_CHAR = u'\\nbr'
UNICODE_UNICODE_CR = '\r'
UNICODE_UNICODE_LF = '\n'
NARROW_CHAR = u'\uFFF0'
WIDE_CHAR = u'\uFFF1'
NON_BREAKING_CHAR = u'\uFFF2'
CR = u'\u000D'
LF = u'\u000A'
NULL = u'\u0000'
TAB = u'\t'
BACK_SPLASH = u'\\'
gIncludePattern = re.compile("^#include +[\"<]+([^\"< >]+)[>\"]+$", re.MULTILINE | re.UNICODE)
## Convert a python unicode string to a normal string
#
# Convert a python unicode string to a normal string
# UniToStr(u'I am a string') is 'I am a string'
#
# @param Uni: The python unicode string
#
# @retval: The formatted normal string
#
def UniToStr(Uni):
return repr(Uni)[2:-1]
## Convert a unicode string to a Hex list
#
# Convert a unicode string to a Hex list
# UniToHexList('ABC') is ['0x41', '0x00', '0x42', '0x00', '0x43', '0x00']
#
# @param Uni: The python unicode string
#
# @retval List: The formatted hex list
#
def UniToHexList(Uni):
List = []
for Item in Uni:
Temp = '%04X' % ord(Item)
List.append('0x' + Temp[2:4])
List.append('0x' + Temp[0:2])
return List
LangConvTable = {'eng':'en', 'fra':'fr', \
'aar':'aa', 'abk':'ab', 'ave':'ae', 'afr':'af', 'aka':'ak', 'amh':'am', \
'arg':'an', 'ara':'ar', 'asm':'as', 'ava':'av', 'aym':'ay', 'aze':'az', \
'bak':'ba', 'bel':'be', 'bul':'bg', 'bih':'bh', 'bis':'bi', 'bam':'bm', \
'ben':'bn', 'bod':'bo', 'bre':'br', 'bos':'bs', 'cat':'ca', 'che':'ce', \
'cha':'ch', 'cos':'co', 'cre':'cr', 'ces':'cs', 'chu':'cu', 'chv':'cv', \
'cym':'cy', 'dan':'da', 'deu':'de', 'div':'dv', 'dzo':'dz', 'ewe':'ee', \
'ell':'el', 'epo':'eo', 'spa':'es', 'est':'et', 'eus':'eu', 'fas':'fa', \
'ful':'ff', 'fin':'fi', 'fij':'fj', 'fao':'fo', 'fry':'fy', 'gle':'ga', \
'gla':'gd', 'glg':'gl', 'grn':'gn', 'guj':'gu', 'glv':'gv', 'hau':'ha', \
'heb':'he', 'hin':'hi', 'hmo':'ho', 'hrv':'hr', 'hat':'ht', 'hun':'hu', \
'hye':'hy', 'her':'hz', 'ina':'ia', 'ind':'id', 'ile':'ie', 'ibo':'ig', \
'iii':'ii', 'ipk':'ik', 'ido':'io', 'isl':'is', 'ita':'it', 'iku':'iu', \
'jpn':'ja', 'jav':'jv', 'kat':'ka', 'kon':'kg', 'kik':'ki', 'kua':'kj', \
'kaz':'kk', 'kal':'kl', 'khm':'km', 'kan':'kn', 'kor':'ko', 'kau':'kr', \
'kas':'ks', 'kur':'ku', 'kom':'kv', 'cor':'kw', 'kir':'ky', 'lat':'la', \
'ltz':'lb', 'lug':'lg', 'lim':'li', 'lin':'ln', 'lao':'lo', 'lit':'lt', \
'lub':'lu', 'lav':'lv', 'mlg':'mg', 'mah':'mh', 'mri':'mi', 'mkd':'mk', \
'mal':'ml', 'mon':'mn', 'mar':'mr', 'msa':'ms', 'mlt':'mt', 'mya':'my', \
'nau':'na', 'nob':'nb', 'nde':'nd', 'nep':'ne', 'ndo':'ng', 'nld':'nl', \
'nno':'nn', 'nor':'no', 'nbl':'nr', 'nav':'nv', 'nya':'ny', 'oci':'oc', \
'oji':'oj', 'orm':'om', 'ori':'or', 'oss':'os', 'pan':'pa', 'pli':'pi', \
'pol':'pl', 'pus':'ps', 'por':'pt', 'que':'qu', 'roh':'rm', 'run':'rn', \
'ron':'ro', 'rus':'ru', 'kin':'rw', 'san':'sa', 'srd':'sc', 'snd':'sd', \
'sme':'se', 'sag':'sg', 'sin':'si', 'slk':'sk', 'slv':'sl', 'smo':'sm', \
'sna':'sn', 'som':'so', 'sqi':'sq', 'srp':'sr', 'ssw':'ss', 'sot':'st', \
'sun':'su', 'swe':'sv', 'swa':'sw', 'tam':'ta', 'tel':'te', 'tgk':'tg', \
'tha':'th', 'tir':'ti', 'tuk':'tk', 'tgl':'tl', 'tsn':'tn', 'ton':'to', \
'tur':'tr', 'tso':'ts', 'tat':'tt', 'twi':'tw', 'tah':'ty', 'uig':'ug', \
'ukr':'uk', 'urd':'ur', 'uzb':'uz', 'ven':'ve', 'vie':'vi', 'vol':'vo', \
'wln':'wa', 'wol':'wo', 'xho':'xh', 'yid':'yi', 'yor':'yo', 'zha':'za', \
'zho':'zh', 'zul':'zu'}
## GetLanguageCode
#
# Check the language code read from .UNI file and convert ISO 639-2 codes to RFC 4646 codes if appropriate
# ISO 639-2 language codes supported in compatiblity mode
# RFC 4646 language codes supported in native mode
#
# @param LangName: Language codes read from .UNI file
#
# @retval LangName: Valid lanugage code in RFC 4646 format or None
#
def GetLanguageCode(LangName, IsCompatibleMode, File):
global LangConvTable
length = len(LangName)
if IsCompatibleMode:
if length == 3 and LangName.isalpha():
TempLangName = LangConvTable.get(LangName.lower())
if TempLangName != None:
return TempLangName
return LangName
else:
EdkLogger.error("Unicode File Parser", FORMAT_INVALID, "Invalid ISO 639-2 language code : %s" % LangName, File)
if length == 2:
if LangName.isalpha():
return LangName
elif length == 3:
if LangName.isalpha() and LangConvTable.get(LangName.lower()) == None:
return LangName
elif length == 5:
if LangName[0:2].isalpha() and LangName[2] == '-':
return LangName
elif length >= 6:
if LangName[0:2].isalpha() and LangName[2] == '-':
return LangName
if LangName[0:3].isalpha() and LangConvTable.get(LangName.lower()) == None and LangName[3] == '-':
return LangName
EdkLogger.error("Unicode File Parser", FORMAT_INVALID, "Invalid RFC 4646 language code : %s" % LangName, File)
## StringDefClassObject
#
# A structure for language definition
#
class StringDefClassObject(object):
def __init__(self, Name = None, Value = None, Referenced = False, Token = None, UseOtherLangDef = ''):
self.StringName = ''
self.StringNameByteList = []
self.StringValue = ''
self.StringValueByteList = ''
self.Token = 0
self.Referenced = Referenced
self.UseOtherLangDef = UseOtherLangDef
self.Length = 0
if Name != None:
self.StringName = Name
self.StringNameByteList = UniToHexList(Name)
if Value != None:
self.StringValue = Value + u'\x00' # Add a NULL at string tail
self.StringValueByteList = UniToHexList(self.StringValue)
self.Length = len(self.StringValueByteList)
if Token != None:
self.Token = Token
def __str__(self):
return repr(self.StringName) + ' ' + \
repr(self.Token) + ' ' + \
repr(self.Referenced) + ' ' + \
repr(self.StringValue) + ' ' + \
repr(self.UseOtherLangDef)
## UniFileClassObject
#
# A structure for .uni file definition
#
class UniFileClassObject(object):
def __init__(self, FileList = [], IsCompatibleMode = False):
self.FileList = FileList
self.Token = 2
self.LanguageDef = [] #[ [u'LanguageIdentifier', u'PrintableName'], ... ]
self.OrderedStringList = {} #{ u'LanguageIdentifier' : [StringDefClassObject] }
self.IsCompatibleMode = IsCompatibleMode
if len(self.FileList) > 0:
self.LoadUniFiles(FileList)
#
# Get Language definition
#
def GetLangDef(self, File, Line):
Lang = Line.split()
if len(Lang) != 3:
try:
FileIn = codecs.open(File, mode='rb', encoding='utf-16').read()
except UnicodeError, X:
EdkLogger.error("build", FILE_READ_FAILURE, "File read failure: %s" % str(X), ExtraData=File);
except:
EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File);
LineNo = GetLineNo(FileIn, Line, False)
EdkLogger.error("Unicode File Parser", PARSER_ERROR, "Wrong language definition",
ExtraData="""%s\n\t*Correct format is like '#langdef eng "English"'""" % Line, File = File, Line = LineNo)
else:
LangName = GetLanguageCode(Lang[1], self.IsCompatibleMode, self.File)
LangPrintName = Lang[2][1:-1]
IsLangInDef = False
for Item in self.LanguageDef:
if Item[0] == LangName:
IsLangInDef = True
break;
if not IsLangInDef:
self.LanguageDef.append([LangName, LangPrintName])
#
# Add language string
#
self.AddStringToList(u'$LANGUAGE_NAME', LangName, LangName, 0, True, Index=0)
self.AddStringToList(u'$PRINTABLE_LANGUAGE_NAME', LangName, LangPrintName, 1, True, Index=1)
return True
#
# Get String name and value
#
def GetStringObject(self, Item):
Name = ''
Language = ''
Value = ''
Name = Item.split()[1]
LanguageList = Item.split(u'#language ')
for IndexI in range(len(LanguageList)):
if IndexI == 0:
continue
else:
Language = LanguageList[IndexI].split()[0]
Value = LanguageList[IndexI][LanguageList[IndexI].find(u'\"') + len(u'\"') : LanguageList[IndexI].rfind(u'\"')] #.replace(u'\r\n', u'')
Language = GetLanguageCode(Language, self.IsCompatibleMode, self.File)
self.AddStringToList(Name, Language, Value)
#
# Get include file list and load them
#
def GetIncludeFile(self, Item, Dir):
FileName = Item[Item.find(u'#include ') + len(u'#include ') :Item.find(u' ', len(u'#include '))][1:-1]
self.LoadUniFile(FileName)
#
# Pre-process before parse .uni file
#
def PreProcess(self, File):
if not os.path.exists(File.Path) or not os.path.isfile(File.Path):
EdkLogger.error("Unicode File Parser", FILE_NOT_FOUND, ExtraData=File.Path)
Dir = File.Dir
try:
FileIn = codecs.open(File.Path, mode='rb', encoding='utf-16').readlines()
except UnicodeError, X:
EdkLogger.error("build", FILE_READ_FAILURE, "File read failure: %s" % str(X), ExtraData=File.Path);
except:
EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File.Path);
Lines = []
#
# Use unique identifier
#
for Line in FileIn:
Line = Line.strip()
#
# Ignore comment line and empty line
#
if Line == u'' or Line.startswith(u'//'):
continue
Line = Line.replace(u'/langdef', u'#langdef')
Line = Line.replace(u'/string', u'#string')
Line = Line.replace(u'/language', u'#language')
Line = Line.replace(u'/include', u'#include')
Line = Line.replace(UNICODE_WIDE_CHAR, WIDE_CHAR)
Line = Line.replace(UNICODE_NARROW_CHAR, NARROW_CHAR)
Line = Line.replace(UNICODE_NON_BREAKING_CHAR, NON_BREAKING_CHAR)
Line = Line.replace(u'\\\\', u'\u0006')
Line = Line.replace(u'\\r\\n', CR + LF)
Line = Line.replace(u'\\n', CR + LF)
Line = Line.replace(u'\\r', CR)
Line = Line.replace(u'\\t', u'\t')
Line = Line.replace(u'''\"''', u'''"''')
Line = Line.replace(u'\t', u' ')
Line = Line.replace(u'\u0006', u'\\')
# if Line.find(u'\\x'):
# hex = Line[Line.find(u'\\x') + 2 : Line.find(u'\\x') + 6]
# hex = "u'\\u" + hex + "'"
IncList = gIncludePattern.findall(Line)
if len(IncList) == 1:
Lines.extend(self.PreProcess(PathClass(str(IncList[0]), Dir)))
continue
Lines.append(Line)
return Lines
#
# Load a .uni file
#
def LoadUniFile(self, File = None):
if File == None:
EdkLogger.error("Unicode File Parser", PARSER_ERROR, 'No unicode file is given')
self.File = File
#
# Process special char in file
#
Lines = self.PreProcess(File)
#
# Get Unicode Information
#
for IndexI in range(len(Lines)):
Line = Lines[IndexI]
if (IndexI + 1) < len(Lines):
SecondLine = Lines[IndexI + 1]
if (IndexI + 2) < len(Lines):
ThirdLine = Lines[IndexI + 2]
#
# Get Language def information
#
if Line.find(u'#langdef ') >= 0:
self.GetLangDef(File, Line)
continue
Name = ''
Language = ''
Value = ''
#
# Get string def information format 1 as below
#
# #string MY_STRING_1
# #language eng
# My first English string line 1
# My first English string line 2
# #string MY_STRING_1
# #language spa
# Mi segunda secuencia 1
# Mi segunda secuencia 2
#
if Line.find(u'#string ') >= 0 and Line.find(u'#language ') < 0 and \
SecondLine.find(u'#string ') < 0 and SecondLine.find(u'#language ') >= 0 and \
ThirdLine.find(u'#string ') < 0 and ThirdLine.find(u'#language ') < 0:
Name = Line[Line.find(u'#string ') + len(u'#string ') : ].strip(' ')
Language = SecondLine[SecondLine.find(u'#language ') + len(u'#language ') : ].strip(' ')
for IndexJ in range(IndexI + 2, len(Lines)):
if Lines[IndexJ].find(u'#string ') < 0 and Lines[IndexJ].find(u'#language ') < 0:
Value = Value + Lines[IndexJ]
else:
IndexI = IndexJ
break
# Value = Value.replace(u'\r\n', u'')
Language = GetLanguageCode(Language, self.IsCompatibleMode, self.File)
self.AddStringToList(Name, Language, Value)
continue
#
# Get string def information format 2 as below
#
# #string MY_STRING_1 #language eng "My first English string line 1"
# "My first English string line 2"
# #language spa "Mi segunda secuencia 1"
# "Mi segunda secuencia 2"
# #string MY_STRING_2 #language eng "My first English string line 1"
# "My first English string line 2"
# #string MY_STRING_2 #language spa "Mi segunda secuencia 1"
# "Mi segunda secuencia 2"
#
if Line.find(u'#string ') >= 0 and Line.find(u'#language ') >= 0:
StringItem = Line
for IndexJ in range(IndexI + 1, len(Lines)):
if Lines[IndexJ].find(u'#string ') >= 0 and Lines[IndexJ].find(u'#language ') >= 0:
IndexI = IndexJ
break
elif Lines[IndexJ].find(u'#string ') < 0 and Lines[IndexJ].find(u'#language ') >= 0:
StringItem = StringItem + Lines[IndexJ]
elif Lines[IndexJ].count(u'\"') >= 2:
StringItem = StringItem[ : StringItem.rfind(u'\"')] + Lines[IndexJ][Lines[IndexJ].find(u'\"') + len(u'\"') : ]
self.GetStringObject(StringItem)
continue
#
# Load multiple .uni files
#
def LoadUniFiles(self, FileList = []):
if len(FileList) > 0:
if len(FileList) > 1:
NewList = [];
for File in FileList:
NewList.append (File)
NewList.sort()
for File in NewList:
self.LoadUniFile(File)
else:
for File in FileList:
self.LoadUniFile(File)
#
# Add a string to list
#
def AddStringToList(self, Name, Language, Value, Token = None, Referenced = False, UseOtherLangDef = '', Index = -1):
if Language not in self.OrderedStringList:
self.OrderedStringList[Language] = []
IsAdded = False
for Item in self.OrderedStringList[Language]:
if Name == Item.StringName:
IsAdded = True
break
if not IsAdded:
Token = len(self.OrderedStringList[Language])
if Index == -1:
self.OrderedStringList[Language].append(StringDefClassObject(Name, Value, Referenced, Token, UseOtherLangDef))
else:
self.OrderedStringList[Language].insert(Index, StringDefClassObject(Name, Value, Referenced, Token, UseOtherLangDef))
#
# Set the string as referenced
#
def SetStringReferenced(self, Name):
for Lang in self.OrderedStringList:
for Item in self.OrderedStringList[Lang]:
if Name == Item.StringName:
Item.Referenced = True
break
#
# Search the string in language definition by Name
#
def FindStringValue(self, Name, Lang):
for Item in self.OrderedStringList[Lang]:
if Item.StringName == Name:
return Item
return None
#
# Search the string in language definition by Token
#
def FindByToken(self, Token, Lang):
for Item in self.OrderedStringList[Lang]:
if Item.Token == Token:
return Item
return None
#
# Re-order strings and re-generate tokens
#
def ReToken(self):
#
# Search each string to find if it is defined for each language
# Use secondary language value to replace if missing in any one language
#
for IndexI in range(0, len(self.LanguageDef)):
LangKey = self.LanguageDef[IndexI][0]
for Item in self.OrderedStringList[LangKey]:
Name = Item.StringName
Value = Item.StringValue[0:-1]
Referenced = Item.Referenced
Index = self.OrderedStringList[LangKey].index(Item)
for IndexJ in range(0, len(self.LanguageDef)):
LangFind = self.LanguageDef[IndexJ][0]
if self.FindStringValue(Name, LangFind) == None:
EdkLogger.debug(EdkLogger.DEBUG_5, Name)
Token = len(self.OrderedStringList[LangFind])
self.AddStringToList(Name, LangFind, Value, Token, Referenced, LangKey, Index)
#
# Retoken
#
# First re-token the first language
LangName = self.LanguageDef[0][0]
ReferencedStringList = []
NotReferencedStringList = []
Token = 0
for Item in self.OrderedStringList[LangName]:
if Item.Referenced == True:
Item.Token = Token
ReferencedStringList.append(Item)
Token = Token + 1
else:
NotReferencedStringList.append(Item)
self.OrderedStringList[LangName] = ReferencedStringList
for Index in range(len(NotReferencedStringList)):
NotReferencedStringList[Index].Token = Token + Index
self.OrderedStringList[LangName].append(NotReferencedStringList[Index])
#
# Adjust the orders of other languages
#
for IndexOfLanguage in range(1, len(self.LanguageDef)):
for OrderedString in self.OrderedStringList[LangName]:
for UnOrderedString in self.OrderedStringList[self.LanguageDef[IndexOfLanguage][0]]:
if OrderedString.StringName == UnOrderedString.StringName:
UnOrderedString.Token = OrderedString.Token
break
#
# Show the instance itself
#
def ShowMe(self):
print self.LanguageDef
#print self.OrderedStringList
for Item in self.OrderedStringList:
print Item
for Member in self.OrderedStringList[Item]:
print str(Member)
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
if __name__ == '__main__':
EdkLogger.Initialize()
EdkLogger.SetLevel(EdkLogger.DEBUG_0)
a = UniFileClassObject(['C:\\Edk\\Strings.uni', 'C:\\Edk\\Strings2.uni'])
a.ReToken()
a.ShowMe()

View File

@@ -0,0 +1,10 @@
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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.
__all__ = ["AutoGen"]

View File

@@ -0,0 +1,152 @@
## @file
# Standardized Error Hanlding infrastructures.
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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.
#
FILE_OPEN_FAILURE = 1
FILE_WRITE_FAILURE = 2
FILE_PARSE_FAILURE = 3
FILE_READ_FAILURE = 4
FILE_CREATE_FAILURE = 5
FILE_CHECKSUM_FAILURE = 6
FILE_COMPRESS_FAILURE = 7
FILE_DECOMPRESS_FAILURE = 8
FILE_MOVE_FAILURE = 9
FILE_DELETE_FAILURE = 10
FILE_COPY_FAILURE = 11
FILE_POSITIONING_FAILURE = 12
FILE_ALREADY_EXIST = 13
FILE_NOT_FOUND = 14
FILE_TYPE_MISMATCH = 15
FILE_CASE_MISMATCH = 16
FILE_DUPLICATED = 17
FILE_UNKNOWN_ERROR = 0x0FFF
OPTION_UNKNOWN = 0x1000
OPTION_MISSING = 0x1001
OPTION_CONFLICT = 0x1002
OPTION_VALUE_INVALID = 0x1003
OPTION_DEPRECATED = 0x1004
OPTION_NOT_SUPPORTED = 0x1005
OPTION_UNKNOWN_ERROR = 0x1FFF
PARAMETER_INVALID = 0x2000
PARAMETER_MISSING = 0x2001
PARAMETER_UNKNOWN_ERROR =0x2FFF
FORMAT_INVALID = 0x3000
FORMAT_NOT_SUPPORTED = 0x3001
FORMAT_UNKNOWN = 0x3002
FORMAT_UNKNOWN_ERROR = 0x3FFF
RESOURCE_NOT_AVAILABLE = 0x4000
RESOURCE_ALLOCATE_FAILURE = 0x4001
RESOURCE_FULL = 0x4002
RESOURCE_OVERFLOW = 0x4003
RESOURCE_UNDERRUN = 0x4004
RESOURCE_UNKNOWN_ERROR = 0x4FFF
ATTRIBUTE_NOT_AVAILABLE = 0x5000
ATTRIBUTE_GET_FAILURE = 0x5001
ATTRIBUTE_SET_FAILURE = 0x5002
ATTRIBUTE_UPDATE_FAILURE = 0x5003
ATTRIBUTE_ACCESS_DENIED = 0x5004
ATTRIBUTE_UNKNOWN_ERROR = 0x5FFF
IO_NOT_READY = 0x6000
IO_BUSY = 0x6001
IO_TIMEOUT = 0x6002
IO_UNKNOWN_ERROR = 0x6FFF
COMMAND_FAILURE = 0x7000
CODE_ERROR = 0xC0DE
AUTOGEN_ERROR = 0xF000
PARSER_ERROR = 0xF001
BUILD_ERROR = 0xF002
GENFDS_ERROR = 0xF003
ECC_ERROR = 0xF004
EOT_ERROR = 0xF005
DDC_ERROR = 0xF009
WARNING_AS_ERROR = 0xF006
MIGRATION_ERROR = 0xF010
ABORT_ERROR = 0xFFFE
UNKNOWN_ERROR = 0xFFFF
## Error message of each error code
gErrorMessage = {
FILE_NOT_FOUND : "File/directory not found",
FILE_OPEN_FAILURE : "File open failure",
FILE_WRITE_FAILURE : "File write failure",
FILE_PARSE_FAILURE : "File parse failure",
FILE_READ_FAILURE : "File read failure",
FILE_CREATE_FAILURE : "File create failure",
FILE_CHECKSUM_FAILURE : "Invalid checksum of file",
FILE_COMPRESS_FAILURE : "File compress failure",
FILE_DECOMPRESS_FAILURE : "File decompress failure",
FILE_MOVE_FAILURE : "File move failure",
FILE_DELETE_FAILURE : "File delete failure",
FILE_COPY_FAILURE : "File copy failure",
FILE_POSITIONING_FAILURE: "Failed to seeking position",
FILE_ALREADY_EXIST : "File or directory already exists",
FILE_TYPE_MISMATCH : "Incorrect file type",
FILE_CASE_MISMATCH : "File name case mismatch",
FILE_DUPLICATED : "Duplicated file found",
FILE_UNKNOWN_ERROR : "Unknown error encountered on file",
OPTION_UNKNOWN : "Unknown option",
OPTION_MISSING : "Missing option",
OPTION_CONFLICT : "Conflict options",
OPTION_VALUE_INVALID : "Invalid value of option",
OPTION_DEPRECATED : "Deprecated option",
OPTION_NOT_SUPPORTED : "Unsupported option",
OPTION_UNKNOWN_ERROR : "Unknown error when processing options",
PARAMETER_INVALID : "Invalid parameter",
PARAMETER_MISSING : "Missing parameter",
PARAMETER_UNKNOWN_ERROR : "Unknown error in parameters",
FORMAT_INVALID : "Invalid syntax/format",
FORMAT_NOT_SUPPORTED : "Not supported syntax/format",
FORMAT_UNKNOWN : "Unknown format",
FORMAT_UNKNOWN_ERROR : "Unknown error in syntax/format ",
RESOURCE_NOT_AVAILABLE : "Not available",
RESOURCE_ALLOCATE_FAILURE : "Allocate failure",
RESOURCE_FULL : "Full",
RESOURCE_OVERFLOW : "Overflow",
RESOURCE_UNDERRUN : "Underrun",
RESOURCE_UNKNOWN_ERROR : "Unkown error",
ATTRIBUTE_NOT_AVAILABLE : "Not available",
ATTRIBUTE_GET_FAILURE : "Failed to retrieve",
ATTRIBUTE_SET_FAILURE : "Failed to set",
ATTRIBUTE_UPDATE_FAILURE: "Failed to update",
ATTRIBUTE_ACCESS_DENIED : "Access denied",
ATTRIBUTE_UNKNOWN_ERROR : "Unknown error when accessing",
COMMAND_FAILURE : "Failed to execute command",
IO_NOT_READY : "Not ready",
IO_BUSY : "Busy",
IO_TIMEOUT : "Timeout",
IO_UNKNOWN_ERROR : "Unknown error in IO operation",
UNKNOWN_ERROR : "Unknown error",
}
## Exception indicating a fatal error
class FatalError(Exception):
pass
if __name__ == "__main__":
pass

View File

@@ -0,0 +1,401 @@
## @file
# This file is used to define common static strings used by INF/DEC/DSC files
#
# Copyright (c) 2007 ~ 2008, Intel Corporation
# All rights reserved. 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.
##
# Common Definitions
#
TAB_SPLIT = '.'
TAB_COMMENT_R8_START = '/*'
TAB_COMMENT_R8_END = '*/'
TAB_COMMENT_R8_SPLIT = '//'
TAB_COMMENT_SPLIT = '#'
TAB_EQUAL_SPLIT = '='
TAB_VALUE_SPLIT = '|'
TAB_COMMA_SPLIT = ','
TAB_SPACE_SPLIT = ' '
TAB_SECTION_START = '['
TAB_SECTION_END = ']'
TAB_OPTION_START = '<'
TAB_OPTION_END = '>'
TAB_SLASH = '\\'
TAB_BACK_SLASH = '/'
TAB_EDK_SOURCE = '$(EDK_SOURCE)'
TAB_EFI_SOURCE = '$(EFI_SOURCE)'
TAB_WORKSPACE = '$(WORKSPACE)'
TAB_ARCH_NULL = ''
TAB_ARCH_COMMON = 'COMMON'
TAB_ARCH_IA32 = 'IA32'
TAB_ARCH_X64 = 'X64'
TAB_ARCH_IPF = 'IPF'
TAB_ARCH_ARM = 'ARM'
TAB_ARCH_EBC = 'EBC'
ARCH_LIST = [TAB_ARCH_IA32, TAB_ARCH_X64, TAB_ARCH_IPF, TAB_ARCH_ARM, TAB_ARCH_EBC]
ARCH_LIST_FULL = [TAB_ARCH_COMMON] + ARCH_LIST
SUP_MODULE_BASE = 'BASE'
SUP_MODULE_SEC = 'SEC'
SUP_MODULE_PEI_CORE = 'PEI_CORE'
SUP_MODULE_PEIM = 'PEIM'
SUP_MODULE_DXE_CORE = 'DXE_CORE'
SUP_MODULE_DXE_DRIVER = 'DXE_DRIVER'
SUP_MODULE_DXE_RUNTIME_DRIVER = 'DXE_RUNTIME_DRIVER'
SUP_MODULE_DXE_SAL_DRIVER = 'DXE_SAL_DRIVER'
SUP_MODULE_DXE_SMM_DRIVER = 'DXE_SMM_DRIVER'
SUP_MODULE_UEFI_DRIVER = 'UEFI_DRIVER'
SUP_MODULE_UEFI_APPLICATION = 'UEFI_APPLICATION'
SUP_MODULE_USER_DEFINED = 'USER_DEFINED'
SUP_MODULE_SMM_DRIVER = 'SMM_DRIVER'
SUP_MODULE_SMM_CORE = 'SMM_CORE'
SUP_MODULE_LIST = [SUP_MODULE_BASE, SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_DXE_CORE, SUP_MODULE_DXE_DRIVER, \
SUP_MODULE_DXE_RUNTIME_DRIVER, SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_DXE_SMM_DRIVER, SUP_MODULE_UEFI_DRIVER, \
SUP_MODULE_UEFI_APPLICATION, SUP_MODULE_USER_DEFINED, SUP_MODULE_SMM_DRIVER, SUP_MODULE_SMM_CORE]
SUP_MODULE_LIST_STRING = TAB_VALUE_SPLIT.join(l for l in SUP_MODULE_LIST)
EDK_COMPONENT_TYPE_LIBRARY = 'LIBRARY'
EDK_COMPONENT_TYPE_SECUARITY_CORE = 'SECUARITY_CORE'
EDK_COMPONENT_TYPE_PEI_CORE = 'PEI_CORE'
EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER = 'COMBINED_PEIM_DRIVER'
EDK_COMPONENT_TYPE_PIC_PEIM = 'PIC_PEIM'
EDK_COMPONENT_TYPE_RELOCATABLE_PEIM = 'RELOCATABLE_PEIM'
EDK_COMPONENT_TYPE_BS_DRIVER = 'BS_DRIVER'
EDK_COMPONENT_TYPE_RT_DRIVER = 'RT_DRIVER'
EDK_COMPONENT_TYPE_SAL_RT_DRIVER = 'SAL_RT_DRIVER'
EDK_COMPONENT_TYPE_APPLICATION = 'APPLICATION'
BINARY_FILE_TYPE_FW = 'FW'
BINARY_FILE_TYPE_GUID = 'GUID'
BINARY_FILE_TYPE_PREEFORM = 'PREEFORM'
BINARY_FILE_TYPE_UEFI_APP = 'UEFI_APP'
BINARY_FILE_TYPE_UNI_UI = 'UNI_UI'
BINARY_FILE_TYPE_UNI_VER = 'UNI_VER'
BINARY_FILE_TYPE_LIB = 'LIB'
BINARY_FILE_TYPE_PE32 = 'PE32'
BINARY_FILE_TYPE_PIC = 'PIC'
BINARY_FILE_TYPE_PEI_DEPEX = 'PEI_DEPEX'
BINARY_FILE_TYPE_DXE_DEPEX = 'DXE_DEPEX'
BINARY_FILE_TYPE_TE = 'TE'
BINARY_FILE_TYPE_VER = 'VER'
BINARY_FILE_TYPE_UI = 'UI'
BINARY_FILE_TYPE_BIN = 'BIN'
BINARY_FILE_TYPE_FV = 'FV'
PLATFORM_COMPONENT_TYPE_LIBRARY = 'LIBRARY'
PLATFORM_COMPONENT_TYPE_LIBRARY_CLASS = 'LIBRARY_CLASS'
PLATFORM_COMPONENT_TYPE_MODULE = 'MODULE'
TAB_LIBRARIES = 'Libraries'
TAB_SOURCES = 'Sources'
TAB_SOURCES_COMMON = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_COMMON
TAB_SOURCES_IA32 = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_IA32
TAB_SOURCES_X64 = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_X64
TAB_SOURCES_IPF = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_IPF
TAB_SOURCES_ARM = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_ARM
TAB_SOURCES_EBC = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_EBC
TAB_BINARIES = 'Binaries'
TAB_BINARIES_COMMON = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_COMMON
TAB_BINARIES_IA32 = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_IA32
TAB_BINARIES_X64 = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_X64
TAB_BINARIES_IPF = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_IPF
TAB_BINARIES_ARM = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_ARM
TAB_BINARIES_EBC = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_EBC
TAB_INCLUDES = 'Includes'
TAB_INCLUDES_COMMON = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_COMMON
TAB_INCLUDES_IA32 = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_IA32
TAB_INCLUDES_X64 = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_X64
TAB_INCLUDES_IPF = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_IPF
TAB_INCLUDES_ARM = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_ARM
TAB_INCLUDES_EBC = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_EBC
TAB_GUIDS = 'Guids'
TAB_GUIDS_COMMON = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_COMMON
TAB_GUIDS_IA32 = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_IA32
TAB_GUIDS_X64 = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_X64
TAB_GUIDS_IPF = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_IPF
TAB_GUIDS_ARM = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_ARM
TAB_GUIDS_EBC = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_EBC
TAB_PROTOCOLS = 'Protocols'
TAB_PROTOCOLS_COMMON = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_COMMON
TAB_PROTOCOLS_IA32 = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_IA32
TAB_PROTOCOLS_X64 = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_X64
TAB_PROTOCOLS_IPF = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_IPF
TAB_PROTOCOLS_ARM = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_ARM
TAB_PROTOCOLS_EBC = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_EBC
TAB_PPIS = 'Ppis'
TAB_PPIS_COMMON = TAB_PPIS + TAB_SPLIT + TAB_ARCH_COMMON
TAB_PPIS_IA32 = TAB_PPIS + TAB_SPLIT + TAB_ARCH_IA32
TAB_PPIS_X64 = TAB_PPIS + TAB_SPLIT + TAB_ARCH_X64
TAB_PPIS_IPF = TAB_PPIS + TAB_SPLIT + TAB_ARCH_IPF
TAB_PPIS_ARM = TAB_PPIS + TAB_SPLIT + TAB_ARCH_ARM
TAB_PPIS_EBC = TAB_PPIS + TAB_SPLIT + TAB_ARCH_EBC
TAB_LIBRARY_CLASSES = 'LibraryClasses'
TAB_LIBRARY_CLASSES_COMMON = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_COMMON
TAB_LIBRARY_CLASSES_IA32 = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_IA32
TAB_LIBRARY_CLASSES_X64 = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_X64
TAB_LIBRARY_CLASSES_IPF = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_IPF
TAB_LIBRARY_CLASSES_ARM = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_ARM
TAB_LIBRARY_CLASSES_EBC = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_EBC
TAB_PACKAGES = 'Packages'
TAB_PACKAGES_COMMON = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_COMMON
TAB_PACKAGES_IA32 = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_IA32
TAB_PACKAGES_X64 = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_X64
TAB_PACKAGES_IPF = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_IPF
TAB_PACKAGES_ARM = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_ARM
TAB_PACKAGES_EBC = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_EBC
TAB_PCDS = 'Pcds'
TAB_PCDS_FIXED_AT_BUILD = 'FixedAtBuild'
TAB_PCDS_PATCHABLE_IN_MODULE = 'PatchableInModule'
TAB_PCDS_FEATURE_FLAG = 'FeatureFlag'
TAB_PCDS_DYNAMIC_EX = 'DynamicEx'
TAB_PCDS_DYNAMIC_EX_DEFAULT = 'DynamicExDefault'
TAB_PCDS_DYNAMIC_EX_VPD = 'DynamicExVpd'
TAB_PCDS_DYNAMIC_EX_HII = 'DynamicExHii'
TAB_PCDS_DYNAMIC = 'Dynamic'
TAB_PCDS_DYNAMIC_DEFAULT = 'DynamicDefault'
TAB_PCDS_DYNAMIC_VPD = 'DynamicVpd'
TAB_PCDS_DYNAMIC_HII = 'DynamicHii'
PCD_DYNAMIC_TYPE_LIST = [TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_DEFAULT, TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_HII]
PCD_DYNAMIC_EX_TYPE_LIST = [TAB_PCDS_DYNAMIC_EX, TAB_PCDS_DYNAMIC_EX_DEFAULT, TAB_PCDS_DYNAMIC_EX_VPD, TAB_PCDS_DYNAMIC_EX_HII]
## Dynamic-ex PCD types
gDynamicExPcd = [TAB_PCDS_DYNAMIC_EX, TAB_PCDS_DYNAMIC_EX_DEFAULT, TAB_PCDS_DYNAMIC_EX_VPD, TAB_PCDS_DYNAMIC_EX_HII]
TAB_PCDS_FIXED_AT_BUILD_NULL = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD
TAB_PCDS_FIXED_AT_BUILD_COMMON = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_COMMON
TAB_PCDS_FIXED_AT_BUILD_IA32 = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_IA32
TAB_PCDS_FIXED_AT_BUILD_X64 = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_X64
TAB_PCDS_FIXED_AT_BUILD_IPF = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_IPF
TAB_PCDS_FIXED_AT_BUILD_ARM = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_ARM
TAB_PCDS_FIXED_AT_BUILD_EBC = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_EBC
TAB_PCDS_PATCHABLE_IN_MODULE_NULL = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE
TAB_PCDS_PATCHABLE_IN_MODULE_COMMON = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_COMMON
TAB_PCDS_PATCHABLE_IN_MODULE_IA32 = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_IA32
TAB_PCDS_PATCHABLE_IN_MODULE_X64 = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_X64
TAB_PCDS_PATCHABLE_IN_MODULE_IPF = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_IPF
TAB_PCDS_PATCHABLE_IN_MODULE_ARM = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_ARM
TAB_PCDS_PATCHABLE_IN_MODULE_EBC = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_EBC
TAB_PCDS_FEATURE_FLAG_NULL = TAB_PCDS + TAB_PCDS_FEATURE_FLAG
TAB_PCDS_FEATURE_FLAG_COMMON = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_COMMON
TAB_PCDS_FEATURE_FLAG_IA32 = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_IA32
TAB_PCDS_FEATURE_FLAG_X64 = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_X64
TAB_PCDS_FEATURE_FLAG_IPF = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_IPF
TAB_PCDS_FEATURE_FLAG_ARM = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_ARM
TAB_PCDS_FEATURE_FLAG_EBC = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_EBC
TAB_PCDS_DYNAMIC_EX_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX
TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX_DEFAULT
TAB_PCDS_DYNAMIC_EX_HII_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX_HII
TAB_PCDS_DYNAMIC_EX_VPD_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX_VPD
TAB_PCDS_DYNAMIC_EX_COMMON = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_COMMON
TAB_PCDS_DYNAMIC_EX_IA32 = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_IA32
TAB_PCDS_DYNAMIC_EX_X64 = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_X64
TAB_PCDS_DYNAMIC_EX_IPF = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_IPF
TAB_PCDS_DYNAMIC_EX_ARM = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_ARM
TAB_PCDS_DYNAMIC_EX_EBC = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_EBC
TAB_PCDS_DYNAMIC_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC
TAB_PCDS_DYNAMIC_DEFAULT_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_DEFAULT
TAB_PCDS_DYNAMIC_HII_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_HII
TAB_PCDS_DYNAMIC_VPD_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_VPD
TAB_PCDS_DYNAMIC_COMMON = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_COMMON
TAB_PCDS_DYNAMIC_IA32 = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_IA32
TAB_PCDS_DYNAMIC_X64 = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_X64
TAB_PCDS_DYNAMIC_IPF = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_IPF
TAB_PCDS_DYNAMIC_ARM = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_ARM
TAB_PCDS_DYNAMIC_EBC = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_EBC
TAB_PCD_DYNAMIC_TYPE_LIST = [TAB_PCDS_DYNAMIC_DEFAULT_NULL, TAB_PCDS_DYNAMIC_VPD_NULL, TAB_PCDS_DYNAMIC_HII_NULL]
TAB_PCD_DYNAMIC_EX_TYPE_LIST = [TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL, TAB_PCDS_DYNAMIC_EX_VPD_NULL, TAB_PCDS_DYNAMIC_EX_HII_NULL]
TAB_DEPEX = 'Depex'
TAB_DEPEX_COMMON = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_COMMON
TAB_DEPEX_IA32 = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_IA32
TAB_DEPEX_X64 = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_X64
TAB_DEPEX_IPF = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_IPF
TAB_DEPEX_ARM = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_ARM
TAB_DEPEX_EBC = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_EBC
TAB_SKUIDS = 'SkuIds'
TAB_LIBRARIES = 'Libraries'
TAB_LIBRARIES_COMMON = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_COMMON
TAB_LIBRARIES_IA32 = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_IA32
TAB_LIBRARIES_X64 = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_X64
TAB_LIBRARIES_IPF = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_IPF
TAB_LIBRARIES_ARM = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_ARM
TAB_LIBRARIES_EBC = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_EBC
TAB_COMPONENTS = 'Components'
TAB_COMPONENTS_COMMON = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_COMMON
TAB_COMPONENTS_IA32 = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_IA32
TAB_COMPONENTS_X64 = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_X64
TAB_COMPONENTS_IPF = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_IPF
TAB_COMPONENTS_ARM = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_ARM
TAB_COMPONENTS_EBC = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_EBC
TAB_COMPONENTS_SOURCE_OVERRIDE_PATH = 'SOURCE_OVERRIDE_PATH'
TAB_BUILD_OPTIONS = 'BuildOptions'
TAB_DEFINE = 'DEFINE'
TAB_NMAKE = 'Nmake'
TAB_USER_EXTENSIONS = 'UserExtensions'
TAB_INCLUDE = '!include'
#
# Common Define
#
TAB_COMMON_DEFINES = 'Defines'
#
# Inf Definitions
#
TAB_INF_DEFINES = TAB_COMMON_DEFINES
TAB_INF_DEFINES_INF_VERSION = 'INF_VERSION'
TAB_INF_DEFINES_BASE_NAME = 'BASE_NAME'
TAB_INF_DEFINES_FILE_GUID = 'FILE_GUID'
TAB_INF_DEFINES_MODULE_TYPE = 'MODULE_TYPE'
TAB_INF_DEFINES_EFI_SPECIFICATION_VERSION = 'EFI_SPECIFICATION_VERSION'
TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION = 'UEFI_SPECIFICATION_VERSION'
TAB_INF_DEFINES_PI_SPECIFICATION_VERSION = 'PI_SPECIFICATION_VERSION'
TAB_INF_DEFINES_EDK_RELEASE_VERSION = 'EDK_RELEASE_VERSION'
TAB_INF_DEFINES_BINARY_MODULE = 'BINARY_MODULE'
TAB_INF_DEFINES_LIBRARY_CLASS = 'LIBRARY_CLASS'
TAB_INF_DEFINES_COMPONENT_TYPE = 'COMPONENT_TYPE'
TAB_INF_DEFINES_MAKEFILE_NAME = 'MAKEFILE_NAME'
TAB_INF_DEFINES_BUILD_NUMBER = 'BUILD_NUMBER'
TAB_INF_DEFINES_BUILD_TYPE = 'BUILD_TYPE'
TAB_INF_DEFINES_FFS_EXT = 'FFS_EXT'
TAB_INF_DEFINES_FV_EXT = 'FV_EXT'
TAB_INF_DEFINES_SOURCE_FV = 'SOURCE_FV'
TAB_INF_DEFINES_VERSION_NUMBER = 'VERSION_NUMBER'
TAB_INF_DEFINES_VERSION = 'VERSION' # for R8 inf, the same as VERSION_NUMBER
TAB_INF_DEFINES_VERSION_STRING = 'VERSION_STRING'
TAB_INF_DEFINES_PCD_IS_DRIVER = 'PCD_IS_DRIVER'
TAB_INF_DEFINES_TIANO_R8_FLASHMAP_H = 'TIANO_R8_FLASHMAP_H'
TAB_INF_DEFINES_ENTRY_POINT = 'ENTRY_POINT'
TAB_INF_DEFINES_UNLOAD_IMAGE = 'UNLOAD_IMAGE'
TAB_INF_DEFINES_CONSTRUCTOR = 'CONSTRUCTOR'
TAB_INF_DEFINES_DESTRUCTOR = 'DESTRUCTOR'
TAB_INF_DEFINES_DEFINE = 'DEFINE'
TAB_INF_DEFINES_SPEC = 'SPEC'
TAB_INF_DEFINES_CUSTOM_MAKEFILE = 'CUSTOM_MAKEFILE'
TAB_INF_DEFINES_MACRO = '__MACROS__'
TAB_INF_DEFINES_SHADOW = 'SHADOW'
TAB_INF_FIXED_PCD = 'FixedPcd'
TAB_INF_FEATURE_PCD = 'FeaturePcd'
TAB_INF_PATCH_PCD = 'PatchPcd'
TAB_INF_PCD = 'Pcd'
TAB_INF_PCD_EX = 'PcdEx'
#
# Dec Definitions
#
TAB_DEC_DEFINES = TAB_COMMON_DEFINES
TAB_DEC_DEFINES_DEC_SPECIFICATION = 'DEC_SPECIFICATION'
TAB_DEC_DEFINES_PACKAGE_NAME = 'PACKAGE_NAME'
TAB_DEC_DEFINES_PACKAGE_GUID = 'PACKAGE_GUID'
TAB_DEC_DEFINES_PACKAGE_VERSION = 'PACKAGE_VERSION'
#
# Dsc Definitions
#
TAB_DSC_DEFINES = TAB_COMMON_DEFINES
TAB_DSC_DEFINES_PLATFORM_NAME = 'PLATFORM_NAME'
TAB_DSC_DEFINES_PLATFORM_GUID = 'PLATFORM_GUID'
TAB_DSC_DEFINES_PLATFORM_VERSION = 'PLATFORM_VERSION'
TAB_DSC_DEFINES_DSC_SPECIFICATION = 'DSC_SPECIFICATION'
TAB_DSC_DEFINES_OUTPUT_DIRECTORY = 'OUTPUT_DIRECTORY'
TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES = 'SUPPORTED_ARCHITECTURES'
TAB_DSC_DEFINES_BUILD_TARGETS = 'BUILD_TARGETS'
TAB_DSC_DEFINES_SKUID_IDENTIFIER = 'SKUID_IDENTIFIER'
TAB_DSC_DEFINES_FLASH_DEFINITION = 'FLASH_DEFINITION'
TAB_DSC_DEFINES_BUILD_NUMBER = 'BUILD_NUMBER'
TAB_DSC_DEFINES_MAKEFILE_NAME = 'MAKEFILE_NAME'
TAB_DSC_DEFINES_BS_BASE_ADDRESS = 'BsBaseAddress'
TAB_DSC_DEFINES_RT_BASE_ADDRESS = 'RtBaseAddress'
TAB_DSC_DEFINES_DEFINE = 'DEFINE'
#
# TargetTxt Definitions
#
TAB_TAT_DEFINES_ACTIVE_PLATFORM = 'ACTIVE_PLATFORM'
TAB_TAT_DEFINES_ACTIVE_MODULE = 'ACTIVE_MODULE'
TAB_TAT_DEFINES_TOOL_CHAIN_CONF = 'TOOL_CHAIN_CONF'
TAB_TAT_DEFINES_MULTIPLE_THREAD = 'MULTIPLE_THREAD'
TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER = 'MAX_CONCURRENT_THREAD_NUMBER'
TAB_TAT_DEFINES_TARGET = 'TARGET'
TAB_TAT_DEFINES_TOOL_CHAIN_TAG = 'TOOL_CHAIN_TAG'
TAB_TAT_DEFINES_TARGET_ARCH = 'TARGET_ARCH'
TAB_TAT_DEFINES_BUILD_RULE_CONF = "BUILD_RULE_CONF"
#
# ToolDef Definitions
#
TAB_TOD_DEFINES_TARGET = 'TARGET'
TAB_TOD_DEFINES_TOOL_CHAIN_TAG = 'TOOL_CHAIN_TAG'
TAB_TOD_DEFINES_TARGET_ARCH = 'TARGET_ARCH'
TAB_TOD_DEFINES_COMMAND_TYPE = 'COMMAND_TYPE'
TAB_TOD_DEFINES_FAMILY = 'FAMILY'
TAB_TOD_DEFINES_BUILDRULEFAMILY = 'BUILDRULEFAMILY'
#
# Conditional Statements
#
TAB_IF = '!if'
TAB_END_IF = '!endif'
TAB_ELSE_IF = '!elseif'
TAB_ELSE = '!else'
TAB_IF_DEF = '!ifdef'
TAB_IF_N_DEF = '!ifndef'
TAB_IF_EXIST = '!if exist'
#
# Unknown section
#
TAB_UNKNOWN = 'UNKNOWN'
#
# Build database path
#
DATABASE_PATH = ":memory:" #"BuildDatabase.db"
# used by ECC
MODIFIER_LIST = ['IN', 'OUT', 'OPTIONAL', 'UNALIGNED', 'EFI_RUNTIMESERVICE', 'EFI_BOOTSERVICE', 'EFIAPI']
# Dependency Expression
DEPEX_SUPPORTED_OPCODE = ["BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "END", "SOR", "TRUE", "FALSE", '(', ')']
TAB_STATIC_LIBRARY = "STATIC-LIBRARY-FILE"
TAB_DYNAMIC_LIBRARY = "DYNAMIC-LIBRARY-FILE"
TAB_FRAMEWORK_IMAGE = "EFI-IMAGE-FILE"
TAB_C_CODE_FILE = "C-CODE-FILE"
TAB_C_HEADER_FILE = "C-HEADER-FILE"
TAB_UNICODE_FILE = "UNICODE-TEXT-FILE"
TAB_DEPENDENCY_EXPRESSION_FILE = "DEPENDENCY-EXPRESSION-FILE"
TAB_UNKNOWN_FILE = "UNKNOWN-TYPE-FILE"
TAB_DEFAULT_BINARY_FILE = "_BINARY_FILE_"

View File

@@ -0,0 +1,120 @@
## @file
# This file is used to create a database used by ECC tool
#
# Copyright (c) 2007 ~ 2008, Intel Corporation
# All rights reserved. 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
#
import sqlite3
import os
import EdkLogger as EdkLogger
from CommonDataClass.DataClass import *
from String import *
from DataType import *
from Table.TableDataModel import TableDataModel
from Table.TableFile import TableFile
from Table.TableInf import TableInf
from Table.TableDec import TableDec
from Table.TableDsc import TableDsc
## Database
#
# This class defined the build databse
# During the phase of initialization, the database will create all tables and
# insert all records of table DataModel
#
# @param object: Inherited from object class
# @param DbPath: A string for the path of the ECC database
#
# @var Conn: Connection of the ECC database
# @var Cur: Cursor of the connection
# @var TblDataModel: Local instance for TableDataModel
#
class Database(object):
def __init__(self, DbPath):
if os.path.exists(DbPath):
os.remove(DbPath)
self.Conn = sqlite3.connect(DbPath, isolation_level = 'DEFERRED')
self.Conn.execute("PRAGMA page_size=8192")
self.Conn.execute("PRAGMA synchronous=OFF")
self.Cur = self.Conn.cursor()
self.TblDataModel = TableDataModel(self.Cur)
self.TblFile = TableFile(self.Cur)
self.TblInf = TableInf(self.Cur)
self.TblDec = TableDec(self.Cur)
self.TblDsc = TableDsc(self.Cur)
## Initialize build database
#
# 1. Delete all old existing tables
# 2. Create new tables
# 3. Initialize table DataModel
#
def InitDatabase(self):
EdkLogger.verbose("\nInitialize ECC database started ...")
#
# Drop all old existing tables
#
# self.TblDataModel.Drop()
# self.TblDsc.Drop()
# self.TblFile.Drop()
#
# Create new tables
#
self.TblDataModel.Create()
self.TblFile.Create()
self.TblInf.Create()
self.TblDec.Create()
self.TblDsc.Create()
#
# Initialize table DataModel
#
self.TblDataModel.InitTable()
EdkLogger.verbose("Initialize ECC database ... DONE!")
## Query a table
#
# @param Table: The instance of the table to be queried
#
def QueryTable(self, Table):
Table.Query()
## Close entire database
#
# Commit all first
# Close the connection and cursor
#
def Close(self):
self.Conn.commit()
self.Cur.close()
self.Conn.close()
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
EdkLogger.Initialize()
EdkLogger.SetLevel(EdkLogger.DEBUG_0)
Db = Database(DATABASE_PATH)
Db.InitDatabase()
Db.QueryTable(Db.TblDataModel)
Db.QueryTable(Db.TblFile)
Db.QueryTable(Db.TblDsc)
Db.Close()

View File

@@ -0,0 +1,563 @@
## @file
# This file is used to define each component of DEC file
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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
#
import os
from String import *
from DataType import *
from Identification import *
from Dictionary import *
from CommonDataClass.PackageClass import *
from CommonDataClass.CommonClass import PcdClass
from BuildToolError import *
from Table.TableDec import TableDec
import Database
from Parsing import *
import GlobalData
#
# Global variable
#
Section = {TAB_UNKNOWN.upper() : MODEL_UNKNOWN,
TAB_DEC_DEFINES.upper() : MODEL_META_DATA_HEADER,
TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,
TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,
TAB_COMPONENTS.upper() : MODEL_META_DATA_COMPONENT,
TAB_GUIDS.upper() : MODEL_EFI_GUID,
TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,
TAB_PPIS.upper() : MODEL_EFI_PPI,
TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD,
TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,
TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG,
TAB_PCDS_DYNAMIC_EX_NULL.upper() : MODEL_PCD_DYNAMIC_EX,
TAB_PCDS_DYNAMIC_NULL.upper() : MODEL_PCD_DYNAMIC,
TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION
}
## DecObject
#
# This class defined basic Dec object which is used by inheriting
#
# @param object: Inherited from object class
#
class DecObject(object):
def __init__(self):
object.__init__()
## Dec
#
# This class defined the structure used in Dec object
#
# @param DecObject: Inherited from DecObject class
# @param Filename: Input value for Filename of Dec file, default is None
# @param IsMergeAllArches: Input value for IsMergeAllArches
# True is to merge all arches
# Fales is not to merge all arches
# default is False
# @param IsToPackage: Input value for IsToPackage
# True is to transfer to PackageObject automatically
# False is not to transfer to PackageObject automatically
# default is False
# @param WorkspaceDir: Input value for current workspace directory, default is None
#
# @var Identification: To store value for Identification, it is a structure as Identification
# @var Defines: To store value for Defines, it is a structure as DecDefines
# @var UserExtensions: To store value for UserExtensions
# @var Package: To store value for Package, it is a structure as PackageClass
# @var WorkspaceDir: To store value for WorkspaceDir
# @var Contents: To store value for Contents, it is a structure as DecContents
# @var KeyList: To store value for KeyList, a list for all Keys used in Dec
#
class Dec(DecObject):
def __init__(self, Filename = None, IsToDatabase = False, IsToPackage = False, WorkspaceDir = None, Database = None, SupArchList = DataType.ARCH_LIST):
self.Identification = Identification()
self.Package = PackageClass()
self.UserExtensions = ''
self.WorkspaceDir = WorkspaceDir
self.SupArchList = SupArchList
self.IsToDatabase = IsToDatabase
self.Cur = Database.Cur
self.TblFile = Database.TblFile
self.TblDec = Database.TblDec
self.FileID = -1
self.KeyList = [
TAB_INCLUDES, TAB_GUIDS, TAB_PROTOCOLS, TAB_PPIS, TAB_LIBRARY_CLASSES, \
TAB_PCDS_FIXED_AT_BUILD_NULL, TAB_PCDS_PATCHABLE_IN_MODULE_NULL, TAB_PCDS_FEATURE_FLAG_NULL, \
TAB_PCDS_DYNAMIC_NULL, TAB_PCDS_DYNAMIC_EX_NULL, TAB_DEC_DEFINES
]
#
# Upper all KEYs to ignore case sensitive when parsing
#
self.KeyList = map(lambda c: c.upper(), self.KeyList)
#
# Init RecordSet
#
self.RecordSet = {}
for Key in self.KeyList:
self.RecordSet[Section[Key]] = []
#
# Load Dec file if filename is not None
#
if Filename != None:
self.LoadDecFile(Filename)
#
# Transfer to Package Object if IsToPackage is True
#
if IsToPackage:
self.DecToPackage()
## Load Dec file
#
# Load the file if it exists
#
# @param Filename: Input value for filename of Dec file
#
def LoadDecFile(self, Filename):
#
# Insert a record for file
#
Filename = NormPath(Filename)
self.Identification.FileFullPath = Filename
(self.Identification.FileRelativePath, self.Identification.FileName) = os.path.split(Filename)
self.FileID = self.TblFile.InsertFile(Filename, MODEL_FILE_DEC)
#
# Init DecTable
#
#self.TblDec.Table = "Dec%s" % self.FileID
#self.TblDec.Create()
#
# Init common datas
#
IfDefList, SectionItemList, CurrentSection, ArchList, ThirdList, IncludeFiles = \
[], [], TAB_UNKNOWN, [], [], []
LineNo = 0
#
# Parse file content
#
IsFindBlockComment = False
ReservedLine = ''
for Line in open(Filename, 'r'):
LineNo = LineNo + 1
#
# Remove comment block
#
if Line.find(TAB_COMMENT_R8_START) > -1:
ReservedLine = GetSplitValueList(Line, TAB_COMMENT_R8_START, 1)[0]
IsFindBlockComment = True
if Line.find(TAB_COMMENT_R8_END) > -1:
Line = ReservedLine + GetSplitValueList(Line, TAB_COMMENT_R8_END, 1)[1]
ReservedLine = ''
IsFindBlockComment = False
if IsFindBlockComment:
continue
#
# Remove comments at tail and remove spaces again
#
Line = CleanString(Line)
if Line == '':
continue
#
# Find a new section tab
# First insert previous section items
# And then parse the content of the new section
#
if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END):
#
# Insert items data of previous section
#
Model = Section[CurrentSection.upper()]
InsertSectionItemsIntoDatabase(self.TblDec, self.FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, self.RecordSet)
#
# Parse the new section
#
SectionItemList = []
ArchList = []
ThirdList = []
CurrentSection = ''
LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT)
for Item in LineList:
ItemList = GetSplitValueList(Item, TAB_SPLIT)
if CurrentSection == '':
CurrentSection = ItemList[0]
else:
if CurrentSection != ItemList[0]:
EdkLogger.error("Parser", PARSER_ERROR, "Different section names '%s' and '%s' are found in one section definition, this is not allowed." % (CurrentSection, ItemList[0]), File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError)
if CurrentSection.upper() not in self.KeyList:
RaiseParserError(Line, CurrentSection, Filename, '', LineNo)
ItemList.append('')
ItemList.append('')
if len(ItemList) > 5:
RaiseParserError(Line, CurrentSection, Filename, '', LineNo)
else:
if ItemList[1] != '' and ItemList[1].upper() not in ARCH_LIST_FULL:
EdkLogger.error("Parser", PARSER_ERROR, "Invalid Arch definition '%s' found" % ItemList[1], File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError)
ArchList.append(ItemList[1].upper())
ThirdList.append(ItemList[2])
continue
#
# Not in any defined section
#
if CurrentSection == TAB_UNKNOWN:
ErrorMsg = "%s is not in any defined section" % Line
EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError)
#
# Add a section item
#
SectionItemList.append([Line, LineNo])
# End of parse
#End of For
#
# Insert items data of last section
#
Model = Section[CurrentSection.upper()]
InsertSectionItemsIntoDatabase(self.TblDec, self.FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, self.RecordSet)
#
# Replace all DEFINE macros with its actual values
#
ParseDefineMacro2(self.TblDec, self.RecordSet, GlobalData.gGlobalDefines)
## Transfer to Package Object
#
# Transfer all contents of a Dec file to a standard Package Object
#
def DecToPackage(self):
#
# Init global information for the file
#
ContainerFile = self.Identification.FileFullPath
#
# Generate Package Header
#
self.GenPackageHeader(ContainerFile)
#
# Generate Includes
#
self.GenIncludes(ContainerFile)
#
# Generate Guids
#
self.GenGuidProtocolPpis(DataType.TAB_GUIDS, ContainerFile)
#
# Generate Protocols
#
self.GenGuidProtocolPpis(DataType.TAB_PROTOCOLS, ContainerFile)
#
# Generate Ppis
#
self.GenGuidProtocolPpis(DataType.TAB_PPIS, ContainerFile)
#
# Generate LibraryClasses
#
self.GenLibraryClasses(ContainerFile)
#
# Generate Pcds
#
self.GenPcds(ContainerFile)
## Get Package Header
#
# Gen Package Header of Dec as <Key> = <Value>
#
# @param ContainerFile: The Dec file full path
#
def GenPackageHeader(self, ContainerFile):
EdkLogger.debug(2, "Generate PackageHeader ...")
#
# Update all defines item in database
#
RecordSet = self.RecordSet[MODEL_META_DATA_HEADER]
for Record in RecordSet:
ValueList = GetSplitValueList(Record[0], TAB_EQUAL_SPLIT)
if len(ValueList) != 2:
RaiseParserError(Record[0], 'Defines', ContainerFile, '<Key> = <Value>', Record[2])
ID, Value1, Value2, Arch, LineNo = Record[3], ValueList[0], ValueList[1], Record[1], Record[2]
SqlCommand = """update %s set Value1 = '%s', Value2 = '%s'
where ID = %s""" % (self.TblDec.Table, ConvertToSqlString2(Value1), ConvertToSqlString2(Value2), ID)
self.TblDec.Exec(SqlCommand)
#
# Get detailed information
#
for Arch in self.SupArchList:
PackageHeader = PackageHeaderClass()
PackageHeader.Name = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_PACKAGE_NAME, Arch, self.FileID)[0]
PackageHeader.Guid = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_PACKAGE_GUID, Arch, self.FileID)[0]
PackageHeader.Version = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_PACKAGE_VERSION, Arch, self.FileID)[0]
PackageHeader.FileName = self.Identification.FileName
PackageHeader.FullPath = self.Identification.FileFullPath
PackageHeader.DecSpecification = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_DEC_SPECIFICATION, Arch, self.FileID)[0]
self.Package.Header[Arch] = PackageHeader
## GenIncludes
#
# Gen Includes of Dec
#
#
# @param ContainerFile: The Dec file full path
#
def GenIncludes(self, ContainerFile):
EdkLogger.debug(2, "Generate %s ..." % TAB_INCLUDES)
Includes = {}
#
# Get all Includes
#
RecordSet = self.RecordSet[MODEL_EFI_INCLUDE]
#
# Go through each arch
#
for Arch in self.SupArchList:
for Record in RecordSet:
if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:
MergeArches(Includes, Record[0], Arch)
for Key in Includes.keys():
Include = IncludeClass()
Include.FilePath = NormPath(Key)
Include.SupArchList = Includes[Key]
self.Package.Includes.append(Include)
## GenPpis
#
# Gen Ppis of Dec
# <CName>=<GuidValue>
#
# @param ContainerFile: The Dec file full path
#
def GenGuidProtocolPpis(self, Type, ContainerFile):
EdkLogger.debug(2, "Generate %s ..." % Type)
Lists = {}
#
# Get all Items
#
RecordSet = self.RecordSet[Section[Type.upper()]]
#
# Go through each arch
#
for Arch in self.SupArchList:
for Record in RecordSet:
if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:
(Name, Value) = GetGuidsProtocolsPpisOfDec(Record[0], Type, ContainerFile, Record[2])
MergeArches(Lists, (Name, Value), Arch)
if self.IsToDatabase:
SqlCommand = """update %s set Value1 = '%s', Value2 = '%s'
where ID = %s""" % (self.TblDec.Table, ConvertToSqlString2(Name), ConvertToSqlString2(Value), Record[3])
self.TblDec.Exec(SqlCommand)
ListMember = None
if Type == TAB_GUIDS:
ListMember = self.Package.GuidDeclarations
elif Type == TAB_PROTOCOLS:
ListMember = self.Package.ProtocolDeclarations
elif Type == TAB_PPIS:
ListMember = self.Package.PpiDeclarations
for Key in Lists.keys():
ListClass = GuidProtocolPpiCommonClass()
ListClass.CName = Key[0]
ListClass.Guid = Key[1]
ListClass.SupArchList = Lists[Key]
ListMember.append(ListClass)
## GenLibraryClasses
#
# Gen LibraryClasses of Dec
# <CName>=<GuidValue>
#
# @param ContainerFile: The Dec file full path
#
def GenLibraryClasses(self, ContainerFile):
EdkLogger.debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES)
LibraryClasses = {}
#
# Get all Guids
#
RecordSet = self.RecordSet[MODEL_EFI_LIBRARY_CLASS]
#
# Go through each arch
#
for Arch in self.SupArchList:
for Record in RecordSet:
if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:
List = GetSplitValueList(Record[0], DataType.TAB_VALUE_SPLIT)
if len(List) != 2:
RaiseParserError(Record[0], 'LibraryClasses', ContainerFile, '<LibraryClassName>|<LibraryClassInstanceFilename>', Record[2])
else:
CheckFileExist(self.Identification.FileRelativePath, List[1], ContainerFile, 'LibraryClasses', Record[0])
MergeArches(LibraryClasses, (List[0], List[1]), Arch)
if self.IsToDatabase:
SqlCommand = """update %s set Value1 = '%s', Value2 = '%s', Value3 = '%s'
where ID = %s""" % (self.TblDec.Table, ConvertToSqlString2(List[0]), ConvertToSqlString2(List[1]), SUP_MODULE_LIST_STRING, Record[3])
self.TblDec.Exec(SqlCommand)
for Key in LibraryClasses.keys():
LibraryClass = LibraryClassClass()
LibraryClass.LibraryClass = Key[0]
LibraryClass.RecommendedInstance = NormPath(Key[1])
LibraryClass.SupModuleList = SUP_MODULE_LIST
LibraryClass.SupArchList = LibraryClasses[Key]
self.Package.LibraryClassDeclarations.append(LibraryClass)
## GenPcds
#
# Gen Pcds of Dec
# <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
#
# @param ContainerFile: The Dec file full path
#
def GenPcds(self, ContainerFile):
EdkLogger.debug(2, "Generate %s ..." % TAB_PCDS)
Pcds = {}
PcdToken = {}
#
# Get all Guids
#
RecordSet1 = self.RecordSet[MODEL_PCD_FIXED_AT_BUILD]
RecordSet2 = self.RecordSet[MODEL_PCD_PATCHABLE_IN_MODULE]
RecordSet3 = self.RecordSet[MODEL_PCD_FEATURE_FLAG]
RecordSet4 = self.RecordSet[MODEL_PCD_DYNAMIC_EX]
RecordSet5 = self.RecordSet[MODEL_PCD_DYNAMIC]
#
# Go through each arch
#
for Arch in self.SupArchList:
for Record in RecordSet1:
if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:
(TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_FIXED_AT_BUILD, ContainerFile, Record[2])
MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch)
PcdToken[Record[3]] = (TokenGuidCName, TokenName)
for Record in RecordSet2:
if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:
(TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_PATCHABLE_IN_MODULE, ContainerFile, Record[2])
MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch)
PcdToken[Record[3]] = (TokenGuidCName, TokenName)
for Record in RecordSet3:
if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:
(TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_FEATURE_FLAG, ContainerFile, Record[2])
MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch)
PcdToken[Record[3]] = (TokenGuidCName, TokenName)
for Record in RecordSet4:
if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:
(TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_DYNAMIC_EX, ContainerFile, Record[2])
MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch)
PcdToken[Record[3]] = (TokenGuidCName, TokenName)
for Record in RecordSet5:
if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:
(TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_DYNAMIC, ContainerFile, Record[2])
MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch)
PcdToken[Record[3]] = (TokenGuidCName, TokenName)
#
# Update to database
#
if self.IsToDatabase:
for Key in PcdToken.keys():
SqlCommand = """update %s set Value2 = '%s' where ID = %s""" % (self.TblDec.Table, ".".join((PcdToken[Key][0], PcdToken[Key][1])), Key)
self.TblDec.Exec(SqlCommand)
for Key in Pcds.keys():
Pcd = PcdClass()
Pcd.CName = Key[1]
Pcd.Token = Key[4]
Pcd.TokenSpaceGuidCName = Key[0]
Pcd.DatumType = Key[3]
Pcd.DefaultValue = Key[2]
Pcd.ItemType = Key[5]
Pcd.SupArchList = Pcds[Key]
self.Package.PcdDeclarations.append(Pcd)
## Show detailed information of Package
#
# Print all members and their values of Package class
#
def ShowPackage(self):
M = self.Package
for Arch in M.Header.keys():
print '\nArch =', Arch
print 'Filename =', M.Header[Arch].FileName
print 'FullPath =', M.Header[Arch].FullPath
print 'BaseName =', M.Header[Arch].Name
print 'Guid =', M.Header[Arch].Guid
print 'Version =', M.Header[Arch].Version
print 'DecSpecification =', M.Header[Arch].DecSpecification
print '\nIncludes =', M.Includes
for Item in M.Includes:
print Item.FilePath, Item.SupArchList
print '\nGuids =', M.GuidDeclarations
for Item in M.GuidDeclarations:
print Item.CName, Item.Guid, Item.SupArchList
print '\nProtocols =', M.ProtocolDeclarations
for Item in M.ProtocolDeclarations:
print Item.CName, Item.Guid, Item.SupArchList
print '\nPpis =', M.PpiDeclarations
for Item in M.PpiDeclarations:
print Item.CName, Item.Guid, Item.SupArchList
print '\nLibraryClasses =', M.LibraryClassDeclarations
for Item in M.LibraryClassDeclarations:
print Item.LibraryClass, Item.RecommendedInstance, Item.SupModuleList, Item.SupArchList
print '\nPcds =', M.PcdDeclarations
for Item in M.PcdDeclarations:
print 'CName=', Item.CName, 'TokenSpaceGuidCName=', Item.TokenSpaceGuidCName, 'DefaultValue=', Item.DefaultValue, 'ItemType=', Item.ItemType, 'Token=', Item.Token, 'DatumType=', Item.DatumType, Item.SupArchList
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
EdkLogger.Initialize()
EdkLogger.SetLevel(EdkLogger.DEBUG_0)
W = os.getenv('WORKSPACE')
F = os.path.join(W, 'Nt32Pkg/Nt32Pkg.dec')
Db = Database.Database('Dec.db')
Db.InitDatabase()
P = Dec(os.path.normpath(F), True, True, W, Db)
P.ShowPackage()
Db.Close()

View File

@@ -0,0 +1,580 @@
## @file
# This file is used to define each component of DEC file in light mode
#
# Copyright (c) 2008, Intel Corporation
# All rights reserved. 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
#
import os
from Misc import GetFiles
from String import *
from DataType import *
from CommonDataClass.PackageClass import *
from CommonDataClass import CommonClass
from BuildToolError import *
from Parsing import *
# Global variable
Section = {TAB_UNKNOWN.upper() : MODEL_UNKNOWN,
TAB_DEC_DEFINES.upper() : MODEL_META_DATA_HEADER,
TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,
TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,
TAB_COMPONENTS.upper() : MODEL_META_DATA_COMPONENT,
TAB_GUIDS.upper() : MODEL_EFI_GUID,
TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,
TAB_PPIS.upper() : MODEL_EFI_PPI,
TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD,
TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,
TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG,
TAB_PCDS_DYNAMIC_EX_NULL.upper() : MODEL_PCD_DYNAMIC_EX,
TAB_PCDS_DYNAMIC_NULL.upper() : MODEL_PCD_DYNAMIC,
TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION
}
## DecObject
#
# This class defined basic Dec object which is used by inheriting
#
# @param object: Inherited from object class
#
class DecObject(object):
def __init__(self):
object.__init__()
## Dec
#
# This class defined the structure used in Dec object
#
# @param DecObject: Inherited from DecObject class
# @param Filename: Input value for Filename of Dec file, default is None
# @param IsMergeAllArches: Input value for IsMergeAllArches
# True is to merge all arches
# Fales is not to merge all arches
# default is False
# @param IsToPackage: Input value for IsToPackage
# True is to transfer to PackageObject automatically
# False is not to transfer to PackageObject automatically
# default is False
# @param WorkspaceDir: Input value for current workspace directory, default is None
#
# @var Identification: To store value for Identification, it is a structure as Identification
# @var Defines: To store value for Defines, it is a structure as DecDefines
# @var UserExtensions: To store value for UserExtensions
# @var Package: To store value for Package, it is a structure as PackageClass
# @var WorkspaceDir: To store value for WorkspaceDir
# @var Contents: To store value for Contents, it is a structure as DecContents
# @var KeyList: To store value for KeyList, a list for all Keys used in Dec
#
class Dec(DecObject):
def __init__(self, Filename = None, IsToPackage = False, WorkspaceDir = None, AllGuidVersionDict = None, SupArchList = DataType.ARCH_LIST):
self.Identification = IdentificationClass()
self.Package = PackageClass()
self.UserExtensions = ''
self.WorkspaceDir = WorkspaceDir
self.SupArchList = SupArchList
self.AllGuidVersionDict = {}
if AllGuidVersionDict:
self.AllGuidVersionDict = AllGuidVersionDict
self.KeyList = [
TAB_INCLUDES, TAB_GUIDS, TAB_PROTOCOLS, TAB_PPIS, TAB_LIBRARY_CLASSES, \
TAB_PCDS_FIXED_AT_BUILD_NULL, TAB_PCDS_PATCHABLE_IN_MODULE_NULL, TAB_PCDS_FEATURE_FLAG_NULL, \
TAB_PCDS_DYNAMIC_NULL, TAB_PCDS_DYNAMIC_EX_NULL, TAB_DEC_DEFINES
]
# Upper all KEYs to ignore case sensitive when parsing
self.KeyList = map(lambda c: c.upper(), self.KeyList)
# Init RecordSet
self.RecordSet = {}
for Key in self.KeyList:
self.RecordSet[Section[Key]] = []
# Init Comment
self.SectionHeaderCommentDict = {}
# Load Dec file if filename is not None
if Filename != None:
self.LoadDecFile(Filename)
# Transfer to Package Object if IsToPackage is True
if IsToPackage:
self.DecToPackage()
## Load Dec file
#
# Load the file if it exists
#
# @param Filename: Input value for filename of Dec file
#
def LoadDecFile(self, Filename):
# Insert a record for file
Filename = NormPath(Filename)
self.Identification.FullPath = Filename
(self.Identification.RelaPath, self.Identification.FileName) = os.path.split(Filename)
if self.Identification.FullPath.find(self.WorkspaceDir) > -1:
self.Identification.PackagePath = os.path.dirname(self.Identification.FullPath[len(self.WorkspaceDir) + 1:])
# Init common datas
IfDefList, SectionItemList, CurrentSection, ArchList, ThirdList, IncludeFiles = \
[], [], TAB_UNKNOWN, [], [], []
LineNo = 0
# Parse file content
IsFindBlockComment = False
ReservedLine = ''
Comment = ''
for Line in open(Filename, 'r'):
LineNo = LineNo + 1
# Remove comment block
if Line.find(TAB_COMMENT_R8_START) > -1:
ReservedLine = GetSplitValueList(Line, TAB_COMMENT_R8_START, 1)[0]
if ReservedLine.strip().startswith(TAB_COMMENT_SPLIT):
Comment = Comment + Line.strip() + '\n'
ReservedLine = ''
else:
Comment = Comment + Line[len(ReservedLine):] + '\n'
IsFindBlockComment = True
if not ReservedLine:
continue
if Line.find(TAB_COMMENT_R8_END) > -1:
Comment = Comment + Line[:Line.find(TAB_COMMENT_R8_END) + len(TAB_COMMENT_R8_END)] + '\n'
Line = ReservedLine + GetSplitValueList(Line, TAB_COMMENT_R8_END, 1)[1]
ReservedLine = ''
IsFindBlockComment = False
if IsFindBlockComment:
Comment = Comment + Line.strip() + '\n'
continue
# Remove comments at tail and remove spaces again
if Line.strip().startswith(TAB_COMMENT_SPLIT) or Line.strip().startswith('--/'):
Comment = Comment + Line.strip() + '\n'
Line = CleanString(Line)
if Line == '':
continue
## Find a new section tab
# First insert previous section items
# And then parse the content of the new section
#
if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END):
# Insert items data of previous section
Model = Section[CurrentSection.upper()]
InsertSectionItems(Model, CurrentSection, SectionItemList, ArchList, ThirdList, self.RecordSet)
# Parse the new section
SectionItemList = []
ArchList = []
ThirdList = []
CurrentSection = ''
LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT)
for Item in LineList:
ItemList = GetSplitValueList(Item, TAB_SPLIT)
if CurrentSection == '':
CurrentSection = ItemList[0]
else:
if CurrentSection != ItemList[0]:
EdkLogger.error("Parser", PARSER_ERROR, "Different section names '%s' and '%s' are found in one section definition, this is not allowed." % (CurrentSection, ItemList[0]), File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError)
if CurrentSection.upper() not in self.KeyList:
RaiseParserError(Line, CurrentSection, Filename, '', LineNo)
ItemList.append('')
ItemList.append('')
if len(ItemList) > 5:
RaiseParserError(Line, CurrentSection, Filename, '', LineNo)
else:
if ItemList[1] != '' and ItemList[1].upper() not in ARCH_LIST_FULL:
EdkLogger.error("Parser", PARSER_ERROR, "Invalid Arch definition '%s' found" % ItemList[1], File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError)
ArchList.append(ItemList[1].upper())
ThirdList.append(ItemList[2])
if Comment:
if Comment.endswith('\n'):
Comment = Comment[:len(Comment) - len('\n')]
self.SectionHeaderCommentDict[Section[CurrentSection.upper()]] = Comment
Comment = ''
continue
# Not in any defined section
if CurrentSection == TAB_UNKNOWN:
ErrorMsg = "%s is not in any defined section" % Line
EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError)
# Add a section item
SectionItemList.append([Line, LineNo, Comment])
Comment = ''
# End of parse
#End of For
#
# Insert items data of last section
#
Model = Section[CurrentSection.upper()]
InsertSectionItems(Model, CurrentSection, SectionItemList, ArchList, ThirdList, self.RecordSet)
if Comment != '':
self.SectionHeaderCommentDict[Model] = Comment
Comment = ''
## Package Object to DEC file
def PackageToDec(self, Package):
Dec = ''
DecList = sdict()
SectionHeaderCommentDict = {}
if Package == None:
return Dec
PackageHeader = Package.PackageHeader
TmpList = []
if PackageHeader.Name:
TmpList.append(TAB_DEC_DEFINES_PACKAGE_NAME + ' = ' + PackageHeader.Name)
if PackageHeader.Guid:
TmpList.append(TAB_DEC_DEFINES_PACKAGE_GUID + ' = ' + PackageHeader.Guid)
if PackageHeader.Version:
TmpList.append(TAB_DEC_DEFINES_PACKAGE_VERSION + ' = ' + PackageHeader.Version)
if PackageHeader.DecSpecification:
TmpList.append(TAB_DEC_DEFINES_DEC_SPECIFICATION + ' = ' + PackageHeader.DecSpecification)
if Package.UserExtensions != None:
for Item in Package.UserExtensions.Defines:
TmpList.append(Item)
DecList['Defines'] =TmpList
if PackageHeader.Description != '':
SectionHeaderCommentDict['Defines'] = PackageHeader.Description
for Item in Package.Includes:
Key = 'Includes.' + Item.SupArchList
Value = Item.FilePath
GenMetaDatSectionItem(Key, Value, DecList)
for Item in Package.GuidDeclarations:
Key = 'Guids.' + Item.SupArchList
Value = Item.CName + '=' + Item.Guid
GenMetaDatSectionItem(Key, Value, DecList)
for Item in Package.ProtocolDeclarations:
Key = 'Protocols.' + Item.SupArchList
Value = Item.CName + '=' + Item.Guid
GenMetaDatSectionItem(Key, Value, DecList)
for Item in Package.PpiDeclarations:
Key = 'Ppis.' + Item.SupArchList
Value = Item.CName + '=' + Item.Guid
GenMetaDatSectionItem(Key, Value, DecList)
for Item in Package.LibraryClassDeclarations:
Key = 'LibraryClasses.' + Item.SupArchList
Value = Item.LibraryClass + '|' + Item.RecommendedInstance
GenMetaDatSectionItem(Key, Value, DecList)
for Item in Package.PcdDeclarations:
Key = 'Pcds' + Item.ItemType + '.' + Item.SupArchList
Value = Item.TokenSpaceGuidCName + '.' + Item.CName
if Item.DefaultValue != '':
Value = Value + '|' + Item.DefaultValue
if Item.DatumType != '':
Value = Value + '|' + Item.DatumType
if Item.Token != '':
Value = Value + '|' + Item.Token
GenMetaDatSectionItem(Key, Value, DecList)
# Transfer Package to Inf
for Key in DecList:
if Key in SectionHeaderCommentDict:
List = SectionHeaderCommentDict[Key].split('\r')
for Item in List:
Dec = Dec + Item + '\n'
Dec = Dec + '[' + Key + ']' + '\n'
for Value in DecList[Key]:
if type(Value) == type([]):
for SubValue in Value:
Dec = Dec + ' ' + SubValue + '\n'
else:
Dec = Dec + ' ' + Value + '\n'
Dec = Dec + '\n'
return Dec
## Transfer to Package Object
#
# Transfer all contents of a Dec file to a standard Package Object
#
def DecToPackage(self):
# Init global information for the file
ContainerFile = self.Identification.FullPath
# Generate Package Header
self.GenPackageHeader(ContainerFile)
# Generate Includes
# Only for R8
self.GenIncludes(ContainerFile)
# Generate Guids
self.GenGuidProtocolPpis(DataType.TAB_GUIDS, ContainerFile)
# Generate Protocols
self.GenGuidProtocolPpis(DataType.TAB_PROTOCOLS, ContainerFile)
# Generate Ppis
self.GenGuidProtocolPpis(DataType.TAB_PPIS, ContainerFile)
# Generate LibraryClasses
self.GenLibraryClasses(ContainerFile)
# Generate Pcds
self.GenPcds(ContainerFile)
# Init MiscFiles
self.GenMiscFiles(ContainerFile)
## GenMiscFiles
#
def GenMiscFiles(self, ContainerFile):
MiscFiles = MiscFileClass()
MiscFiles.Name = 'ModuleFiles'
for Item in GetFiles(os.path.dirname(ContainerFile), ['CVS', '.svn'], False):
File = CommonClass.FileClass()
File.Filename = Item
MiscFiles.Files.append(File)
self.Package.MiscFiles = MiscFiles
## Get Package Header
#
# Gen Package Header of Dec as <Key> = <Value>
#
# @param ContainerFile: The Dec file full path
#
def GenPackageHeader(self, ContainerFile):
EdkLogger.debug(2, "Generate PackageHeader ...")
#
# Update all defines item in database
#
RecordSet = self.RecordSet[MODEL_META_DATA_HEADER]
PackageHeader = PackageHeaderClass()
OtherDefines = []
for Record in RecordSet:
ValueList = GetSplitValueList(Record[0], TAB_EQUAL_SPLIT)
if len(ValueList) != 2:
OtherDefines.append(Record[0])
else:
Name = ValueList[0]
Value = ValueList[1]
if Name == TAB_DEC_DEFINES_PACKAGE_NAME:
PackageHeader.Name = Value
elif Name == TAB_DEC_DEFINES_PACKAGE_GUID:
PackageHeader.Guid = Value
elif Name == TAB_DEC_DEFINES_PACKAGE_VERSION:
PackageHeader.Version = Value
elif Name == TAB_DEC_DEFINES_DEC_SPECIFICATION:
PackageHeader.DecSpecification = Value
else:
OtherDefines.append(Record[0])
PackageHeader.FileName = self.Identification.FileName
PackageHeader.FullPath = self.Identification.FullPath
PackageHeader.RelaPath = self.Identification.RelaPath
PackageHeader.PackagePath = self.Identification.PackagePath
PackageHeader.ModulePath = self.Identification.ModulePath
PackageHeader.CombinePath = os.path.normpath(os.path.join(PackageHeader.PackagePath, PackageHeader.ModulePath, PackageHeader.FileName))
if MODEL_META_DATA_HEADER in self.SectionHeaderCommentDict:
PackageHeader.Description = self.SectionHeaderCommentDict[MODEL_META_DATA_HEADER]
self.Package.PackageHeader = PackageHeader
UE = UserExtensionsClass()
UE.Defines = OtherDefines
self.Package.UserExtensions = UE
## GenIncludes
#
# Gen Includes of Dec
#
# @param ContainerFile: The Dec file full path
#
def GenIncludes(self, ContainerFile):
EdkLogger.debug(2, "Generate %s ..." % TAB_INCLUDES)
Includes = {}
# Get all Includes
RecordSet = self.RecordSet[MODEL_EFI_INCLUDE]
# Go through each arch
for Record in RecordSet:
Arch = Record[1]
Key = Record[0]
Include = IncludeClass()
Include.FilePath = NormPath(Key)
Include.SupArchList = Arch
self.Package.Includes.append(Include)
## GenPpis
#
# Gen Ppis of Dec
# <CName>=<GuidValue>
#
# @param ContainerFile: The Dec file full path
#
def GenGuidProtocolPpis(self, Type, ContainerFile):
EdkLogger.debug(2, "Generate %s ..." % Type)
Lists = {}
# Get all Items
RecordSet = self.RecordSet[Section[Type.upper()]]
# Go through each arch
for Record in RecordSet:
Arch = Record[1]
(Name, Value) = GetGuidsProtocolsPpisOfDec(Record[0], Type, ContainerFile, Record[2])
ListMember = None
if Type == TAB_GUIDS:
ListMember = self.Package.GuidDeclarations
elif Type == TAB_PROTOCOLS:
ListMember = self.Package.ProtocolDeclarations
elif Type == TAB_PPIS:
ListMember = self.Package.PpiDeclarations
ListClass = GuidProtocolPpiCommonClass()
ListClass.CName = Name
ListClass.Guid = Value
ListClass.SupArchList = Arch
ListMember.append(ListClass)
## GenLibraryClasses
#
# Gen LibraryClasses of Dec
# <CName>=<GuidValue>
#
# @param ContainerFile: The Dec file full path
#
def GenLibraryClasses(self, ContainerFile):
EdkLogger.debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES)
LibraryClasses = {}
# Get all Guids
RecordSet = self.RecordSet[MODEL_EFI_LIBRARY_CLASS]
# Go through each arch
for Record in RecordSet:
Arch = Record[1]
List = GetSplitValueList(Record[0], DataType.TAB_VALUE_SPLIT)
if len(List) != 2:
continue
LibraryClass = LibraryClassClass()
LibraryClass.LibraryClass = List[0]
LibraryClass.RecommendedInstance = NormPath(List[1])
LibraryClass.SupArchList = Arch
self.Package.LibraryClassDeclarations.append(LibraryClass)
def AddPcd(self, CName, Token, TokenSpaceGuidCName, DatumType, DefaultValue, ItemType, Arch):
Pcd = CommonClass.PcdClass()
Pcd.CName = CName
Pcd.Token = Token
Pcd.TokenSpaceGuidCName = TokenSpaceGuidCName
Pcd.DatumType = DatumType
Pcd.DefaultValue = DefaultValue
Pcd.ItemType = ItemType
Pcd.SupArchList = Arch
self.Package.PcdDeclarations.append(Pcd)
## GenPcds
#
# Gen Pcds of Dec
# <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
#
# @param ContainerFile: The Dec file full path
#
def GenPcds(self, ContainerFile):
EdkLogger.debug(2, "Generate %s ..." % TAB_PCDS)
Pcds = {}
PcdToken = {}
# Get all Pcds
RecordSet1 = self.RecordSet[MODEL_PCD_FIXED_AT_BUILD]
RecordSet2 = self.RecordSet[MODEL_PCD_PATCHABLE_IN_MODULE]
RecordSet3 = self.RecordSet[MODEL_PCD_FEATURE_FLAG]
RecordSet4 = self.RecordSet[MODEL_PCD_DYNAMIC_EX]
RecordSet5 = self.RecordSet[MODEL_PCD_DYNAMIC]
# Go through each pcd
for Record in RecordSet1:
Arch = Record[1]
(TokenGuidCName, TokenName, DefaultValue, DatumType, Token, ItemType) = GetPcdOfDec(Record[0], TAB_PCDS_FIXED_AT_BUILD, ContainerFile, Record[2])
self.AddPcd(TokenName, Token, TokenGuidCName, DatumType, DefaultValue, ItemType, Arch)
for Record in RecordSet2:
Arch = Record[1]
(TokenGuidCName, TokenName, DefaultValue, DatumType, Token, ItemType) = GetPcdOfDec(Record[0], TAB_PCDS_PATCHABLE_IN_MODULE, ContainerFile, Record[2])
self.AddPcd(TokenName, Token, TokenGuidCName, DatumType, DefaultValue, ItemType, Arch)
for Record in RecordSet3:
Arch = Record[1]
(TokenGuidCName, TokenName, DefaultValue, DatumType, Token, ItemType) = GetPcdOfDec(Record[0], TAB_PCDS_FEATURE_FLAG, ContainerFile, Record[2])
self.AddPcd(TokenName, Token, TokenGuidCName, DatumType, DefaultValue, ItemType, Arch)
for Record in RecordSet4:
Arch = Record[1]
(TokenGuidCName, TokenName, DefaultValue, DatumType, Token, ItemType) = GetPcdOfDec(Record[0], TAB_PCDS_DYNAMIC_EX, ContainerFile, Record[2])
self.AddPcd(TokenName, Token, TokenGuidCName, DatumType, DefaultValue, ItemType, Arch)
for Record in RecordSet5:
Arch = Record[1]
(TokenGuidCName, TokenName, DefaultValue, DatumType, Token, ItemType) = GetPcdOfDec(Record[0], TAB_PCDS_DYNAMIC, ContainerFile, Record[2])
self.AddPcd(TokenName, Token, TokenGuidCName, DatumType, DefaultValue, ItemType, Arch)
## Show detailed information of Package
#
# Print all members and their values of Package class
#
def ShowPackage(self):
M = self.Package
print 'Filename =', M.PackageHeader.FileName
print 'FullPath =', M.PackageHeader.FullPath
print 'RelaPath =', M.PackageHeader.RelaPath
print 'PackagePath =', M.PackageHeader.PackagePath
print 'ModulePath =', M.PackageHeader.ModulePath
print 'CombinePath =', M.PackageHeader.CombinePath
print 'BaseName =', M.PackageHeader.Name
print 'Guid =', M.PackageHeader.Guid
print 'Version =', M.PackageHeader.Version
print 'DecSpecification =', M.PackageHeader.DecSpecification
print '\nIncludes ='#, M.Includes
for Item in M.Includes:
print Item.FilePath, Item.SupArchList
print '\nGuids ='#, M.GuidDeclarations
for Item in M.GuidDeclarations:
print Item.CName, Item.Guid, Item.SupArchList
print '\nProtocols ='#, M.ProtocolDeclarations
for Item in M.ProtocolDeclarations:
print Item.CName, Item.Guid, Item.SupArchList
print '\nPpis ='#, M.PpiDeclarations
for Item in M.PpiDeclarations:
print Item.CName, Item.Guid, Item.SupArchList
print '\nLibraryClasses ='#, M.LibraryClassDeclarations
for Item in M.LibraryClassDeclarations:
print Item.LibraryClass, Item.RecommendedInstance, Item.SupModuleList, Item.SupArchList
print '\nPcds ='#, M.PcdDeclarations
for Item in M.PcdDeclarations:
print 'CName=', Item.CName, 'TokenSpaceGuidCName=', Item.TokenSpaceGuidCName, 'DefaultValue=', Item.DefaultValue, 'ItemType=', Item.ItemType, 'Token=', Item.Token, 'DatumType=', Item.DatumType, Item.SupArchList
print '\nUserExtensions =', M.UserExtensions.Defines
print '\n*** FileList ***'
for Item in M.MiscFiles.Files:
print Item.Filename
print '****************\n'
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
EdkLogger.Initialize()
EdkLogger.SetLevel(EdkLogger.QUIET)
W = os.getenv('WORKSPACE')
F = os.path.join(W, 'MdeModulePkg/MdeModulePkg.dec')
P = Dec(os.path.normpath(F), True, W)
P.ShowPackage()
print P.PackageToDec(P.Package)

View File

@@ -0,0 +1,75 @@
## @file
# Define a dictionary structure
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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
#
import EdkLogger
from DataType import *
## Convert a text file to a dictionary
#
# Convert a text file to a dictionary of (name:value) pairs.
#
# @retval 0 Convert successful
# @retval 1 Open file failed
#
def ConvertTextFileToDictionary(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter):
try:
F = open(FileName,'r')
Keys = []
for Line in F:
if Line.startswith(CommentCharacter):
continue
LineList = Line.split(KeySplitCharacter,1)
if len(LineList) >= 2:
Key = LineList[0].split()
if len(Key) == 1 and Key[0][0] != CommentCharacter and Key[0] not in Keys:
if ValueSplitFlag:
Dictionary[Key[0]] = LineList[1].replace('\\','/').split(ValueSplitCharacter)
else:
Dictionary[Key[0]] = LineList[1].strip().replace('\\','/')
Keys += [Key[0]]
F.close()
return 0
except:
EdkLogger.info('Open file failed')
return 1
## Print the dictionary
#
# Print all items of dictionary one by one
#
# @param Dict: The dictionary to be printed
#
def printDict(Dict):
if Dict != None:
KeyList = Dict.keys()
for Key in KeyList:
if Dict[Key] != '':
print Key + ' = ' + str(Dict[Key])
## Print the dictionary
#
# Print the items of dictionary which matched with input key
#
# @param list: The dictionary to be printed
# @param key: The key of the item to be printed
#
def printList(Key, List):
if type(List) == type([]):
if len(List) > 0:
if key.find(TAB_SPLIT) != -1:
print "\n" + Key
for Item in List:
print Item

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,318 @@
## @file
# This is the base class for applications that operate on an EDK II Workspace
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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
#
import os, sys, time
from DataType import *
## EdkIIWorkspace
#
# Collect WorkspaceDir from the environment, the Verbose command line flag, and detect an icon bitmap file.
#
# @var StartTime: Time of build system starting
# @var PrintRunTime: Printable time of build system running
# @var PrintRunStatus: Printable status of build system running
# @var RunStatus: Status of build system running
#
class EdkIIWorkspace:
def __init__(self):
self.StartTime = time.time()
self.PrintRunTime = False
self.PrintRunStatus = False
self.RunStatus = ''
#
# Check environment valiable 'WORKSPACE'
#
if os.environ.get('WORKSPACE') == None:
print 'ERROR: WORKSPACE not defined. Please run EdkSetup from the EDK II install directory.'
return False
self.CurrentWorkingDir = os.getcwd()
self.WorkspaceDir = os.path.realpath(os.environ.get('WORKSPACE'))
(Drive, Path) = os.path.splitdrive(self.WorkspaceDir)
if Drive == '':
(Drive, CwdPath) = os.path.splitdrive(self.CurrentWorkingDir)
if Drive != '':
self.WorkspaceDir = Drive + Path
else:
self.WorkspaceDir = Drive.upper() + Path
self.WorkspaceRelativeWorkingDir = self.WorkspaceRelativePath (self.CurrentWorkingDir)
try:
#
# Load TianoCoreOrgLogo, used for GUI tool
#
self.Icon = wx.Icon(self.WorkspaceFile('tools/Python/TianoCoreOrgLogo.gif'),wx.BITMAP_TYPE_GIF)
except:
self.Icon = None
self.Verbose = False
for Arg in sys.argv:
if Arg.lower() == '-v':
self.Verbose = True
## Close build system
#
# Close build system and print running time and status
#
def Close(self):
if self.PrintRunTime:
Seconds = int(time.time() - self.StartTime)
if Seconds < 60:
print 'Run Time: %d seconds' % (Seconds)
else:
Minutes = Seconds / 60
Seconds = Seconds % 60
if Minutes < 60:
print 'Run Time: %d minutes %d seconds' % (Minutes, Seconds)
else:
Hours = Minutes / 60
Minutes = Minutes % 60
print 'Run Time: %d hours %d minutes %d seconds' % (Hours, Minutes, Seconds)
if self.RunStatus != '':
print self.RunStatus
## Convert to a workspace relative filename
#
# Convert a full path filename to a workspace relative filename.
#
# @param FileName: The filename to be Converted
#
# @retval None Workspace dir is not found in the full path
# @retval string The relative filename
#
def WorkspaceRelativePath(self, FileName):
FileName = os.path.realpath(FileName)
if FileName.find(self.WorkspaceDir) != 0:
return None
return FileName.replace (self.WorkspaceDir, '').strip('\\').strip('/')
## Convert to a full path filename
#
# Convert a workspace relative filename to a full path filename.
#
# @param FileName: The filename to be Converted
#
# @retval string The full path filename
#
def WorkspaceFile(self, FileName):
return os.path.realpath(os.path.join(self.WorkspaceDir,FileName))
## Convert to a real path filename
#
# Convert ${WORKSPACE} to real path
#
# @param FileName: The filename to be Converted
#
# @retval string The full path filename
#
def WorkspacePathConvert(self, FileName):
return os.path.realpath(FileName.replace(TAB_WORKSPACE, self.WorkspaceDir))
## Convert XML into a DOM
#
# Parse an XML file into a DOM and return the DOM.
#
# @param FileName: The filename to be parsed
#
# @retval XmlParseFile (self.WorkspaceFile(FileName))
#
def XmlParseFile (self, FileName):
if self.Verbose:
print FileName
return XmlParseFile (self.WorkspaceFile(FileName))
## Convert a XML section
#
# Parse a section of an XML file into a DOM(Document Object Model) and return the DOM.
#
# @param FileName: The filename to be parsed
# @param SectionTag: The tag name of the section to be parsed
#
# @retval XmlParseFileSection (self.WorkspaceFile(FileName), SectionTag)
#
def XmlParseFileSection (self, FileName, SectionTag):
if self.Verbose:
print FileName
return XmlParseFileSection (self.WorkspaceFile(FileName), SectionTag)
## Save a XML file
#
# Save a DOM(Document Object Model) into an XML file.
#
# @param Dom: The Dom to be saved
# @param FileName: The filename
#
# @retval XmlSaveFile (Dom, self.WorkspaceFile(FileName))
#
def XmlSaveFile (self, Dom, FileName):
if self.Verbose:
print FileName
return XmlSaveFile (Dom, self.WorkspaceFile(FileName))
## Convert Text File To Dictionary
#
# Convert a workspace relative text file to a dictionary of (name:value) pairs.
#
# @param FileName: Text filename
# @param Dictionary: Dictionary to store data
# @param CommentCharacter: Comment char, be used to ignore comment content
# @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char
# @param ValueSplitFlag: Value split flag, be used to decide if has multiple values
# @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char
#
# @retval ConvertTextFileToDictionary(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter)
#
def ConvertTextFileToDictionary(self, FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter):
if self.Verbose:
print FileName
return ConvertTextFileToDictionary(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter)
## Convert Dictionary To Text File
#
# Convert a dictionary of (name:value) pairs to a workspace relative text file.
#
# @param FileName: Text filename
# @param Dictionary: Dictionary to store data
# @param CommentCharacter: Comment char, be used to ignore comment content
# @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char
# @param ValueSplitFlag: Value split flag, be used to decide if has multiple values
# @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char
#
# @retval ConvertDictionaryToTextFile(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter)
#
def ConvertDictionaryToTextFile(self, FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter):
if self.Verbose:
print FileName
return ConvertDictionaryToTextFile(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter)
## Convert Text File To Dictionary
#
# Convert a text file to a dictionary of (name:value) pairs.
#
# @param FileName: Text filename
# @param Dictionary: Dictionary to store data
# @param CommentCharacter: Comment char, be used to ignore comment content
# @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char
# @param ValueSplitFlag: Value split flag, be used to decide if has multiple values
# @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char
#
# @retval True Convert successfully
# @retval False Open file failed
#
def ConvertTextFileToDictionary(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter):
try:
F = open(FileName,'r')
except:
return False
Keys = []
for Line in F:
LineList = Line.split(KeySplitCharacter,1)
if len(LineList) >= 2:
Key = LineList[0].split()
if len(Key) == 1 and Key[0][0] != CommentCharacter and Key[0] not in Keys:
if ValueSplitFlag:
Dictionary[Key[0]] = LineList[1].replace('\\','/').split(ValueSplitCharacter)
else:
Dictionary[Key[0]] = LineList[1].strip().replace('\\','/')
Keys += [Key[0]]
F.close()
return True
## Convert Dictionary To Text File
#
# Convert a dictionary of (name:value) pairs to a text file.
#
# @param FileName: Text filename
# @param Dictionary: Dictionary to store data
# @param CommentCharacter: Comment char, be used to ignore comment content
# @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char
# @param ValueSplitFlag: Value split flag, be used to decide if has multiple values
# @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char
#
# @retval True Convert successfully
# @retval False Open file failed
#
def ConvertDictionaryToTextFile(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter):
try:
F = open(FileName,'r')
Lines = []
Lines = F.readlines()
F.close()
except:
Lines = []
Keys = Dictionary.keys()
MaxLength = 0
for Key in Keys:
if len(Key) > MaxLength:
MaxLength = len(Key)
Index = 0
for Line in Lines:
LineList = Line.split(KeySplitCharacter,1)
if len(LineList) >= 2:
Key = LineList[0].split()
if len(Key) == 1 and Key[0][0] != CommentCharacter and Key[0] in Dictionary:
if ValueSplitFlag:
Line = '%-*s %c %s\n' % (MaxLength, Key[0], KeySplitCharacter, ' '.join(Dictionary[Key[0]]))
else:
Line = '%-*s %c %s\n' % (MaxLength, Key[0], KeySplitCharacter, Dictionary[Key[0]])
Lines.pop(Index)
if Key[0] in Keys:
Lines.insert(Index,Line)
Keys.remove(Key[0])
Index += 1
for RemainingKey in Keys:
if ValueSplitFlag:
Line = '%-*s %c %s\n' % (MaxLength, RemainingKey, KeySplitCharacter,' '.join(Dictionary[RemainingKey]))
else:
Line = '%-*s %c %s\n' % (MaxLength, RemainingKey, KeySplitCharacter, Dictionary[RemainingKey])
Lines.append(Line)
try:
F = open(FileName,'w')
except:
return False
F.writelines(Lines)
F.close()
return True
## Create a new directory
#
# @param Directory: Directory to be created
#
def CreateDirectory(Directory):
if not os.access(Directory, os.F_OK):
os.makedirs (Directory)
## Create a new file
#
# @param Directory: Directory to be created
# @param FileName: Filename to be created
# @param Mode: The mode of open file, defautl is 'w'
#
def CreateFile(Directory, FileName, Mode='w'):
CreateDirectory (Directory)
return open(os.path.join(Directory, FileName), Mode)
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
# Nothing to do here. Could do some unit tests
pass

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,269 @@
## @file
# This file implements the log mechanism for Python tools.
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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
import sys, os, logging
import traceback
from BuildToolError import *
## Log level constants
DEBUG_0 = 1
DEBUG_1 = 2
DEBUG_2 = 3
DEBUG_3 = 4
DEBUG_4 = 5
DEBUG_5 = 6
DEBUG_6 = 7
DEBUG_7 = 8
DEBUG_8 = 9
DEBUG_9 = 10
VERBOSE = 15
INFO = 20
WARN = 30
QUIET = 40
ERROR = 50
IsRaiseError = True
# Tool name
_ToolName = os.path.basename(sys.argv[0])
# For validation purpose
_LogLevels = [DEBUG_0, DEBUG_1, DEBUG_2, DEBUG_3, DEBUG_4, DEBUG_5, DEBUG_6, DEBUG_7, DEBUG_8, DEBUG_9, VERBOSE, WARN, INFO, ERROR, QUIET]
# For DEBUG level (All DEBUG_0~9 are applicable)
_DebugLogger = logging.getLogger("tool_debug")
_DebugFormatter = logging.Formatter("[%(asctime)s.%(msecs)d]: %(message)s", datefmt="%H:%M:%S")
# For VERBOSE, INFO, WARN level
_InfoLogger = logging.getLogger("tool_info")
_InfoFormatter = logging.Formatter("%(message)s")
# For ERROR level
_ErrorLogger = logging.getLogger("tool_error")
_ErrorFormatter = logging.Formatter("%(message)s")
# String templates for ERROR/WARN/DEBUG log message
_ErrorMessageTemplate = '\n\n%(tool)s...\n%(file)s(%(line)s): error %(errorcode)04X: %(msg)s\n\t%(extra)s'
_ErrorMessageTemplateWithoutFile = '\n\n%(tool)s...\n : error %(errorcode)04X: %(msg)s\n\t%(extra)s'
_WarningMessageTemplate = '%(tool)s...\n%(file)s(%(line)s): warning: %(msg)s'
_WarningMessageTemplateWithoutFile = '%(tool)s: : warning: %(msg)s'
_DebugMessageTemplate = '%(file)s(%(line)s): debug: \n %(msg)s'
#
# Flag used to take WARN as ERROR.
# By default, only ERROR message will break the tools execution.
#
_WarningAsError = False
## Log debug message
#
# @param Level DEBUG level (DEBUG0~9)
# @param Message Debug information
# @param ExtraData More information associated with "Message"
#
def debug(Level, Message, ExtraData=None):
if _DebugLogger.level > Level:
return
if Level > DEBUG_9:
return
# Find out the caller method information
CallerStack = traceback.extract_stack()[-2]
TemplateDict = {
"file" : CallerStack[0],
"line" : CallerStack[1],
"msg" : Message,
}
if ExtraData != None:
LogText = _DebugMessageTemplate % TemplateDict + "\n %s" % ExtraData
else:
LogText = _DebugMessageTemplate % TemplateDict
_DebugLogger.log(Level, LogText)
## Log verbose message
#
# @param Message Verbose information
#
def verbose(Message):
return _InfoLogger.log(VERBOSE, Message)
## Log warning message
#
# Warning messages are those which might be wrong but won't fail the tool.
#
# @param ToolName The name of the tool. If not given, the name of caller
# method will be used.
# @param Message Warning information
# @param File The name of file which caused the warning.
# @param Line The line number in the "File" which caused the warning.
# @param ExtraData More information associated with "Message"
#
def warn(ToolName, Message, File=None, Line=None, ExtraData=None):
if _InfoLogger.level > WARN:
return
# if no tool name given, use caller's source file name as tool name
if ToolName == None or ToolName == "":
ToolName = os.path.basename(traceback.extract_stack()[-2][0])
if Line == None:
Line = "..."
else:
Line = "%d" % Line
TemplateDict = {
"tool" : ToolName,
"file" : File,
"line" : Line,
"msg" : Message,
}
if File != None:
LogText = _WarningMessageTemplate % TemplateDict
else:
LogText = _WarningMessageTemplateWithoutFile % TemplateDict
if ExtraData != None:
LogText += "\n %s" % ExtraData
_InfoLogger.log(WARN, LogText)
# Raise an execption if indicated
if _WarningAsError == True:
raise FatalError(WARNING_AS_ERROR)
## Log INFO message
info = _InfoLogger.info
## Log ERROR message
#
# Once an error messages is logged, the tool's execution will be broken by raising
# an execption. If you don't want to break the execution later, you can give
# "RaiseError" with "False" value.
#
# @param ToolName The name of the tool. If not given, the name of caller
# method will be used.
# @param ErrorCode The error code
# @param Message Warning information
# @param File The name of file which caused the error.
# @param Line The line number in the "File" which caused the warning.
# @param ExtraData More information associated with "Message"
# @param RaiseError Raise an exception to break the tool's executuion if
# it's True. This is the default behavior.
#
def error(ToolName, ErrorCode, Message=None, File=None, Line=None, ExtraData=None, RaiseError=IsRaiseError):
if Line == None:
Line = "..."
else:
Line = "%d" % Line
if Message == None:
if ErrorCode in gErrorMessage:
Message = gErrorMessage[ErrorCode]
else:
Message = gErrorMessage[UNKNOWN_ERROR]
if ExtraData == None:
ExtraData = ""
TemplateDict = {
"tool" : _ToolName,
"file" : File,
"line" : Line,
"errorcode" : ErrorCode,
"msg" : Message,
"extra" : ExtraData
}
if File != None:
LogText = _ErrorMessageTemplate % TemplateDict
else:
LogText = _ErrorMessageTemplateWithoutFile % TemplateDict
_ErrorLogger.log(ERROR, LogText)
if RaiseError:
raise FatalError(ErrorCode)
# Log information which should be always put out
quiet = _ErrorLogger.error
## Initialize log system
def Initialize():
#
# Since we use different format to log different levels of message into different
# place (stdout or stderr), we have to use different "Logger" objects to do this.
#
# For DEBUG level (All DEBUG_0~9 are applicable)
_DebugLogger.setLevel(INFO)
_DebugChannel = logging.StreamHandler(sys.stdout)
_DebugChannel.setFormatter(_DebugFormatter)
_DebugLogger.addHandler(_DebugChannel)
# For VERBOSE, INFO, WARN level
_InfoLogger.setLevel(INFO)
_InfoChannel = logging.StreamHandler(sys.stdout)
_InfoChannel.setFormatter(_InfoFormatter)
_InfoLogger.addHandler(_InfoChannel)
# For ERROR level
_ErrorLogger.setLevel(INFO)
_ErrorCh = logging.StreamHandler(sys.stderr)
_ErrorCh.setFormatter(_ErrorFormatter)
_ErrorLogger.addHandler(_ErrorCh)
## Set log level
#
# @param Level One of log level in _LogLevel
def SetLevel(Level):
if Level not in _LogLevels:
info("Not supported log level (%d). Use default level instead." % Level)
Level = INFO
_DebugLogger.setLevel(Level)
_InfoLogger.setLevel(Level)
_ErrorLogger.setLevel(Level)
## Get current log level
def GetLevel():
return _InfoLogger.getEffectiveLevel()
## Raise up warning as error
def SetWarningAsError():
global _WarningAsError
_WarningAsError = True
## Specify a file to store the log message as well as put on console
#
# @param LogFile The file path used to store the log message
#
def SetLogFile(LogFile):
if os.path.exists(LogFile):
os.remove(LogFile)
_Ch = logging.FileHandler(LogFile)
_Ch.setFormatter(_DebugFormatter)
_DebugLogger.addHandler(_Ch)
_Ch= logging.FileHandler(LogFile)
_Ch.setFormatter(_InfoFormatter)
_InfoLogger.addHandler(_Ch)
_Ch = logging.FileHandler(LogFile)
_Ch.setFormatter(_ErrorFormatter)
_ErrorLogger.addHandler(_Ch)
if __name__ == '__main__':
pass

View File

@@ -0,0 +1,116 @@
## @file
# This file is used to define each component of FDF file
#
# Copyright (c) 2008, Intel Corporation
# All rights reserved. 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 FdfParserLite import FdfParser
from Table.TableFdf import TableFdf
from CommonDataClass.DataClass import MODEL_FILE_FDF, MODEL_PCD, MODEL_META_DATA_COMPONENT
from String import NormPath
## FdfObject
#
# This class defined basic Fdf object which is used by inheriting
#
# @param object: Inherited from object class
#
class FdfObject(object):
def __init__(self):
object.__init__()
## Fdf
#
# This class defined the structure used in Fdf object
#
# @param FdfObject: Inherited from FdfObject class
# @param Filename: Input value for Ffilename of Fdf file, default is None
# @param WorkspaceDir: Input value for current workspace directory, default is None
#
class Fdf(FdfObject):
def __init__(self, Filename = None, IsToDatabase = False, WorkspaceDir = None, Database = None):
self.WorkspaceDir = WorkspaceDir
self.IsToDatabase = IsToDatabase
self.Cur = Database.Cur
self.TblFile = Database.TblFile
self.TblFdf = Database.TblFdf
self.FileID = -1
self.FileList = {}
#
# Load Fdf file if filename is not None
#
if Filename != None:
self.LoadFdfFile(Filename)
#
# Insert a FDF file record into database
#
def InsertFile(self, Filename):
FileID = -1
Filename = NormPath(Filename)
if Filename not in self.FileList:
FileID = self.TblFile.InsertFile(Filename, MODEL_FILE_FDF)
self.FileList[Filename] = FileID
return self.FileList[Filename]
## Load Fdf file
#
# Load the file if it exists
#
# @param Filename: Input value for filename of Fdf file
#
def LoadFdfFile(self, Filename):
FileList = []
#
# Parse Fdf file
#
Filename = NormPath(Filename)
Fdf = FdfParser(Filename)
Fdf.ParseFile()
#
# Insert inf file and pcd information
#
if self.IsToDatabase:
(Model, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled) = \
(0, '', '', '', 'COMMON', -1, -1, -1, -1, -1, -1, 0)
for Index in range(0, len(Fdf.Profile.PcdDict)):
pass
for Key in Fdf.Profile.PcdDict.keys():
Model = MODEL_PCD
Value1 = ''
Value2 = ".".join((Key[1], Key[0]))
FileName = Fdf.Profile.PcdFileLineDict[Key][0]
StartLine = Fdf.Profile.PcdFileLineDict[Key][1]
BelongsToFile = self.InsertFile(FileName)
self.TblFdf.Insert(Model, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled)
for Index in range(0, len(Fdf.Profile.InfList)):
Model = MODEL_META_DATA_COMPONENT
Value1 = Fdf.Profile.InfList[Index]
Value2 = ''
FileName = Fdf.Profile.InfFileLineList[Index][0]
StartLine = Fdf.Profile.InfFileLineList[Index][1]
BelongsToFile = self.InsertFile(FileName)
self.TblFdf.Insert(Model, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled)
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
pass

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
## @file
# This file is used to define common static strings used by INF/DEC/DSC files
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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 re
gIsWindows = None
gEdkCompatibilityPkg = "EdkCompatibilityPkg"
gWorkspace = "."
gEdkSource = "EdkCompatibilityPkg"
gEfiSource = "."
gEcpSource = "EdkCompatibilityPkg"
gOptions = None
gCaseInsensitive = False
gGlobalDefines = {}
gAllFiles = None
gEdkGlobal = {}
gOverrideDir = {}
# for debug trace purpose when problem occurs
gProcessingFile = ''
gBuildingModule = ''
## Regular expression for matching macro used in DSC/DEC/INF file inclusion
gMacroPattern = re.compile("\$\(([_A-Z][_A-Z0-9]*)\)", re.UNICODE)

View File

@@ -0,0 +1,58 @@
## @file
# This file is used to define the identification of INF/DEC/DSC files
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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.
## Identification
#
# This class defined basic Identification information structure which is used by INF/DEC/DSC files
#
# @param object: Inherited from object class
#
# @var FileName: To store data for Filename
# @var FileFullPath: To store data for full path of the file
# @var FileRelativePath: To store data for relative path of the file
# @var RunStatus: Status of build system running
#
class Identification(object):
def __init__(self):
self.FileName = ''
self.FileFullPath = ''
self.FileRelativePath = ''
self.PackagePath = ''
## GetFileName
#
# Reserved
#
def GetFileName(self, FileFullPath, FileRelativePath):
pass
## GetFileName
#
# Reserved
#
def GetFileFullPath(self, FileName, FileRelativePath):
pass
## GetFileName
#
# Reserved
#
def GetFileRelativePath(self, FileName, FileFullPath):
pass
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
id = Identification()

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,876 @@
## @file
# This file is used to define each component of INF file
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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
#
import os
import re
import EdkLogger
from CommonDataClass.ModuleClass import *
from CommonDataClass import CommonClass
from String import *
from DataType import *
from BuildToolError import *
from Misc import sdict
from Misc import GetFiles
from Parsing import *
# Global variable
Section = {TAB_UNKNOWN.upper() : MODEL_UNKNOWN,
TAB_INF_DEFINES.upper() : MODEL_META_DATA_HEADER,
TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION,
TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,
TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE,
TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,
TAB_PACKAGES.upper() : MODEL_META_DATA_PACKAGE,
TAB_NMAKE.upper() : MODEL_META_DATA_NMAKE,
TAB_INF_FIXED_PCD.upper() : MODEL_PCD_FIXED_AT_BUILD,
TAB_INF_PATCH_PCD.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,
TAB_INF_FEATURE_PCD.upper() : MODEL_PCD_FEATURE_FLAG,
TAB_INF_PCD_EX.upper() : MODEL_PCD_DYNAMIC_EX,
TAB_INF_PCD.upper() : MODEL_PCD_DYNAMIC,
TAB_SOURCES.upper() : MODEL_EFI_SOURCE_FILE,
TAB_GUIDS.upper() : MODEL_EFI_GUID,
TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,
TAB_PPIS.upper() : MODEL_EFI_PPI,
TAB_DEPEX.upper() : MODEL_EFI_DEPEX,
TAB_BINARIES.upper() : MODEL_EFI_BINARY_FILE,
TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION
}
gComponentType2ModuleType = {
"LIBRARY" : "BASE",
"SECURITY_CORE" : "SEC",
"PEI_CORE" : "PEI_CORE",
"COMBINED_PEIM_DRIVER" : "PEIM",
"PIC_PEIM" : "PEIM",
"RELOCATABLE_PEIM" : "PEIM",
"PE32_PEIM" : "PEIM",
"BS_DRIVER" : "DXE_DRIVER",
"RT_DRIVER" : "DXE_RUNTIME_DRIVER",
"SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
"APPLICATION" : "UEFI_APPLICATION",
"LOGO" : "BASE",
}
class InfHeader(ModuleHeaderClass):
_Mapping_ = {
# Required Fields
TAB_INF_DEFINES_BASE_NAME : "Name",
TAB_INF_DEFINES_FILE_GUID : "Guid",
TAB_INF_DEFINES_MODULE_TYPE : "ModuleType",
TAB_INF_DEFINES_EFI_SPECIFICATION_VERSION : "EfiSpecificationVersion",
TAB_INF_DEFINES_EDK_RELEASE_VERSION : "EdkReleaseVersion",
# Optional Fields
TAB_INF_DEFINES_INF_VERSION : "InfVersion",
TAB_INF_DEFINES_BINARY_MODULE : "BinaryModule",
TAB_INF_DEFINES_COMPONENT_TYPE : "ComponentType",
TAB_INF_DEFINES_MAKEFILE_NAME : "MakefileName",
TAB_INF_DEFINES_BUILD_NUMBER : "BuildNumber",
TAB_INF_DEFINES_BUILD_TYPE : "BuildType",
TAB_INF_DEFINES_FFS_EXT : "FfsExt",
TAB_INF_DEFINES_FV_EXT : "FvExt",
TAB_INF_DEFINES_SOURCE_FV : "SourceFv",
TAB_INF_DEFINES_VERSION_NUMBER : "VersionNumber",
TAB_INF_DEFINES_VERSION_STRING : "VersionString",
TAB_INF_DEFINES_VERSION : "Version",
TAB_INF_DEFINES_PCD_IS_DRIVER : "PcdIsDriver",
TAB_INF_DEFINES_TIANO_R8_FLASHMAP_H : "TianoR8FlashMap_h",
TAB_INF_DEFINES_SHADOW : "Shadow",
}
def __init__(self):
ModuleHeaderClass.__init__(self)
self.VersionNumber = ''
self.VersionString = ''
#print self.__dict__
def __setitem__(self, key, value):
self.__dict__[self._Mapping_[key]] = value
def __getitem__(self, key):
return self.__dict__[self._Mapping_[key]]
## "in" test support
def __contains__(self, key):
return key in self._Mapping_
## InfObject
#
# This class defined basic Inf object which is used by inheriting
#
# @param object: Inherited from object class
#
class InfObject(object):
def __init__(self):
object.__init__()
## Inf
#
# This class defined the structure used in Inf object
#
# @param InfObject: Inherited from InfObject class
# @param Ffilename: Input value for Ffilename of Inf file, default is None
# @param IsMergeAllArches: Input value for IsMergeAllArches
# True is to merge all arches
# Fales is not to merge all arches
# default is False
# @param IsToModule: Input value for IsToModule
# True is to transfer to ModuleObject automatically
# False is not to transfer to ModuleObject automatically
# default is False
# @param WorkspaceDir: Input value for current workspace directory, default is None
#
# @var Identification: To store value for Identification, it is a structure as Identification
# @var UserExtensions: To store value for UserExtensions
# @var Module: To store value for Module, it is a structure as ModuleClass
# @var WorkspaceDir: To store value for WorkspaceDir
# @var KeyList: To store value for KeyList, a list for all Keys used in Inf
#
class Inf(InfObject):
def __init__(self, Filename = None, IsToModule = False, WorkspaceDir = None, PackageDir = None, SupArchList = DataType.ARCH_LIST):
self.Identification = IdentificationClass()
self.Module = ModuleClass()
self.WorkspaceDir = WorkspaceDir
self.PackageDir = PackageDir
self.SupArchList = SupArchList
self.KeyList = [
TAB_SOURCES, TAB_BUILD_OPTIONS, TAB_BINARIES, TAB_INCLUDES, TAB_GUIDS,
TAB_PROTOCOLS, TAB_PPIS, TAB_LIBRARY_CLASSES, TAB_PACKAGES, TAB_INF_FIXED_PCD,
TAB_INF_PATCH_PCD, TAB_INF_FEATURE_PCD, TAB_INF_PCD, TAB_INF_PCD_EX,
TAB_DEPEX, TAB_INF_DEFINES
]
# Upper all KEYs to ignore case sensitive when parsing
self.KeyList = map(lambda c: c.upper(), self.KeyList)
# Init RecordSet
self.RecordSet = {}
for Key in self.KeyList:
self.RecordSet[Section[Key]] = []
# Init Comment
self.SectionHeaderCommentDict = {}
# Load Inf file if filename is not None
if Filename != None:
self.LoadInfFile(Filename)
# Transfer to Module Object if IsToModule is True
if IsToModule:
self.InfToModule()
## Module Object to INF file
def ModuleToInf(self, Module):
Inf = ''
InfList = sdict()
SectionHeaderCommentDict = {}
if Module == None:
return Inf
ModuleHeader = Module.ModuleHeader
TmpList = []
# Common define items
if ModuleHeader.Name:
TmpList.append(TAB_INF_DEFINES_BASE_NAME + ' = ' + ModuleHeader.Name)
if ModuleHeader.Guid:
TmpList.append(TAB_INF_DEFINES_FILE_GUID + ' = ' + ModuleHeader.Guid)
if ModuleHeader.Version:
TmpList.append(TAB_INF_DEFINES_VERSION_STRING + ' = ' + ModuleHeader.Version)
if ModuleHeader.ModuleType:
TmpList.append(TAB_INF_DEFINES_MODULE_TYPE + ' = ' + ModuleHeader.ModuleType)
if ModuleHeader.PcdIsDriver:
TmpList.append(TAB_INF_DEFINES_PCD_IS_DRIVER + ' = ' + ModuleHeader.PcdIsDriver)
# Externs
for Item in Module.Externs:
if Item.EntryPoint:
TmpList.append(TAB_INF_DEFINES_ENTRY_POINT + ' = ' + Item.EntryPoint)
if Item.UnloadImage:
TmpList.append(TAB_INF_DEFINES_UNLOAD_IMAGE + ' = ' + Item.UnloadImage)
if Item.Constructor:
TmpList.append(TAB_INF_DEFINES_CONSTRUCTOR + ' = ' + Item.Constructor)
if Item.Destructor:
TmpList.append(TAB_INF_DEFINES_DESTRUCTOR + ' = ' + Item.Destructor)
# Other define items
if Module.UserExtensions != None:
for Item in Module.UserExtensions.Defines:
TmpList.append(Item)
InfList['Defines'] = TmpList
if ModuleHeader.Description != '':
SectionHeaderCommentDict['Defines'] = ModuleHeader.Description
if Module.UserExtensions != None:
InfList['BuildOptions'] = Module.UserExtensions.BuildOptions
for Item in Module.Includes:
Key = 'Includes.' + GetStringOfList(Item.SupArchList)
Value = GetHelpTextList(Item.HelpTextList)
Value.append(Item.FilePath)
GenMetaDatSectionItem(Key, Value, InfList)
for Item in Module.LibraryClasses:
Key = 'LibraryClasses.' + GetStringOfList(Item.SupArchList)
Value = GetHelpTextList(Item.HelpTextList)
NewValue = Item.LibraryClass
if Item.RecommendedInstance:
NewValue = NewValue + '|' + Item.RecommendedInstance
if Item.FeatureFlag:
NewValue = NewValue + '|' + Item.FeatureFlag
Value.append(NewValue)
GenMetaDatSectionItem(Key, Value, InfList)
for Item in Module.PackageDependencies:
Key = 'Packages.' + GetStringOfList(Item.SupArchList)
Value = GetHelpTextList(Item.HelpTextList)
Value.append(Item.FilePath)
GenMetaDatSectionItem(Key, Value, InfList)
for Item in Module.PcdCodes:
Key = 'Pcds' + Item.ItemType + '.' + GetStringOfList(Item.SupArchList)
Value = GetHelpTextList(Item.HelpTextList)
NewValue = Item.TokenSpaceGuidCName + '.' + Item.CName
if Item.DefaultValue != '':
NewValue = NewValue + '|' + Item.DefaultValue
Value.append(NewValue)
GenMetaDatSectionItem(Key, Value, InfList)
for Item in Module.Sources:
Key = 'Sources.' + GetStringOfList(Item.SupArchList)
Value = GetHelpTextList(Item.HelpTextList)
NewValue = Item.SourceFile
if Item.ToolChainFamily != '':
NewValue = NewValue + '|' + Item.ToolChainFamily
if Item.TagName != '':
NewValue = NewValue + '|' + Item.TagName
if Item.ToolCode != '':
NewValue = NewValue + '|' + Item.ToolCode
if Item.FeatureFlag != '':
NewValue = NewValue + '|' + Item.FeatureFlag
Value.append(NewValue)
if Item.HelpText != '':
SectionHeaderCommentDict[Key] = Item.HelpText
GenMetaDatSectionItem(Key, Value, InfList)
for Item in Module.Guids:
Key = 'Guids.' + GetStringOfList(Item.SupArchList)
Value = GetHelpTextList(Item.HelpTextList)
Value.append(Item.CName)
GenMetaDatSectionItem(Key, Value, InfList)
for Item in Module.Protocols:
Key = 'Protocols.' + GetStringOfList(Item.SupArchList)
Value = GetHelpTextList(Item.HelpTextList)
Value.append(Item.CName)
GenMetaDatSectionItem(Key, Value, InfList)
for Item in Module.Ppis:
Key = 'Ppis.' + GetStringOfList(Item.SupArchList)
Value = GetHelpTextList(Item.HelpTextList)
Value.append(Item.CName)
GenMetaDatSectionItem(Key, Value, InfList)
if Module.PeiDepex:
Key = 'Depex'
Value = Module.PeiDepex.Depex
GenMetaDatSectionItem(Key, Value, InfList)
if Module.DxeDepex:
Key = 'Depex'
Value = Module.DxeDepex.Depex
GenMetaDatSectionItem(Key, Value, InfList)
if Module.SmmDepex:
Key = 'Depex'
Value = Module.SmmDepex.Depex
GenMetaDatSectionItem(Key, Value, InfList)
for Item in Module.Binaries:
Key = 'Binaries.' + GetStringOfList(Item.SupArchList)
Value = GetHelpTextList(Item.HelpTextList)
NewValue = Item.FileType + '|' + Item.BinaryFile + '|' + Item.Target
if Item.FeatureFlag != '':
NewValue = NewValue + '|' + Item.FeatureFlag
Value.append(NewValue)
GenMetaDatSectionItem(Key, Value, InfList)
# Transfer Module to Inf
for Key in InfList:
if Key in SectionHeaderCommentDict:
List = SectionHeaderCommentDict[Key].split('\r')
for Item in List:
Inf = Inf + Item + '\n'
Inf = Inf + '[' + Key + ']' + '\n'
for Value in InfList[Key]:
if type(Value) == type([]):
for SubValue in Value:
Inf = Inf + ' ' + SubValue + '\n'
else:
Inf = Inf + ' ' + Value + '\n'
Inf = Inf + '\n'
return Inf
## Transfer to Module Object
#
# Transfer all contents of an Inf file to a standard Module Object
#
def InfToModule(self):
# Init global information for the file
ContainerFile = self.Identification.FullPath
# Generate Module Header
self.GenModuleHeader(ContainerFile)
# Generate BuildOptions
self.GenBuildOptions(ContainerFile)
# Generate Includes
self.GenIncludes(ContainerFile)
# Generate LibraryClasses
self.GenLibraryClasses(ContainerFile)
# Generate Packages
self.GenPackages(ContainerFile)
# Generate Pcds
self.GenPcds(ContainerFile)
# Generate Sources
self.GenSources(ContainerFile)
# Generate Guids
self.GenGuidProtocolPpis(DataType.TAB_GUIDS, ContainerFile)
# Generate Protocols
self.GenGuidProtocolPpis(DataType.TAB_PROTOCOLS, ContainerFile)
# Generate Ppis
self.GenGuidProtocolPpis(DataType.TAB_PPIS, ContainerFile)
# Generate Depexes
self.GenDepexes(ContainerFile)
# Generate Binaries
self.GenBinaries(ContainerFile)
# Init MiscFiles
self.GenMiscFiles(ContainerFile)
## GenMiscFiles
#
def GenMiscFiles(self, ContainerFile):
MiscFiles = MiscFileClass()
MiscFiles.Name = 'ModuleFiles'
for Item in GetFiles(os.path.dirname(ContainerFile), ['CVS', '.svn'], False):
File = CommonClass.FileClass()
File.Filename = Item
MiscFiles.Files.append(File)
self.Module.MiscFiles = MiscFiles
## Load Inf file
#
# Load the file if it exists
#
# @param Filename: Input value for filename of Inf file
#
def LoadInfFile(self, Filename):
# Insert a record for file
Filename = NormPath(Filename)
self.Identification.FullPath = Filename
(self.Identification.RelaPath, self.Identification.FileName) = os.path.split(Filename)
if self.Identification.FullPath.find(self.WorkspaceDir) > -1:
self.Identification.ModulePath = os.path.dirname(self.Identification.FullPath[len(self.WorkspaceDir) + 1:])
if self.PackageDir:
self.Identification.PackagePath = self.PackageDir
if self.Identification.ModulePath.find(self.PackageDir) == 0:
self.Identification.ModulePath = self.Identification.ModulePath[len(self.PackageDir) + 1:]
# Init common datas
IfDefList, SectionItemList, CurrentSection, ArchList, ThirdList, IncludeFiles = \
[], [], TAB_UNKNOWN, [], [], []
LineNo = 0
# Parse file content
IsFindBlockComment = False
ReservedLine = ''
Comment = ''
for Line in open(Filename, 'r'):
LineNo = LineNo + 1
# Remove comment block
if Line.find(TAB_COMMENT_R8_START) > -1:
ReservedLine = GetSplitValueList(Line, TAB_COMMENT_R8_START, 1)[0]
if ReservedLine.strip().startswith(TAB_COMMENT_SPLIT):
Comment = Comment + Line.strip() + '\n'
ReservedLine = ''
else:
Comment = Comment + Line[len(ReservedLine):] + '\n'
IsFindBlockComment = True
if not ReservedLine:
continue
if Line.find(TAB_COMMENT_R8_END) > -1:
Comment = Comment + Line[:Line.find(TAB_COMMENT_R8_END) + len(TAB_COMMENT_R8_END)] + '\n'
Line = ReservedLine + GetSplitValueList(Line, TAB_COMMENT_R8_END, 1)[1]
ReservedLine = ''
IsFindBlockComment = False
if IsFindBlockComment:
Comment = Comment + Line.strip() + '\n'
continue
# Remove comments at tail and remove spaces again
if Line.strip().startswith(TAB_COMMENT_SPLIT) or Line.strip().startswith('--/'):
Comment = Comment + Line.strip() + '\n'
Line = CleanString(Line)
if Line == '':
continue
## Find a new section tab
# First insert previous section items
# And then parse the content of the new section
if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END):
if Line[1:3] == "--":
continue
Model = Section[CurrentSection.upper()]
# Insert items data of previous section
InsertSectionItems(Model, CurrentSection, SectionItemList, ArchList, ThirdList, self.RecordSet)
# Parse the new section
SectionItemList = []
ArchList = []
ThirdList = []
CurrentSection = ''
LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT)
for Item in LineList:
ItemList = GetSplitValueList(Item, TAB_SPLIT)
if CurrentSection == '':
CurrentSection = ItemList[0]
else:
if CurrentSection != ItemList[0]:
EdkLogger.error("Parser", PARSER_ERROR, "Different section names '%s' and '%s' are found in one section definition, this is not allowed." % (CurrentSection, ItemList[0]), File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError)
if CurrentSection.upper() not in self.KeyList:
RaiseParserError(Line, CurrentSection, Filename, '', LineNo)
ItemList.append('')
ItemList.append('')
if len(ItemList) > 5:
RaiseParserError(Line, CurrentSection, Filename, '', LineNo)
else:
if ItemList[1] != '' and ItemList[1].upper() not in ARCH_LIST_FULL:
EdkLogger.error("Parser", PARSER_ERROR, "Invalid Arch definition '%s' found" % ItemList[1], File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError)
ArchList.append(ItemList[1].upper())
ThirdList.append(ItemList[2])
if Comment:
if Comment.endswith('\n'):
Comment = Comment[:len(Comment) - len('\n')]
self.SectionHeaderCommentDict[Section[CurrentSection.upper()]] = Comment
Comment = ''
continue
# Not in any defined section
if CurrentSection == TAB_UNKNOWN:
ErrorMsg = "%s is not in any defined section" % Line
EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError)
# Add a section item
SectionItemList.append([Line, LineNo, Comment])
Comment = ''
# End of parse
#End of For
# Insert items data of last section
Model = Section[CurrentSection.upper()]
InsertSectionItems(Model, CurrentSection, SectionItemList, ArchList, ThirdList, self.RecordSet)
if Comment != '':
self.SectionHeaderCommentDict[Model] = Comment
Comment = ''
## Show detailed information of Module
#
# Print all members and their values of Module class
#
def ShowModule(self):
M = self.Module
print 'Filename =', M.ModuleHeader.FileName
print 'FullPath =', M.ModuleHeader.FullPath
print 'RelaPath =', M.ModuleHeader.RelaPath
print 'PackagePath =', M.ModuleHeader.PackagePath
print 'ModulePath =', M.ModuleHeader.ModulePath
print 'CombinePath =', M.ModuleHeader.CombinePath
print 'BaseName =', M.ModuleHeader.Name
print 'Guid =', M.ModuleHeader.Guid
print 'Version =', M.ModuleHeader.Version
print '\nIncludes ='
for Item in M.Includes:
print Item.FilePath, Item.SupArchList
print '\nLibraryClasses ='
for Item in M.LibraryClasses:
print Item.LibraryClass, Item.RecommendedInstance, Item.RecommendedInstanceGuid, Item.RecommendedInstanceVersion, Item.FeatureFlag, Item.SupModuleList, Item.SupArchList, Item.Define
print '\nPackageDependencies ='
for Item in M.PackageDependencies:
print Item.FilePath, Item.SupArchList, Item.FeatureFlag
print '\nPcds ='
for Item in M.PcdCodes:
print '\tCName=',Item.CName, 'TokenSpaceGuidCName=', Item.TokenSpaceGuidCName, 'DefaultValue=', Item.DefaultValue, 'ItemType=', Item.ItemType, Item.SupArchList
print '\nSources ='
for Source in M.Sources:
print Source.SourceFile, 'Fam=', Source.ToolChainFamily, 'Pcd=', Source.FeatureFlag, 'Tag=', Source.TagName, 'ToolCode=', Source.ToolCode, Source.SupArchList
print '\nGuids ='
for Item in M.Guids:
print Item.CName, Item.SupArchList, Item.FeatureFlag
print '\nProtocols ='
for Item in M.Protocols:
print Item.CName, Item.SupArchList, Item.FeatureFlag
print '\nPpis ='
for Item in M.Ppis:
print Item.CName, Item.SupArchList, Item.FeatureFlag
print '\nDepex ='
for Item in M.Depex:
print Item.Depex, Item.SupArchList, Item.Define
print '\nBinaries ='
for Binary in M.Binaries:
print 'Type=', Binary.FileType, 'Target=', Binary.Target, 'Name=', Binary.BinaryFile, 'FeatureFlag=', Binary.FeatureFlag, 'SupArchList=', Binary.SupArchList
print '\n*** FileList ***'
for Item in M.MiscFiles.Files:
print Item.Filename
print '****************\n'
## Convert [Defines] section content to ModuleHeaderClass
#
# Convert [Defines] section content to ModuleHeaderClass
#
# @param Defines The content under [Defines] section
# @param ModuleHeader An object of ModuleHeaderClass
# @param Arch The supported ARCH
#
def GenModuleHeader(self, ContainerFile):
EdkLogger.debug(2, "Generate ModuleHeader ...")
# Update all defines item in database
RecordSet = self.RecordSet[MODEL_META_DATA_HEADER]
ModuleHeader = ModuleHeaderClass()
ModuleExtern = ModuleExternClass()
OtherDefines = []
for Record in RecordSet:
ValueList = GetSplitValueList(Record[0], TAB_EQUAL_SPLIT)
if len(ValueList) != 2:
OtherDefines.append(Record[0])
else:
Name = ValueList[0]
Value = ValueList[1]
if Name == TAB_INF_DEFINES_BASE_NAME:
ModuleHeader.Name = Value
ModuleHeader.BaseName = Value
elif Name == TAB_INF_DEFINES_FILE_GUID:
ModuleHeader.Guid = Value
elif Name == TAB_INF_DEFINES_VERSION_STRING:
ModuleHeader.Version = Value
elif Name == TAB_INF_DEFINES_PCD_IS_DRIVER:
ModuleHeader.PcdIsDriver = Value
elif Name == TAB_INF_DEFINES_MODULE_TYPE:
ModuleHeader.ModuleType = Value
elif Name == TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION:
ModuleHeader.UefiSpecificationVersion = Value
elif Name == TAB_INF_DEFINES_PI_SPECIFICATION_VERSION:
ModuleHeader.PiSpecificationVersion = Value
elif Name == TAB_INF_DEFINES_ENTRY_POINT:
ModuleExtern.EntryPoint = Value
elif Name == TAB_INF_DEFINES_UNLOAD_IMAGE:
ModuleExtern.UnloadImage = Value
elif Name == TAB_INF_DEFINES_CONSTRUCTOR:
ModuleExtern.Constructor = Value
elif Name == TAB_INF_DEFINES_DESTRUCTOR:
ModuleExtern.Destructor = Value
else:
OtherDefines.append(Record[0])
ModuleHeader.FileName = self.Identification.FileName
ModuleHeader.FullPath = self.Identification.FullPath
ModuleHeader.RelaPath = self.Identification.RelaPath
ModuleHeader.PackagePath = self.Identification.PackagePath
ModuleHeader.ModulePath = self.Identification.ModulePath
ModuleHeader.CombinePath = os.path.normpath(os.path.join(ModuleHeader.PackagePath, ModuleHeader.ModulePath, ModuleHeader.FileName))
if MODEL_META_DATA_HEADER in self.SectionHeaderCommentDict:
ModuleHeader.Description = self.SectionHeaderCommentDict[MODEL_META_DATA_HEADER]
self.Module.ModuleHeader = ModuleHeader
self.Module.Externs.append(ModuleExtern)
UE = self.Module.UserExtensions
if UE == None:
UE = UserExtensionsClass()
UE.Defines = OtherDefines
self.Module.UserExtensions = UE
## GenBuildOptions
#
# Gen BuildOptions of Inf
# [<Family>:]<ToolFlag>=Flag
#
# @param ContainerFile: The Inf file full path
#
def GenBuildOptions(self, ContainerFile):
EdkLogger.debug(2, "Generate %s ..." % TAB_BUILD_OPTIONS)
BuildOptions = {}
# Get all BuildOptions
RecordSet = self.RecordSet[MODEL_META_DATA_BUILD_OPTION]
UE = self.Module.UserExtensions
if UE == None:
UE = UserExtensionsClass()
for Record in RecordSet:
UE.BuildOptions.append(Record[0])
self.Module.UserExtensions = UE
## GenIncludes
#
# Gen Includes of Inf
#
# @param ContainerFile: The Inf file full path
#
def GenIncludes(self, ContainerFile):
EdkLogger.debug(2, "Generate %s ..." % TAB_INCLUDES)
Includes = sdict()
# Get all Includes
RecordSet = self.RecordSet[MODEL_EFI_INCLUDE]
for Record in RecordSet:
Include = IncludeClass()
Include.FilePath = Record[0]
Include.SupArchList = Record[1]
if GenerateHelpText(Record[5], ''):
Include.HelpTextList.append(GenerateHelpText(Record[5], ''))
self.Module.Includes.append(Include)
#self.Module.FileList.extend(GetFiles(os.path.normpath(os.path.join(self.Identification.FileRelativePath, Include.FilePath)), ['CVS', '.svn']))
## GenLibraryClasses
#
# Get LibraryClass of Inf
# <LibraryClassKeyWord>|<LibraryInstance>
#
# @param ContainerFile: The Inf file full path
#
def GenLibraryClasses(self, ContainerFile):
EdkLogger.debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES)
LibraryClasses = {}
# Get all LibraryClasses
RecordSet = self.RecordSet[MODEL_EFI_LIBRARY_CLASS]
for Record in RecordSet:
(LibClassName, LibClassIns, Pcd, SupModelList) = GetLibraryClassOfInf([Record[0], Record[4]], ContainerFile, self.WorkspaceDir, Record[2])
LibraryClass = CommonClass.LibraryClassClass()
LibraryClass.LibraryClass = LibClassName
LibraryClass.RecommendedInstance = LibClassIns
LibraryClass.FeatureFlag = Pcd
LibraryClass.SupArchList = Record[1]
LibraryClass.SupModuleList = Record[4]
if GenerateHelpText(Record[5], ''):
LibraryClass.HelpTextList.append(GenerateHelpText(Record[5], ''))
self.Module.LibraryClasses.append(LibraryClass)
## GenPackages
#
# Gen Packages of Inf
#
# @param ContainerFile: The Inf file full path
#
def GenPackages(self, ContainerFile):
EdkLogger.debug(2, "Generate %s ..." % TAB_PACKAGES)
Packages = {}
# Get all Packages
RecordSet = self.RecordSet[MODEL_META_DATA_PACKAGE]
for Record in RecordSet:
(PackagePath, Pcd) = GetPackage(Record[0], ContainerFile, self.WorkspaceDir, Record[2])
Package = ModulePackageDependencyClass()
Package.FilePath = NormPath(PackagePath)
Package.SupArchList = Record[1]
Package.FeatureFlag = Pcd
if GenerateHelpText(Record[5], ''):
Package.HelpTextList.append(GenerateHelpText(Record[5], ''))
self.Module.PackageDependencies.append(Package)
def AddPcd(self, CName, TokenSpaceGuidCName, DefaultValue, ItemType, Arch, HelpTextList):
Pcd = PcdClass()
Pcd.CName = CName
Pcd.TokenSpaceGuidCName = TokenSpaceGuidCName
Pcd.DefaultValue = DefaultValue
Pcd.ItemType = ItemType
Pcd.SupArchList = Arch
if GenerateHelpText(HelpTextList, ''):
Pcd.HelpTextList.append(GenerateHelpText(HelpTextList, ''))
self.Module.PcdCodes.append(Pcd)
## GenPcds
#
# Gen Pcds of Inf
# <TokenSpaceGuidCName>.<PcdCName>[|<Value>]
#
# @param ContainerFile: The Dec file full path
#
def GenPcds(self, ContainerFile):
EdkLogger.debug(2, "Generate %s ..." % TAB_PCDS)
Pcds = {}
PcdToken = {}
# Get all Pcds
RecordSet1 = self.RecordSet[MODEL_PCD_FIXED_AT_BUILD]
RecordSet2 = self.RecordSet[MODEL_PCD_PATCHABLE_IN_MODULE]
RecordSet3 = self.RecordSet[MODEL_PCD_FEATURE_FLAG]
RecordSet4 = self.RecordSet[MODEL_PCD_DYNAMIC_EX]
RecordSet5 = self.RecordSet[MODEL_PCD_DYNAMIC]
# Go through each arch
for Record in RecordSet1:
(TokenSpaceGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], TAB_PCDS_FIXED_AT_BUILD, ContainerFile, Record[2])
self.AddPcd(TokenName, TokenSpaceGuidCName, Value, Type, Record[1], Record[5])
for Record in RecordSet2:
(TokenSpaceGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], TAB_PCDS_PATCHABLE_IN_MODULE, ContainerFile, Record[2])
self.AddPcd(TokenName, TokenSpaceGuidCName, Value, Type, Record[1], Record[5])
for Record in RecordSet3:
(TokenSpaceGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], TAB_PCDS_FEATURE_FLAG, ContainerFile, Record[2])
self.AddPcd(TokenName, TokenSpaceGuidCName, Value, Type, Record[1], Record[5])
for Record in RecordSet4:
(TokenSpaceGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], TAB_PCDS_DYNAMIC_EX, ContainerFile, Record[2])
self.AddPcd(TokenName, TokenSpaceGuidCName, Value, Type, Record[1], Record[5])
for Record in RecordSet5:
(TokenSpaceGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], '', ContainerFile, Record[2])
self.AddPcd(TokenName, TokenSpaceGuidCName, Value, Type, Record[1], Record[5])
## GenSources
#
# Gen Sources of Inf
# <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
#
# @param ContainerFile: The Dec file full path
#
def GenSources(self, ContainerFile):
EdkLogger.debug(2, "Generate %s ..." % TAB_SOURCES)
Sources = {}
# Get all Sources
RecordSet = self.RecordSet[MODEL_EFI_SOURCE_FILE]
for Record in RecordSet:
(Filename, Family, TagName, ToolCode, Pcd) = GetSource(Record[0], ContainerFile, self.Identification.RelaPath, Record[2])
Source = ModuleSourceFileClass(Filename, TagName, ToolCode, Family, Pcd, Record[1])
if GenerateHelpText(Record[5], ''):
Source.HelpTextList.append(GenerateHelpText(Record[5], ''))
if MODEL_EFI_SOURCE_FILE in self.SectionHeaderCommentDict:
Source.HelpText = self.SectionHeaderCommentDict[MODEL_EFI_SOURCE_FILE]
self.Module.Sources.append(Source)
#self.Module.FileList.append(os.path.normpath(os.path.join(self.Identification.RelaPath, Filename)))
## GenDepexes
#
# Gen Depex of Inf
#
# @param ContainerFile: The Inf file full path
#
def GenDepexes(self, ContainerFile):
EdkLogger.debug(2, "Generate %s ..." % TAB_DEPEX)
Depex = {}
# Get all Depexes
RecordSet = self.RecordSet[MODEL_EFI_DEPEX]
DepexString = ''
for Record in RecordSet:
DepexString = DepexString + Record[0] + '\n'
Dep = ModuleDepexClass()
if DepexString.endswith('\n'):
DepexString = DepexString[:len(DepexString) - len('\n')]
Dep.Depex = DepexString
if self.Module.ModuleHeader.ModuleType in ['DXE_SMM_DRIVER']:
self.Module.SmmDepex = Dep
elif self.Module.ModuleHeader.ModuleType in ['PEI_CORE', 'PEIM']:
self.Module.PeiDepex = Dep
else:
self.Module.DxeDepex = Dep
# for Record in RecordSet:
#
# Dep = ModuleDepexClass()
# Dep.Depex = Record[0]
# Dep.SupArchList = Record[1]
# if GenerateHelpText(Record[5], ''):
# Dep.HelpTextList.append(GenerateHelpText(Record[5], ''))
# DepexString = DepexString + Dep
# List.append(Dep)
# self.Module.Depex = List
# if self.Module.ModuleHeader.ModuleType in ['DXE_SMM_DRIVER']:
# self.Module.SmmDepex = List
# elif self.Module.ModuleHeader.ModuleType in ['PEI_CORE', 'PEIM']:
# self.Module.PeiDepex = List
# else:
# self.Module.DxeDepex = List
## GenBinaries
#
# Gen Binary of Inf
# <FileType>|<Filename>|<Target>[|<TokenSpaceGuidCName>.<PcdCName>]
#
# @param ContainerFile: The Dec file full path
#
def GenBinaries(self, ContainerFile):
EdkLogger.debug(2, "Generate %s ..." % TAB_BINARIES)
Binaries = {}
# Get all Guids
RecordSet = self.RecordSet[MODEL_EFI_BINARY_FILE]
for Record in RecordSet:
(FileType, Filename, Target, Pcd) = GetBinary(Record[0], ContainerFile, self.Identification.RelaPath, Record[2])
Binary = ModuleBinaryFileClass(Filename, FileType, Target, Pcd, Record[1])
if GenerateHelpText(Record[5], ''):
Binary.HelpTextList.append(GenerateHelpText(Record[5], ''))
self.Module.Binaries.append(Binary)
#self.Module.FileList.append(os.path.normpath(os.path.join(self.Identification.RelaPath, Filename)))
## GenGuids
#
# Gen Guids of Inf
# <CName>=<GuidValue>
#
# @param ContainerFile: The Inf file full path
#
def GenGuidProtocolPpis(self, Type, ContainerFile):
EdkLogger.debug(2, "Generate %s ..." % Type)
Lists = {}
# Get all Items
if Type == TAB_GUIDS:
ListMember = self.Module.Guids
elif Type == TAB_PROTOCOLS:
ListMember = self.Module.Protocols
elif Type == TAB_PPIS:
ListMember = self.Module.Ppis
RecordSet = self.RecordSet[Section[Type.upper()]]
for Record in RecordSet:
(Name, Value) = GetGuidsProtocolsPpisOfInf(Record[0], Type, ContainerFile, Record[2])
ListClass = GuidProtocolPpiCommonClass()
ListClass.CName = Name
ListClass.SupArchList = Record[1]
ListClass.FeatureFlag = Value
if GenerateHelpText(Record[5], ''):
ListClass.HelpTextList.append(GenerateHelpText(Record[5], ''))
ListMember.append(ListClass)
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
EdkLogger.Initialize()
EdkLogger.SetLevel(EdkLogger.QUIET)
W = os.getenv('WORKSPACE')
F = os.path.join(W, 'MdeModulePkg/Application/HelloWorld/HelloWorld.inf')
P = Inf(os.path.normpath(F), True, W, 'MdeModulePkg')
P.ShowModule()
print P.ModuleToInf(P.Module)

View File

@@ -0,0 +1,567 @@
## @file
# Contains several utilitities shared by migration tools.
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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
#
import os
import re
import EdkLogger
from optparse import OptionParser
from Common.BuildToolError import *
from XmlRoutines import *
from CommonDataClass.CommonClass import *
## Set all fields of CommonClass object.
#
# Set all attributes of CommonClass object from XML Dom object of XmlCommon.
#
# @param Common The destine CommonClass object.
# @param XmlCommon The source XML Dom object.
#
def SetCommon(Common, XmlCommon):
XmlTag = "Usage"
Common.Usage = XmlAttribute(XmlCommon, XmlTag).split()
XmlTag = "FeatureFlag"
Common.FeatureFlag = XmlAttribute(XmlCommon, XmlTag)
XmlTag = "SupArchList"
Common.SupArchList = XmlAttribute(XmlCommon, XmlTag).split()
XmlTag = XmlNodeName(XmlCommon) + "/" + "HelpText"
Common.HelpText = XmlElement(XmlCommon, XmlTag)
## Set some fields of CommonHeaderClass object.
#
# Set Name, Guid, FileName and FullPath fields of CommonHeaderClass object from
# XML Dom object of XmlCommonHeader, NameTag and FileName.
#
# @param CommonHeader The destine CommonClass object.
# @param XmlCommonHeader The source XML Dom object.
# @param NameTag The name tag in XML Dom object.
# @param FileName The file name of the XML file.
#
def SetIdentification(CommonHeader, XmlCommonHeader, NameTag, FileName):
XmlParentTag = XmlNodeName(XmlCommonHeader)
XmlTag = XmlParentTag + "/" + NameTag
CommonHeader.Name = XmlElement(XmlCommonHeader, XmlTag)
XmlTag = XmlParentTag + "/" + "GuidValue"
CommonHeader.Guid = XmlElement(XmlCommonHeader, XmlTag)
XmlTag = XmlParentTag + "/" + "Version"
CommonHeader.Version = XmlElement(XmlCommonHeader, XmlTag)
CommonHeader.FileName = os.path.basename(FileName)
CommonHeader.FullPath = os.path.abspath(FileName)
## Regular expression to match specification and value.
mReSpecification = re.compile(r"(?P<Specification>\w+)\s+(?P<Value>\w*)")
## Add specification to specification dictionary.
#
# Abstract specification name, value pair from Specification String and add them
# to specification dictionary.
#
# @param SpecificationDict The destine Specification dictionary.
# @param SpecificationString The source Specification String from which the
# specification name and value pair is abstracted.
#
def AddToSpecificationDict(SpecificationDict, SpecificationString):
"""Abstract specification name, value pair from Specification String"""
for SpecificationMatch in mReSpecification.finditer(SpecificationString):
Specification = SpecificationMatch.group("Specification")
Value = SpecificationMatch.group("Value")
SpecificationDict[Specification] = Value
## Set all fields of CommonHeaderClass object.
#
# Set all attributes of CommonHeaderClass object from XML Dom object of
# XmlCommonHeader, NameTag and FileName.
#
# @param CommonHeader The destine CommonClass object.
# @param XmlCommonHeader The source XML Dom object.
# @param NameTag The name tag in XML Dom object.
# @param FileName The file name of the XML file.
#
def SetCommonHeader(CommonHeader, XmlCommonHeader):
"""Set all attributes of CommonHeaderClass object from XmlCommonHeader"""
XmlParent = XmlNodeName(XmlCommonHeader)
XmlTag = XmlParent + "/" + "Abstract"
CommonHeader.Abstract = XmlElement(XmlCommonHeader, XmlTag)
XmlTag = XmlParent + "/" + "Description"
CommonHeader.Description = XmlElement(XmlCommonHeader, XmlTag)
XmlTag = XmlParent + "/" + "Copyright"
CommonHeader.Copyright = XmlElement(XmlCommonHeader, XmlTag)
XmlTag = XmlParent + "/" + "License"
CommonHeader.License = XmlElement(XmlCommonHeader, XmlTag)
XmlTag = XmlParent + "/" + "Specification"
Specification = XmlElement(XmlCommonHeader, XmlTag)
AddToSpecificationDict(CommonHeader.Specification, Specification)
XmlTag = XmlParent + "/" + "ModuleType"
CommonHeader.ModuleType = XmlElement(XmlCommonHeader, XmlTag)
## Load a new Cloned Record class object.
#
# Read an input XML ClonedRecord DOM object and return an object of Cloned Record
# contained in the DOM object.
#
# @param XmlCloned A child XML DOM object in a Common XML DOM.
#
# @retvel ClonedRecord A new Cloned Record object created by XmlCloned.
#
def LoadClonedRecord(XmlCloned):
ClonedRecord = ClonedRecordClass()
XmlTag = "Id"
ClonedRecord.Id = int(XmlAttribute(XmlCloned, XmlTag))
XmlTag = "FarGuid"
ClonedRecord.FarGuid = XmlAttribute(XmlCloned, XmlTag)
XmlTag = "Cloned/PackageGuid"
ClonedRecord.PackageGuid = XmlElement(XmlCloned, XmlTag)
XmlTag = "Cloned/PackageVersion"
ClonedRecord.PackageVersion = XmlElement(XmlCloned, XmlTag)
XmlTag = "Cloned/ModuleGuid"
ClonedRecord.ModuleGuid = XmlElement(XmlCloned, XmlTag)
XmlTag = "Cloned/ModuleVersion"
ClonedRecord.ModuleVersion = XmlElement(XmlCloned, XmlTag)
return ClonedRecord
## Load a new Guid/Protocol/Ppi common class object.
#
# Read an input XML Guid/Protocol/Ppi DOM object and return an object of
# Guid/Protocol/Ppi contained in the DOM object.
#
# @param XmlGuidProtocolPpiCommon A child XML DOM object in a Common XML DOM.
#
# @retvel GuidProtocolPpiCommon A new GuidProtocolPpiCommon class object
# created by XmlGuidProtocolPpiCommon.
#
def LoadGuidProtocolPpiCommon(XmlGuidProtocolPpiCommon):
GuidProtocolPpiCommon = GuidProtocolPpiCommonClass()
XmlTag = "Name"
GuidProtocolPpiCommon.Name = XmlAttribute(XmlGuidProtocolPpiCommon, XmlTag)
XmlParent = XmlNodeName(XmlGuidProtocolPpiCommon)
if XmlParent == "Entry":
XmlTag = "%s/C_Name" % XmlParent
elif XmlParent == "GuidCNames":
XmlTag = "%s/GuidCName" % XmlParent
else:
XmlTag = "%s/%sCName" % (XmlParent, XmlParent)
GuidProtocolPpiCommon.CName = XmlElement(XmlGuidProtocolPpiCommon, XmlTag)
XmlTag = XmlParent + "/" + "GuidValue"
GuidProtocolPpiCommon.Guid = XmlElement(XmlGuidProtocolPpiCommon, XmlTag)
if XmlParent.endswith("Notify"):
GuidProtocolPpiCommon.Notify = True
XmlTag = "GuidTypeList"
GuidTypes = XmlAttribute(XmlGuidProtocolPpiCommon, XmlTag)
GuidProtocolPpiCommon.GuidTypeList = GuidTypes.split()
XmlTag = "SupModuleList"
SupModules = XmlAttribute(XmlGuidProtocolPpiCommon, XmlTag)
GuidProtocolPpiCommon.SupModuleList = SupModules.split()
SetCommon(GuidProtocolPpiCommon, XmlGuidProtocolPpiCommon)
return GuidProtocolPpiCommon
## Load a new Pcd class object.
#
# Read an input XML Pcd DOM object and return an object of Pcd
# contained in the DOM object.
#
# @param XmlPcd A child XML DOM object in a Common XML DOM.
#
# @retvel Pcd A new Pcd object created by XmlPcd.
#
def LoadPcd(XmlPcd):
"""Return a new PcdClass object equivalent to XmlPcd"""
Pcd = PcdClass()
XmlTag = "PcdEntry/C_Name"
Pcd.CName = XmlElement(XmlPcd, XmlTag)
XmlTag = "PcdEntry/Token"
Pcd.Token = XmlElement(XmlPcd, XmlTag)
XmlTag = "PcdEntry/TokenSpaceGuidCName"
Pcd.TokenSpaceGuidCName = XmlElement(XmlPcd, XmlTag)
XmlTag = "PcdEntry/DatumType"
Pcd.DatumType = XmlElement(XmlPcd, XmlTag)
XmlTag = "PcdEntry/MaxDatumSize"
Pcd.MaxDatumSize = XmlElement(XmlPcd, XmlTag)
XmlTag = "PcdEntry/DefaultValue"
Pcd.DefaultValue = XmlElement(XmlPcd, XmlTag)
XmlTag = "PcdItemType"
Pcd.ItemType = XmlAttribute(XmlPcd, XmlTag)
XmlTag = "PcdEntry/ValidUsage"
Pcd.ValidUsage = XmlElement(XmlPcd, XmlTag).split()
XmlTag = "SupModuleList"
Pcd.SupModuleList = XmlAttribute(XmlPcd, XmlTag).split()
SetCommon(Pcd, XmlPcd)
return Pcd
## Load a new LibraryClass class object.
#
# Read an input XML LibraryClass DOM object and return an object of LibraryClass
# contained in the DOM object.
#
# @param XmlLibraryClass A child XML DOM object in a Common XML DOM.
#
# @retvel LibraryClass A new LibraryClass object created by XmlLibraryClass.
#
def LoadLibraryClass(XmlLibraryClass):
LibraryClass = LibraryClassClass()
XmlTag = "LibraryClass/Keyword"
LibraryClass.LibraryClass = XmlElement(XmlLibraryClass, XmlTag)
if LibraryClass.LibraryClass == "":
XmlTag = "Name"
LibraryClass.LibraryClass = XmlAttribute(XmlLibraryClass, XmlTag)
XmlTag = "LibraryClass/IncludeHeader"
LibraryClass.IncludeHeader = XmlElement(XmlLibraryClass, XmlTag)
XmlTag = "RecommendedInstanceVersion"
RecommendedInstanceVersion = XmlAttribute(XmlLibraryClass, XmlTag)
LibraryClass.RecommendedInstanceVersion = RecommendedInstanceVersion
XmlTag = "RecommendedInstanceGuid"
RecommendedInstanceGuid = XmlAttribute(XmlLibraryClass, XmlTag)
LibraryClass.RecommendedInstanceGuid = RecommendedInstanceGuid
XmlTag = "SupModuleList"
SupModules = XmlAttribute(XmlLibraryClass, XmlTag)
LibraryClass.SupModuleList = SupModules.split()
SetCommon(LibraryClass, XmlLibraryClass)
return LibraryClass
## Load a new Build Option class object.
#
# Read an input XML BuildOption DOM object and return an object of Build Option
# contained in the DOM object.
#
# @param XmlBuildOption A child XML DOM object in a Common XML DOM.
#
# @retvel BuildOption A new Build Option object created by XmlBuildOption.
#
def LoadBuildOption(XmlBuildOption):
"""Return a new BuildOptionClass object equivalent to XmlBuildOption"""
BuildOption = BuildOptionClass()
BuildOption.Option = XmlElementData(XmlBuildOption)
XmlTag = "BuildTargets"
BuildOption.BuildTargetList = XmlAttribute(XmlBuildOption, XmlTag).split()
XmlTag = "ToolChainFamily"
BuildOption.ToolChainFamily = XmlAttribute(XmlBuildOption, XmlTag)
XmlTag = "TagName"
BuildOption.TagName = XmlAttribute(XmlBuildOption, XmlTag)
XmlTag = "ToolCode"
BuildOption.ToolCode = XmlAttribute(XmlBuildOption, XmlTag)
XmlTag = "SupArchList"
BuildOption.SupArchList = XmlAttribute(XmlBuildOption, XmlTag).split()
return BuildOption
## Load a new User Extensions class object.
#
# Read an input XML UserExtensions DOM object and return an object of User
# Extensions contained in the DOM object.
#
# @param XmlUserExtensions A child XML DOM object in a Common XML DOM.
#
# @retvel UserExtensions A new User Extensions object created by
# XmlUserExtensions.
#
def LoadUserExtensions(XmlUserExtensions):
UserExtensions = UserExtensionsClass()
XmlTag = "UserID"
UserExtensions.UserID = XmlAttribute(XmlUserExtensions, XmlTag)
XmlTag = "Identifier"
UserExtensions.Identifier = XmlAttribute(XmlUserExtensions, XmlTag)
UserExtensions.Content = XmlElementData(XmlUserExtensions)
return UserExtensions
## Store content to a text file object.
#
# Write some text file content to a text file object. The contents may echo
# in screen in a verbose way.
#
# @param TextFile The text file object.
# @param Content The string object to be written to a text file.
#
def StoreTextFile(TextFile, Content):
EdkLogger.verbose(Content)
TextFile.write(Content)
## Add item to a section.
#
# Add an Item with specific CPU architecture to section dictionary.
# The possible duplication is ensured to be removed.
#
# @param Section Section dictionary indexed by CPU architecture.
# @param Arch CPU architecture: Ia32, X64, Ipf, ARM, Ebc or Common.
# @param Item The Item to be added to section dictionary.
#
def AddToSection(Section, Arch, Item):
SectionArch = Section.get(Arch, [])
if Item not in SectionArch:
SectionArch.append(Item)
Section[Arch] = SectionArch
## Get section contents.
#
# Return the content of section named SectionName.
# the contents is based on Methods and ObjectLists.
#
# @param SectionName The name of the section.
# @param Method A function returning a string item of an object.
# @param ObjectList The list of object.
#
# @retval Section The string content of a section.
#
def GetSection(SectionName, Method, ObjectList):
SupportedArches = ["common", "Ia32", "X64", "Ipf", "Ebc", "ARM"]
SectionDict = {}
for Object in ObjectList:
Item = Method(Object)
if Item == "":
continue
Item = " %s" % Item
Arches = Object.SupArchList
if len(Arches) == 0:
AddToSection(SectionDict, "common", Item)
else:
for Arch in SupportedArches:
if Arch.upper() in Arches:
AddToSection(SectionDict, Arch, Item)
Section = ""
for Arch in SupportedArches:
SectionArch = "\n".join(SectionDict.get(Arch, []))
if SectionArch != "":
Section += "[%s.%s]\n%s\n" % (SectionName, Arch, SectionArch)
Section += "\n"
if Section != "":
Section += "\n"
return Section
## Store file header to a text file.
#
# Write standard file header to a text file. The content includes copyright,
# abstract, description and license extracted from CommonHeader class object.
#
# @param TextFile The text file object.
# @param CommonHeader The source CommonHeader class object.
#
def StoreHeader(TextFile, CommonHeader):
CopyRight = CommonHeader.Copyright
Abstract = CommonHeader.Abstract
Description = CommonHeader.Description
License = CommonHeader.License
Header = "#/** @file\n#\n"
Header += "# " + Abstract + "\n#\n"
Header += "# " + Description.strip().replace("\n", "\n# ") + "\n"
Header += "# " + CopyRight + "\n#\n"
Header += "# " + License.replace("\n", "\n# ").replace(" ", " ")
Header += "\n#\n#**/\n\n"
StoreTextFile(TextFile, Header)
## Store file header to a text file.
#
# Write Defines section to a text file. DefinesTupleList determines the content.
#
# @param TextFile The text file object.
# @param DefinesTupleList The list of (Tag, Value) to be added as one item.
#
def StoreDefinesSection(TextFile, DefinesTupleList):
Section = "[Defines]\n"
for DefineItem in DefinesTupleList:
Section += " %-30s = %s\n" % DefineItem
Section += "\n\n"
StoreTextFile(TextFile, Section)
## Return one User Extension section.
#
# Read the input UserExtentsions class object and return one section.
#
# @param UserExtensions An input UserExtensions class object.
#
# @retval UserExtensionSection A section representing UserExtensions object.
#
def GetUserExtensions(UserExtensions):
UserId = UserExtensions.UserID
Identifier = UserExtensions.Identifier
Content = UserExtensions.Content
return "[UserExtensions.%s.%s]\n %s\n\n" % (UserId, Identifier, Content)
## Regular expression to match an equation.
mReEquation = re.compile(r"\s*(\S+)\s*=\s*(\S*)\s*")
## Return a value tuple matching information in a text fle.
#
# Parse the text file and return a value tuple corresponding to an input tag
# tuple. In case of any error, an tuple of empty strings is returned.
#
# @param FileName The file name of the text file.
# @param TagTuple A tuple of tags as the key to the value.
#
# @param ValueTupe The returned tuple corresponding to the tag tuple.
#
def GetTextFileInfo(FileName, TagTuple):
ValueTuple = [""] * len(TagTuple)
try:
for Line in open(FileName):
Line = Line.split("#", 1)[0]
MatchEquation = mReEquation.match(Line)
if MatchEquation:
Tag = MatchEquation.group(1).upper()
Value = MatchEquation.group(2)
for Index in range(len(TagTuple)):
if TagTuple[Index] == Tag:
ValueTuple[Index] = Value
except:
EdkLogger.info("IO Error in reading file %s" % FileName)
return ValueTuple
## Return a value tuple matching information in an XML fle.
#
# Parse the XML file and return a value tuple corresponding to an input tag
# tuple. In case of any error, an tuple of empty strings is returned.
#
# @param FileName The file name of the XML file.
# @param TagTuple A tuple of tags as the key to the value.
#
# @param ValueTupe The returned tuple corresponding to the tag tuple.
#
def GetXmlFileInfo(FileName, TagTuple):
XmlDom = XmlParseFile(FileName)
return tuple([XmlElement(XmlDom, XmlTag) for XmlTag in TagTuple])
## Parse migration command line options
#
# Use standard Python module optparse to parse command line option of this tool.
#
# @param Source The source file type.
# @param Destinate The destinate file type.
#
# @retval Options A optparse object containing the parsed options.
# @retval InputFile Path of an source file to be migrated.
#
def MigrationOptionParser(Source, Destinate, ToolName, VersionNumber = 1.0):
# use clearer usage to override default usage message
UsageString = "%s [-a] [-v|-q] [-o <output_file>] <input_file>" % ToolName
Version = "%s Version %.2f" % (ToolName, VersionNumber)
Copyright = "Copyright (c) 2007, Intel Corporation. All rights reserved."
Parser = OptionParser(description=Copyright, version=Version, usage=UsageString)
Parser.add_option("-o", "--output", dest="OutputFile", help="The name of the %s file to be created." % Destinate)
Parser.add_option("-a", "--auto", dest="AutoWrite", action="store_true", default=False, help="Automatically create the %s file using the name of the %s file and replacing file extension" % (Source, Destinate))
Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")
Options, Args = Parser.parse_args()
# Set logging level
if Options.verbose:
EdkLogger.setLevel(EdkLogger.VERBOSE)
elif Options.quiet:
EdkLogger.setLevel(EdkLogger.QUIET)
else:
EdkLogger.setLevel(EdkLogger.INFO)
# error check
if len(Args) == 0:
raise MigrationError(PARAMETER_MISSING, name="Input file", usage=Parser.get_usage())
if len(Args) > 1:
raise MigrationError(PARAMETER_INVALID, name="Too many input files", usage=Parser.get_usage())
InputFile = Args[0]
if not os.path.exists(InputFile):
raise MigrationError(FILE_NOT_FOUND, name=InputFile)
if Options.OutputFile:
if Options.AutoWrite:
raise MigrationError(OPTION_CONFLICT, arg1="-o", arg2="-a", usage=Parser.get_usage())
else:
if Options.AutoWrite:
Options.OutputFile = os.path.splitext(InputFile)[0] + "." + Destinate.lower()
else:
raise MigrationError(OPTION_MISSING, name="-o", usage=Parser.get_usage())
return Options, InputFile
# This acts like the main() function for the script, unless it is 'import'ed
# into another script.
if __name__ == '__main__':
pass

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,935 @@
## @file
# This file is used to define common parsing related functions used in parsing INF/DEC/DSC process
#
# Copyright (c) 2008, Intel Corporation
# All rights reserved. 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 String import *
from CommonDataClass.DataClass import *
from DataType import *
## ParseContent
#
# Parse content of a DSC/INF/DEC file
#
def ParseContent(Lines, ):
for Line in Lines:
LineNo = LineNo + 1
#
# Remove comments at tail and remove spaces again
#
Line = CleanString(Line)
if Line == '':
continue
#
# Find a new section tab
# First insert previous section items
# And then parse the content of the new section
#
if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END):
#
# Insert items data of previous section
#
self.InsertSectionItemsIntoDatabase(FileID, Filename, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList)
#
# Parse the new section
#
SectionItemList = []
ArchList = []
ThirdList = []
LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT)
for Item in LineList:
ItemList = GetSplitValueList(Item, TAB_SPLIT)
CurrentSection = ItemList[0]
if CurrentSection.upper() not in self.KeyList:
RaiseParserError(Line, CurrentSection, Filename, '', LineNo)
ItemList.append('')
ItemList.append('')
if len(ItemList) > 5:
RaiseParserError(Line, CurrentSection, Filename, '', LineNo)
else:
if ItemList[1] != '' and ItemList[1].upper() not in ARCH_LIST_FULL:
EdkLogger.error("Parser", PARSER_ERROR, "Invalid Arch definition '%s' found" % ItemList[1], File=Filename, Line=LineNo)
ArchList.append(ItemList[1].upper())
ThirdList.append(ItemList[2])
continue
#
# Not in any defined section
#
if CurrentSection == TAB_UNKNOWN:
ErrorMsg = "%s is not in any defined section" % Line
EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, File=Filename, Line=LineNo)
#
# Add a section item
#
SectionItemList.append([Line, LineNo])
# End of parse
#End of For
## 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
#
for Key in GlobalMacro.keys():
Macros[Key] = GlobalMacro[Key]
#
# Replace the Macros
#
for Key in RecordSets.keys():
if RecordSets[Key] != []:
for Item in RecordSets[Key]:
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
#
for Key in GlobalMacro.keys():
Macros[Key] = GlobalMacro[Key]
#
# 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):
if String.find(TAB_EQUAL_SPLIT) < 0:
RaiseParserError(String, 'BuildOptions', File, '[<Family>:]<ToolFlag>=Flag', LineNo)
(Family, ToolChain, Flag) = ('', '', '')
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 != 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 == 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])
#
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)
return (List[0], List[1], List[2], List[3])
## 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)

Binary file not shown.

View File

@@ -0,0 +1,703 @@
## @file
# This file is used to define common string related functions used in parsing process
#
# Copyright (c) 2007 ~ 2008, Intel Corporation
# All rights reserved. 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
#
import re
import DataType
import os.path
import string
import EdkLogger as EdkLogger
from GlobalData import *
from BuildToolError import *
## GetSplitValueList
#
# Get a value list from a string with multiple values splited with SplitTag
# The default SplitTag is DataType.TAB_VALUE_SPLIT
# 'AAA|BBB|CCC' -> ['AAA', 'BBB', 'CCC']
#
# @param String: The input string to be splitted
# @param SplitTag: The split key, default is DataType.TAB_VALUE_SPLIT
# @param MaxSplit: The max number of split values, default is -1
#
# @retval list() A list for splitted string
#
def GetSplitValueList(String, SplitTag = DataType.TAB_VALUE_SPLIT, MaxSplit = -1):
return map(lambda l: l.strip(), String.split(SplitTag, MaxSplit))
## MergeArches
#
# Find a key's all arches in dict, add the new arch to the list
# If not exist any arch, set the arch directly
#
# @param Dict: The input value for Dict
# @param Key: The input value for Key
# @param Arch: The Arch to be added or merged
#
def MergeArches(Dict, Key, Arch):
if Key in Dict.keys():
Dict[Key].append(Arch)
else:
Dict[Key] = Arch.split()
## GenDefines
#
# Parse a string with format "DEFINE <VarName> = <PATH>"
# Generate a map Defines[VarName] = PATH
# Return False if invalid format
#
# @param String: String with DEFINE statement
# @param Arch: Supportted Arch
# @param Defines: DEFINE statement to be parsed
#
# @retval 0 DEFINE statement found, and valid
# @retval 1 DEFINE statement found, but not valid
# @retval -1 DEFINE statement not found
#
def GenDefines(String, Arch, Defines):
if String.find(DataType.TAB_DEFINE + ' ') > -1:
List = String.replace(DataType.TAB_DEFINE + ' ', '').split(DataType.TAB_EQUAL_SPLIT)
if len(List) == 2:
Defines[(CleanString(List[0]), Arch)] = CleanString(List[1])
return 0
else:
return -1
return 1
## GenInclude
#
# Parse a string with format "!include <Filename>"
# Return the file path
# Return False if invalid format or NOT FOUND
#
# @param String: String with INCLUDE statement
# @param IncludeFiles: INCLUDE statement to be parsed
# @param Arch: Supportted Arch
#
# @retval True
# @retval False
#
def GenInclude(String, IncludeFiles, Arch):
if String.upper().find(DataType.TAB_INCLUDE.upper() + ' ') > -1:
IncludeFile = CleanString(String[String.upper().find(DataType.TAB_INCLUDE.upper() + ' ') + len(DataType.TAB_INCLUDE + ' ') : ])
MergeArches(IncludeFiles, IncludeFile, Arch)
return True
else:
return False
## GetLibraryClassesWithModuleType
#
# Get Library Class definition when no module type defined
#
# @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 library classes successfully
#
def GetLibraryClassesWithModuleType(Lines, Key, KeyValues, CommentCharacter):
newKey = SplitModuleType(Key)
Lines = Lines.split(DataType.TAB_SECTION_END, 1)[1]
LineList = Lines.splitlines()
for Line in LineList:
Line = CleanString(Line, CommentCharacter)
if Line != '' and Line[0] != CommentCharacter:
KeyValues.append([CleanString(Line, CommentCharacter), newKey[1]])
return True
## GetDynamics
#
# Get Dynamic Pcds
#
# @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 Dynamic Pcds successfully
#
def GetDynamics(Lines, Key, KeyValues, CommentCharacter):
#
# Get SkuId Name List
#
SkuIdNameList = SplitModuleType(Key)
Lines = Lines.split(DataType.TAB_SECTION_END, 1)[1]
LineList = Lines.splitlines()
for Line in LineList:
Line = CleanString(Line, CommentCharacter)
if Line != '' and Line[0] != CommentCharacter:
KeyValues.append([CleanString(Line, CommentCharacter), SkuIdNameList[1]])
return True
## SplitModuleType
#
# Split ModuleType out of section defien to get key
# [LibraryClass.Arch.ModuleType|ModuleType|ModuleType] -> [ 'LibraryClass.Arch', ['ModuleType', 'ModuleType', 'ModuleType'] ]
#
# @param Key: String to be parsed
#
# @retval ReturnValue A list for module types
#
def SplitModuleType(Key):
KeyList = Key.split(DataType.TAB_SPLIT)
#
# Fill in for arch
#
KeyList.append('')
#
# Fill in for moduletype
#
KeyList.append('')
ReturnValue = []
KeyValue = KeyList[0]
if KeyList[1] != '':
KeyValue = KeyValue + DataType.TAB_SPLIT + KeyList[1]
ReturnValue.append(KeyValue)
ReturnValue.append(GetSplitValueList(KeyList[2]))
return ReturnValue
## Replace macro in strings list
#
# This method replace macros used in a given string list. The macros are
# given in a dictionary.
#
# @param StringList StringList to be processed
# @param MacroDefinitions The macro definitions in the form of dictionary
# @param SelfReplacement To decide whether replace un-defined macro to ''
#
# @retval NewList A new string list whose macros are replaced
#
def ReplaceMacros(StringList, MacroDefinitions={}, SelfReplacement = False):
NewList = []
for String in StringList:
if type(String) == type(''):
NewList.append(ReplaceMacro(String, MacroDefinitions, SelfReplacement))
else:
NewList.append(String)
return NewList
## Replace macro in string
#
# This method replace macros used in given string. The macros are given in a
# dictionary.
#
# @param String String to be processed
# @param MacroDefinitions The macro definitions in the form of dictionary
# @param SelfReplacement To decide whether replace un-defined macro to ''
#
# @retval string The string whose macros are replaced
#
def ReplaceMacro(String, MacroDefinitions={}, SelfReplacement = False):
LastString = String
while MacroDefinitions:
MacroUsed = gMacroPattern.findall(String)
# no macro found in String, stop replacing
if len(MacroUsed) == 0:
break
for Macro in MacroUsed:
if Macro not in MacroDefinitions:
if SelfReplacement:
String = String.replace("$(%s)" % Macro, '')
continue
String = String.replace("$(%s)" % Macro, MacroDefinitions[Macro])
# in case there's macro not defined
if String == LastString:
break
LastString = String
return String
## NormPath
#
# Create a normal path
# And replace DFEINE in the path
#
# @param Path: The input value for Path to be converted
# @param Defines: A set for DEFINE statement
#
# @retval Path Formatted path
#
def NormPath(Path, Defines = {}):
IsRelativePath = False
if Path:
if Path[0] == '.':
IsRelativePath = True
#
# Replace with Define
#
if Defines:
Path = ReplaceMacro(Path, Defines)
#
# To local path format
#
Path = os.path.normpath(Path)
if IsRelativePath and Path[0] != '.':
Path = os.path.join('.', Path)
return Path
## CleanString
#
# Remove comments in a string
# Remove spaces
#
# @param Line: The string to be cleaned
# @param CommentCharacter: Comment char, used to ignore comment content, default is DataType.TAB_COMMENT_SPLIT
#
# @retval Path Formatted path
#
def CleanString(Line, CommentCharacter = DataType.TAB_COMMENT_SPLIT, AllowCppStyleComment=False):
#
# remove whitespace
#
Line = Line.strip();
#
# Replace R8's comment character
#
if AllowCppStyleComment:
Line = Line.replace(DataType.TAB_COMMENT_R8_SPLIT, CommentCharacter)
#
# remove comments
#
Line = Line.split(CommentCharacter, 1)[0];
#
# remove whitespace again
#
Line = Line.strip();
return Line
## GetMultipleValuesOfKeyFromLines
#
# Parse multiple strings to clean comment and spaces
# The result is saved to KeyValues
#
# @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 Successfully executed
#
def GetMultipleValuesOfKeyFromLines(Lines, Key, KeyValues, CommentCharacter):
Lines = Lines.split(DataType.TAB_SECTION_END, 1)[1]
LineList = Lines.split('\n')
for Line in LineList:
Line = CleanString(Line, CommentCharacter)
if Line != '' and Line[0] != CommentCharacter:
KeyValues += [Line]
return True
## GetDefineValue
#
# Parse a DEFINE statement to get defined value
# DEFINE Key Value
#
# @param String: The content to be parsed
# @param Key: The key of DEFINE statement
# @param CommentCharacter: Comment char, used to ignore comment content
#
# @retval string The defined value
#
def GetDefineValue(String, Key, CommentCharacter):
String = CleanString(String)
return String[String.find(Key + ' ') + len(Key + ' ') : ]
## GetSingleValueOfKeyFromLines
#
# Parse multiple strings as below to get value of each definition line
# Key1 = Value1
# Key2 = Value2
# The result is saved to Dictionary
#
# @param Lines: The content to be parsed
# @param Dictionary: To store data after parsing
# @param CommentCharacter: Comment char, be used to ignore comment content
# @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char
# @param ValueSplitFlag: Value split flag, be used to decide if has multiple values
# @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char
#
# @retval True Successfully executed
#
def GetSingleValueOfKeyFromLines(Lines, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter):
Lines = Lines.split('\n')
Keys = []
Value = ''
DefineValues = ['']
SpecValues = ['']
for Line in Lines:
#
# Handle DEFINE and SPEC
#
if Line.find(DataType.TAB_INF_DEFINES_DEFINE + ' ') > -1:
if '' in DefineValues:
DefineValues.remove('')
DefineValues.append(GetDefineValue(Line, DataType.TAB_INF_DEFINES_DEFINE, CommentCharacter))
continue
if Line.find(DataType.TAB_INF_DEFINES_SPEC + ' ') > -1:
if '' in SpecValues:
SpecValues.remove('')
SpecValues.append(GetDefineValue(Line, DataType.TAB_INF_DEFINES_SPEC, CommentCharacter))
continue
#
# Handle Others
#
LineList = Line.split(KeySplitCharacter, 1)
if len(LineList) >= 2:
Key = LineList[0].split()
if len(Key) == 1 and Key[0][0] != CommentCharacter:
#
# Remove comments and white spaces
#
LineList[1] = CleanString(LineList[1], CommentCharacter)
if ValueSplitFlag:
Value = map(string.strip, LineList[1].split(ValueSplitCharacter))
else:
Value = CleanString(LineList[1], CommentCharacter).splitlines()
if Key[0] in Dictionary:
if Key[0] not in Keys:
Dictionary[Key[0]] = Value
Keys.append(Key[0])
else:
Dictionary[Key[0]].extend(Value)
else:
Dictionary[DataType.TAB_INF_DEFINES_MACRO][Key[0]] = Value[0]
if DefineValues == []:
DefineValues = ['']
if SpecValues == []:
SpecValues = ['']
Dictionary[DataType.TAB_INF_DEFINES_DEFINE] = DefineValues
Dictionary[DataType.TAB_INF_DEFINES_SPEC] = SpecValues
return True
## The content to be parsed
#
# Do pre-check for a file before it is parsed
# Check $()
# Check []
#
# @param FileName: Used for error report
# @param FileContent: File content to be parsed
# @param SupSectionTag: Used for error report
#
def PreCheck(FileName, FileContent, SupSectionTag):
LineNo = 0
IsFailed = False
NewFileContent = ''
for Line in FileContent.splitlines():
LineNo = LineNo + 1
#
# Clean current line
#
Line = CleanString(Line)
#
# Remove commented line
#
if Line.find(DataType.TAB_COMMA_SPLIT) == 0:
Line = ''
#
# Check $()
#
if Line.find('$') > -1:
if Line.find('$(') < 0 or Line.find(')') < 0:
EdkLogger.error("Parser", FORMAT_INVALID, Line=LineNo, File=FileName, RaiseError = EdkLogger.IsRaiseError)
#
# Check []
#
if Line.find('[') > -1 or Line.find(']') > -1:
#
# Only get one '[' or one ']'
#
if not (Line.find('[') > -1 and Line.find(']') > -1):
EdkLogger.error("Parser", FORMAT_INVALID, Line=LineNo, File=FileName, RaiseError = EdkLogger.IsRaiseError)
#
# Regenerate FileContent
#
NewFileContent = NewFileContent + Line + '\r\n'
if IsFailed:
EdkLogger.error("Parser", FORMAT_INVALID, Line=LineNo, File=FileName, RaiseError = EdkLogger.IsRaiseError)
return NewFileContent
## CheckFileType
#
# Check if the Filename is including ExtName
# Return True if it exists
# Raise a error message if it not exists
#
# @param CheckFilename: Name of the file to be checked
# @param ExtName: Ext name of the file to be checked
# @param ContainerFilename: The container file which describes the file to be checked, used for error report
# @param SectionName: Used for error report
# @param Line: The line in container file which defines the file to be checked
#
# @retval True The file type is correct
#
def CheckFileType(CheckFilename, ExtName, ContainerFilename, SectionName, Line, LineNo = -1):
if CheckFilename != '' and CheckFilename != None:
(Root, Ext) = os.path.splitext(CheckFilename)
if Ext.upper() != ExtName.upper():
ContainerFile = open(ContainerFilename, 'r').read()
if LineNo == -1:
LineNo = GetLineNo(ContainerFile, Line)
ErrorMsg = "Invalid %s. '%s' is found, but '%s' file is needed" % (SectionName, CheckFilename, ExtName)
EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, Line=LineNo,
File=ContainerFilename, RaiseError = EdkLogger.IsRaiseError)
return True
## CheckFileExist
#
# Check if the file exists
# Return True if it exists
# Raise a error message if it not exists
#
# @param CheckFilename: Name of the file to be checked
# @param WorkspaceDir: Current workspace dir
# @param ContainerFilename: The container file which describes the file to be checked, used for error report
# @param SectionName: Used for error report
# @param Line: The line in container file which defines the file to be checked
#
# @retval The file full path if the file exists
#
def CheckFileExist(WorkspaceDir, CheckFilename, ContainerFilename, SectionName, Line, LineNo = -1):
CheckFile = ''
if CheckFilename != '' and CheckFilename != None:
CheckFile = WorkspaceFile(WorkspaceDir, CheckFilename)
if not os.path.isfile(CheckFile):
ContainerFile = open(ContainerFilename, 'r').read()
if LineNo == -1:
LineNo = GetLineNo(ContainerFile, Line)
ErrorMsg = "Can't find file '%s' defined in section '%s'" % (CheckFile, SectionName)
EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg,
File=ContainerFilename, Line = LineNo, RaiseError = EdkLogger.IsRaiseError)
return CheckFile
## GetLineNo
#
# Find the index of a line in a file
#
# @param FileContent: Search scope
# @param Line: Search key
#
# @retval int Index of the line
# @retval -1 The line is not found
#
def GetLineNo(FileContent, Line, IsIgnoreComment = True):
LineList = FileContent.splitlines()
for Index in range(len(LineList)):
if LineList[Index].find(Line) > -1:
#
# Ignore statement in comment
#
if IsIgnoreComment:
if LineList[Index].strip()[0] == DataType.TAB_COMMENT_SPLIT:
continue
return Index + 1
return -1
## RaiseParserError
#
# Raise a parser error
#
# @param Line: String which has error
# @param Section: Used for error report
# @param File: File which has the string
# @param Format: Correct format
#
def RaiseParserError(Line, Section, File, Format = '', LineNo = -1):
if LineNo == -1:
LineNo = GetLineNo(open(os.path.normpath(File), 'r').read(), Line)
ErrorMsg = "Invalid statement '%s' is found in section '%s'" % (Line, Section)
if Format != '':
Format = "Correct format is " + Format
EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, File=File, Line=LineNo, ExtraData=Format, RaiseError = EdkLogger.IsRaiseError)
## WorkspaceFile
#
# Return a full path with workspace dir
#
# @param WorkspaceDir: Workspace dir
# @param Filename: Relative file name
#
# @retval string A full path
#
def WorkspaceFile(WorkspaceDir, Filename):
return os.path.join(NormPath(WorkspaceDir), NormPath(Filename))
## Split string
#
# Revmove '"' which startswith and endswith string
#
# @param String: The string need to be splited
#
# @retval String: The string after removed '""'
#
def SplitString(String):
if String.startswith('\"'):
String = String[1:]
if String.endswith('\"'):
String = String[:-1]
return String
## Convert To Sql String
#
# 1. Replace "'" with "''" in each item of StringList
#
# @param StringList: A list for strings to be converted
#
def ConvertToSqlString(StringList):
return map(lambda s: s.replace("'", "''") , StringList)
## Convert To Sql String
#
# 1. Replace "'" with "''" in the String
#
# @param String: A String to be converted
#
def ConvertToSqlString2(String):
return String.replace("'", "''")
#
# Remove comment block
#
def RemoveBlockComment(Lines):
IsFindBlockComment = False
IsFindBlockCode = False
ReservedLine = ''
NewLines = []
for Line in Lines:
Line = Line.strip()
#
# Remove comment block
#
if Line.find(DataType.TAB_COMMENT_R8_START) > -1:
ReservedLine = GetSplitValueList(Line, DataType.TAB_COMMENT_R8_START, 1)[0]
IsFindBlockComment = True
if Line.find(DataType.TAB_COMMENT_R8_END) > -1:
Line = ReservedLine + GetSplitValueList(Line, DataType.TAB_COMMENT_R8_END, 1)[1]
ReservedLine = ''
IsFindBlockComment = False
if IsFindBlockComment:
NewLines.append('')
continue
NewLines.append(Line)
return NewLines
#
# Get String of a List
#
def GetStringOfList(List, Split = ' '):
if type(List) != type([]):
return List
Str = ''
for Item in List:
Str = Str + Item + Split
return Str.strip()
#
# Get HelpTextList from HelpTextClassList
#
def GetHelpTextList(HelpTextClassList):
List = []
if HelpTextClassList:
for HelpText in HelpTextClassList:
if HelpText.String.endswith('\n'):
HelpText.String = HelpText.String[0: len(HelpText.String) - len('\n')]
List.extend(HelpText.String.split('\n'))
return List
def StringToArray(String):
if isinstance(String, unicode):
if len(unicode) ==0:
return "{0x00, 0x00}"
return "{%s, 0x00, 0x00}" % ", ".join(["0x%02x, 0x00" % ord(C) for C in String])
elif String.startswith('L"'):
if String == "L\"\"":
return "{0x00, 0x00}"
else:
return "{%s, 0x00, 0x00}" % ", ".join(["0x%02x, 0x00" % ord(C) for C in String[2:-1]])
elif String.startswith('"'):
if String == "\"\"":
return "{0x00}";
else:
return "{%s, 0x00}" % ", ".join(["0x%02x" % ord(C) for C in String[1:-1]])
else:
return '{%s, 0}' % ', '.join(String.split())
def StringArrayLength(String):
if isinstance(String, unicode):
return (len(String) + 1) * 2 + 1;
elif String.startswith('L"'):
return (len(String) - 3 + 1) * 2
elif String.startswith('"'):
return (len(String) - 2 + 1)
else:
return len(String.split()) + 1
def RemoveDupOption(OptionString, Which="/I", Against=None):
OptionList = OptionString.split()
ValueList = []
if Against:
ValueList += Against
for Index in range(len(OptionList)):
Opt = OptionList[Index]
if not Opt.startswith(Which):
continue
if len(Opt) > len(Which):
Val = Opt[len(Which):]
else:
Val = ""
if Val in ValueList:
OptionList[Index] = ""
else:
ValueList.append(Val)
return " ".join(OptionList)
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
pass

View File

@@ -0,0 +1,174 @@
## @file
# This file is used to define each component of Target.txt file
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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
#
import os
import EdkLogger
import DataType
from BuildToolError import *
import GlobalData
gDefaultTargetTxtFile = "Conf/target.txt"
## TargetTxtClassObject
#
# This class defined content used in file target.txt
#
# @param object: Inherited from object class
# @param Filename: Input value for full path of target.txt
#
# @var TargetTxtDictionary: To store keys and values defined in target.txt
#
class TargetTxtClassObject(object):
def __init__(self, Filename = None):
self.TargetTxtDictionary = {
DataType.TAB_TAT_DEFINES_ACTIVE_PLATFORM : '',
DataType.TAB_TAT_DEFINES_ACTIVE_MODULE : '',
DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF : '',
DataType.TAB_TAT_DEFINES_MULTIPLE_THREAD : '',
DataType.TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER : '',
DataType.TAB_TAT_DEFINES_TARGET : [],
DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG : [],
DataType.TAB_TAT_DEFINES_TARGET_ARCH : [],
DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF : '',
}
if Filename != None:
self.LoadTargetTxtFile(Filename)
## LoadTargetTxtFile
#
# Load target.txt file and parse it, return a set structure to store keys and values
#
# @param Filename: Input value for full path of target.txt
#
# @retval set() A set structure to store keys and values
# @retval 1 Error happenes in parsing
#
def LoadTargetTxtFile(self, Filename):
if os.path.exists(Filename) and os.path.isfile(Filename):
return self.ConvertTextFileToDict(Filename, '#', '=')
else:
EdkLogger.error("Target.txt Parser", FILE_NOT_FOUND, ExtraData=Filename)
return 1
## ConvertTextFileToDict
#
# Convert a text file to a dictionary of (name:value) pairs.
# The data is saved to self.TargetTxtDictionary
#
# @param FileName: Text filename
# @param CommentCharacter: Comment char, be used to ignore comment content
# @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char
#
# @retval 0 Convert successfully
# @retval 1 Open file failed
#
def ConvertTextFileToDict(self, FileName, CommentCharacter, KeySplitCharacter):
F = None
try:
F = open(FileName,'r')
except:
EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=FileName)
if F != None:
F.close()
for Line in F:
Line = Line.strip()
if Line.startswith(CommentCharacter) or Line == '':
continue
LineList = Line.split(KeySplitCharacter, 1)
Key = LineList[0].strip()
if len(LineList) == 2:
Value = LineList[1].strip()
else:
Value = ""
if Key in [DataType.TAB_TAT_DEFINES_ACTIVE_PLATFORM, DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF, \
DataType.TAB_TAT_DEFINES_ACTIVE_MODULE, DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF]:
self.TargetTxtDictionary[Key] = Value.replace('\\', '/')
elif Key in [DataType.TAB_TAT_DEFINES_TARGET, DataType.TAB_TAT_DEFINES_TARGET_ARCH, \
DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG]:
self.TargetTxtDictionary[Key] = Value.split()
elif Key == DataType.TAB_TAT_DEFINES_MULTIPLE_THREAD:
if Value not in ["Enable", "Disable"]:
EdkLogger.error("build", FORMAT_INVALID, "Invalid setting of [%s]: %s." % (Key, Value),
ExtraData="\tSetting must be one of [Enable, Disable]",
File=FileName)
self.TargetTxtDictionary[Key] = Value
elif Key == DataType.TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER:
try:
V = int(Value, 0)
except:
EdkLogger.error("build", FORMAT_INVALID, "Invalid number of [%s]: %s." % (Key, Value),
File=FileName)
self.TargetTxtDictionary[Key] = Value
#elif Key not in GlobalData.gGlobalDefines:
# GlobalData.gGlobalDefines[Key] = Value
F.close()
return 0
## Print the dictionary
#
# Print all items of dictionary one by one
#
# @param Dict: The dictionary to be printed
#
def printDict(Dict):
if Dict != None:
KeyList = Dict.keys()
for Key in KeyList:
if Dict[Key] != '':
print Key + ' = ' + str(Dict[Key])
## Print the dictionary
#
# Print the items of dictionary which matched with input key
#
# @param list: The dictionary to be printed
# @param key: The key of the item to be printed
#
def printList(Key, List):
if type(List) == type([]):
if len(List) > 0:
if Key.find(TAB_SPLIT) != -1:
print "\n" + Key
for Item in List:
print Item
## TargetTxtDict
#
# Load target.txt in input workspace dir
#
# @param WorkSpace: Workspace dir
#
# @retval Target An instance of TargetTxtClassObject() with loaded target.txt
#
def TargetTxtDict(WorkSpace):
Target = TargetTxtClassObject()
Target.LoadTargetTxtFile(os.path.normpath(os.path.join(WorkSpace, gDefaultTargetTxtFile)))
return Target
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
pass
Target = TargetTxtDict(os.getenv("WORKSPACE"))
print Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER]
print Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET]
print Target.TargetTxtDictionary

View File

@@ -0,0 +1,217 @@
## @file
# This file is used to define each component of tools_def.txt file
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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
#
import os
import re
import EdkLogger
from Dictionary import *
from BuildToolError import *
from TargetTxtClassObject import *
##
# Static vailabes used for pattern
#
gMacroRefPattern = re.compile('(DEF\([^\(\)]+\))')
gEnvRefPattern = re.compile('(ENV\([^\(\)]+\))')
gMacroDefPattern = re.compile("DEFINE\s+([^\s]+)")
gDefaultToolsDefFile = "Conf/tools_def.txt"
## ToolDefClassObject
#
# This class defined content used in file tools_def.txt
#
# @param object: Inherited from object class
# @param Filename: Input value for full path of tools_def.txt
#
# @var ToolsDefTxtDictionary: To store keys and values defined in target.txt
# @var MacroDictionary: To store keys and values defined in DEFINE statement
#
class ToolDefClassObject(object):
def __init__(self, FileName = None):
self.ToolsDefTxtDictionary = {}
self.MacroDictionary = {}
for Env in os.environ:
self.MacroDictionary["ENV(%s)" % Env] = os.environ[Env]
if FileName != None:
self.LoadToolDefFile(FileName)
## LoadToolDefFile
#
# Load target.txt file and parse it, return a set structure to store keys and values
#
# @param Filename: Input value for full path of tools_def.txt
#
def LoadToolDefFile(self, FileName):
FileContent = []
if os.path.isfile(FileName):
try:
F = open(FileName,'r')
FileContent = F.readlines()
except:
EdkLogger.error("tools_def.txt parser", FILE_OPEN_FAILURE, ExtraData=FileName)
else:
EdkLogger.error("tools_def.txt parser", FILE_NOT_FOUND, ExtraData=FileName)
self.ToolsDefTxtDatabase = {
TAB_TOD_DEFINES_TARGET : [],
TAB_TOD_DEFINES_TOOL_CHAIN_TAG : [],
TAB_TOD_DEFINES_TARGET_ARCH : [],
TAB_TOD_DEFINES_COMMAND_TYPE : []
}
for Index in range(len(FileContent)):
Line = FileContent[Index].strip()
if Line == "" or Line[0] == '#':
continue
NameValuePair = Line.split("=", 1)
if len(NameValuePair) != 2:
EdkLogger.warn("tools_def.txt parser", "Line %d: not correct assignment statement, skipped" % (Index + 1))
continue
Name = NameValuePair[0].strip()
Value = NameValuePair[1].strip()
if Name == "IDENTIFIER":
EdkLogger.debug(EdkLogger.DEBUG_8, "Line %d: Found identifier statement, skipped: %s" % ((Index + 1), Value))
continue
MacroDefinition = gMacroDefPattern.findall(Name)
if MacroDefinition != []:
Done, Value = self.ExpandMacros(Value)
if not Done:
EdkLogger.error("tools_def.txt parser", ATTRIBUTE_NOT_AVAILABLE,
"Macro or Environment has not been defined",
ExtraData=Value[4:-1], File=FileName, Line=Index+1)
MacroName = MacroDefinition[0].strip()
self.MacroDictionary["DEF(%s)" % MacroName] = Value
EdkLogger.debug(EdkLogger.DEBUG_8, "Line %d: Found macro: %s = %s" % ((Index + 1), MacroName, Value))
continue
Done, Value = self.ExpandMacros(Value)
if not Done:
EdkLogger.error("tools_def.txt parser", ATTRIBUTE_NOT_AVAILABLE,
"Macro or Environment has not been defined",
ExtraData=Value[4:-1], File=FileName, Line=Index+1)
List = Name.split('_')
if len(List) != 5:
EdkLogger.verbose("Line %d: Not a valid name of definition: %s" % ((Index + 1), Name))
continue
elif List[4] == '*':
EdkLogger.verbose("Line %d: '*' is not allowed in last field: %s" % ((Index + 1), Name))
continue
else:
self.ToolsDefTxtDictionary[Name] = Value
if List[0] != '*':
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET] += [List[0]]
if List[1] != '*':
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG] += [List[1]]
if List[2] != '*':
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH] += [List[2]]
if List[3] != '*':
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE] += [List[3]]
if List[4] == TAB_TOD_DEFINES_FAMILY and List[2] == '*' and List[3] == '*':
if TAB_TOD_DEFINES_FAMILY not in self.ToolsDefTxtDatabase:
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY] = {}
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY][List[1]] = Value
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY] = {}
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY][List[1]] = Value
elif List[1] not in self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY]:
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY][List[1]] = Value
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY][List[1]] = Value
elif self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY][List[1]] != Value:
EdkLogger.verbose("Line %d: No override allowed for the family of a tool chain: %s" % ((Index + 1), Name))
if List[4] == TAB_TOD_DEFINES_BUILDRULEFAMILY and List[2] == '*' and List[3] == '*':
if TAB_TOD_DEFINES_BUILDRULEFAMILY not in self.ToolsDefTxtDatabase \
or List[1] not in self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY]:
EdkLogger.verbose("Line %d: The family is not specified, but BuildRuleFamily is specified for the tool chain: %s" % ((Index + 1), Name))
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY][List[1]] = Value
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET]))
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG]))
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH]))
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE]))
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET].sort()
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG].sort()
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH].sort()
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE].sort()
KeyList = [TAB_TOD_DEFINES_TARGET, TAB_TOD_DEFINES_TOOL_CHAIN_TAG, TAB_TOD_DEFINES_TARGET_ARCH, TAB_TOD_DEFINES_COMMAND_TYPE]
for Index in range(3,-1,-1):
for Key in dict(self.ToolsDefTxtDictionary):
List = Key.split('_')
if List[Index] == '*':
for String in self.ToolsDefTxtDatabase[KeyList[Index]]:
List[Index] = String
NewKey = '%s_%s_%s_%s_%s' % tuple(List)
if NewKey not in self.ToolsDefTxtDictionary:
self.ToolsDefTxtDictionary[NewKey] = self.ToolsDefTxtDictionary[Key]
continue
del self.ToolsDefTxtDictionary[Key]
elif List[Index] not in self.ToolsDefTxtDatabase[KeyList[Index]]:
del self.ToolsDefTxtDictionary[Key]
## ExpandMacros
#
# Replace defined macros with real value
#
# @param Value: The string with unreplaced macros
#
# @retval Value: The string which has been replaced with real value
#
def ExpandMacros(self, Value):
EnvReference = gEnvRefPattern.findall(Value)
for Ref in EnvReference:
if Ref not in self.MacroDictionary:
return False, Ref
Value = Value.replace(Ref, self.MacroDictionary[Ref])
MacroReference = gMacroRefPattern.findall(Value)
for Ref in MacroReference:
if Ref not in self.MacroDictionary:
return False, Ref
Value = Value.replace(Ref, self.MacroDictionary[Ref])
return True, Value
## ToolDefDict
#
# Load tools_def.txt in input workspace dir
#
# @param WorkSpace: Workspace dir
#
# @retval ToolDef An instance of ToolDefClassObject() with loaded tools_def.txt
#
def ToolDefDict(WorkSpace):
Target = TargetTxtDict(WorkSpace)
ToolDef = ToolDefClassObject()
if DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF in Target.TargetTxtDictionary:
gDefaultToolsDefFile = Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
ToolDef.LoadToolDefFile(os.path.normpath(os.path.join(WorkSpace, gDefaultToolsDefFile)))
return ToolDef
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
ToolDef = ToolDefDict(os.getenv("WORKSPACE"))
pass

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,228 @@
## @file
# This is an XML API that uses a syntax similar to XPath, but it is written in
# standard python so that no extra python packages are required to use it.
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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
#
import xml.dom.minidom
## Create a element of XML
#
# @param Name
# @param String
# @param NodeList
# @param AttributeList
#
# @revel Element
#
def CreateXmlElement(Name, String, NodeList, AttributeList):
Doc = xml.dom.minidom.Document()
Element = Doc.createElement(Name)
if String != '' and String != None:
Element.appendChild(Doc.createTextNode(String))
for Item in NodeList:
if type(Item) == type([]):
Key = Item[0]
Value = Item[1]
if Key != '' and Key != None and Value != '' and Value != None:
Node = Doc.createElement(Key)
Node.appendChild(Doc.createTextNode(Value))
Element.appendChild(Node)
else:
Element.appendChild(Item)
for Item in AttributeList:
Key = Item[0]
Value = Item[1]
if Key != '' and Key != None and Value != '' and Value != None:
Element.setAttribute(Key, Value)
return Element
## Get a list of XML nodes using XPath style syntax.
#
# Return a list of XML DOM nodes from the root Dom specified by XPath String.
# If the input Dom or String is not valid, then an empty list is returned.
#
# @param Dom The root XML DOM node.
# @param String A XPath style path.
#
# @revel Nodes A list of XML nodes matching XPath style Sting.
#
def XmlList(Dom, String):
if String == None or String == "" or Dom == None or Dom == "":
return []
if Dom.nodeType == Dom.DOCUMENT_NODE:
Dom = Dom.documentElement
if String[0] == "/":
String = String[1:]
TagList = String.split('/')
Nodes = [Dom]
Index = 0
End = len(TagList) - 1
while Index <= End:
ChildNodes = []
for Node in Nodes:
if Node.nodeType == Node.ELEMENT_NODE and Node.tagName == TagList[Index]:
if Index < End:
ChildNodes.extend(Node.childNodes)
else:
ChildNodes.append(Node)
Nodes = ChildNodes
ChildNodes = []
Index += 1
return Nodes
## Get a single XML node using XPath style syntax.
#
# Return a single XML DOM node from the root Dom specified by XPath String.
# If the input Dom or String is not valid, then an empty string is returned.
#
# @param Dom The root XML DOM node.
# @param String A XPath style path.
#
# @revel Node A single XML node matching XPath style Sting.
#
def XmlNode(Dom, String):
if String == None or String == "" or Dom == None or Dom == "":
return ""
if Dom.nodeType == Dom.DOCUMENT_NODE:
Dom = Dom.documentElement
if String[0] == "/":
String = String[1:]
TagList = String.split('/')
Index = 0
End = len(TagList) - 1
ChildNodes = [Dom]
while Index <= End:
for Node in ChildNodes:
if Node.nodeType == Node.ELEMENT_NODE and Node.tagName == TagList[Index]:
if Index < End:
ChildNodes = Node.childNodes
else:
return Node
break
Index += 1
return ""
## Get a single XML element using XPath style syntax.
#
# Return a single XML element from the root Dom specified by XPath String.
# If the input Dom or String is not valid, then an empty string is returned.
#
# @param Dom The root XML DOM object.
# @param Strin A XPath style path.
#
# @revel Element An XML element matching XPath style Sting.
#
def XmlElement(Dom, String):
try:
return XmlNode(Dom, String).firstChild.data.strip()
except:
return ""
## Get a single XML element of the current node.
#
# Return a single XML element specified by the current root Dom.
# If the input Dom is not valid, then an empty string is returned.
#
# @param Dom The root XML DOM object.
#
# @revel Element An XML element in current root Dom.
#
def XmlElementData(Dom):
try:
return Dom.firstChild.data.strip()
except:
return ""
## Get a list of XML elements using XPath style syntax.
#
# Return a list of XML elements from the root Dom specified by XPath String.
# If the input Dom or String is not valid, then an empty list is returned.
#
# @param Dom The root XML DOM object.
# @param String A XPath style path.
#
# @revel Elements A list of XML elements matching XPath style Sting.
#
def XmlElementList(Dom, String):
return map(XmlElementData, XmlList(Dom, String))
## Get the XML attribute of the current node.
#
# Return a single XML attribute named Attribute from the current root Dom.
# If the input Dom or Attribute is not valid, then an empty string is returned.
#
# @param Dom The root XML DOM object.
# @param Attribute The name of Attribute.
#
# @revel Element A single XML element matching XPath style Sting.
#
def XmlAttribute(Dom, Attribute):
try:
return Dom.getAttribute(Attribute).strip()
except:
return ''
## Get the XML node name of the current node.
#
# Return a single XML node name from the current root Dom.
# If the input Dom is not valid, then an empty string is returned.
#
# @param Dom The root XML DOM object.
#
# @revel Element A single XML element matching XPath style Sting.
#
def XmlNodeName(Dom):
try:
return Dom.nodeName.strip()
except:
return ''
## Parse an XML file.
#
# Parse the input XML file named FileName and return a XML DOM it stands for.
# If the input File is not a valid XML file, then an empty string is returned.
#
# @param FileName The XML file name.
#
# @revel Dom The Dom object achieved from the XML file.
#
def XmlParseFile(FileName):
try:
XmlFile = open(FileName)
Dom = xml.dom.minidom.parse(XmlFile)
XmlFile.close()
return Dom
except Exception, X:
print X
return ""
# This acts like the main() function for the script, unless it is 'import'ed
# into another script.
if __name__ == '__main__':
# Nothing to do here. Could do some unit tests.
A = CreateXmlElement('AAA', 'CCC', [['AAA', '111'], ['BBB', '222']], [['A', '1'], ['B', '2']])
B = CreateXmlElement('ZZZ', 'CCC', [['XXX', '111'], ['YYY', '222']], [['A', '1'], ['B', '2']])
C = CreateXmlList('DDD', 'EEE', [A, B], ['FFF', 'GGG'])
print C.toprettyxml(indent = " ")
pass

View File

@@ -0,0 +1,473 @@
## @file
# This file is used to define common items of class object
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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.
#
# Generate help text
#
def GenerateHelpText(Text, Lang):
if Text:
Ht = HelpTextClass()
Ht.Lang = Lang
Ht.String = Text
return Ht
return None
## CommonClass
#
# This class defined common items used in Module/Platform/Package files
#
# @param object: Inherited from object class
# @param Usage: Input value for Usage, default is []
# @param FeatureFlag: Input value for FeatureFalg, default is ''
# @param SupArchList: Input value for SupArchList, default is []
# @param HelpText: Input value for HelpText, default is ''
#
# @var Usage: To store value for Usage, selection scope is in below list
# ALWAYS_CONSUMED | SOMETIMES_CONSUMED | ALWAYS_PRODUCED | SOMETIMES_PRODUCED | TO_START | BY_START | PRIVATE
# @var FeatureFlag: To store value for FeatureFlag
# @var SupArchList: To store value for SupArchList, selection scope is in below list
# EBC | IA32 | X64 | IPF | ARM | PPC
# @var HelpText: To store value for HelpText
#
class CommonClass(object):
def __init__(self, Usage = None, FeatureFlag = '', SupArchList = None, HelpText = ''):
self.Usage = Usage
if self.Usage == None:
self.Usage = []
self.FeatureFlag = FeatureFlag
self.SupArchList = SupArchList
if self.SupArchList == None:
self.SupArchList = []
self.HelpText = HelpText
self.HelpTextList = []
## CommonClass
#
# This class defined common items used in Module/Platform/Package files
#
# @param object: Inherited from object class
#
# @var Abstract: To store value for Abstract
# @var Description: To store value for Description
# @var Copyright: To store value for Copyright
# @var License: To store value for License
# @var Specification: To store value for Specification
#
class CommonHeaderClass(object):
def __init__(self):
self.Abstract = ''
self.Description = ''
self.Copyright = ''
self.License = ''
self.Specification = {}
## HelpTextClass
#
# This class defined HelpText item used in PKG file
#
# @param object: Inherited from object class
#
# @var Lang: To store value for Lang
# @var String: To store value for String
#
class HelpTextClass(object):
def __init__(self):
self.Lang = ''
self.String = ''
## DefineClass
#
# This class defined item DEFINE used in Module/Platform/Package files
#
# @param object: Inherited from object class
#
# @var Define: To store value for Define, it is a set structure as
# { (DefineName, Arch) : DefineValue, ... }
#
class DefineClass(object):
def __init__(self):
self.Define = {}
## ClonedRecordClass
#
# This class defined ClonedRecord items used in Module/Platform/Package files
#
# @param object: Inherited from object class
#
# @var Id: To store value for Id
# @var FarGuid: To store value for FarGuid
# @var PackageGuid: To store value for PackageGuid
# @var PackageVersion: To store value for PackageVersion
# @var ModuleGuid: To store value for ModuleGuid
# @var ModuleVersion: To store value for ModuleVersion
#
class ClonedRecordClass(object):
def __init__(self):
self.Id = 0
self.FarGuid = ''
self.PackageGuid = ''
self.PackageVersion = ''
self.ModuleGuid = ''
self.ModuleVersion = ''
## IdentificationClass
#
# This class defined Identification items used in Module/Platform/Package files
#
# @param object: Inherited from object class
#
# @var Name: To store value for Name
# ModuleName(Inf) / PackageName(Dec) / PlatformName(Dsc)
# @var Guid: To store value for Guid
# @var Version: To store value for Version
# @var FileName: To store value for FileName
# @var FullPath: To store value for FullPath
#
class IdentificationClass(object):
def __init__(self):
self.Name = ''
self.BaseName = ''
self.Guid = ''
self.Version = ''
self.FileName = ''
self.FullPath = ''
self.RelaPath = ''
self.PackagePath = ''
self.ModulePath = ''
self.CombinePath = ''
## IncludeStatementClass
#
# This class defined IncludeFiles item used in Module/Platform/Package files
#
# @param object: Inherited from object class
#
# @var IncludeFiles: To store value for IncludeFiles
# It is a set structure as { IncludeFile : [Arch1, Arch2, ...], ... }
#
class IncludeStatementClass(object):
def __init__(self):
self.IncludeFiles = {}
## GuidProtocolPpiCommonClass
#
# This class defined Guid, Protocol and Ppi like items used in Module/Platform/Package files
#
# @param CommonClass: Inherited from CommonClass class
#
# @var Name: To store value for Name
# @var CName: To store value for CName
# @var Guid: To store value for Guid
# @var Notify: To store value for Notify
# @var GuidTypeList: To store value for GuidTypeList, selection scope is in below list
# DATA_HUB_RECORD | EFI_EVENT | EFI_SYSTEM_CONFIGURATION_TABLE | EFI_VARIABLE | GUID | HII_PACKAGE_LIST | HOB | TOKEN_SPACE_GUID
# @var SupModuleList: To store value for SupModuleList, selection scope is in below list
# BASE | SEC | PEI_CORE | PEIM | DXE_CORE | DXE_DRIVER | DXE_RUNTIME_DRIVER | DXE_SAL_DRIVER | DXE_SMM_DRIVER | UEFI_DRIVER | UEFI_APPLICATION | USER_DEFINED
#
class GuidProtocolPpiCommonClass(CommonClass):
def __init__(self):
self.Name = ''
self.CName = ''
self.Guid = ''
self.VariableName = ''
self.Notify = False
self.GuidTypeList = []
self.GuidTypeLists = []
self.SupModuleList = []
CommonClass.__init__(self)
## LibraryClassClass
#
# This class defined Library item used in Module/Platform/Package files
#
# @param CommonClass: Inherited from CommonClass class
# @param DefineClass: Inherited from DefineClass class
#
# @var LibraryClass: To store value for LibraryClass
# @var IncludeHeader: To store value for IncludeHeader
# @var RecommendedInstanceVersion: To store value for RecommendedInstanceVersion
# @var RecommendedInstanceGuid: To store value for RecommendedInstanceGuid
# @var RecommendedInstance: To store value for RecommendedInstance, selection scope is in below list
# DATA_HUB_RECORD | EFI_EVENT | EFI_SYSTEM_CONFIGURATION_TABLE | EFI_VARIABLE | GUID | HII_PACKAGE_LIST | HOB | TOKEN_SPACE_GUID
# @var SupModuleList: To store value for SupModuleList, selection scope is in below list
# BASE | SEC | PEI_CORE | PEIM | DXE_CORE | DXE_DRIVER | DXE_RUNTIME_DRIVER | DXE_SAL_DRIVER | DXE_SMM_DRIVER | UEFI_DRIVER | UEFI_APPLICATION | USER_DEFINED
#
class LibraryClassClass(CommonClass, DefineClass):
def __init__(self):
self.LibraryClass = ''
self.IncludeHeader = ''
self.RecommendedInstanceVersion = ''
self.RecommendedInstanceGuid = ''
self.RecommendedInstance = ''
self.SupModuleList = []
CommonClass.__init__(self)
DefineClass.__init__(self)
## GuidClass
#
# This class defined Guid item used in Module/Platform/Package files
#
# @param GuidProtocolPpiCommonClass: Inherited from GuidProtocolPpiCommonClass class
#
class GuidClass(GuidProtocolPpiCommonClass):
def __init__(self):
GuidProtocolPpiCommonClass.__init__(self)
## ProtocolClass
#
# This class defined Protocol item used in Module/Platform/Package files
#
# @param GuidProtocolPpiCommonClass: Inherited from GuidProtocolPpiCommonClass class
#
class ProtocolClass(GuidProtocolPpiCommonClass):
def __init__(self):
GuidProtocolPpiCommonClass.__init__(self)
## PpiClass
#
# This class defined Ppi item used in Module/Platform/Package files
#
# @param GuidProtocolPpiCommonClass: Inherited from GuidProtocolPpiCommonClass class
#
class PpiClass(GuidProtocolPpiCommonClass):
def __init__(self):
GuidProtocolPpiCommonClass.__init__(self)
## SkuInfoClass
#
# This class defined SkuInfo item used in Module/Platform/Package files
#
# @param object: Inherited from object class
# @param SkuIdName: Input value for SkuIdName, default is ''
# @param SkuId: Input value for SkuId, default is ''
# @param VariableName: Input value for VariableName, default is ''
# @param VariableGuid: Input value for VariableGuid, default is ''
# @param VariableOffset: Input value for VariableOffset, default is ''
# @param HiiDefaultValue: Input value for HiiDefaultValue, default is ''
# @param VpdOffset: Input value for VpdOffset, default is ''
# @param DefaultValue: Input value for DefaultValue, default is ''
#
# @var SkuIdName: To store value for SkuIdName
# @var SkuId: To store value for SkuId
# @var VariableName: To store value for VariableName
# @var VariableGuid: To store value for VariableGuid
# @var VariableOffset: To store value for VariableOffset
# @var HiiDefaultValue: To store value for HiiDefaultValue
# @var VpdOffset: To store value for VpdOffset
# @var DefaultValue: To store value for DefaultValue
#
class SkuInfoClass(object):
def __init__(self, SkuIdName = '', SkuId = '', VariableName = '', VariableGuid = '', VariableOffset = '',
HiiDefaultValue = '', VpdOffset = '', DefaultValue = '', VariableGuidValue = ''):
self.SkuIdName = SkuIdName
self.SkuId = SkuId
#
# Used by Hii
#
self.VariableName = VariableName
self.VariableGuid = VariableGuid
self.VariableGuidValue = VariableGuidValue
self.VariableOffset = VariableOffset
self.HiiDefaultValue = HiiDefaultValue
#
# Used by Vpd
#
self.VpdOffset = VpdOffset
#
# Used by Default
#
self.DefaultValue = DefaultValue
## Convert the class to a string
#
# Convert each member of the class to string
# Organize to a signle line format string
#
# @retval Rtn Formatted String
#
def __str__(self):
Rtn = Rtn = 'SkuId = ' + str(self.SkuId) + "," + \
'SkuIdName = ' + str(self.SkuIdName) + "," + \
'VariableName = ' + str(self.VariableName) + "," + \
'VariableGuid = ' + str(self.VariableGuid) + "," + \
'VariableOffset = ' + str(self.VariableOffset) + "," + \
'HiiDefaultValue = ' + str(self.HiiDefaultValue) + "," + \
'VpdOffset = ' + str(self.VpdOffset) + "," + \
'DefaultValue = ' + str(self.DefaultValue) + ","
return Rtn
## PcdErrorClass
#
#
#
class PcdErrorClass(object):
def __init__(self):
self.ValidValueList = ''
self.ValidValueListLang = ''
self.ValidValueRange = ''
self.Expression = ''
self.ErrorNumber = ''
self.ErrorMessage = []
## PcdClass
#
# This class defined Pcd item used in Module/Platform/Package files
#
# @param CommonClass: Inherited from CommonClass class
# @param CName: Input value for CName, default is ''
# @param Token: Input value for Token, default is ''
# @param TokenSpaceGuidCName: Input value for TokenSpaceGuidCName, default is ''
# @param DatumType: Input value for DatumType, default is ''
# @param MaxDatumSize: Input value for MaxDatumSize, default is ''
# @param DefaultValue: Input value for DefaultValue, default is ''
# @param ItemType: Input value for ItemType, default is ''
# @param ValidUsage: Input value for ValidUsage, default is []
# @param SkuInfoList: Input value for SkuInfoList, default is {}
# @param SupModuleList: Input value for SupModuleList, default is []
#
# @var CName: To store value for CName
# @var Token: To store value for Token
# @var TokenSpaceGuidCName: To store value for TokenSpaceGuidCName
# @var DatumType: To store value for DatumType, selection scope is in below list
# UINT8 | UINT16 | UINT32 | UINT64 | VOID* | BOOLEAN
# @var MaxDatumSize: To store value for MaxDatumSize
# @var DefaultValue: To store value for DefaultValue
# @var ItemType: To store value for ItemType, selection scope is in below list
# FEATURE_FLAG | FIXED_AT_BUILD | PATCHABLE_IN_MODULE | DYNAMIC | DYNAMIC_EX
# @var ValidUsage: To store value for ValidUsage, selection scope is in below list
# FEATURE_FLAG | FIXED_AT_BUILD | PATCHABLE_IN_MODULE | DYNAMIC | DYNAMIC_EX
# @var SkuInfoList: To store value for SkuInfoList
# It is a set structure as { [SkuIdName] : SkuInfoClass }
# @var SupModuleList: To store value for SupModuleList, selection scope is in below list
# BASE | SEC | PEI_CORE | PEIM | DXE_CORE | DXE_DRIVER | DXE_RUNTIME_DRIVER | DXE_SAL_DRIVER | DXE_SMM_DRIVER | UEFI_DRIVER | UEFI_APPLICATION | USER_DEFINED
#
class PcdClass(CommonClass):
def __init__(self, CName = '', Token = '', TokenSpaceGuidCName = '', DatumType = '', MaxDatumSize = '', DefaultValue = '', ItemType = '', ValidUsage = None, SkuInfoList = None, SupModuleList = None):
self.CName = CName
self.Token = Token
self.TokenSpaceGuidCName = TokenSpaceGuidCName
self.DatumType = DatumType
self.MaxDatumSize = MaxDatumSize
self.DefaultValue = DefaultValue
self.ItemType = ItemType
self.ValidUsage = ValidUsage
self.PcdItemType = ''
self.TokenSpaceGuidValue = ''
self.PcdUsage = ''
self.PcdCName = ''
self.Value = ''
self.Offset = ''
if self.ValidUsage == None:
self.ValidUsage = []
self.SkuInfoList = SkuInfoList
if self.SkuInfoList == None:
self.SkuInfoList = {}
self.SupModuleList = SupModuleList
if self.SupModuleList == None:
self.SupModuleList = []
CommonClass.__init__(self)
self.PcdErrors = []
## BuildOptionClass
#
# This class defined BuildOption item used in Module/Platform/Package files
#
# @param IncludeStatementClass: Inherited from IncludeStatementClass class
# @param ToolChainFamily: Input value for ToolChainFamily, default is ''
# @param ToolChain: Input value for ToolChain, default is ''
# @param Option: Input value for Option, default is ''
#
# @var Statement: To store value for Statement
# It is a string in a special format as "Family:Target_TagName_Tarch_ToolCode_FLAGS = String"
# @var ToolChainFamily: To store value for ToolChainFamily
# @var ToolChain: To store value for ToolChain
# @var Option: To store value for Option
# @var BuildTarget: To store value for BuildTarget
# @var TagName: To store value for TagName
# @var ToolCode: To store value for ToolCode
# @var SupArchList: To store value for SupArchList, selection scope is in below list
# EBC | IA32 | X64 | IPF | ARM | PPC
#
class BuildOptionClass(IncludeStatementClass):
def __init__(self, ToolChainFamily = '', ToolChain = '', Option = ''):
IncludeStatementClass.__init__(self)
self.Statement = ''
self.ToolChainFamily = ToolChainFamily
self.ToolChain = ToolChain
self.Option = Option
self.BuildTarget = ''
self.TagName = ''
self.ToolCode = ''
self.SupArchList = []
## IncludeClass
#
# This class defined Include item used in Module/Platform/Package files
#
# @param CommonClass: Inherited from CommonClass class
#
# @var FilePath: To store value for FilePath
# @var ModuleType: To store value for ModuleType
# @var Comment: To store value for Comment
#
class IncludeClass(CommonClass):
def __init__(self):
self.FilePath = ''
self.ModuleType = ''
self.SupModuleList = []
self.Comment = ''
CommonClass.__init__(self)
## FileClass
#
#
class FileClass(CommonClass):
def __init__(self):
self.Filename = ''
self.Executable = ''
self.Family = ''
self.FileType = ''
CommonClass.__init__(self)
## MiscFileClass
#
#
class MiscFileClass(CommonHeaderClass):
def __init__(self):
CommonHeaderClass.__init__(self)
self.Name = ''
self.Files = []
## UserExtensionsClass
#
# This class defined UserExtensions item used in Module/Platform/Package files
#
# @param object: Inherited from object class
#
# @var UserID: To store value for UserID
# @var Identifier: To store value for Identifier
# @var Content: To store value for Content
#
class UserExtensionsClass(object):
def __init__(self):
self.UserID = ''
self.Identifier = 0
self.Content = ''
self.Defines = []
self.BuildOptions = []

View File

@@ -0,0 +1,351 @@
## @file
# This file is used to define class for data sturcture used in ECC
#
# Copyright (c) 2008, Intel Corporation
# All rights reserved. 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
#
import Common.EdkLogger as EdkLogger
##
# Static values for data models
#
MODEL_UNKNOWN = 0
MODEL_FILE_C = 1001
MODEL_FILE_H = 1002
MODEL_FILE_ASM = 1003
MODEL_FILE_INF = 1011
MODEL_FILE_DEC = 1012
MODEL_FILE_DSC = 1013
MODEL_FILE_FDF = 1014
MODEL_FILE_INC = 1015
MODEL_FILE_CIF = 1016
MODEL_IDENTIFIER_FILE_HEADER = 2001
MODEL_IDENTIFIER_FUNCTION_HEADER = 2002
MODEL_IDENTIFIER_COMMENT = 2003
MODEL_IDENTIFIER_PARAMETER = 2004
MODEL_IDENTIFIER_STRUCTURE = 2005
MODEL_IDENTIFIER_VARIABLE = 2006
MODEL_IDENTIFIER_INCLUDE = 2007
MODEL_IDENTIFIER_PREDICATE_EXPRESSION = 2008
MODEL_IDENTIFIER_ENUMERATE = 2009
MODEL_IDENTIFIER_PCD = 2010
MODEL_IDENTIFIER_UNION = 2011
MODEL_IDENTIFIER_MACRO_IFDEF = 2012
MODEL_IDENTIFIER_MACRO_IFNDEF = 2013
MODEL_IDENTIFIER_MACRO_DEFINE = 2014
MODEL_IDENTIFIER_MACRO_ENDIF = 2015
MODEL_IDENTIFIER_MACRO_PROGMA = 2016
MODEL_IDENTIFIER_FUNCTION_CALLING = 2018
MODEL_IDENTIFIER_TYPEDEF = 2017
MODEL_IDENTIFIER_FUNCTION_DECLARATION = 2019
MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION = 2020
MODEL_EFI_PROTOCOL = 3001
MODEL_EFI_PPI = 3002
MODEL_EFI_GUID = 3003
MODEL_EFI_LIBRARY_CLASS = 3004
MODEL_EFI_LIBRARY_INSTANCE = 3005
MODEL_EFI_PCD = 3006
MODEL_EFI_SOURCE_FILE = 3007
MODEL_EFI_BINARY_FILE = 3008
MODEL_EFI_SKU_ID = 3009
MODEL_EFI_INCLUDE = 3010
MODEL_EFI_DEPEX = 3011
MODEL_PCD = 4000
MODEL_PCD_FIXED_AT_BUILD = 4001
MODEL_PCD_PATCHABLE_IN_MODULE = 4002
MODEL_PCD_FEATURE_FLAG = 4003
MODEL_PCD_DYNAMIC_EX = 4004
MODEL_PCD_DYNAMIC_EX_DEFAULT = 4005
MODEL_PCD_DYNAMIC_EX_VPD = 4006
MODEL_PCD_DYNAMIC_EX_HII = 4007
MODEL_PCD_DYNAMIC = 4008
MODEL_PCD_DYNAMIC_DEFAULT = 4009
MODEL_PCD_DYNAMIC_VPD = 4010
MODEL_PCD_DYNAMIC_HII = 4011
MODEL_META_DATA_HEADER = 5001
MODEL_META_DATA_INCLUDE = 5002
MODEL_META_DATA_DEFINE = 5003
MODEL_META_DATA_CONDITIONAL_STATEMENT_IF = 5004
MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE = 5005
MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF = 5006
MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF = 5007
MODEL_META_DATA_BUILD_OPTION = 5008
MODEL_META_DATA_COMPONENT = 5009
MODEL_META_DATA_USER_EXTENSION = 5010
MODEL_META_DATA_PACKAGE = 5011
MODEL_META_DATA_NMAKE = 5012
MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF = 50013
MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF = 5014
MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH = 5015
MODEL_LIST = [('MODEL_UNKNOWN', MODEL_UNKNOWN),
('MODEL_FILE_C', MODEL_FILE_C),
('MODEL_FILE_H', MODEL_FILE_H),
('MODEL_FILE_ASM', MODEL_FILE_ASM),
('MODEL_FILE_INF', MODEL_FILE_INF),
('MODEL_FILE_DEC', MODEL_FILE_DEC),
('MODEL_FILE_DSC', MODEL_FILE_DSC),
('MODEL_FILE_FDF', MODEL_FILE_FDF),
('MODEL_FILE_INC', MODEL_FILE_INC),
('MODEL_IDENTIFIER_FILE_HEADER', MODEL_IDENTIFIER_FILE_HEADER),
('MODEL_IDENTIFIER_FUNCTION_HEADER', MODEL_IDENTIFIER_FUNCTION_HEADER),
('MODEL_IDENTIFIER_COMMENT', MODEL_IDENTIFIER_COMMENT),
('MODEL_IDENTIFIER_PARAMETER', MODEL_IDENTIFIER_PARAMETER),
('MODEL_IDENTIFIER_STRUCTURE', MODEL_IDENTIFIER_STRUCTURE),
('MODEL_IDENTIFIER_VARIABLE', MODEL_IDENTIFIER_VARIABLE),
('MODEL_IDENTIFIER_INCLUDE', MODEL_IDENTIFIER_INCLUDE),
('MODEL_IDENTIFIER_PREDICATE_EXPRESSION', MODEL_IDENTIFIER_PREDICATE_EXPRESSION),
('MODEL_IDENTIFIER_ENUMERATE', MODEL_IDENTIFIER_ENUMERATE),
('MODEL_IDENTIFIER_PCD', MODEL_IDENTIFIER_PCD),
('MODEL_IDENTIFIER_UNION', MODEL_IDENTIFIER_UNION),
('MODEL_IDENTIFIER_MACRO_IFDEF', MODEL_IDENTIFIER_MACRO_IFDEF),
('MODEL_IDENTIFIER_MACRO_IFNDEF', MODEL_IDENTIFIER_MACRO_IFNDEF),
('MODEL_IDENTIFIER_MACRO_DEFINE', MODEL_IDENTIFIER_MACRO_DEFINE),
('MODEL_IDENTIFIER_MACRO_ENDIF', MODEL_IDENTIFIER_MACRO_ENDIF),
('MODEL_IDENTIFIER_MACRO_PROGMA', MODEL_IDENTIFIER_MACRO_PROGMA),
('MODEL_IDENTIFIER_FUNCTION_CALLING', MODEL_IDENTIFIER_FUNCTION_CALLING),
('MODEL_IDENTIFIER_TYPEDEF', MODEL_IDENTIFIER_TYPEDEF),
('MODEL_IDENTIFIER_FUNCTION_DECLARATION', MODEL_IDENTIFIER_FUNCTION_DECLARATION),
('MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION', MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION),
('MODEL_EFI_PROTOCOL', MODEL_EFI_PROTOCOL),
('MODEL_EFI_PPI', MODEL_EFI_PPI),
('MODEL_EFI_GUID', MODEL_EFI_GUID),
('MODEL_EFI_LIBRARY_CLASS', MODEL_EFI_LIBRARY_CLASS),
('MODEL_EFI_LIBRARY_INSTANCE', MODEL_EFI_LIBRARY_INSTANCE),
('MODEL_EFI_PCD', MODEL_EFI_PCD),
('MODEL_EFI_SKU_ID', MODEL_EFI_SKU_ID),
('MODEL_EFI_INCLUDE', MODEL_EFI_INCLUDE),
('MODEL_EFI_DEPEX', MODEL_EFI_DEPEX),
('MODEL_IDENTIFIER_UNION', MODEL_IDENTIFIER_UNION),
('MODEL_EFI_SOURCE_FILE', MODEL_EFI_SOURCE_FILE),
('MODEL_EFI_BINARY_FILE', MODEL_EFI_BINARY_FILE),
('MODEL_PCD', MODEL_PCD),
('MODEL_PCD_FIXED_AT_BUILD', MODEL_PCD_FIXED_AT_BUILD),
('MODEL_PCD_PATCHABLE_IN_MODULE', MODEL_PCD_PATCHABLE_IN_MODULE),
('MODEL_PCD_FEATURE_FLAG', MODEL_PCD_FEATURE_FLAG),
('MODEL_PCD_DYNAMIC_EX', MODEL_PCD_DYNAMIC_EX),
('MODEL_PCD_DYNAMIC_EX_DEFAULT', MODEL_PCD_DYNAMIC_EX_DEFAULT),
('MODEL_PCD_DYNAMIC_EX_VPD', MODEL_PCD_DYNAMIC_EX_VPD),
('MODEL_PCD_DYNAMIC_EX_HII', MODEL_PCD_DYNAMIC_EX_HII),
('MODEL_PCD_DYNAMIC', MODEL_PCD_DYNAMIC),
('MODEL_PCD_DYNAMIC_DEFAULT', MODEL_PCD_DYNAMIC_DEFAULT),
('MODEL_PCD_DYNAMIC_VPD', MODEL_PCD_DYNAMIC_VPD),
('MODEL_PCD_DYNAMIC_HII', MODEL_PCD_DYNAMIC_HII),
("MODEL_META_DATA_HEADER", MODEL_META_DATA_HEADER),
("MODEL_META_DATA_INCLUDE", MODEL_META_DATA_INCLUDE),
("MODEL_META_DATA_DEFINE", MODEL_META_DATA_DEFINE),
("MODEL_META_DATA_CONDITIONAL_STATEMENT_IF", MODEL_META_DATA_CONDITIONAL_STATEMENT_IF),
("MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE", MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE),
("MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF", MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF),
("MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF", MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF),
("MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH", MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH),
("MODEL_META_DATA_BUILD_OPTION", MODEL_META_DATA_BUILD_OPTION),
("MODEL_META_DATA_COMPONENT", MODEL_META_DATA_COMPONENT),
('MODEL_META_DATA_USER_EXTENSION', MODEL_META_DATA_USER_EXTENSION),
('MODEL_META_DATA_PACKAGE', MODEL_META_DATA_PACKAGE),
('MODEL_META_DATA_NMAKE', MODEL_META_DATA_NMAKE)
]
## FunctionClass
#
# This class defines a structure of a function
#
# @param ID: ID of a Function
# @param Header: Header of a Function
# @param Modifier: Modifier of a Function
# @param Name: Name of a Function
# @param ReturnStatement: ReturnStatement of a Funciont
# @param StartLine: StartLine of a Function
# @param StartColumn: StartColumn of a Function
# @param EndLine: EndLine of a Function
# @param EndColumn: EndColumn of a Function
# @param BodyStartLine: BodyStartLine of a Function Body
# @param BodyStartColumn: BodyStartColumn of a Function Body
# @param BelongsToFile: The Function belongs to which file
# @param IdentifierList: IdentifierList of a File
# @param PcdList: PcdList of a File
#
# @var ID: ID of a Function
# @var Header: Header of a Function
# @var Modifier: Modifier of a Function
# @var Name: Name of a Function
# @var ReturnStatement: ReturnStatement of a Funciont
# @var StartLine: StartLine of a Function
# @var StartColumn: StartColumn of a Function
# @var EndLine: EndLine of a Function
# @var EndColumn: EndColumn of a Function
# @var BodyStartLine: StartLine of a Function Body
# @var BodyStartColumn: StartColumn of a Function Body
# @var BelongsToFile: The Function belongs to which file
# @var IdentifierList: IdentifierList of a File
# @var PcdList: PcdList of a File
#
class FunctionClass(object):
def __init__(self, ID = -1, Header = '', Modifier = '', Name = '', ReturnStatement = '', \
StartLine = -1, StartColumn = -1, EndLine = -1, EndColumn = -1, \
BodyStartLine = -1, BodyStartColumn = -1, BelongsToFile = -1, \
IdentifierList = [], PcdList = [], \
FunNameStartLine = -1, FunNameStartColumn = -1):
self.ID = ID
self.Header = Header
self.Modifier = Modifier
self.Name = Name
self.ReturnStatement = ReturnStatement
self.StartLine = StartLine
self.StartColumn = StartColumn
self.EndLine = EndLine
self.EndColumn = EndColumn
self.BodyStartLine = BodyStartLine
self.BodyStartColumn = BodyStartColumn
self.BelongsToFile = BelongsToFile
self.FunNameStartLine = FunNameStartLine
self.FunNameStartColumn = FunNameStartColumn
self.IdentifierList = IdentifierList
self.PcdList = PcdList
## IdentifierClass
#
# This class defines a structure of a variable
#
# @param ID: ID of a Identifier
# @param Modifier: Modifier of a Identifier
# @param Type: Type of a Identifier
# @param Name: Name of a Identifier
# @param Value: Value of a Identifier
# @param Model: Model of a Identifier
# @param BelongsToFile: The Identifier belongs to which file
# @param BelongsToFunction: The Identifier belongs to which function
# @param StartLine: StartLine of a Identifier
# @param StartColumn: StartColumn of a Identifier
# @param EndLine: EndLine of a Identifier
# @param EndColumn: EndColumn of a Identifier
#
# @var ID: ID of a Identifier
# @var Modifier: Modifier of a Identifier
# @var Type: Type of a Identifier
# @var Name: Name of a Identifier
# @var Value: Value of a Identifier
# @var Model: Model of a Identifier
# @var BelongsToFile: The Identifier belongs to which file
# @var BelongsToFunction: The Identifier belongs to which function
# @var StartLine: StartLine of a Identifier
# @var StartColumn: StartColumn of a Identifier
# @var EndLine: EndLine of a Identifier
# @var EndColumn: EndColumn of a Identifier
#
class IdentifierClass(object):
def __init__(self, ID = -1, Modifier = '', Type = '', Name = '', Value = '', Model = MODEL_UNKNOWN, \
BelongsToFile = -1, BelongsToFunction = -1, StartLine = -1, StartColumn = -1, EndLine = -1, EndColumn = -1):
self.ID = ID
self.Modifier = Modifier
self.Type = Type
self.Name = Name
self.Value = Value
self.Model = Model
self.BelongsToFile = BelongsToFile
self.BelongsToFunction = BelongsToFunction
self.StartLine = StartLine
self.StartColumn = StartColumn
self.EndLine = EndLine
self.EndColumn = EndColumn
## PcdClass
#
# This class defines a structure of a Pcd
#
# @param ID: ID of a Pcd
# @param CName: CName of a Pcd
# @param TokenSpaceGuidCName: TokenSpaceGuidCName of a Pcd
# @param Token: Token of a Pcd
# @param DatumType: DatumType of a Pcd
# @param Model: Model of a Pcd
# @param BelongsToFile: The Pcd belongs to which file
# @param BelongsToFunction: The Pcd belongs to which function
# @param StartLine: StartLine of a Pcd
# @param StartColumn: StartColumn of a Pcd
# @param EndLine: EndLine of a Pcd
# @param EndColumn: EndColumn of a Pcd
#
# @var ID: ID of a Pcd
# @var CName: CName of a Pcd
# @var TokenSpaceGuidCName: TokenSpaceGuidCName of a Pcd
# @var Token: Token of a Pcd
# @var DatumType: DatumType of a Pcd
# @var Model: Model of a Pcd
# @var BelongsToFile: The Pcd belongs to which file
# @var BelongsToFunction: The Pcd belongs to which function
# @var StartLine: StartLine of a Pcd
# @var StartColumn: StartColumn of a Pcd
# @var EndLine: EndLine of a Pcd
# @var EndColumn: EndColumn of a Pcd
#
class PcdDataClass(object):
def __init__(self, ID = -1, CName = '', TokenSpaceGuidCName = '', Token = '', DatumType = '', Model = MODEL_UNKNOWN, \
BelongsToFile = -1, BelongsToFunction = -1, StartLine = -1, StartColumn = -1, EndLine = -1, EndColumn = -1):
self.ID = ID
self.CName = CName
self.TokenSpaceGuidCName = TokenSpaceGuidCName
self.Token = Token
self.DatumType = DatumType
self.BelongsToFile = BelongsToFile
self.BelongsToFunction = BelongsToFunction
self.StartLine = StartLine
self.StartColumn = StartColumn
self.EndLine = EndLine
self.EndColumn = EndColumn
## FileClass
#
# This class defines a structure of a file
#
# @param ID: ID of a File
# @param Name: Name of a File
# @param ExtName: ExtName of a File
# @param Path: Path of a File
# @param FullPath: FullPath of a File
# @param Model: Model of a File
# @param TimeStamp: TimeStamp of a File
# @param FunctionList: FunctionList of a File
# @param IdentifierList: IdentifierList of a File
# @param PcdList: PcdList of a File
#
# @var ID: ID of a File
# @var Name: Name of a File
# @var ExtName: ExtName of a File
# @var Path: Path of a File
# @var FullPath: FullPath of a File
# @var Model: Model of a File
# @var TimeStamp: TimeStamp of a File
# @var FunctionList: FunctionList of a File
# @var IdentifierList: IdentifierList of a File
# @var PcdList: PcdList of a File
#
class FileClass(object):
def __init__(self, ID = -1, Name = '', ExtName = '', Path = '', FullPath = '', Model = MODEL_UNKNOWN, TimeStamp = '', \
FunctionList = [], IdentifierList = [], PcdList = []):
self.ID = ID
self.Name = Name
self.ExtName = ExtName
self.Path = Path
self.FullPath = FullPath
self.Model = Model
self.TimeStamp = TimeStamp
self.FunctionList = FunctionList
self.IdentifierList = IdentifierList
self.PcdList = PcdList

View File

@@ -0,0 +1,159 @@
## @file
# This file is used to define a class object to describe a distribution package
#
# Copyright (c) 2008, Intel Corporation
# All rights reserved. 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
#
import os.path
from CommonClass import *
from Common.Misc import sdict
from Common.Misc import GetFiles
from Common.DecClassObjectLight import Dec
from Common.InfClassObjectLight import Inf
from Common.XmlParser import *
## DistributionPackageHeaderClass
#
class DistributionPackageHeaderClass(IdentificationClass, CommonHeaderClass):
def __init__(self):
IdentificationClass.__init__(self)
CommonHeaderClass.__init__(self)
self.ReadOnly = 'False'
self.RePackage = 'True'
self.Vendor = ''
self.Date = ''
self.Signature = 'Md5Sum'
self.XmlSpecification = ''
## DistributionPackageClass
#
#
class DistributionPackageClass(object):
def __init__(self):
self.Header = DistributionPackageHeaderClass()
self.PackageSurfaceArea = sdict() # {(Guid, Version, Path) : PackageObj}
self.ModuleSurfaceArea = sdict() # {(Guid, Version, Path) : ModuleObj}
self.Tools = MiscFileClass()
self.MiscellaneousFiles = MiscFileClass()
self.UserExtensions = []
## Get all included packages and modules for a distribution package
#
# @param WorkspaceDir: WorkspaceDir
# @param PackageList: A list of all packages
# @param ModuleList: A list of all modules
#
def GetDistributionPackage(self, WorkspaceDir, PackageList, ModuleList):
AllGuidVersionDict = {}
# Get Packages
if PackageList:
for PackageFile in PackageList:
PackageFileFullPath = os.path.normpath(os.path.join(WorkspaceDir, PackageFile))
DecObj = Dec(PackageFileFullPath, True, WorkspaceDir)
PackageObj = DecObj.Package
AllGuidVersionDict[PackageFileFullPath] = [PackageObj.PackageHeader.Guid, PackageObj.PackageHeader.Version]
# Parser inf file one bye one
for File in PackageObj.MiscFiles.Files:
Filename = os.path.normpath(os.path.join(PackageObj.PackageHeader.RelaPath, File.Filename))
(Name, ExtName) = os.path.splitext(Filename)
if ExtName.upper() == '.INF':
InfObj = Inf(Filename, True, WorkspaceDir, DecObj.Identification.PackagePath)
ModuleObj = InfObj.Module
AllGuidVersionDict[File] = [ModuleObj.ModuleHeader.Guid, ModuleObj.ModuleHeader.Version]
# Find and update Guid/Version of LibraryClass
for Item in ModuleObj.LibraryClasses:
if Item.RecommendedInstance:
LibClassIns = os.path.normpath(os.path.join(WorkspaceDir, Item.RecommendedInstance))
Guid, Version = '', ''
if LibClassIns in AllGuidVersionDict:
Guid = AllGuidVersionDict[LibClassIns][0]
Version = AllGuidVersionDict[LibClassIns][1]
else:
Lib = Inf(LibClassIns, True, WorkspaceDir)
Guid = Lib.Module.ModuleHeader.Guid
Version = Lib.Module.ModuleHeader.Version
AllGuidVersionDict[LibClassIns] = [Guid, Version]
Item.RecommendedInstanceGuid = Guid
Item.RecommendedInstanceVersion = Version
# Find and update Guid/Version of
for Item in ModuleObj.PackageDependencies:
if Item.FilePath:
PackageFilePath = os.path.normpath(os.path.join(WorkspaceDir, Item.FilePath))
Guid, Version = '', ''
if PackageFilePath in AllGuidVersionDict:
Guid = AllGuidVersionDict[PackageFilePath][0]
Version = AllGuidVersionDict[PackageFilePath][1]
else:
PackageDependencies = Dec(PackageFilePath, True, WorkspaceDir)
Guid = PackageDependencies.Package.PackageHeader.Guid
Version = PackageDependencies.Package.PackageHeader.Version
AllGuidVersionDict[PackageFilePath] = [Guid, Version]
Item.PackageGuid = Guid
Item.PackageVersion = Version
# Add module to package
PackageObj.Modules[(ModuleObj.ModuleHeader.Guid, ModuleObj.ModuleHeader.Version, ModuleObj.ModuleHeader.CombinePath)] = ModuleObj
self.PackageSurfaceArea[(PackageObj.PackageHeader.Guid, PackageObj.PackageHeader.Version, PackageObj.PackageHeader.CombinePath)] = PackageObj
# Get Modules
if ModuleList:
for ModuleFile in ModuleList:
ModuleFileFullPath = os.path.normpath(os.path.join(WorkspaceDir, ModuleFile))
InfObj = Inf(ModuleFileFullPath, True, WorkspaceDir)
ModuleObj = InfObj.Module
AllGuidVersionDict[ModuleFileFullPath] = [ModuleObj.ModuleHeader.Guid, ModuleObj.ModuleHeader.Version]
# Find and update Guid/Version of LibraryClass
for Item in ModuleObj.LibraryClasses:
if Item.RecommendedInstance:
LibClassIns = os.path.normpath(os.path.join(WorkspaceDir, Item.RecommendedInstance))
Guid, Version = '', ''
if LibClassIns in AllGuidVersionDict:
Guid = AllGuidVersionDict[LibClassIns][0]
Version = AllGuidVersionDict[LibClassIns][1]
else:
Lib = Inf(LibClassIns, True, WorkspaceDir)
Guid = Lib.Module.ModuleHeader.Guid
Version = Lib.Module.ModuleHeader.Version
AllGuidVersionDict[LibClassIns] = [Guid, Version]
Item.RecommendedInstanceGuid = Guid
Item.RecommendedInstanceVersion = Version
# Find and update Guid/Version of
for Item in ModuleObj.PackageDependencies:
if Item.FilePath:
PackageFilePath = os.path.normpath(os.path.join(WorkspaceDir, Item.FilePath))
Guid, Version = '', ''
if PackageFilePath in AllGuidVersionDict:
Guid = AllGuidVersionDict[PackageFilePath][0]
Version = AllGuidVersionDict[PackageFilePath][1]
else:
PackageDependencies = Dec(PackageFilePath, True, WorkspaceDir)
Guid = PackageDependencies.Package.PackageHeader.Guid
Version = PackageDependencies.Package.PackageHeader.Version
AllGuidVersionDict[PackageFilePath] = [Guid, Version]
Item.PackageGuid = Guid
Item.PackageVersion = Version
self.ModuleSurfaceArea[(ModuleObj.ModuleHeader.Guid, ModuleObj.ModuleHeader.Version, ModuleObj.ModuleHeader.CombinePath)] = ModuleObj
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
pass
D = DistributionPackageClass()
D.GetDistributionPackage(os.getenv('WORKSPACE'), ['MdePkg/MdePkg.dec', 'TianoModulePkg/TianoModulePkg.dec'], ['MdeModulePkg/Application/HelloWorld/HelloWorld.inf'])
Xml = DistributionPackageXml()
print Xml.ToXml(D)
E = Xml.FromXml('C:\\2.xml')
#print Xml.ToXml(E)

View File

@@ -0,0 +1,402 @@
## @file
# classes represent data in FDF
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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.
#
## FD data in FDF
#
#
class FDClassObject:
## The constructor
#
# @param self The object pointer
#
def __init__(self):
self.FdUiName = ''
self.CreateFileName = None
self.BaseAddress = None
self.BaseAddressPcd = None
self.Size = None
self.SizePcd = None
self.ErasePolarity = '1'
# 3-tuple list (blockSize, numBlocks, pcd)
self.BlockSizeList = []
# DefineVarDict[var] = value
self.DefineVarDict = {}
# SetVarDict[var] = value
self.SetVarDict = {}
self.RegionList = []
self.vtfRawDict = {}
## FV data in FDF
#
#
class FvClassObject:
## The constructor
#
# @param self The object pointer
#
def __init__(self):
self.UiFvName = None
self.CreateFileName = None
# 3-tuple list (blockSize, numBlocks, pcd)
self.BlockSizeList = []
# DefineVarDict[var] = value
self.DefineVarDict = {}
# SetVarDict[var] = value
self.SetVarDict = {}
self.FvAlignment = None
# FvAttributeDict[attribute] = TRUE/FALSE (1/0)
self.FvAttributeDict = {}
self.FvNameGuid = None
self.AprioriSectionList = []
self.FfsList = []
self.BsBaseAddress = None
self.RtBaseAddress = None
## Region data in FDF
#
#
class RegionClassObject:
## The constructor
#
# @param self The object pointer
#
def __init__(self):
self.Offset = None # The begin position of the Region
self.Size = None # The Size of the Region
self.PcdOffset = None
self.PcdSize = None
self.SetVarDict = {}
self.RegionType = None
self.RegionDataList = []
## FFS data in FDF
#
#
class FfsClassObject:
## The constructor
#
# @param self The object pointer
#
def __init__(self):
self.NameGuid = None
self.Fixed = False
self.CheckSum = False
self.Alignment = None
self.SectionList = []
## FILE statement data in FDF
#
#
class FileStatementClassObject (FfsClassObject) :
## The constructor
#
# @param self The object pointer
#
def __init__(self):
FfsClassObject.__init__(self)
self.FvFileType = None
self.FileName = None
self.KeyStringList = []
self.FvName = None
self.FdName = None
self.DefineVarDict = {}
self.AprioriSection = None
self.KeepReloc = None
## INF statement data in FDF
#
#
class FfsInfStatementClassObject(FfsClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
FfsClassObject.__init__(self)
self.Rule = None
self.Version = None
self.Ui = None
self.InfFileName = None
self.BuildNum = ''
self.KeyStringList = []
self.KeepReloc = None
self.UseArch = None
## APRIORI section data in FDF
#
#
class AprioriSectionClassObject:
## The constructor
#
# @param self The object pointer
#
def __init__(self):
# DefineVarDict[var] = value
self.DefineVarDict = {}
self.FfsList = []
## section data in FDF
#
#
class SectionClassObject:
## The constructor
#
# @param self The object pointer
#
def __init__(self):
self.Alignment = None
## Depex expression section in FDF
#
#
class DepexSectionClassObject (SectionClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
self.DepexType = None
self.Expression = None
## Compress section data in FDF
#
#
class CompressSectionClassObject (SectionClassObject) :
## The constructor
#
# @param self The object pointer
#
def __init__(self):
SectionClassObject.__init__(self)
self.CompType = None
self.SectionList = []
## Data section data in FDF
#
#
class DataSectionClassObject (SectionClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
SectionClassObject.__init__(self)
self.SecType = None
self.SectFileName = None
self.SectionList = []
self.KeepReloc = True
## Rule section data in FDF
#
#
class EfiSectionClassObject (SectionClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
SectionClassObject.__init__(self)
self.SectionType = None
self.Optional = False
self.FileType = None
self.StringData = None
self.FileName = None
self.FileExtension = None
self.BuildNum = None
self.KeepReloc = None
## FV image section data in FDF
#
#
class FvImageSectionClassObject (SectionClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
SectionClassObject.__init__(self)
self.Fv = None
self.FvName = None
self.FvFileType = None
self.FvFileName = None
self.FvFileExtension = None
## GUIDed section data in FDF
#
#
class GuidSectionClassObject (SectionClassObject) :
## The constructor
#
# @param self The object pointer
#
def __init__(self):
SectionClassObject.__init__(self)
self.NameGuid = None
self.SectionList = []
self.SectionType = None
self.ProcessRequired = False
self.AuthStatusValid = False
## UI section data in FDF
#
#
class UiSectionClassObject (SectionClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
SectionClassObject.__init__(self)
self.StringData = None
self.FileName = None
## Version section data in FDF
#
#
class VerSectionClassObject (SectionClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
SectionClassObject.__init__(self)
self.BuildNum = None
self.StringData = None
self.FileName = None
## Rule data in FDF
#
#
class RuleClassObject :
## The constructor
#
# @param self The object pointer
#
def __init__(self):
self.Arch = None
self.ModuleType = None # For Module Type
self.TemplateName = None
self.NameGuid = None
self.Fixed = False
self.Alignment = None
self.CheckSum = False
self.FvFileType = None # for Ffs File Type
self.KeyStringList = []
self.KeepReloc = None
## Complex rule data in FDF
#
#
class RuleComplexFileClassObject(RuleClassObject) :
## The constructor
#
# @param self The object pointer
#
def __init__(self):
RuleClassObject.__init__(self)
self.SectionList = []
## Simple rule data in FDF
#
#
class RuleSimpleFileClassObject(RuleClassObject) :
## The constructor
#
# @param self The object pointer
#
def __init__(self):
RuleClassObject.__init__(self)
self.FileName = None
self.SectionType = ''
self.FileExtension = None
## File extension rule data in FDF
#
#
class RuleFileExtensionClassObject(RuleClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
RuleClassObject.__init__(self)
self.FileExtension = None
## Capsule data in FDF
#
#
class CapsuleClassObject :
## The constructor
#
# @param self The object pointer
#
def __init__(self):
self.SpecName = None
self.UiCapsuleName = None
self.CreateFile = None
self.GroupIdNumber = None
# DefineVarDict[var] = value
self.DefineVarDict = {}
# SetVarDict[var] = value
self.SetVarDict = {}
# TokensDict[var] = value
self.TokensDict = {}
self.CapsuleDataList = []
## VTF data in FDF
#
#
class VtfClassObject :
## The constructor
#
# @param self The object pointer
#
def __init__(self):
self.KeyArch = None
self.ArchList = None
self.UiName = None
self.ResetBin = None
self.ComponentStatementList = []
## VTF component data in FDF
#
#
class ComponentStatementClassObject :
## The constructor
#
# @param self The object pointer
#
def __init__(self):
self.CompName = None
self.CompLoc = None
self.CompType = None
self.CompVer = None
self.CompCs = None
self.CompBin = None
self.CompSym = None
self.CompSize = None
self.FilePos = None
## OptionROM data in FDF
#
#
class OptionRomClassObject:
## The constructor
#
# @param self The object pointer
#
def __init__(self):
self.DriverName = None
self.FfsList = []

View File

@@ -0,0 +1,486 @@
## @file
# This file is used to define a class object to describe a module
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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 CommonClass import *
## ModuleHeaderClass
#
# This class defined header items used in Module file
#
# @param IdentificationClass: Inherited from IdentificationClass class
# @param CommonHeaderClass: Inherited from CommonHeaderClass class
# @param DefineClass: Inherited from DefineClass class
#
# @var ModuleType: To store value for ModuleType
# @var SupArchList: To store value for SupArchList, selection scope is in below list
# EBC | IA32 | X64 | IPF | ARM | PPC
# @var BinaryModule: To store value for BinaryModule
# @var OutputFileBasename: To store value for OutputFileBasename
# @var ClonedFrom: To store value for ClonedFrom, it is a set structure as
# [ ClonedRecordClass, ... ]
# @var PcdIsDriver: To store value for PcdIsDriver, selection scope is in below list
# PEI_PCD_DRIVER | DXE_PCD_DRIVER
# @var TianoR8FlashMap_h: To store value for TianoR8FlashMap_h
# @var InfVersion: To store value for InfVersion
# @var EfiSpecificationVersion: To store value for EfiSpecificationVersion
# @var EdkReleaseVersion: To store value for EdkReleaseVersion
# @var LibraryClass: To store value for LibraryClass, it is a set structure as
# [ LibraryClassClass, ...]
# @var ComponentType: To store value for ComponentType, selection scope is in below list
# LIBRARY | SECURITY_CORE | PEI_CORE | COMBINED_PEIM_DRIVER | PIC_PEIM | RELOCATABLE_PEIM | BS_DRIVER | RT_DRIVER | SAL_RT_DRIVER | APPLICATION
# @var MakefileName: To store value for MakefileName
# @var BuildNumber: To store value for BuildNumber
# @var BuildType: To store value for BuildType
# @var FfsExt: To store value for FfsExt
# @var FvExt: To store value for FvExt
# @var SourceFv: To store value for SourceFv
# @var CustomMakefile: To store value for CustomMakefile, it is a set structure as
# { Family : Filename, ... }
# @var Shadow: To store value for Shadow
# @var MacroDefines To store the defined macros
#
class ModuleHeaderClass(IdentificationClass, CommonHeaderClass, DefineClass):
def __init__(self):
IdentificationClass.__init__(self)
CommonHeaderClass.__init__(self)
DefineClass.__init__(self)
self.ModuleType = ''
self.SupModuleList = []
self.SupArchList = []
self.BinaryModule = False
self.OutputFileBasename = ''
self.ClonedFrom = []
self.PcdIsDriver = ''
self.TianoR8FlashMap_h = False
self.InfVersion = ''
self.EfiSpecificationVersion = ''
self.PiSpecificationVersion = ''
self.UefiSpecificationVersion = ''
self.EdkReleaseVersion = ''
self.LibraryClass = []
self.ComponentType = ''
self.MakefileName = ''
self.BuildNumber = ''
self.BuildType = ''
self.FfsExt = ''
self.FvExt = ''
self.SourceFv = ''
self.CustomMakefile = {}
self.Shadow = ''
self.MacroDefines = {}
self.SourceOverridePath = ''
self.Specification = []
## ModuleSourceFileClass
#
# This class defined source file item used in Module file
#
# @param CommonClass: Inherited from CommonClass class
# @param SourceFile: Input value for SourceFile, default is ''
# @param TagName: Input value for TagName, default is ''
# @param ToolCode: Input value for ToolCode, default is ''
# @param ToolChainFamily: Input value for ToolChainFamily, default is ''
# @param FeatureFlag: Input value for FeatureFlag, default is ''
# @param SupArchList: Input value for SupArchList, default is []
#
# @var SourceFile: To store value for SourceFile
# @var TagName: To store value for TagName
# @var ToolCode: To store value for ToolCode
# @var ToolChainFamily: To store value for ToolChainFamily
#
class ModuleSourceFileClass(CommonClass):
def __init__(self, SourceFile = '', TagName = '', ToolCode = '', ToolChainFamily = '', FeatureFlag = '', SupArchList = None):
self.SourceFile = SourceFile
self.TagName = TagName
self.ToolCode = ToolCode
self.ToolChainFamily = ToolChainFamily
self.FileType = ''
CommonClass.__init__(self, FeatureFlag = FeatureFlag, SupArchList = SupArchList)
## ModuleBinaryFileClass
#
# This class defined binary file item used in Module file
#
# @param CommonClass: Inherited from CommonClass class
# @param BinaryFile: Input value for BinaryFile, default is ''
# @param FileType: Input value for FileType, default is ''
# @param FeatureFlag: Input value for FeatureFlag, default is ''
# @param SupArchList: Input value for SupArchList, default is []
#
# @var BinaryFile: To store value for BinaryFile
# @var FileType: To store value for FileType, selection scope is in below list
# FW | GUID | PREEFORM | UEFI_APP | UNI_UI | UNI_VER | LIB | PE32 | PIC | PEI_DEPEX | DXE_DEPEX | TE | VER | UI | BIN | FV
# @var Target: To store value for Target
# @var ToolChainFamily: To store value for ToolChainFamily
#
class ModuleBinaryFileClass(CommonClass):
def __init__(self, BinaryFile = '', FileType = '', Target = '', FeatureFlag = '', SupArchList = None):
self.BinaryFile = BinaryFile
self.FileType = FileType
self.Target = Target
CommonClass.__init__(self, FeatureFlag = FeatureFlag, SupArchList = SupArchList)
self.Filenames = []
self.PatchPcdValues = []
self.PcdExValues = []
self.LibraryInstances = []
self.BuildFlags = []
## ModulePackageDependencyClass
#
# This class defined package dependency item used in Module file
#
# @param CommonClass: Inherited from CommonClass class
# @param DefineClass: Input value for DefineClass class
#
# @var FilePath: To store value for FilePath
# @var PackageName: To store value for PackageName
# @var PackageVersion: To store value for PackageVersion
# @var PackageGuid: To store value for PackageGuid
#
class ModulePackageDependencyClass(CommonClass, DefineClass):
def __init__(self):
self.FilePath = ''
self.PackageName = ''
self.PackageVersion = ''
self.PackageGuid = ''
self.Description = ''
CommonClass.__init__(self)
DefineClass.__init__(self)
## ModuleLibraryClass
#
# This class defined library item used in Module file
#
# @param CommonClass: Inherited from CommonClass class
#
# @var Library: To store value for Library
#
class ModuleLibraryClass(CommonClass):
def __init__(self):
self.Library = ''
CommonClass.__init__(self)
## ModuleEventClass
#
# This class defined event item used in Module file
#
# @param CommonClass: Inherited from CommonClass class
#
# @var CName: To store value for CName
# @var GuidCName: To store value for GuidCName
# @var Type: To store value for Type, selection scope is in below list
# CREATE_EVENT | SIGNAL_EVENT
#
class ModuleEventClass(CommonClass):
def __init__(self):
self.CName = ''
self.GuidCName = ''
self.Type = ''
CommonClass.__init__(self)
## ModuleHobClass
#
# This class defined hob item used in Module file
#
# @param CommonClass: Inherited from CommonClass class
#
# @var GuidCName: To store value for GuidCName
# @var Type: To store value for Type, selection scope is in below list
# PHIT | MEMORY_ALLOCATION | RESOURCE_DESCRIPTOR | GUID_EXTENSION | FIRMWARE_VOLUME | CPU | POOL | CAPSULE_VOLUME
#
class ModuleHobClass(CommonClass):
def __init__(self):
self.Type = ''
self.GuidCName = ''
CommonClass.__init__(self)
## ModuleVariableClass
#
# This class defined variable item used in Module file
#
# @param CommonClass: Inherited from CommonClass class
#
# @var GuidCName: To store value for GuidCName
# @var Name: To store value for Name
#
class ModuleVariableClass(CommonClass):
def __init__(self):
self.Name = ''
self.GuidCName = ''
CommonClass.__init__(self)
## ModuleBootModeClass
#
# This class defined boot mode item used in Module file
#
# @param CommonClass: Inherited from CommonClass class
#
# @var Name: To store value for Name, selection scope is in below list
# FULL | MINIMAL | NO_CHANGE | DIAGNOSTICS | DEFAULT | S2_RESUME | S3_RESUME | S4_RESUME | S5_RESUME | FLASH_UPDATE | RECOVERY_FULL | RECOVERY_MINIMAL | RECOVERY_NO_CHANGE | RECOVERY_DIAGNOSTICS | RECOVERY_DEFAULT | RECOVERY_S2_RESUME | RECOVERY_S3_RESUME | RECOVERY_S4_RESUME | RECOVERY_S5_RESUME | RECOVERY_FLASH_UPDATE
#
class ModuleBootModeClass(CommonClass):
def __init__(self):
self.Name = ''
CommonClass.__init__(self)
## ModuleSystemTableClass
#
# This class defined system table item used in Module file
#
# @param CommonClass: Inherited from CommonClass class
#
# @var CName: To store value for CName
#
class ModuleSystemTableClass(CommonClass):
def __init__(self):
self.CName = ''
CommonClass.__init__(self)
## ModuleDataHubClass
#
# This class defined data hub item used in Module file
#
# @param CommonClass: Inherited from CommonClass class
#
# @var CName: To store value for CName
#
class ModuleDataHubClass(CommonClass):
def __init__(self):
self.CName = ''
CommonClass.__init__(self)
## ModuleHiiPackageClass
#
# This class defined Hii package item used in Module file
#
# @param CommonClass: Inherited from CommonClass class
#
# @var CName: To store value for CName
#
class ModuleHiiPackageClass(CommonClass):
def __init__(self):
self.CName = ''
CommonClass.__init__(self)
## ModuleExternImageClass
#
# This class defined Extern Image item used in Module file
#
# @param object: Inherited from object class
#
# @var ModuleEntryPoint: To store value for ModuleEntryPoint
# @var ModuleUnloadImage: To store value for ModuleUnloadImage
#
class ModuleExternImageClass(object):
def __init__(self):
self.ModuleEntryPoint = ''
self.ModuleUnloadImage = ''
## ModuleExternLibraryClass
#
# This class defined Extern Library item used in Module file
#
# @param object: Inherited from object class
#
# @var Constructor: To store value for Constructor
# @var Destructor: To store value for Destructor
#
class ModuleExternLibraryClass(object):
def __init__(self):
self.Constructor = ''
self.Destructor = ''
## ModuleExternDriverClass
#
# This class defined Extern Driver item used in Module file
#
# @param object: Inherited from object class
#
# @var DriverBinding: To store value for DriverBinding
# @var ComponentName: To store value for ComponentName
# @var DriverConfig: To store value for DriverConfig
# @var DriverDiag: To store value for DriverDiag
#
class ModuleExternDriverClass(object):
def __init__(self):
self.DriverBinding= ''
self.ComponentName = ''
self.DriverConfig = ''
self.DriverDiag = ''
## ModuleExternCallBackClass
#
# This class defined Extern Call Back item used in Module file
#
# @param object: Inherited from object class
#
# @var SetVirtualAddressMapCallBack: To store value for SetVirtualAddressMapCallBack
# @var ExitBootServicesCallBack: To store value for ExitBootServicesCallBack
#
class ModuleExternCallBackClass(object):
def __init__(self):
self.SetVirtualAddressMapCallBack = ''
self.ExitBootServicesCallBack = ''
## ModuleExternClass
#
# This class defined Extern used in Module file
#
# @param object: Inherited from object class
#
#
class ModuleExternClass(CommonClass):
def __init__(self):
self.EntryPoint = ''
self.UnloadImage = ''
self.Constructor = ''
self.Destructor = ''
CommonClass.__init__(self)
## ModuleDepexClass
#
# This class defined depex item used in Module file
#
# @param CommonClass: Inherited from CommonClass class
# @param DefineClass: Input value for DefineClass class
#
# @var Depex: To store value for Depex
#
class ModuleDepexClass(CommonClass, DefineClass):
def __init__(self):
CommonClass.__init__(self)
DefineClass.__init__(self)
self.Depex = ''
## ModuleNmakeClass
#
# This class defined nmake item used in Module file
#
# @param CommonClass: Inherited from CommonClass class
#
# @var Name: To store value for Name
# @var Value: To store value for Value
#
class ModuleNmakeClass(CommonClass):
def __init__(self):
CommonClass.__init__(self)
self.Name = ''
self.Value = ''
## ModuleClass
#
# This class defined a complete module item
#
# @param object: Inherited from object class
#
# @var Header: To store value for Header, it is a structure as
# {Arch : ModuleHeaderClass}
# @var LibraryClasses: To store value for LibraryClasses, it is a list structure as
# [ LibraryClassClass, ...]
# @var Libraries: To store value for Libraries, it is a list structure as
# [ ModuleLibraryClass, ...]
# @var Sources: To store value for Sources, it is a list structure as
# [ ModuleSourceFileClass, ...]
# @var Binaries: To store value for Binaries, it is a list structure as
# [ ModuleBinaryFileClass, ...]
# @var NonProcessedFiles: To store value for NonProcessedFiles, it is a list structure as
# [ '', '', ...]
# @var PackageDependencies: To store value for PackageDependencies, it is a list structure as
# [ ModulePackageDependencyClass, ... ]
# @var Nmake: To store value for Nmake, it is a list structure as
# [ ModuleNmakeClass, ... ]
# @var Depex: To store value for Depex, it is a list structure as
# [ ModuleDepexClass, ... ]
# @var Includes: To store value for Includes, it is a list structure as
# [ IncludeClass, ...]
# @var Protocols: To store value for Protocols, it is a list structure as
# [ ProtocolClass, ...]
# @var Ppis: To store value for Ppis, it is a list structure as
# [ PpiClass, ...]
# @var Events: To store value for Events, it is a list structure as
# [ ModuleEventClass, ...]
# @var Hobs: To store value for Hobs, it is a list structure as
# [ ModuleHobClass, ...]
# @var Variables: To store value for Variables, it is a list structure as
# [ ModuleVariableClass, ...]
# @var BootModes: To store value for BootModes, it is a list structure as
# [ ModuleBootModeClass, ...]
# @var SystemTables: To store value for SystemTables, it is a list structure as
# [ ModuleSystemTableClass, ...]
# @var DataHubs: To store value for DataHubs, it is a list structure as
# [ ModuleDataHubClass, ...]
# @var HiiPackages: To store value for HiiPackages, it is a list structure as
# [ ModuleHiiPackageClass, ...]
# @var Guids: To store value for Guids, it is a list structure as
# [ GuidClass, ...]
# @var PcdCodes: To store value for PcdCodes, it is a list structure as
# [ PcdClass, ...]
# @var ExternImages: To store value for ExternImages, it is a list structure as
# [ ModuleExternImageClass, ...]
# @var ExternLibraries: To store value for ExternLibraries, it is a list structure as
# [ ModuleExternLibraryClass, ...]
# @var ExternDrivers: To store value for ExternDrivers, it is a list structure as
# [ ModuleExternDriverClass, ...]
# @var ExternCallBacks: To store value for ExternCallBacks, it is a list structure as
# [ ModuleExternCallBackClass, ...]
# @var BuildOptions: To store value for BuildOptions, it is a list structure as
# [ BuildOptionClass, ...]
# @var UserExtensions: To store value for UserExtensions, it is a list structure as
# [ UserExtensionsClass, ...]
#
class ModuleClass(object):
def __init__(self):
self.Header = {}
self.ModuleHeader = ModuleHeaderClass()
self.LibraryClasses = []
self.Libraries = []
self.Sources = []
self.Binaries = []
self.NonProcessedFiles = []
self.PackageDependencies = []
self.Nmake = []
self.Depex = []
self.PeiDepex = None
self.DxeDepex = None
self.SmmDepex = None
self.Includes = []
self.Protocols = []
self.Ppis = []
self.Events = []
self.Hobs = []
self.Variables = []
self.BootModes = []
self.SystemTables = []
self.DataHubs = []
self.HiiPackages = []
self.Guids = []
self.PcdCodes = []
self.ExternImages = []
self.ExternLibraries = []
self.ExternDrivers = []
self.ExternCallBacks = []
self.Externs = []
self.BuildOptions = []
self.UserExtensions = None
self.MiscFiles = None
self.FileList = []
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
M = ModuleClass()

View File

@@ -0,0 +1,127 @@
## @file
# This file is used to define a class object to describe a package
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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 CommonClass import *
from Common.Misc import sdict
## PackageHeaderClass
#
# This class defined header items used in Package file
#
# @param IdentificationClass: Inherited from IdentificationClass class
# @param CommonHeaderClass: Inherited from CommonHeaderClass class
#
# @var DecSpecification: To store value for DecSpecification
# @var ReadOnly: To store value for ReadOnly
# @var RePackage: To store value for RePackage
# @var ClonedFrom: To store value for ClonedFrom, it is a set structure as
# [ ClonedRecordClass, ...]
#
class PackageHeaderClass(IdentificationClass, CommonHeaderClass):
def __init__(self):
IdentificationClass.__init__(self)
CommonHeaderClass.__init__(self)
self.DecSpecification = ''
self.ReadOnly = False
self.RePackage = False
self.PackagePath = ''
self.ClonedFrom = []
## PackageIndustryStdHeaderClass
#
# This class defined industry std header items used in Package file
#
# @param CommonHeaderClass: Inherited from CommonHeaderClass class
#
# @var Name: To store value for Name
# @var IncludeHeader: To store value for IncludeHeader
#
class PackageIndustryStdHeaderClass(CommonClass):
def __init__(self):
self.Name = ''
self.IncludeHeader = ''
CommonClass.__init__(self)
## PackageIncludePkgHeaderClass
#
# This class defined include Pkg header items used in Package file
#
# @param object: Inherited from object class
#
# @var IncludeHeader: To store value for IncludeHeader
# @var ModuleType: To store value for ModuleType, it is a set structure as
# BASE | SEC | PEI_CORE | PEIM | DXE_CORE | DXE_DRIVER | DXE_RUNTIME_DRIVER | DXE_SAL_DRIVER | DXE_SMM_DRIVER | TOOL | UEFI_DRIVER | UEFI_APPLICATION | USER_DEFINED
#
class PackageIncludePkgHeaderClass(object):
def __init__(self):
self.IncludeHeader = ''
self.ModuleType = []
## PackageClass
#
# This class defined a complete package item
#
# @param object: Inherited from object class
#
# @var Header: To store value for Header, it is a structure as
# {Arch : PackageHeaderClass}
# @var Includes: To store value for Includes, it is a list structure as
# [ IncludeClass, ...]
# @var LibraryClassDeclarations: To store value for LibraryClassDeclarations, it is a list structure as
# [ LibraryClassClass, ...]
# @var IndustryStdHeaders: To store value for IndustryStdHeaders, it is a list structure as
# [ PackageIndustryStdHeader, ...]
# @var ModuleFiles: To store value for ModuleFiles, it is a list structure as
# [ '', '', ...]
# @var PackageIncludePkgHeaders: To store value for PackageIncludePkgHeaders, it is a list structure as
# [ PackageIncludePkgHeader, ...]
# @var GuidDeclarations: To store value for GuidDeclarations, it is a list structure as
# [ GuidClass, ...]
# @var ProtocolDeclarations: To store value for ProtocolDeclarations, it is a list structure as
# [ ProtocolClass, ...]
# @var PpiDeclarations: To store value for PpiDeclarations, it is a list structure as
# [ PpiClass, ...]
# @var PcdDeclarations: To store value for PcdDeclarations, it is a list structure as
# [ PcdClass, ...]
# @var UserExtensions: To store value for UserExtensions, it is a list structure as
# [ UserExtensionsClass, ...]
#
class PackageClass(object):
def __init__(self):
self.PackageHeader = PackageHeaderClass()
self.Header = {}
self.Includes = []
self.LibraryClassDeclarations = []
self.IndustryStdHeaders = []
self.ModuleFiles = []
# {[Guid, Value, Path(relative to WORKSPACE)]: ModuleClassObj}
self.Modules = sdict()
self.PackageIncludePkgHeaders = []
self.GuidDeclarations = []
self.ProtocolDeclarations = []
self.PpiDeclarations = []
self.PcdDeclarations = []
self.PcdChecks = []
self.UserExtensions = UserExtensionsClass()
self.MiscFiles = MiscFileClass()
self.FileList = []
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
P = PackageClass()

View File

@@ -0,0 +1,432 @@
## @file
# This file is used to define a class object to describe a platform
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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 CommonClass import *
## SkuInfoListClass
#
# This class defined sku info list item used in platform file
#
# @param IncludeStatementClass: Inherited from IncludeStatementClass class
#
# @var SkuInfoList: To store value for SkuInfoList, it is a set structure as
# { SkuName : SkuId }
#
class SkuInfoListClass(IncludeStatementClass):
def __init__(self):
IncludeStatementClass.__init__(self)
self.SkuInfoList = {}
## PlatformHeaderClass
#
# This class defined header items used in Platform file
#
# @param IdentificationClass: Inherited from IdentificationClass class
# @param CommonHeaderClass: Inherited from CommonHeaderClass class
# @param DefineClass: Inherited from DefineClass class
#
# @var DscSpecification: To store value for DscSpecification
# @var SupArchList: To store value for SupArchList, selection scope is in below list
# EBC | IA32 | X64 | IPF | ARM | PPC
# @var BuildTargets: To store value for BuildTargets, selection scope is in below list
# RELEASE | DEBUG
# @var IntermediateDirectories: To store value for IntermediateDirectories, selection scope is in below list
# MODULE | UNIFIED
# @var OutputDirectory: To store value for OutputDirectory
# @var ForceDebugTarget: To store value for ForceDebugTarget
# @var SkuIdName: To store value for SkuIdName
# @var BuildNumber: To store value for BuildNumber
# @var MakefileName: To store value for MakefileName
# @var ClonedFrom: To store value for ClonedFrom, it is a list structure as
# [ ClonedRecordClass, ... ]
#
class PlatformHeaderClass(IdentificationClass, CommonHeaderClass, DefineClass):
def __init__(self):
IdentificationClass.__init__(self)
CommonHeaderClass.__init__(self)
DefineClass.__init__(self)
self.DscSpecification = ''
self.SupArchList = []
self.BuildTargets = []
self.IntermediateDirectories = ''
self.OutputDirectory = ''
self.ForceDebugTarget = ''
self.SkuIdName = []
self.BuildNumber = ''
self.MakefileName = ''
self.ClonedFrom = []
## PlatformFlashDefinitionFileClass
#
# This class defined FlashDefinitionFile item used in platform file
#
# @param object: Inherited from object class
#
# @var Id: To store value for Id
# @var UiName: To store value for UiName
# @var Preferred: To store value for Preferred
# @var FilePath: To store value for FilePath
#
class PlatformFlashDefinitionFileClass(object):
def __init__(self):
self.Id = ''
self.UiName = ''
self.Preferred = False
self.FilePath = ''
## PlatformFvImageOptionClass
#
# This class defined FvImageOption item used in platform file
#
# @param object: Inherited from object class
#
# @var FvImageOptionName: To store value for FvImageOptionName
# @var FvImageOptionValues: To store value for FvImageOptionValues
#
class PlatformFvImageOptionClass(object):
def __init__(self):
self.FvImageOptionName = ''
self.FvImageOptionValues = []
## PlatformFvImageClass
#
# This class defined FvImage item used in platform file
#
# @param object: Inherited from object class
#
# @var Name: To store value for Name
# @var Value: To store value for Value
# @var Type: To store value for Type, selection scope is in below list
# Attributes | Options | Components | ImageName
# @var FvImageNames: To store value for FvImageNames
# @var FvImageOptions: To store value for FvImageOptions, it is a list structure as
# [ PlatformFvImageOption, ...]
#
class PlatformFvImageClass(object):
def __init__(self):
self.Name = ''
self.Value = ''
self.Type = ''
self.FvImageNames = []
self.FvImageOptions = []
## PlatformFvImageNameClass
#
# This class defined FvImageName item used in platform file
#
# @param object: Inherited from object class
#
# @var Name: To store value for Name
# @var Type: To store value for Type, selection scope is in below list
# FV_MAIN | FV_MAIN_COMPACT | NV_STORAGE | FV_RECOVERY | FV_RECOVERY_FLOPPY | FV_FILE | CAPSULE_CARGO | NULL | USER_DEFINED
# @var FvImageOptions: To store value for FvImageOptions, it is a list structure as
# [ PlatformFvImageOption, ...]
#
class PlatformFvImageNameClass(object):
def __init__(self):
self.Name = ''
self.Type = ''
self.FvImageOptions = []
## PlatformFvImagesClass
#
# This class defined FvImages item used in platform file
#
# @param object: Inherited from object class
#
# @var FvImages: To store value for FvImages
#
class PlatformFvImagesClass(object):
def __init__(self):
self.FvImages = []
## PlatformAntTaskClass
#
# This class defined AntTask item used in platform file
#
# @param object: Inherited from object class
#
# @var Id: To store value for Id
# @var AntCmdOptions: To store value for AntCmdOptions
# @var FilePath: To store value for FilePath
#
class PlatformAntTaskClass(object):
def __init__(self):
self.Id = ''
self.AntCmdOptions = ''
self.FilePath = ''
## PlatformFfsSectionClass
#
# This class defined FfsSection item used in platform file
#
# @param CommonClass: Inherited from CommonClass class
#
# @var BindingOrder: To store value for BindingOrder
# @var Compressible: To store value for Compressible
# @var SectionType: To store value for SectionType
# @var EncapsulationType: To store value for EncapsulationType
# @var ToolName: To store value for ToolName
# @var Filenames: To store value for Filenames
# @var Args: To store value for Args
# @var OutFile: To store value for OutFile
# @var OutputFileExtension: To store value for OutputFileExtension
# @var ToolNameElement: To store value for ToolNameElement
#
class PlatformFfsSectionClass(CommonClass):
def __init__(self):
CommonClass.__init__(self)
self.BindingOrder = ''
self.Compressible = ''
self.SectionType = ''
self.EncapsulationType = ''
self.ToolName = ''
self.Filenames = []
self.Args = ''
self.OutFile = ''
self.OutputFileExtension = ''
self.ToolNameElement = ''
## PlatformFfsSectionsClass
#
# This class defined FfsSections item used in platform file
#
# @param CommonClass: Inherited from CommonClass class
#
# @var BindingOrder: To store value for BindingOrder
# @var Compressible: To store value for Compressible
# @var SectionType: To store value for SectionType
# @var EncapsulationType: To store value for EncapsulationType
# @var ToolName: To store value for ToolName
# @var Section: To store value for Section, it is a list structure as
# [ PlatformFfsSectionClass, ... ]
# @var Sections: To store value for Sections, it is a list structure as
# [ PlatformFfsSectionsClass, ...]
#
class PlatformFfsSectionsClass(CommonClass):
def __init__(self):
CommonClass.__init__(self)
self.BindingOrder = ''
self.Compressible = ''
self.SectionType = ''
self.EncapsulationType = ''
self.ToolName = ''
self.Section = []
self.Sections = []
## PlatformFfsClass
#
# This class defined Ffs item used in platform file
#
# @param object: Inherited from object class
#
# @var Attribute: To store value for Attribute, it is a set structure as
# { [(Name, PlatformFfsSectionsClass)] : Value}
# @var Sections: To store value for Sections, it is a list structure as
# [ PlatformFfsSectionsClass]
# @var ToolName: To store value for ToolName
#
class PlatformFfsClass(object):
def __init__(self):
self.Attribute = {}
self.Sections = []
self.Key = ''
## PlatformBuildOptionClass
#
# This class defined BuildOption item used in platform file
#
# @param object: Inherited from object class
#
# @var UserDefinedAntTasks: To store value for UserDefinedAntTasks, it is a set structure as
# { [Id] : PlatformAntTaskClass, ...}
# @var Options: To store value for Options, it is a list structure as
# [ BuildOptionClass, ...]
# @var UserExtensions: To store value for UserExtensions, it is a set structure as
# { [(UserID, Identifier)] : UserExtensionsClass, ...}
# @var FfsKeyList: To store value for FfsKeyList, it is a set structure as
# { [FfsKey]: PlatformFfsClass, ...}
#
class PlatformBuildOptionClass(object):
def __init__(self):
self.UserDefinedAntTasks = {}
self.Options = []
self.UserExtensions = {}
self.FfsKeyList = {}
## PlatformBuildOptionClasses
#
# This class defined BuildOption item list used in platform file
#
# @param IncludeStatementClass: Inherited from IncludeStatementClass class
#
# @var FvBinding: To store value for FvBinding
# @var FfsFileNameGuid: To store value for FfsFileNameGuid
# @var FfsFormatKey: To store value for FfsFormatKey
# @var BuildOptionList: To store value for BuildOptionList, it is a list structure as
# [ BuildOptionClass, ... ]
#
class PlatformBuildOptionClasses(IncludeStatementClass):
def __init__(self):
IncludeStatementClass.__init__(self)
self.FvBinding = ''
self.FfsFileNameGuid = ''
self.FfsFormatKey = ''
self.BuildOptionList = []
## PlatformLibraryClass
#
# This class defined Library item used in platform file
#
# @param CommonClass: Inherited from CommonClass class
# @param DefineClass: Inherited from DefineClass class
# @param Name: Input value for Name, default is ''
# @param FilePath: Input value for FilePath, default is ''
#
# @var Name: To store value for Name
# @var FilePath: To store value for FilePath
# @var ModuleType: To store value for ModuleType
# @var SupModuleList: To store value for SupModuleList
# @var ModuleGuid: To store value for ModuleGuid
# @var ModuleVersion: To store value for ModuleVersion
# @var PackageGuid: To store value for PackageGuid
# @var PackageVersion: To store value for PackageVersion
#
class PlatformLibraryClass(CommonClass, DefineClass):
def __init__(self, Name = '', FilePath = ''):
CommonClass.__init__(self)
DefineClass.__init__(self)
self.Name = Name
self.FilePath = FilePath
self.ModuleType = []
self.SupModuleList = []
self.ModuleGuid = ''
self.ModuleVersion = ''
self.PackageGuid = ''
self.PackageVersion = ''
## PlatformLibraryClasses
#
# This class defined Library item list used in platform file
#
# @param IncludeStatementClass: Inherited from IncludeStatementClass class
#
# @var LibraryList: To store value for LibraryList, it is a list structure as
# [ PlatformLibraryClass, ... ]
#
class PlatformLibraryClasses(IncludeStatementClass):
def __init__(self):
IncludeStatementClass.__init__(self)
self.LibraryList = []
## PlatformModuleClass
#
# This class defined Module item used in platform file
#
# @param CommonClass: Inherited from CommonClass class
# @param DefineClass: Inherited from DefineClass class
# @param IncludeStatementClass: Inherited from IncludeStatementClass class
#
# @var Name: To store value for Name (Library name or libraryclass name or module name)
# @var FilePath: To store value for FilePath
# @var Type: To store value for Type, selection scope is in below list
# LIBRARY | LIBRARY_CLASS | MODULE
# @var ModuleType: To store value for ModuleType
# @var ExecFilePath: To store value for ExecFilePath
# @var LibraryClasses: To store value for LibraryClasses, it is a structure as
# PlatformLibraryClasses
# @var PcdBuildDefinitions: To store value for PcdBuildDefinitions, it is a list structure as
# [ PcdClass, ...]
# @var ModuleSaBuildOption: To store value for ModuleSaBuildOption, it is a structure as
# PlatformBuildOptionClasses
# @var Specifications: To store value for Specifications, it is a list structure as
# [ '', '', ...]
#
class PlatformModuleClass(CommonClass, DefineClass, IncludeStatementClass):
def __init__(self):
CommonClass.__init__(self)
DefineClass.__init__(self)
self.Name = ''
self.FilePath = ''
self.Type = ''
self.ModuleType = ''
self.ExecFilePath = ''
self.LibraryClasses = PlatformLibraryClasses()
self.PcdBuildDefinitions = []
self.ModuleSaBuildOption = PlatformBuildOptionClasses()
self.Specifications = []
self.SourceOverridePath = ''
## PlatformModuleClasses
#
# This class defined Module item list used in platform file
#
# @param IncludeStatementClass: Inherited from IncludeStatementClass class
#
# @var ModuleList: To store value for ModuleList, it is a list structure as
# [ PlatformModuleClass, ... ]
#
class PlatformModuleClasses(IncludeStatementClass):
def __init__(self):
IncludeStatementClass.__init__(self)
self.ModuleList = []
## PlatformClass
#
# This class defined a complete platform item
#
# @param object: Inherited from object class
#
# @var Header: To store value for Header, it is a structure as
# {Arch : PlatformHeaderClass()}
# @var SkuInfos: To store value for SkuInfos, it is a structure as
# SkuInfoListClass
# @var Libraries: To store value for Libraries, it is a structure as
# PlatformLibraryClasses
# @var LibraryClasses: To store value for LibraryClasses, it is a structure as
# PlatformLibraryClasses
# @var Modules: To store value for Modules, it is a structure as
# PlatformModuleClasses
# @var FlashDefinitionFile: To store value for FlashDefinitionFile, it is a structure as
# PlatformFlashDefinitionFileClass
# @var BuildOptions: To store value for BuildOptions, it is a structure as
# PlatformBuildOptionClasses
# @var DynamicPcdBuildDefinitions: To store value for DynamicPcdBuildDefinitions, it is a list structure as
# [ PcdClass, ...]
# @var Fdf: To store value for Fdf, it is a list structure as
# [ FdfClass, ...]
# @var UserExtensions: To store value for UserExtensions, it is a list structure as
# [ UserExtensionsClass, ...]
#
class PlatformClass(object):
def __init__(self):
self.Header = {}
self.SkuInfos = SkuInfoListClass()
self.Libraries = PlatformLibraryClasses()
self.LibraryClasses = PlatformLibraryClasses()
self.Modules = PlatformModuleClasses()
self.FlashDefinitionFile = PlatformFlashDefinitionFileClass()
self.BuildOptions = PlatformBuildOptionClasses()
self.DynamicPcdBuildDefinitions = []
self.Fdf = []
self.UserExtensions = []
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
P = PlatformClass()

View File

@@ -0,0 +1,626 @@
grammar C;
options {
language=Python;
backtrack=true;
memoize=true;
k=2;
}
@header {
import CodeFragment
import FileProfile
}
@members {
def printTokenInfo(self, line, offset, tokenText):
print str(line)+ ',' + str(offset) + ':' + str(tokenText)
def StorePredicateExpression(self, StartLine, StartOffset, EndLine, EndOffset, Text):
PredExp = CodeFragment.PredicateExpression(Text, (StartLine, StartOffset), (EndLine, EndOffset))
FileProfile.PredicateExpressionList.append(PredExp)
def StoreEnumerationDefinition(self, StartLine, StartOffset, EndLine, EndOffset, Text):
EnumDef = CodeFragment.EnumerationDefinition(Text, (StartLine, StartOffset), (EndLine, EndOffset))
FileProfile.EnumerationDefinitionList.append(EnumDef)
def StoreStructUnionDefinition(self, StartLine, StartOffset, EndLine, EndOffset, Text):
SUDef = CodeFragment.StructUnionDefinition(Text, (StartLine, StartOffset), (EndLine, EndOffset))
FileProfile.StructUnionDefinitionList.append(SUDef)
def StoreTypedefDefinition(self, StartLine, StartOffset, EndLine, EndOffset, FromText, ToText):
Tdef = CodeFragment.TypedefDefinition(FromText, ToText, (StartLine, StartOffset), (EndLine, EndOffset))
FileProfile.TypedefDefinitionList.append(Tdef)
def StoreFunctionDefinition(self, StartLine, StartOffset, EndLine, EndOffset, ModifierText, DeclText, LeftBraceLine, LeftBraceOffset, DeclLine, DeclOffset):
FuncDef = CodeFragment.FunctionDefinition(ModifierText, DeclText, (StartLine, StartOffset), (EndLine, EndOffset), (LeftBraceLine, LeftBraceOffset), (DeclLine, DeclOffset))
FileProfile.FunctionDefinitionList.append(FuncDef)
def StoreVariableDeclaration(self, StartLine, StartOffset, EndLine, EndOffset, ModifierText, DeclText):
VarDecl = CodeFragment.VariableDeclaration(ModifierText, DeclText, (StartLine, StartOffset), (EndLine, EndOffset))
FileProfile.VariableDeclarationList.append(VarDecl)
def StoreFunctionCalling(self, StartLine, StartOffset, EndLine, EndOffset, FuncName, ParamList):
FuncCall = CodeFragment.FunctionCalling(FuncName, ParamList, (StartLine, StartOffset), (EndLine, EndOffset))
FileProfile.FunctionCallingList.append(FuncCall)
}
translation_unit
: external_declaration*
;
/*function_declaration
@after{
print $function_declaration.text
}
: declaration_specifiers IDENTIFIER '(' parameter_list ')' ';'
;
*/
external_declaration
options {k=1;}
/*@after{
print $external_declaration.text
}*/
: ( declaration_specifiers? declarator declaration* '{' )=> function_definition
| declaration
| macro_statement (';')?
;
function_definition
scope {
ModifierText;
DeclText;
LBLine;
LBOffset;
DeclLine;
DeclOffset;
}
@init {
$function_definition::ModifierText = '';
$function_definition::DeclText = '';
$function_definition::LBLine = 0;
$function_definition::LBOffset = 0;
$function_definition::DeclLine = 0;
$function_definition::DeclOffset = 0;
}
@after{
self.StoreFunctionDefinition($function_definition.start.line, $function_definition.start.charPositionInLine, $function_definition.stop.line, $function_definition.stop.charPositionInLine, $function_definition::ModifierText, $function_definition::DeclText, $function_definition::LBLine, $function_definition::LBOffset, $function_definition::DeclLine, $function_definition::DeclOffset)
}
: d=declaration_specifiers? declarator
( declaration+ a=compound_statement // K&R style
| b=compound_statement // ANSI style
) {
if d != None:
$function_definition::ModifierText = $declaration_specifiers.text
else:
$function_definition::ModifierText = ''
$function_definition::DeclText = $declarator.text
$function_definition::DeclLine = $declarator.start.line
$function_definition::DeclOffset = $declarator.start.charPositionInLine
if a != None:
$function_definition::LBLine = $a.start.line
$function_definition::LBOffset = $a.start.charPositionInLine
else:
$function_definition::LBLine = $b.start.line
$function_definition::LBOffset = $b.start.charPositionInLine
}
;
declaration
: a='typedef' b=declaration_specifiers?
c=init_declarator_list d=';'
{
if b != None:
self.StoreTypedefDefinition($a.line, $a.charPositionInLine, $d.line, $d.charPositionInLine, $b.text, $c.text)
else:
self.StoreTypedefDefinition($a.line, $a.charPositionInLine, $d.line, $d.charPositionInLine, '', $c.text)
}
| s=declaration_specifiers t=init_declarator_list? e=';'
{
if t != None:
self.StoreVariableDeclaration($s.start.line, $s.start.charPositionInLine, $t.start.line, $t.start.charPositionInLine, $s.text, $t.text)
}
;
declaration_specifiers
: ( storage_class_specifier
| type_specifier
| type_qualifier
)+
;
init_declarator_list
: init_declarator (',' init_declarator)*
;
init_declarator
: declarator ('=' initializer)?
;
storage_class_specifier
: 'extern'
| 'static'
| 'auto'
| 'register'
| 'STATIC'
;
type_specifier
: 'void'
| 'char'
| 'short'
| 'int'
| 'long'
| 'float'
| 'double'
| 'signed'
| 'unsigned'
| s=struct_or_union_specifier
{
if s.stop != None:
self.StoreStructUnionDefinition($s.start.line, $s.start.charPositionInLine, $s.stop.line, $s.stop.charPositionInLine, $s.text)
}
| e=enum_specifier
{
if e.stop != None:
self.StoreEnumerationDefinition($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)
}
| (IDENTIFIER type_qualifier* declarator)=> type_id
;
type_id
: IDENTIFIER
//{self.printTokenInfo($a.line, $a.pos, $a.text)}
;
struct_or_union_specifier
options {k=3;}
: struct_or_union IDENTIFIER? '{' struct_declaration_list '}'
| struct_or_union IDENTIFIER
;
struct_or_union
: 'struct'
| 'union'
;
struct_declaration_list
: struct_declaration+
;
struct_declaration
: specifier_qualifier_list struct_declarator_list ';'
;
specifier_qualifier_list
: ( type_qualifier | type_specifier )+
;
struct_declarator_list
: struct_declarator (',' struct_declarator)*
;
struct_declarator
: declarator (':' constant_expression)?
| ':' constant_expression
;
enum_specifier
options {k=3;}
: 'enum' '{' enumerator_list ','? '}'
| 'enum' IDENTIFIER '{' enumerator_list ','? '}'
| 'enum' IDENTIFIER
;
enumerator_list
: enumerator (',' enumerator)*
;
enumerator
: IDENTIFIER ('=' constant_expression)?
;
type_qualifier
: 'const'
| 'volatile'
| 'IN'
| 'OUT'
| 'OPTIONAL'
| 'CONST'
| 'UNALIGNED'
| 'VOLATILE'
| 'GLOBAL_REMOVE_IF_UNREFERENCED'
| 'EFIAPI'
| 'EFI_BOOTSERVICE'
| 'EFI_RUNTIMESERVICE'
;
declarator
: pointer? ('EFIAPI')? ('EFI_BOOTSERVICE')? ('EFI_RUNTIMESERVICE')? direct_declarator
// | ('EFIAPI')? ('EFI_BOOTSERVICE')? ('EFI_RUNTIMESERVICE')? pointer? direct_declarator
| pointer
;
direct_declarator
: IDENTIFIER declarator_suffix*
| '(' ('EFIAPI')? declarator ')' declarator_suffix+
;
declarator_suffix
: '[' constant_expression ']'
| '[' ']'
| '(' parameter_type_list ')'
| '(' identifier_list ')'
| '(' ')'
;
pointer
: '*' type_qualifier+ pointer?
| '*' pointer
| '*'
;
parameter_type_list
: parameter_list (',' ('OPTIONAL')? '...')?
;
parameter_list
: parameter_declaration (',' ('OPTIONAL')? parameter_declaration)*
;
parameter_declaration
: declaration_specifiers (declarator|abstract_declarator)* ('OPTIONAL')?
//accomerdate user-defined type only, no declarator follow.
| pointer* IDENTIFIER
;
identifier_list
: IDENTIFIER
(',' IDENTIFIER)*
;
type_name
: specifier_qualifier_list abstract_declarator?
| type_id
;
abstract_declarator
: pointer direct_abstract_declarator?
| direct_abstract_declarator
;
direct_abstract_declarator
: ( '(' abstract_declarator ')' | abstract_declarator_suffix ) abstract_declarator_suffix*
;
abstract_declarator_suffix
: '[' ']'
| '[' constant_expression ']'
| '(' ')'
| '(' parameter_type_list ')'
;
initializer
: assignment_expression
| '{' initializer_list ','? '}'
;
initializer_list
: initializer (',' initializer )*
;
// E x p r e s s i o n s
argument_expression_list
: assignment_expression ('OPTIONAL')? (',' assignment_expression ('OPTIONAL')?)*
;
additive_expression
: (multiplicative_expression) ('+' multiplicative_expression | '-' multiplicative_expression)*
;
multiplicative_expression
: (cast_expression) ('*' cast_expression | '/' cast_expression | '%' cast_expression)*
;
cast_expression
: '(' type_name ')' cast_expression
| unary_expression
;
unary_expression
: postfix_expression
| '++' unary_expression
| '--' unary_expression
| unary_operator cast_expression
| 'sizeof' unary_expression
| 'sizeof' '(' type_name ')'
;
postfix_expression
scope {
FuncCallText;
}
@init {
$postfix_expression::FuncCallText = '';
}
: p=primary_expression {$postfix_expression::FuncCallText += $p.text}
( '[' expression ']'
| '(' a=')'{self.StoreFunctionCalling($p.start.line, $p.start.charPositionInLine, $a.line, $a.charPositionInLine, $postfix_expression::FuncCallText, '')}
| '(' c=argument_expression_list b=')' {self.StoreFunctionCalling($p.start.line, $p.start.charPositionInLine, $b.line, $b.charPositionInLine, $postfix_expression::FuncCallText, $c.text)}
| '(' macro_parameter_list ')'
| '.' x=IDENTIFIER {$postfix_expression::FuncCallText += '.' + $x.text}
| '*' y=IDENTIFIER {$postfix_expression::FuncCallText = $y.text}
| '->' z=IDENTIFIER {$postfix_expression::FuncCallText += '->' + $z.text}
| '++'
| '--'
)*
;
macro_parameter_list
: parameter_declaration (',' parameter_declaration)*
;
unary_operator
: '&'
| '*'
| '+'
| '-'
| '~'
| '!'
;
primary_expression
: IDENTIFIER
| constant
| '(' expression ')'
;
constant
: HEX_LITERAL
| OCTAL_LITERAL
| DECIMAL_LITERAL
| CHARACTER_LITERAL
| (IDENTIFIER* STRING_LITERAL+)+ IDENTIFIER*
| FLOATING_POINT_LITERAL
;
/////
expression
: assignment_expression (',' assignment_expression)*
;
constant_expression
: conditional_expression
;
assignment_expression
: lvalue assignment_operator assignment_expression
| conditional_expression
;
lvalue
: unary_expression
;
assignment_operator
: '='
| '*='
| '/='
| '%='
| '+='
| '-='
| '<<='
| '>>='
| '&='
| '^='
| '|='
;
conditional_expression
: e=logical_or_expression ('?' expression ':' conditional_expression {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)})?
;
logical_or_expression
: logical_and_expression ('||' logical_and_expression)*
;
logical_and_expression
: inclusive_or_expression ('&&' inclusive_or_expression)*
;
inclusive_or_expression
: exclusive_or_expression ('|' exclusive_or_expression)*
;
exclusive_or_expression
: and_expression ('^' and_expression)*
;
and_expression
: equality_expression ('&' equality_expression)*
;
equality_expression
: relational_expression (('=='|'!=') relational_expression )*
;
relational_expression
: shift_expression (('<'|'>'|'<='|'>=') shift_expression)*
;
shift_expression
: additive_expression (('<<'|'>>') additive_expression)*
;
// S t a t e m e n t s
statement
: labeled_statement
| compound_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
| macro_statement
| asm2_statement
| asm1_statement
| asm_statement
| declaration
;
asm2_statement
: '__asm__'? IDENTIFIER '(' (~(';'))* ')' ';'
;
asm1_statement
: '_asm' '{' (~('}'))* '}'
;
asm_statement
: '__asm' '{' (~('}'))* '}'
;
macro_statement
: IDENTIFIER '(' declaration* statement_list? expression? ')'
;
labeled_statement
: IDENTIFIER ':' statement
| 'case' constant_expression ':' statement
| 'default' ':' statement
;
compound_statement
: '{' declaration* statement_list? '}'
;
statement_list
: statement+
;
expression_statement
: ';'
| expression ';'
;
selection_statement
: 'if' '(' e=expression ')' {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)} statement (options {k=1; backtrack=false;}:'else' statement)?
| 'switch' '(' expression ')' statement
;
iteration_statement
: 'while' '(' e=expression ')' statement {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)}
| 'do' statement 'while' '(' e=expression ')' ';' {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)}
| 'for' '(' expression_statement e=expression_statement expression? ')' statement {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)}
;
jump_statement
: 'goto' IDENTIFIER ';'
| 'continue' ';'
| 'break' ';'
| 'return' ';'
| 'return' expression ';'
;
IDENTIFIER
: LETTER (LETTER|'0'..'9')*
;
fragment
LETTER
: '$'
| 'A'..'Z'
| 'a'..'z'
| '_'
;
CHARACTER_LITERAL
: ('L')? '\'' ( EscapeSequence | ~('\''|'\\') ) '\''
;
STRING_LITERAL
: ('L')? '"' ( EscapeSequence | ~('\\'|'"') )* '"'
;
HEX_LITERAL : '0' ('x'|'X') HexDigit+ IntegerTypeSuffix? ;
DECIMAL_LITERAL : ('0' | '1'..'9' '0'..'9'*) IntegerTypeSuffix? ;
OCTAL_LITERAL : '0' ('0'..'7')+ IntegerTypeSuffix? ;
fragment
HexDigit : ('0'..'9'|'a'..'f'|'A'..'F') ;
fragment
IntegerTypeSuffix
: ('u'|'U')
| ('l'|'L')
| ('u'|'U') ('l'|'L')
| ('u'|'U') ('l'|'L') ('l'|'L')
;
FLOATING_POINT_LITERAL
: ('0'..'9')+ '.' ('0'..'9')* Exponent? FloatTypeSuffix?
| '.' ('0'..'9')+ Exponent? FloatTypeSuffix?
| ('0'..'9')+ Exponent FloatTypeSuffix?
| ('0'..'9')+ Exponent? FloatTypeSuffix
;
fragment
Exponent : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
fragment
FloatTypeSuffix : ('f'|'F'|'d'|'D') ;
fragment
EscapeSequence
: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
| OctalEscape
;
fragment
OctalEscape
: '\\' ('0'..'3') ('0'..'7') ('0'..'7')
| '\\' ('0'..'7') ('0'..'7')
| '\\' ('0'..'7')
;
fragment
UnicodeEscape
: '\\' 'u' HexDigit HexDigit HexDigit HexDigit
;
WS : (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;}
;
// ingore '\' of line concatenation
BS : ('\\') {$channel=HIDDEN;}
;
// ingore function modifiers
//FUNC_MODIFIERS : 'EFIAPI' {$channel=HIDDEN;}
// ;
UnicodeVocabulary
: '\u0003'..'\uFFFE'
;
COMMENT
: '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
;
LINE_COMMENT
: '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
;
// ignore #line info for now
LINE_COMMAND
: '#' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,865 @@
## @file
# This file is used to define checkpoints used by ECC tool
#
# Copyright (c) 2008, Intel Corporation
# All rights reserved. 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 os
import re
from CommonDataClass.DataClass import *
from Common.DataType import SUP_MODULE_LIST_STRING, TAB_VALUE_SPLIT
from EccToolError import *
import EccGlobalData
import c
## Check
#
# This class is to define checkpoints used by ECC tool
#
# @param object: Inherited from object class
#
class Check(object):
def __init__(self):
pass
# Check all required checkpoints
def Check(self):
self.MetaDataFileCheck()
self.DoxygenCheck()
self.IncludeFileCheck()
self.PredicateExpressionCheck()
self.DeclAndDataTypeCheck()
self.FunctionLayoutCheck()
self.NamingConventionCheck()
# C Function Layout Checking
def FunctionLayoutCheck(self):
self.FunctionLayoutCheckReturnType()
self.FunctionLayoutCheckModifier()
self.FunctionLayoutCheckName()
self.FunctionLayoutCheckPrototype()
self.FunctionLayoutCheckBody()
self.FunctionLayoutCheckLocalVariable()
def WalkTree(self):
IgnoredPattern = c.GetIgnoredDirListPattern()
for Dirpath, Dirnames, Filenames in os.walk(EccGlobalData.gTarget):
for Dir in Dirnames:
Dirname = os.path.join(Dirpath, Dir)
if os.path.islink(Dirname):
Dirname = os.path.realpath(Dirname)
if os.path.isdir(Dirname):
# symlinks to directories are treated as directories
Dirnames.remove(Dir)
Dirnames.append(Dirname)
if IgnoredPattern.match(Dirpath.upper()):
continue
yield (Dirpath, Dirnames, Filenames)
# Check whether return type exists and in the first line
def FunctionLayoutCheckReturnType(self):
if EccGlobalData.gConfig.CFunctionLayoutCheckReturnType == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking function layout return type ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.c', '.h'):
FullName = os.path.join(Dirpath, F)
c.CheckFuncLayoutReturnType(FullName)
# Check whether any optional functional modifiers exist and next to the return type
def FunctionLayoutCheckModifier(self):
if EccGlobalData.gConfig.CFunctionLayoutCheckOptionalFunctionalModifier == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking function layout modifier ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.c', '.h'):
FullName = os.path.join(Dirpath, F)
c.CheckFuncLayoutModifier(FullName)
# Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list
# Check whether the closing parenthesis is on its own line and also indented two spaces
def FunctionLayoutCheckName(self):
if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionName == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking function layout function name ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.c', '.h'):
FullName = os.path.join(Dirpath, F)
c.CheckFuncLayoutName(FullName)
# Check whether the function prototypes in include files have the same form as function definitions
def FunctionLayoutCheckPrototype(self):
if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionPrototype == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking function layout function prototype ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.c'):
FullName = os.path.join(Dirpath, F)
EdkLogger.quiet("[PROTOTYPE]" + FullName)
c.CheckFuncLayoutPrototype(FullName)
# Check whether the body of a function is contained by open and close braces that must be in the first column
def FunctionLayoutCheckBody(self):
if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionBody == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking function layout function body ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.c'):
FullName = os.path.join(Dirpath, F)
c.CheckFuncLayoutBody(FullName)
# Check whether the data declarations is the first code in a module.
# self.CFunctionLayoutCheckDataDeclaration = 1
# Check whether no initialization of a variable as part of its declaration
def FunctionLayoutCheckLocalVariable(self):
if EccGlobalData.gConfig.CFunctionLayoutCheckNoInitOfVariable == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking function layout local variables ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.c'):
FullName = os.path.join(Dirpath, F)
c.CheckFuncLayoutLocalVariable(FullName)
# Check whether no use of STATIC for functions
# self.CFunctionLayoutCheckNoStatic = 1
# Declarations and Data Types Checking
def DeclAndDataTypeCheck(self):
self.DeclCheckNoUseCType()
self.DeclCheckInOutModifier()
self.DeclCheckEFIAPIModifier()
self.DeclCheckEnumeratedType()
self.DeclCheckStructureDeclaration()
self.DeclCheckSameStructure()
self.DeclCheckUnionType()
# Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files.
def DeclCheckNoUseCType(self):
if EccGlobalData.gConfig.DeclarationDataTypeCheckNoUseCType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking Declaration No use C type ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.h', '.c'):
FullName = os.path.join(Dirpath, F)
c.CheckDeclNoUseCType(FullName)
# Check whether the modifiers IN, OUT, OPTIONAL, and UNALIGNED are used only to qualify arguments to a function and should not appear in a data type declaration
def DeclCheckInOutModifier(self):
if EccGlobalData.gConfig.DeclarationDataTypeCheckInOutModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking Declaration argument modifier ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.h', '.c'):
FullName = os.path.join(Dirpath, F)
c.CheckDeclArgModifier(FullName)
# Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols
def DeclCheckEFIAPIModifier(self):
if EccGlobalData.gConfig.DeclarationDataTypeCheckEFIAPIModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
pass
# Check whether Enumerated Type has a 'typedef' and the name is capital
def DeclCheckEnumeratedType(self):
if EccGlobalData.gConfig.DeclarationDataTypeCheckEnumeratedType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking Declaration enum typedef ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.h', '.c'):
FullName = os.path.join(Dirpath, F)
EdkLogger.quiet("[ENUM]" + FullName)
c.CheckDeclEnumTypedef(FullName)
# Check whether Structure Type has a 'typedef' and the name is capital
def DeclCheckStructureDeclaration(self):
if EccGlobalData.gConfig.DeclarationDataTypeCheckStructureDeclaration == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking Declaration struct typedef ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.h', '.c'):
FullName = os.path.join(Dirpath, F)
EdkLogger.quiet("[STRUCT]" + FullName)
c.CheckDeclStructTypedef(FullName)
# Check whether having same Structure
def DeclCheckSameStructure(self):
if EccGlobalData.gConfig.DeclarationDataTypeCheckSameStructure == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking same struct ...")
AllStructure = {}
for IdentifierTable in EccGlobalData.gIdentifierTableList:
SqlCommand = """select ID, Name, BelongsToFile from %s where Model = %s""" %(IdentifierTable, MODEL_IDENTIFIER_STRUCTURE)
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
for Record in RecordSet:
if Record[1] != '':
if Record[1] not in AllStructure.keys():
AllStructure[Record[1]] = Record[2]
else:
ID = AllStructure[Record[1]]
SqlCommand = """select FullPath from File where ID = %s """ % ID
NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
OtherMsg = "The structure name '%s' is duplicate" % Record[1]
if NewRecordSet != []:
OtherMsg = "The structure name [%s] is duplicate with the one defined in %s, maybe struct NOT typedefed or the typedef new type NOT used to qualify variables" % (Record[1], NewRecordSet[0][0])
if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE, Record[1]):
EccGlobalData.gDb.TblReport.Insert(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE, OtherMsg = OtherMsg, BelongsToTable = IdentifierTable, BelongsToItem = Record[0])
# Check whether Union Type has a 'typedef' and the name is capital
def DeclCheckUnionType(self):
if EccGlobalData.gConfig.DeclarationDataTypeCheckUnionType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking Declaration union typedef ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.h', '.c'):
FullName = os.path.join(Dirpath, F)
EdkLogger.quiet("[UNION]" + FullName)
c.CheckDeclUnionTypedef(FullName)
# Predicate Expression Checking
def PredicateExpressionCheck(self):
self.PredicateExpressionCheckBooleanValue()
self.PredicateExpressionCheckNonBooleanOperator()
self.PredicateExpressionCheckComparisonNullType()
# Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE
def PredicateExpressionCheckBooleanValue(self):
if EccGlobalData.gConfig.PredicateExpressionCheckBooleanValue == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking predicate expression Boolean value ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.c'):
FullName = os.path.join(Dirpath, F)
EdkLogger.quiet("[BOOLEAN]" + FullName)
c.CheckBooleanValueComparison(FullName)
# Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=).
def PredicateExpressionCheckNonBooleanOperator(self):
if EccGlobalData.gConfig.PredicateExpressionCheckNonBooleanOperator == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking predicate expression Non-Boolean variable...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.c'):
FullName = os.path.join(Dirpath, F)
EdkLogger.quiet("[NON-BOOLEAN]" + FullName)
c.CheckNonBooleanValueComparison(FullName)
# Check whether a comparison of any pointer to zero must be done via the NULL type
def PredicateExpressionCheckComparisonNullType(self):
if EccGlobalData.gConfig.PredicateExpressionCheckComparisonNullType == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking predicate expression NULL pointer ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.c'):
FullName = os.path.join(Dirpath, F)
EdkLogger.quiet("[POINTER]" + FullName)
c.CheckPointerNullComparison(FullName)
# Include file checking
def IncludeFileCheck(self):
self.IncludeFileCheckIfndef()
self.IncludeFileCheckData()
self.IncludeFileCheckSameName()
# Check whether having include files with same name
def IncludeFileCheckSameName(self):
if EccGlobalData.gConfig.IncludeFileCheckSameName == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking same header file name ...")
SqlCommand = """select ID, FullPath from File
where Model = 1002 order by Name """
RecordDict = {}
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
for Record in RecordSet:
List = Record[1].replace('/', '\\').split('\\')
if len(List) >= 2:
Key = List[-2] + '\\' + List[-1]
else:
Key = List[0]
if Key not in RecordDict:
RecordDict[Key] = [Record]
else:
RecordDict[Key].append(Record)
for Key in RecordDict:
if len(RecordDict[Key]) > 1:
for Item in RecordDict[Key]:
EccGlobalData.gDb.TblReport.Insert(ERROR_INCLUDE_FILE_CHECK_NAME, OtherMsg = "The file name for '%s' is duplicate" % (Item[1]), BelongsToTable = 'File', BelongsToItem = Item[0])
# Check whether all include file contents is guarded by a #ifndef statement.
def IncludeFileCheckIfndef(self):
if EccGlobalData.gConfig.IncludeFileCheckIfndefStatement == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking header file ifndef ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.h'):
FullName = os.path.join(Dirpath, F)
MsgList = c.CheckHeaderFileIfndef(FullName)
# Check whether include files NOT contain code or define data variables
def IncludeFileCheckData(self):
if EccGlobalData.gConfig.IncludeFileCheckData == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking header file data ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.h'):
FullName = os.path.join(Dirpath, F)
MsgList = c.CheckHeaderFileData(FullName)
# Doxygen document checking
def DoxygenCheck(self):
self.DoxygenCheckFileHeader()
self.DoxygenCheckFunctionHeader()
self.DoxygenCheckCommentDescription()
self.DoxygenCheckCommentFormat()
self.DoxygenCheckCommand()
# Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5
def DoxygenCheckFileHeader(self):
if EccGlobalData.gConfig.DoxygenCheckFileHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking Doxygen file header ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.h', '.c'):
FullName = os.path.join(Dirpath, F)
MsgList = c.CheckFileHeaderDoxygenComments(FullName)
# Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5
def DoxygenCheckFunctionHeader(self):
if EccGlobalData.gConfig.DoxygenCheckFunctionHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking Doxygen function header ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.h', '.c'):
FullName = os.path.join(Dirpath, F)
MsgList = c.CheckFuncHeaderDoxygenComments(FullName)
# Check whether the first line of text in a comment block is a brief description of the element being documented.
# The brief description must end with a period.
def DoxygenCheckCommentDescription(self):
if EccGlobalData.gConfig.DoxygenCheckCommentDescription == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
pass
# Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.
def DoxygenCheckCommentFormat(self):
if EccGlobalData.gConfig.DoxygenCheckCommentFormat == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking Doxygen comment ///< ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.h', '.c'):
FullName = os.path.join(Dirpath, F)
MsgList = c.CheckDoxygenTripleForwardSlash(FullName)
# Check whether only Doxygen commands allowed to mark the code are @bug and @todo.
def DoxygenCheckCommand(self):
if EccGlobalData.gConfig.DoxygenCheckCommand == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking Doxygen command ...")
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.h', '.c'):
FullName = os.path.join(Dirpath, F)
MsgList = c.CheckDoxygenCommand(FullName)
# Meta-Data File Processing Checking
def MetaDataFileCheck(self):
self.MetaDataFileCheckPathName()
self.MetaDataFileCheckGenerateFileList()
self.MetaDataFileCheckLibraryInstance()
self.MetaDataFileCheckLibraryInstanceDependent()
self.MetaDataFileCheckLibraryInstanceOrder()
self.MetaDataFileCheckLibraryNoUse()
self.MetaDataFileCheckBinaryInfInFdf()
self.MetaDataFileCheckPcdDuplicate()
self.MetaDataFileCheckPcdFlash()
self.MetaDataFileCheckPcdNoUse()
self.MetaDataFileCheckGuidDuplicate()
self.MetaDataFileCheckModuleFileNoUse()
self.MetaDataFileCheckPcdType()
# Check whether each file defined in meta-data exists
def MetaDataFileCheckPathName(self):
if EccGlobalData.gConfig.MetaDataFileCheckPathName == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
# This item is covered when parsing Inf/Dec/Dsc files
pass
# Generate a list for all files defined in meta-data files
def MetaDataFileCheckGenerateFileList(self):
if EccGlobalData.gConfig.MetaDataFileCheckGenerateFileList == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
# This item is covered when parsing Inf/Dec/Dsc files
pass
# Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.
# Each Library Instance must specify the Supported Module Types in its Inf file,
# and any module specifying the library instance must be one of the supported types.
def MetaDataFileCheckLibraryInstance(self):
if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstance == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking for library instance type issue ...")
SqlCommand = """select A.ID, A.Value2, B.Value2 from Inf as A left join Inf as B
where A.Value1 = 'LIBRARY_CLASS' and A.Model = %s
and B.Value1 = 'MODULE_TYPE' and B.Model = %s and A.BelongsToFile = B.BelongsToFile
group by A.BelongsToFile""" % (MODEL_META_DATA_HEADER, MODEL_META_DATA_HEADER)
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
LibraryClasses = {}
for Record in RecordSet:
List = Record[1].split('|', 1)
SupModType = []
if len(List) == 1:
SupModType = SUP_MODULE_LIST_STRING.split(TAB_VALUE_SPLIT)
elif len(List) == 2:
SupModType = List[1].split()
if List[0] not in LibraryClasses:
LibraryClasses[List[0]] = SupModType
else:
for Item in SupModType:
if Item not in LibraryClasses[List[0]]:
LibraryClasses[List[0]].append(Item)
if Record[2] != 'BASE' and Record[2] not in SupModType:
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_2, OtherMsg = "The Library Class '%s' does not specify its supported module types" % (List[0]), BelongsToTable = 'Inf', BelongsToItem = Record[0])
SqlCommand = """select A.ID, A.Value1, B.Value2 from Inf as A left join Inf as B
where A.Model = %s and B.Value1 = '%s' and B.Model = %s
and B.BelongsToFile = A.BelongsToFile""" \
% (MODEL_EFI_LIBRARY_CLASS, 'MODULE_TYPE', MODEL_META_DATA_HEADER)
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
# Merge all LibraryClasses' supmodlist
RecordDict = {}
for Record in RecordSet:
if Record[1] not in RecordDict:
RecordDict[Record[1]] = [str(Record[2])]
else:
if Record[2] not in RecordDict[Record[1]]:
RecordDict[Record[1]].append(Record[2])
for Record in RecordSet:
if Record[1] in LibraryClasses:
if Record[2] not in LibraryClasses[Record[1]] and 'BASE' not in RecordDict[Record[1]]:
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]):
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, OtherMsg = "The type of Library Class [%s] defined in Inf file does not match the type of the module" % (Record[1]), BelongsToTable = 'Inf', BelongsToItem = Record[0])
else:
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]):
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, OtherMsg = "The type of Library Class [%s] defined in Inf file does not match the type of the module" % (Record[1]), BelongsToTable = 'Inf', BelongsToItem = Record[0])
# Check whether a Library Instance has been defined for all dependent library classes
def MetaDataFileCheckLibraryInstanceDependent(self):
if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceDependent == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking for library instance dependent issue ...")
SqlCommand = """select ID, Value1, Value2 from Dsc where Model = %s""" % MODEL_EFI_LIBRARY_CLASS
LibraryClasses = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)
for LibraryClass in LibraryClasses:
if LibraryClass[1].upper() != 'NULL':
LibraryIns = os.path.normpath(os.path.join(EccGlobalData.gWorkspace, LibraryClass[2]))
SqlCommand = """select Value2 from Inf where BelongsToFile =
(select ID from File where lower(FullPath) = lower('%s'))
and Value1 = '%s'""" % (LibraryIns, 'LIBRARY_CLASS')
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
IsFound = False
for Record in RecordSet:
LibName = Record[0].split('|', 1)[0]
if LibraryClass[1] == LibName:
IsFound = True
if not IsFound:
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT, LibraryClass[1]):
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT, OtherMsg = "The Library Class [%s] is not specified in '%s'" % (LibraryClass[1], LibraryClass[2]), BelongsToTable = 'Dsc', BelongsToItem = LibraryClass[0])
# Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies
def MetaDataFileCheckLibraryInstanceOrder(self):
if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceOrder == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
# This checkpoint is not necessary for Ecc check
pass
# Check whether the unnecessary inclusion of library classes in the Inf file
def MetaDataFileCheckLibraryNoUse(self):
if EccGlobalData.gConfig.MetaDataFileCheckLibraryNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking for library instance not used ...")
SqlCommand = """select ID, Value1 from Inf as A where A.Model = %s and A.Value1 not in (select B.Value1 from Dsc as B where Model = %s)""" % (MODEL_EFI_LIBRARY_CLASS, MODEL_EFI_LIBRARY_CLASS)
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
for Record in RecordSet:
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE, Record[1]):
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE, OtherMsg = "The Library Class [%s] is not used in any platform" % (Record[1]), BelongsToTable = 'Inf', BelongsToItem = Record[0])
# Check whether an Inf file is specified in the FDF file, but not in the Dsc file, then the Inf file must be for a Binary module only
def MetaDataFileCheckBinaryInfInFdf(self):
if EccGlobalData.gConfig.MetaDataFileCheckBinaryInfInFdf == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking for non-binary modules defined in FDF files ...")
SqlCommand = """select A.ID, A.Value1 from Fdf as A
where A.Model = %s
and A.Enabled > -1
and A.Value1 not in
(select B.Value1 from Dsc as B
where B.Model = %s
and B.Enabled > -1)""" % (MODEL_META_DATA_COMPONENT, MODEL_META_DATA_COMPONENT)
RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)
for Record in RecordSet:
FdfID = Record[0]
FilePath = Record[1]
FilePath = os.path.normpath(os.path.join(EccGlobalData.gWorkspace, FilePath))
SqlCommand = """select ID from Inf where Model = %s and BelongsToFile = (select ID from File where FullPath like '%s')
""" % (MODEL_EFI_SOURCE_FILE, FilePath)
NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
if NewRecordSet!= []:
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF, FilePath):
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF, OtherMsg = "File [%s] defined in FDF file and not in DSC file must be a binary module" % (FilePath), BelongsToTable = 'Fdf', BelongsToItem = FdfID)
# Check whether a PCD is set in a Dsc file or the FDF file, but not in both.
def MetaDataFileCheckPcdDuplicate(self):
if EccGlobalData.gConfig.MetaDataFileCheckPcdDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking for duplicate PCDs defined in both DSC and FDF files ...")
SqlCommand = """
select A.ID, A.Value2, B.ID, B.Value2 from Dsc as A, Fdf as B
where A.Model >= %s and A.Model < %s
and B.Model >= %s and B.Model < %s
and A.Value2 = B.Value2
and A.Enabled > -1
and B.Enabled > -1
group by A.ID
"""% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)
RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)
for Record in RecordSet:
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[1]):
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg = "The PCD [%s] is defined in both FDF file and DSC file" % (Record[1]), BelongsToTable = 'Dsc', BelongsToItem = Record[0])
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[3]):
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg = "The PCD [%s] is defined in both FDF file and DSC file" % (Record[3]), BelongsToTable = 'Fdf', BelongsToItem = Record[2])
EdkLogger.quiet("Checking for duplicate PCDs defined in DEC files ...")
SqlCommand = """
select A.ID, A.Value2 from Dec as A, Dec as B
where A.Model >= %s and A.Model < %s
and B.Model >= %s and B.Model < %s
and A.Value2 = B.Value2
and ((A.Arch = B.Arch) and (A.Arch != 'COMMON' or B.Arch != 'COMMON'))
and A.ID != B.ID
and A.Enabled > -1
and B.Enabled > -1
and A.BelongsToFile = B.BelongsToFile
group by A.ID
"""% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)
RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)
for Record in RecordSet:
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[1]):
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg = "The PCD [%s] is defined duplicated in DEC file" % (Record[1]), BelongsToTable = 'Dec', BelongsToItem = Record[0])
# Check whether PCD settings in the FDF file can only be related to flash.
def MetaDataFileCheckPcdFlash(self):
if EccGlobalData.gConfig.MetaDataFileCheckPcdFlash == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking only Flash related PCDs are used in FDF ...")
SqlCommand = """
select ID, Value2, BelongsToFile from Fdf as A
where A.Model >= %s and Model < %s
and A.Enabled > -1
and A.Value2 not like '%%Flash%%'
"""% (MODEL_PCD, MODEL_META_DATA_HEADER)
RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)
for Record in RecordSet:
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, Record[1]):
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, OtherMsg = "The PCD [%s] defined in FDF file is not related to Flash" % (Record[1]), BelongsToTable = 'Fdf', BelongsToItem = Record[0])
# Check whether PCDs used in Inf files but not specified in Dsc or FDF files
def MetaDataFileCheckPcdNoUse(self):
if EccGlobalData.gConfig.MetaDataFileCheckPcdNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking for non-specified PCDs ...")
SqlCommand = """
select ID, Value2, BelongsToFile from Inf as A
where A.Model >= %s and Model < %s
and A.Enabled > -1
and A.Value2 not in
(select Value2 from Dsc as B
where B.Model >= %s and B.Model < %s
and B.Enabled > -1)
and A.Value2 not in
(select Value2 from Fdf as C
where C.Model >= %s and C.Model < %s
and C.Enabled > -1)
"""% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
for Record in RecordSet:
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, Record[1]):
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, OtherMsg = "The PCD [%s] defined in INF file is not specified in either DSC or FDF files" % (Record[1]), BelongsToTable = 'Inf', BelongsToItem = Record[0])
# Check whether having duplicate guids defined for Guid/Protocol/Ppi
def MetaDataFileCheckGuidDuplicate(self):
if EccGlobalData.gConfig.MetaDataFileCheckGuidDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking for duplicate GUID/PPI/PROTOCOL ...")
# Check Guid
self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDec)
self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDsc)
self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID)
# Check protocol
self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDec)
self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDsc)
self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL)
# Check ppi
self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDec)
self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDsc)
self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI)
# Check whether all files under module directory are described in INF files
def MetaDataFileCheckModuleFileNoUse(self):
if EccGlobalData.gConfig.MetaDataFileCheckModuleFileNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking for no used module files ...")
SqlCommand = """
select upper(Path) from File where ID in (select BelongsToFile from INF where BelongsToFile != -1)
"""
InfPathSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
InfPathList = []
for Item in InfPathSet:
if Item[0] not in InfPathList:
InfPathList.append(Item[0])
SqlCommand = """
select ID, Path, FullPath from File where upper(FullPath) not in
(select upper(A.Path) || '\\' || upper(B.Value1) from File as A, INF as B
where A.ID in (select BelongsToFile from INF where Model = %s group by BelongsToFile) and
B.BelongsToFile = A.ID and B.Model = %s)
and (Model = %s or Model = %s)
""" % (MODEL_EFI_SOURCE_FILE, MODEL_EFI_SOURCE_FILE, MODEL_FILE_C, MODEL_FILE_H)
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
for Record in RecordSet:
Path = Record[1]
Path = Path.upper().replace('\X64', '').replace('\IA32', '').replace('\EBC', '').replace('\IPF', '').replace('\ARM', '')
if Path in InfPathList:
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE, Record[2]):
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE, OtherMsg = "The source file [%s] is existing in module directory but it is not described in INF file." % (Record[2]), BelongsToTable = 'File', BelongsToItem = Record[0])
# Check whether the PCD is correctly used in C function via its type
def MetaDataFileCheckPcdType(self):
if EccGlobalData.gConfig.MetaDataFileCheckPcdType == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking for pcd type in c code function usage ...")
SqlCommand = """
select ID, Model, Value1, BelongsToFile from INF where Model > %s and Model < %s
""" % (MODEL_PCD, MODEL_META_DATA_HEADER)
PcdSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
for Pcd in PcdSet:
Model = Pcd[1]
PcdName = Pcd[2]
if len(Pcd[2].split(".")) > 1:
PcdName = Pcd[2].split(".")[1]
BelongsToFile = Pcd[3]
SqlCommand = """
select ID from File where FullPath in
(select B.Path || '\\' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s
and B.ID = %s)
""" %(MODEL_EFI_SOURCE_FILE, BelongsToFile, BelongsToFile)
TableSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
for Tbl in TableSet:
TblName = 'Identifier' + str(Tbl[0])
SqlCommand = """
select Name, ID from %s where value like '%%%s%%' and Model = %s
""" % (TblName, PcdName, MODEL_IDENTIFIER_FUNCTION_CALLING)
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
TblNumber = TblName.replace('Identifier', '')
for Record in RecordSet:
FunName = Record[0]
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, FunName):
if Model in [MODEL_PCD_FIXED_AT_BUILD] and not FunName.startswith('FixedPcdGet'):
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, OtherMsg = "The pcd '%s' is defined as a FixPcd but now it is called by c function [%s]" % (PcdName, FunName), BelongsToTable = TblName, BelongsToItem = Record[1])
if Model in [MODEL_PCD_FEATURE_FLAG] and (not FunName.startswith('FeaturePcdGet') and not FunName.startswith('FeaturePcdSet')):
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, OtherMsg = "The pcd '%s' is defined as a FeaturePcd but now it is called by c function [%s]" % (PcdName, FunName), BelongsToTable = TblName, BelongsToItem = Record[1])
if Model in [MODEL_PCD_PATCHABLE_IN_MODULE] and (not FunName.startswith('PatchablePcdGet') and not FunName.startswith('PatchablePcdSet')):
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, OtherMsg = "The pcd '%s' is defined as a PatchablePcd but now it is called by c function [%s]" % (PcdName, FunName), BelongsToTable = TblName, BelongsToItem = Record[1])
#ERROR_META_DATA_FILE_CHECK_PCD_TYPE
pass
# Check whether these is duplicate Guid/Ppi/Protocol name
def CheckGuidProtocolPpi(self, ErrorID, Model, Table):
Name = ''
if Model == MODEL_EFI_GUID:
Name = 'guid'
if Model == MODEL_EFI_PROTOCOL:
Name = 'protocol'
if Model == MODEL_EFI_PPI:
Name = 'ppi'
SqlCommand = """
select A.ID, A.Value1 from %s as A, %s as B
where A.Model = %s and B.Model = %s
and A.Value1 = B.Value1 and A.ID <> B.ID
and A.Enabled > -1
and B.Enabled > -1
group by A.ID
""" % (Table.Table, Table.Table, Model, Model)
RecordSet = Table.Exec(SqlCommand)
for Record in RecordSet:
if not EccGlobalData.gException.IsException(ErrorID, Record[1]):
EccGlobalData.gDb.TblReport.Insert(ErrorID, OtherMsg = "The %s name [%s] is defined more than one time" % (Name.upper(), Record[1]), BelongsToTable = Table.Table, BelongsToItem = Record[0])
# Check whether these is duplicate Guid/Ppi/Protocol value
def CheckGuidProtocolPpiValue(self, ErrorID, Model):
Name = ''
Table = EccGlobalData.gDb.TblDec
if Model == MODEL_EFI_GUID:
Name = 'guid'
if Model == MODEL_EFI_PROTOCOL:
Name = 'protocol'
if Model == MODEL_EFI_PPI:
Name = 'ppi'
SqlCommand = """
select A.ID, A.Value2 from %s as A, %s as B
where A.Model = %s and B.Model = %s
and A.Value2 = B.Value2 and A.ID <> B.ID
group by A.ID
""" % (Table.Table, Table.Table, Model, Model)
RecordSet = Table.Exec(SqlCommand)
for Record in RecordSet:
if not EccGlobalData.gException.IsException(ErrorID, Record[1]):
EccGlobalData.gDb.TblReport.Insert(ErrorID, OtherMsg = "The %s value [%s] is used more than one time" % (Name.upper(), Record[1]), BelongsToTable = Table.Table, BelongsToItem = Record[0])
# Naming Convention Check
def NamingConventionCheck(self):
for Dirpath, Dirnames, Filenames in self.WalkTree():
for F in Filenames:
if os.path.splitext(F)[1] in ('.h', '.c'):
FullName = os.path.join(Dirpath, F)
Id = c.GetTableID(FullName)
if Id < 0:
continue
FileTable = 'Identifier' + str(Id)
self.NamingConventionCheckDefineStatement(FileTable)
self.NamingConventionCheckTypedefStatement(FileTable)
self.NamingConventionCheckIfndefStatement(FileTable)
self.NamingConventionCheckVariableName(FileTable)
self.NamingConventionCheckSingleCharacterVariable(FileTable)
self.NamingConventionCheckPathName()
self.NamingConventionCheckFunctionName()
# Check whether only capital letters are used for #define declarations
def NamingConventionCheckDefineStatement(self, FileTable):
if EccGlobalData.gConfig.NamingConventionCheckDefineStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking naming covention of #define statement ...")
SqlCommand = """select ID, Value from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_MACRO_DEFINE)
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
for Record in RecordSet:
Name = Record[1].strip().split()[1]
if Name.find('(') != -1:
Name = Name[0:Name.find('(')]
if Name.upper() != Name:
if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT, Name):
EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT, OtherMsg = "The #define name [%s] does not follow the rules" % (Name), BelongsToTable = FileTable, BelongsToItem = Record[0])
# Check whether only capital letters are used for typedef declarations
def NamingConventionCheckTypedefStatement(self, FileTable):
if EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking naming covention of #typedef statement ...")
SqlCommand = """select ID, Name from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_TYPEDEF)
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
for Record in RecordSet:
Name = Record[1].strip()
if Name != '' and Name != None:
if Name[0] == '(':
Name = Name[1:Name.find(')')]
if Name.find('(') > -1:
Name = Name[Name.find('(') + 1 : Name.find(')')]
Name = Name.replace('WINAPI', '')
Name = Name.replace('*', '').strip()
if Name.upper() != Name:
if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT, Name):
EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT, OtherMsg = "The #typedef name [%s] does not follow the rules" % (Name), BelongsToTable = FileTable, BelongsToItem = Record[0])
# Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.
def NamingConventionCheckIfndefStatement(self, FileTable):
if EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking naming covention of #ifndef statement ...")
SqlCommand = """select ID, Value from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_MACRO_IFNDEF)
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
for Record in RecordSet:
Name = Record[1].replace('#ifndef', '').strip()
if Name[0] != '_' or Name[-1] != '_':
if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT, Name):
EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT, OtherMsg = "The #ifndef name [%s] does not follow the rules" % (Name), BelongsToTable = FileTable, BelongsToItem = Record[0])
# Rule for path name, variable name and function name
# 1. First character should be upper case
# 2. Existing lower case in a word
# 3. No space existence
# Check whether the path name followed the rule
def NamingConventionCheckPathName(self):
if EccGlobalData.gConfig.NamingConventionCheckPathName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking naming covention of file path name ...")
Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')
SqlCommand = """select ID, Name from File"""
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
for Record in RecordSet:
if not Pattern.match(Record[1]):
if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME, Record[1]):
EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME, OtherMsg = "The file path [%s] does not follow the rules" % (Record[1]), BelongsToTable = 'File', BelongsToItem = Record[0])
# Rule for path name, variable name and function name
# 1. First character should be upper case
# 2. Existing lower case in a word
# 3. No space existence
# 4. Global variable name must start with a 'g'
# Check whether the variable name followed the rule
def NamingConventionCheckVariableName(self, FileTable):
if EccGlobalData.gConfig.NamingConventionCheckVariableName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking naming covention of variable name ...")
Pattern = re.compile(r'^[A-Zgm]+\S*[a-z]\S*$')
SqlCommand = """select ID, Name from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_VARIABLE)
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
for Record in RecordSet:
if not Pattern.match(Record[1]):
if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Record[1]):
EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, OtherMsg = "The variable name [%s] does not follow the rules" % (Record[1]), BelongsToTable = FileTable, BelongsToItem = Record[0])
# Rule for path name, variable name and function name
# 1. First character should be upper case
# 2. Existing lower case in a word
# 3. No space existence
# Check whether the function name followed the rule
def NamingConventionCheckFunctionName(self):
if EccGlobalData.gConfig.NamingConventionCheckFunctionName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking naming covention of function name ...")
Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')
SqlCommand = """select ID, Name from Function"""
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
for Record in RecordSet:
if not Pattern.match(Record[1]):
if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME, Record[1]):
EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME, OtherMsg = "The function name [%s] does not follow the rules" % (Record[1]), BelongsToTable = 'Function', BelongsToItem = Record[0])
# Check whether NO use short variable name with single character
def NamingConventionCheckSingleCharacterVariable(self, FileTable):
if EccGlobalData.gConfig.NamingConventionCheckSingleCharacterVariable == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking naming covention of single character variable name ...")
SqlCommand = """select ID, Name from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_VARIABLE)
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
for Record in RecordSet:
Variable = Record[1].replace('*', '')
if len(Variable) == 1:
if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE, Record[1]):
EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE, OtherMsg = "The variable name [%s] does not follow the rules" % (Record[1]), BelongsToTable = FileTable, BelongsToItem = Record[0])
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
Check = Check()
Check.Check()

View File

@@ -0,0 +1,165 @@
## @file
# fragments of source file
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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.
#
## The description of comment contents and start & end position
#
#
class Comment :
## The constructor
#
# @param self The object pointer
# @param Str The message to record
# @param Begin The start position tuple.
# @param End The end position tuple.
# @param CommentType The type of comment (T_COMMENT_TWO_SLASH or T_COMMENT_SLASH_STAR).
#
def __init__(self, Str, Begin, End, CommentType):
self.Content = Str
self.StartPos = Begin
self.EndPos = End
self.Type = CommentType
## The description of preprocess directives and start & end position
#
#
class PP_Directive :
## The constructor
#
# @param self The object pointer
# @param Str The message to record
# @param Begin The start position tuple.
# @param End The end position tuple.
#
def __init__(self, Str, Begin, End):
self.Content = Str
self.StartPos = Begin
self.EndPos = End
## The description of predicate expression and start & end position
#
#
class PredicateExpression :
## The constructor
#
# @param self The object pointer
# @param Str The message to record
# @param Begin The start position tuple.
# @param End The end position tuple.
#
def __init__(self, Str, Begin, End):
self.Content = Str
self.StartPos = Begin
self.EndPos = End
## The description of function definition and start & end position
#
#
class FunctionDefinition :
## The constructor
#
# @param self The object pointer
# @param Str The message to record
# @param Begin The start position tuple.
# @param End The end position tuple.
# @param LBPos The left brace position tuple.
#
def __init__(self, ModifierStr, DeclStr, Begin, End, LBPos, NamePos):
self.Modifier = ModifierStr
self.Declarator = DeclStr
self.StartPos = Begin
self.EndPos = End
self.LeftBracePos = LBPos
self.NamePos = NamePos
## The description of variable declaration and start & end position
#
#
class VariableDeclaration :
## The constructor
#
# @param self The object pointer
# @param Str The message to record
# @param Begin The start position tuple.
# @param NamePos The name position tuple.
#
def __init__(self, ModifierStr, DeclStr, Begin, NamePos):
self.Modifier = ModifierStr
self.Declarator = DeclStr
self.StartPos = Begin
self.NameStartPos = NamePos
## The description of enum definition and start & end position
#
#
class EnumerationDefinition :
## The constructor
#
# @param self The object pointer
# @param Str The message to record
# @param Begin The start position tuple.
# @param End The end position tuple.
#
def __init__(self, Str, Begin, End):
self.Content = Str
self.StartPos = Begin
self.EndPos = End
## The description of struct/union definition and start & end position
#
#
class StructUnionDefinition :
## The constructor
#
# @param self The object pointer
# @param Str The message to record
# @param Begin The start position tuple.
# @param End The end position tuple.
#
def __init__(self, Str, Begin, End):
self.Content = Str
self.StartPos = Begin
self.EndPos = End
## The description of 'Typedef' definition and start & end position
#
#
class TypedefDefinition :
## The constructor
#
# @param self The object pointer
# @param Str The message to record
# @param Begin The start position tuple.
# @param End The end position tuple.
#
def __init__(self, FromStr, ToStr, Begin, End):
self.FromType = FromStr
self.ToType = ToStr
self.StartPos = Begin
self.EndPos = End
class FunctionCalling:
## The constructor
#
# @param self The object pointer
# @param Str The message to record
# @param Begin The start position tuple.
# @param End The end position tuple.
#
def __init__(self, Name, Param, Begin, End):
self.FuncName = Name
self.ParamList = Param
self.StartPos = Begin
self.EndPos = End

View File

@@ -0,0 +1,624 @@
## @file
# preprocess source file
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import re
import os
import sys
import antlr3
from CLexer import CLexer
from CParser import CParser
import FileProfile
from CodeFragment import Comment
from CodeFragment import PP_Directive
from ParserWarning import Warning
##define T_CHAR_SPACE ' '
##define T_CHAR_NULL '\0'
##define T_CHAR_CR '\r'
##define T_CHAR_TAB '\t'
##define T_CHAR_LF '\n'
##define T_CHAR_SLASH '/'
##define T_CHAR_BACKSLASH '\\'
##define T_CHAR_DOUBLE_QUOTE '\"'
##define T_CHAR_SINGLE_QUOTE '\''
##define T_CHAR_STAR '*'
##define T_CHAR_HASH '#'
(T_CHAR_SPACE, T_CHAR_NULL, T_CHAR_CR, T_CHAR_TAB, T_CHAR_LF, T_CHAR_SLASH, \
T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \
(' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')
SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')
(T_COMMENT_TWO_SLASH, T_COMMENT_SLASH_STAR) = (0, 1)
(T_PP_INCLUDE, T_PP_DEFINE, T_PP_OTHERS) = (0, 1, 2)
## The collector for source code fragments.
#
# PreprocessFile method should be called prior to ParseFile
#
# GetNext*** procedures mean these procedures will get next token first, then make judgement.
# Get*** procedures mean these procedures will make judgement on current token only.
#
class CodeFragmentCollector:
## The constructor
#
# @param self The object pointer
# @param FileName The file that to be parsed
#
def __init__(self, FileName):
self.Profile = FileProfile.FileProfile(FileName)
self.Profile.FileLinesList.append(T_CHAR_LF)
self.FileName = FileName
self.CurrentLineNumber = 1
self.CurrentOffsetWithinLine = 0
self.__Token = ""
self.__SkippedChars = ""
## __IsWhiteSpace() method
#
# Whether char at current FileBufferPos is whitespace
#
# @param self The object pointer
# @param Char The char to test
# @retval True The char is a kind of white space
# @retval False The char is NOT a kind of white space
#
def __IsWhiteSpace(self, Char):
if Char in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_SPACE, T_CHAR_TAB, T_CHAR_LF):
return True
else:
return False
## __SkipWhiteSpace() method
#
# Skip white spaces from current char, return number of chars skipped
#
# @param self The object pointer
# @retval Count The number of chars skipped
#
def __SkipWhiteSpace(self):
Count = 0
while not self.__EndOfFile():
Count += 1
if self.__CurrentChar() in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_LF, T_CHAR_SPACE, T_CHAR_TAB):
self.__SkippedChars += str(self.__CurrentChar())
self.__GetOneChar()
else:
Count = Count - 1
return Count
## __EndOfFile() method
#
# Judge current buffer pos is at file end
#
# @param self The object pointer
# @retval True Current File buffer position is at file end
# @retval False Current File buffer position is NOT at file end
#
def __EndOfFile(self):
NumberOfLines = len(self.Profile.FileLinesList)
SizeOfLastLine = NumberOfLines
if NumberOfLines > 0:
SizeOfLastLine = len(self.Profile.FileLinesList[-1])
if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1:
return True
elif self.CurrentLineNumber > NumberOfLines:
return True
else:
return False
## __EndOfLine() method
#
# Judge current buffer pos is at line end
#
# @param self The object pointer
# @retval True Current File buffer position is at line end
# @retval False Current File buffer position is NOT at line end
#
def __EndOfLine(self):
SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
if self.CurrentOffsetWithinLine >= SizeOfCurrentLine - 1:
return True
else:
return False
## Rewind() method
#
# Reset file data buffer to the initial state
#
# @param self The object pointer
#
def Rewind(self):
self.CurrentLineNumber = 1
self.CurrentOffsetWithinLine = 0
## __UndoOneChar() method
#
# Go back one char in the file buffer
#
# @param self The object pointer
# @retval True Successfully go back one char
# @retval False Not able to go back one char as file beginning reached
#
def __UndoOneChar(self):
if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0:
return False
elif self.CurrentOffsetWithinLine == 0:
self.CurrentLineNumber -= 1
self.CurrentOffsetWithinLine = len(self.__CurrentLine()) - 1
else:
self.CurrentOffsetWithinLine -= 1
return True
## __GetOneChar() method
#
# Move forward one char in the file buffer
#
# @param self The object pointer
#
def __GetOneChar(self):
if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
self.CurrentLineNumber += 1
self.CurrentOffsetWithinLine = 0
else:
self.CurrentOffsetWithinLine += 1
## __CurrentChar() method
#
# Get the char pointed to by the file buffer pointer
#
# @param self The object pointer
# @retval Char Current char
#
def __CurrentChar(self):
CurrentChar = self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine]
# if CurrentChar > 255:
# raise Warning("Non-Ascii char found At Line %d, offset %d" % (self.CurrentLineNumber, self.CurrentOffsetWithinLine), self.FileName, self.CurrentLineNumber)
return CurrentChar
## __NextChar() method
#
# Get the one char pass the char pointed to by the file buffer pointer
#
# @param self The object pointer
# @retval Char Next char
#
def __NextChar(self):
if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
return self.Profile.FileLinesList[self.CurrentLineNumber][0]
else:
return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1]
## __SetCurrentCharValue() method
#
# Modify the value of current char
#
# @param self The object pointer
# @param Value The new value of current char
#
def __SetCurrentCharValue(self, Value):
self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value
## __SetCharValue() method
#
# Modify the value of current char
#
# @param self The object pointer
# @param Value The new value of current char
#
def __SetCharValue(self, Line, Offset, Value):
self.Profile.FileLinesList[Line - 1][Offset] = Value
## __CurrentLine() method
#
# Get the list that contains current line contents
#
# @param self The object pointer
# @retval List current line contents
#
def __CurrentLine(self):
return self.Profile.FileLinesList[self.CurrentLineNumber - 1]
## __InsertComma() method
#
# Insert ',' to replace PP
#
# @param self The object pointer
# @retval List current line contents
#
def __InsertComma(self, Line):
if self.Profile.FileLinesList[Line - 1][0] != T_CHAR_HASH:
BeforeHashPart = str(self.Profile.FileLinesList[Line - 1]).split(T_CHAR_HASH)[0]
if BeforeHashPart.rstrip().endswith(T_CHAR_COMMA) or BeforeHashPart.rstrip().endswith(';'):
return
if Line - 2 >= 0 and str(self.Profile.FileLinesList[Line - 2]).rstrip().endswith(','):
return
if Line - 2 >= 0 and str(self.Profile.FileLinesList[Line - 2]).rstrip().endswith(';'):
return
if str(self.Profile.FileLinesList[Line]).lstrip().startswith(',') or str(self.Profile.FileLinesList[Line]).lstrip().startswith(';'):
return
self.Profile.FileLinesList[Line - 1].insert(self.CurrentOffsetWithinLine, ',')
## PreprocessFile() method
#
# Preprocess file contents, replace comments with spaces.
# In the end, rewind the file buffer pointer to the beginning
# BUGBUG: No !include statement processing contained in this procedure
# !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
#
# @param self The object pointer
#
def PreprocessFile(self):
self.Rewind()
InComment = False
DoubleSlashComment = False
HashComment = False
PPExtend = False
CommentObj = None
PPDirectiveObj = None
# HashComment in quoted string " " is ignored.
InString = False
InCharLiteral = False
self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesListFromFile]
while not self.__EndOfFile():
if not InComment and self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE:
InString = not InString
if not InComment and self.__CurrentChar() == T_CHAR_SINGLE_QUOTE:
InCharLiteral = not InCharLiteral
# meet new line, then no longer in a comment for // and '#'
if self.__CurrentChar() == T_CHAR_LF:
if HashComment and PPDirectiveObj != None:
if PPDirectiveObj.Content.rstrip(T_CHAR_CR).endswith(T_CHAR_BACKSLASH):
PPDirectiveObj.Content += T_CHAR_LF
PPExtend = True
else:
PPExtend = False
EndLinePos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine)
if InComment and DoubleSlashComment:
InComment = False
DoubleSlashComment = False
CommentObj.Content += T_CHAR_LF
CommentObj.EndPos = EndLinePos
FileProfile.CommentList.append(CommentObj)
CommentObj = None
if InComment and HashComment and not PPExtend:
InComment = False
HashComment = False
PPDirectiveObj.Content += T_CHAR_LF
PPDirectiveObj.EndPos = EndLinePos
FileProfile.PPDirectiveList.append(PPDirectiveObj)
PPDirectiveObj = None
if InString or InCharLiteral:
CurrentLine = "".join(self.__CurrentLine())
if CurrentLine.rstrip(T_CHAR_LF).rstrip(T_CHAR_CR).endswith(T_CHAR_BACKSLASH):
SlashIndex = CurrentLine.rindex(T_CHAR_BACKSLASH)
self.__SetCharValue(self.CurrentLineNumber, SlashIndex, T_CHAR_SPACE)
if InComment and not DoubleSlashComment and not HashComment:
CommentObj.Content += T_CHAR_LF
self.CurrentLineNumber += 1
self.CurrentOffsetWithinLine = 0
# check for */ comment end
elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH:
CommentObj.Content += self.__CurrentChar()
# self.__SetCurrentCharValue(T_CHAR_SPACE)
self.__GetOneChar()
CommentObj.Content += self.__CurrentChar()
# self.__SetCurrentCharValue(T_CHAR_SPACE)
CommentObj.EndPos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine)
FileProfile.CommentList.append(CommentObj)
CommentObj = None
self.__GetOneChar()
InComment = False
# set comments to spaces
elif InComment:
if HashComment:
# // follows hash PP directive
if self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH:
InComment = False
HashComment = False
PPDirectiveObj.EndPos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine - 1)
FileProfile.PPDirectiveList.append(PPDirectiveObj)
PPDirectiveObj = None
continue
else:
PPDirectiveObj.Content += self.__CurrentChar()
if PPExtend:
self.__SetCurrentCharValue(T_CHAR_SPACE)
else:
CommentObj.Content += self.__CurrentChar()
# self.__SetCurrentCharValue(T_CHAR_SPACE)
self.__GetOneChar()
# check for // comment
elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH:
InComment = True
DoubleSlashComment = True
CommentObj = Comment('', (self.CurrentLineNumber, self.CurrentOffsetWithinLine), None, T_COMMENT_TWO_SLASH)
# check for '#' comment
elif self.__CurrentChar() == T_CHAR_HASH and not InString and not InCharLiteral:
InComment = True
HashComment = True
PPDirectiveObj = PP_Directive('', (self.CurrentLineNumber, self.CurrentOffsetWithinLine), None)
# check for /* comment start
elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR:
CommentObj = Comment('', (self.CurrentLineNumber, self.CurrentOffsetWithinLine), None, T_COMMENT_SLASH_STAR)
CommentObj.Content += self.__CurrentChar()
# self.__SetCurrentCharValue( T_CHAR_SPACE)
self.__GetOneChar()
CommentObj.Content += self.__CurrentChar()
# self.__SetCurrentCharValue( T_CHAR_SPACE)
self.__GetOneChar()
InComment = True
else:
self.__GetOneChar()
EndLinePos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine)
if InComment and DoubleSlashComment:
CommentObj.EndPos = EndLinePos
FileProfile.CommentList.append(CommentObj)
if InComment and HashComment and not PPExtend:
PPDirectiveObj.EndPos = EndLinePos
FileProfile.PPDirectiveList.append(PPDirectiveObj)
self.Rewind()
def PreprocessFileWithClear(self):
self.Rewind()
InComment = False
DoubleSlashComment = False
HashComment = False
PPExtend = False
CommentObj = None
PPDirectiveObj = None
# HashComment in quoted string " " is ignored.
InString = False
InCharLiteral = False
self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesListFromFile]
while not self.__EndOfFile():
if not InComment and self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE:
InString = not InString
if not InComment and self.__CurrentChar() == T_CHAR_SINGLE_QUOTE:
InCharLiteral = not InCharLiteral
# meet new line, then no longer in a comment for // and '#'
if self.__CurrentChar() == T_CHAR_LF:
if HashComment and PPDirectiveObj != None:
if PPDirectiveObj.Content.rstrip(T_CHAR_CR).endswith(T_CHAR_BACKSLASH):
PPDirectiveObj.Content += T_CHAR_LF
PPExtend = True
else:
PPExtend = False
EndLinePos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine)
if InComment and DoubleSlashComment:
InComment = False
DoubleSlashComment = False
CommentObj.Content += T_CHAR_LF
CommentObj.EndPos = EndLinePos
FileProfile.CommentList.append(CommentObj)
CommentObj = None
if InComment and HashComment and not PPExtend:
InComment = False
HashComment = False
PPDirectiveObj.Content += T_CHAR_LF
PPDirectiveObj.EndPos = EndLinePos
FileProfile.PPDirectiveList.append(PPDirectiveObj)
PPDirectiveObj = None
if InString or InCharLiteral:
CurrentLine = "".join(self.__CurrentLine())
if CurrentLine.rstrip(T_CHAR_LF).rstrip(T_CHAR_CR).endswith(T_CHAR_BACKSLASH):
SlashIndex = CurrentLine.rindex(T_CHAR_BACKSLASH)
self.__SetCharValue(self.CurrentLineNumber, SlashIndex, T_CHAR_SPACE)
if InComment and not DoubleSlashComment and not HashComment:
CommentObj.Content += T_CHAR_LF
self.CurrentLineNumber += 1
self.CurrentOffsetWithinLine = 0
# check for */ comment end
elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH:
CommentObj.Content += self.__CurrentChar()
self.__SetCurrentCharValue(T_CHAR_SPACE)
self.__GetOneChar()
CommentObj.Content += self.__CurrentChar()
self.__SetCurrentCharValue(T_CHAR_SPACE)
CommentObj.EndPos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine)
FileProfile.CommentList.append(CommentObj)
CommentObj = None
self.__GetOneChar()
InComment = False
# set comments to spaces
elif InComment:
if HashComment:
# // follows hash PP directive
if self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH:
InComment = False
HashComment = False
PPDirectiveObj.EndPos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine - 1)
FileProfile.PPDirectiveList.append(PPDirectiveObj)
PPDirectiveObj = None
continue
else:
PPDirectiveObj.Content += self.__CurrentChar()
# if PPExtend:
# self.__SetCurrentCharValue(T_CHAR_SPACE)
else:
CommentObj.Content += self.__CurrentChar()
self.__SetCurrentCharValue(T_CHAR_SPACE)
self.__GetOneChar()
# check for // comment
elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH:
InComment = True
DoubleSlashComment = True
CommentObj = Comment('', (self.CurrentLineNumber, self.CurrentOffsetWithinLine), None, T_COMMENT_TWO_SLASH)
# check for '#' comment
elif self.__CurrentChar() == T_CHAR_HASH and not InString and not InCharLiteral:
InComment = True
HashComment = True
PPDirectiveObj = PP_Directive('', (self.CurrentLineNumber, self.CurrentOffsetWithinLine), None)
# check for /* comment start
elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR:
CommentObj = Comment('', (self.CurrentLineNumber, self.CurrentOffsetWithinLine), None, T_COMMENT_SLASH_STAR)
CommentObj.Content += self.__CurrentChar()
self.__SetCurrentCharValue( T_CHAR_SPACE)
self.__GetOneChar()
CommentObj.Content += self.__CurrentChar()
self.__SetCurrentCharValue( T_CHAR_SPACE)
self.__GetOneChar()
InComment = True
else:
self.__GetOneChar()
EndLinePos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine)
if InComment and DoubleSlashComment:
CommentObj.EndPos = EndLinePos
FileProfile.CommentList.append(CommentObj)
if InComment and HashComment and not PPExtend:
PPDirectiveObj.EndPos = EndLinePos
FileProfile.PPDirectiveList.append(PPDirectiveObj)
self.Rewind()
## ParseFile() method
#
# Parse the file profile buffer to extract fd, fv ... information
# Exception will be raised if syntax error found
#
# @param self The object pointer
#
def ParseFile(self):
self.PreprocessFile()
# restore from ListOfList to ListOfString
self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
FileStringContents = ''
for fileLine in self.Profile.FileLinesList:
FileStringContents += fileLine
cStream = antlr3.StringStream(FileStringContents)
lexer = CLexer(cStream)
tStream = antlr3.CommonTokenStream(lexer)
parser = CParser(tStream)
parser.translation_unit()
def ParseFileWithClearedPPDirective(self):
self.PreprocessFileWithClear()
# restore from ListOfList to ListOfString
self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
FileStringContents = ''
for fileLine in self.Profile.FileLinesList:
FileStringContents += fileLine
cStream = antlr3.StringStream(FileStringContents)
lexer = CLexer(cStream)
tStream = antlr3.CommonTokenStream(lexer)
parser = CParser(tStream)
parser.translation_unit()
def CleanFileProfileBuffer(self):
FileProfile.CommentList = []
FileProfile.PPDirectiveList = []
FileProfile.PredicateExpressionList = []
FileProfile.FunctionDefinitionList = []
FileProfile.VariableDeclarationList = []
FileProfile.EnumerationDefinitionList = []
FileProfile.StructUnionDefinitionList = []
FileProfile.TypedefDefinitionList = []
FileProfile.FunctionCallingList = []
def PrintFragments(self):
print '################# ' + self.FileName + '#####################'
print '/****************************************/'
print '/*************** COMMENTS ***************/'
print '/****************************************/'
for comment in FileProfile.CommentList:
print str(comment.StartPos) + comment.Content
print '/****************************************/'
print '/********* PREPROCESS DIRECTIVES ********/'
print '/****************************************/'
for pp in FileProfile.PPDirectiveList:
print str(pp.StartPos) + pp.Content
print '/****************************************/'
print '/********* VARIABLE DECLARATIONS ********/'
print '/****************************************/'
for var in FileProfile.VariableDeclarationList:
print str(var.StartPos) + var.Modifier + ' '+ var.Declarator
print '/****************************************/'
print '/********* FUNCTION DEFINITIONS *********/'
print '/****************************************/'
for func in FileProfile.FunctionDefinitionList:
print str(func.StartPos) + func.Modifier + ' '+ func.Declarator + ' ' + str(func.NamePos)
print '/****************************************/'
print '/************ ENUMERATIONS **************/'
print '/****************************************/'
for enum in FileProfile.EnumerationDefinitionList:
print str(enum.StartPos) + enum.Content
print '/****************************************/'
print '/*********** STRUCTS/UNIONS *************/'
print '/****************************************/'
for su in FileProfile.StructUnionDefinitionList:
print str(su.StartPos) + su.Content
print '/****************************************/'
print '/********* PREDICATE EXPRESSIONS ********/'
print '/****************************************/'
for predexp in FileProfile.PredicateExpressionList:
print str(predexp.StartPos) + predexp.Content
print '/****************************************/'
print '/************** TYPEDEFS ****************/'
print '/****************************************/'
for typedef in FileProfile.TypedefDefinitionList:
print str(typedef.StartPos) + typedef.ToType
if __name__ == "__main__":
collector = CodeFragmentCollector(sys.argv[1])
collector.PreprocessFile()
print "For Test."

View File

@@ -0,0 +1,264 @@
## @file
# This file is used to define class Configuration
#
# Copyright (c) 2008, Intel Corporation
# All rights reserved. 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
#
import os
import Common.EdkLogger as EdkLogger
from Common.DataType import *
from Common.String import *
## Configuration
#
# This class is used to define all items in configuration file
#
# @param Filename: The name of configuration file, the default is config.ini
#
class Configuration(object):
def __init__(self, Filename):
self.Filename = Filename
self.Version = 0.1
## Identify to if check all items
# 1 - Check all items and ignore all other detailed items
# 0 - Not check all items, the tool will go through all other detailed items to decide to check or not
#
self.CheckAll = 0
## Identify to if automatically correct mistakes
# 1 - Automatically correct
# 0 - Not automatically correct
# Only the following check points can be automatically corrected, others not listed below are not supported even it is 1
#
# GeneralCheckTab
# GeneralCheckIndentation
# GeneralCheckLine
# GeneralCheckCarriageReturn
# SpaceCheckAll
#
self.AutoCorrect = 0
# List customized Modifer here, split with ','
# Defaultly use the definition in class DataType
self.ModifierList = MODIFIER_LIST
## General Checking
self.GeneralCheckAll = 0
# Check whether NO Tab is used, replaced with spaces
self.GeneralCheckNoTab = 1
# The width of Tab
self.GeneralCheckTabWidth = 2
# Check whether the indentation is followed coding style
self.GeneralCheckIndentation = 1
# The width of indentation
self.GeneralCheckIndentationWidth = 2
# Check whether no line is exceeding defined widty
self.GeneralCheckLine = 1
# The width of a line
self.GeneralCheckLineWidth = 120
# Check whether no use of _asm in the source file
self.GeneralCheckNo_Asm = 1
# Check whether no use of "#progma" in source file except "#pragma pack(#)".
self.GeneralCheckNoProgma = 1
# Check whether there is a carriage return at the end of the file
self.GeneralCheckCarriageReturn = 1
# Check whether the file exists
self.GeneralCheckFileExistence = 1
## Space Checking
self.SpaceCheckAll = 1
## Predicate Expression Checking
self.PredicateExpressionCheckAll = 0
# Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE
self.PredicateExpressionCheckBooleanValue = 1
# Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=).
self.PredicateExpressionCheckNonBooleanOperator = 1
# Check whether a comparison of any pointer to zero must be done via the NULL type
self.PredicateExpressionCheckComparisonNullType = 1
## Headers Checking
self.HeaderCheckAll = 0
# Check whether File header exists
self.HeaderCheckFile = 1
# Check whether Function header exists
self.HeaderCheckFunction = 1
## C Function Layout Checking
self.CFunctionLayoutCheckAll = 0
# Check whether return type exists and in the first line
self.CFunctionLayoutCheckReturnType = 1
# Check whether any optional functional modifiers exist and next to the return type
self.CFunctionLayoutCheckOptionalFunctionalModifier = 1
# Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list
# Check whether the closing parenthesis is on its own line and also indented two spaces
self.CFunctionLayoutCheckFunctionName = 1
# Check whether the function prototypes in include files have the same form as function definitions
self.CFunctionLayoutCheckFunctionPrototype = 1
# Check whether the body of a function is contained by open and close braces that must be in the first column
self.CFunctionLayoutCheckFunctionBody = 1
# Check whether the data declarations is the first code in a module.
self.CFunctionLayoutCheckDataDeclaration = 1
# Check whether no initialization of a variable as part of its declaration
self.CFunctionLayoutCheckNoInitOfVariable = 1
# Check whether no use of STATIC for functions
self.CFunctionLayoutCheckNoStatic = 1
## Include Files Checking
self.IncludeFileCheckAll = 0
#Check whether having include files with same name
self.IncludeFileCheckSameName = 1
# Check whether all include file contents is guarded by a #ifndef statement.
# the #ifndef must be the first line of code following the file header comment
# the #endif must appear on the last line in the file
self.IncludeFileCheckIfndefStatement = 1
# Check whether include files contain only public or only private data
# Check whether include files NOT contain code or define data variables
self.IncludeFileCheckData = 1
## Declarations and Data Types Checking
self.DeclarationDataTypeCheckAll = 0
# Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files.
self.DeclarationDataTypeCheckNoUseCType = 1
# Check whether the modifiers IN, OUT, OPTIONAL, and UNALIGNED are used only to qualify arguments to a function and should not appear in a data type declaration
self.DeclarationDataTypeCheckInOutModifier = 1
# Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols
self.DeclarationDataTypeCheckEFIAPIModifier = 1
# Check whether Enumerated Type has a 'typedef' and the name is capital
self.DeclarationDataTypeCheckEnumeratedType = 1
# Check whether Structure Type has a 'typedef' and the name is capital
self.DeclarationDataTypeCheckStructureDeclaration = 1
# Check whether having same Structure
self.DeclarationDataTypeCheckSameStructure = 1
# Check whether Union Type has a 'typedef' and the name is capital
self.DeclarationDataTypeCheckUnionType = 1
## Naming Conventions Checking
self.NamingConventionCheckAll = 0
# Check whether only capital letters are used for #define declarations
self.NamingConventionCheckDefineStatement = 1
# Check whether only capital letters are used for typedef declarations
self.NamingConventionCheckTypedefStatement = 1
# Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.
self.NamingConventionCheckIfndefStatement = 1
# Rule for path name, variable name and function name
# 1. First character should be upper case
# 2. Existing lower case in a word
# 3. No space existence
# Check whether the path name followed the rule
self.NamingConventionCheckPathName = 1
# Check whether the variable name followed the rule
self.NamingConventionCheckVariableName = 1
# Check whether the function name followed the rule
self.NamingConventionCheckFunctionName = 1
# Check whether NO use short variable name with single character
self.NamingConventionCheckSingleCharacterVariable = 1
## Doxygen Checking
self.DoxygenCheckAll = 0
# Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5
self.DoxygenCheckFileHeader = 1
# Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5
self.DoxygenCheckFunctionHeader = 1
# Check whether the first line of text in a comment block is a brief description of the element being documented.
# The brief description must end with a period.
self.DoxygenCheckCommentDescription = 1
# Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.
self.DoxygenCheckCommentFormat = 1
# Check whether only Doxygen commands allowed to mark the code are @bug and @todo.
self.DoxygenCheckCommand = 1
## Meta-Data File Processing Checking
self.MetaDataFileCheckAll = 0
# Check whether each file defined in meta-data exists
self.MetaDataFileCheckPathName = 1
# Generate a list for all files defined in meta-data files
self.MetaDataFileCheckGenerateFileList = 1
# The path of log file
self.MetaDataFileCheckPathOfGenerateFileList = 'File.log'
# Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.
# Each Library Instance must specify the Supported Module Types in its INF file,
# and any module specifying the library instance must be one of the supported types.
self.MetaDataFileCheckLibraryInstance = 1
# Check whether a Library Instance has been defined for all dependent library classes
self.MetaDataFileCheckLibraryInstanceDependent = 1
# Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies
self.MetaDataFileCheckLibraryInstanceOrder = 1
# Check whether the unnecessary inclusion of library classes in the INF file
self.MetaDataFileCheckLibraryNoUse = 1
# Check whether an INF file is specified in the FDF file, but not in the DSC file, then the INF file must be for a Binary module only
self.MetaDataFileCheckBinaryInfInFdf = 1
# Not to report error and warning related OS include file such as "windows.h" and "stdio.h"
# Check whether a PCD is set in a DSC file or the FDF file, but not in both.
self.MetaDataFileCheckPcdDuplicate = 1
# Check whether PCD settings in the FDF file can only be related to flash.
self.MetaDataFileCheckPcdFlash = 1
# Check whether PCDs used in INF files but not specified in DSC or FDF files
self.MetaDataFileCheckPcdNoUse = 1
# Check whether having duplicate guids defined for Guid/Protocol/Ppi
self.MetaDataFileCheckGuidDuplicate = 1
# Check whether all files under module directory are described in INF files
self.MetaDataFileCheckModuleFileNoUse = 1
# Check whether the PCD is correctly used in C function via its type
self.MetaDataFileCheckPcdType = 1
#
# The check points in this section are reserved
#
# GotoStatementCheckAll = 0
#
self.SpellingCheckAll = 0
# The directory listed here will not be parsed, split with ','
self.SkipDirList = []
self.ParseConfig()
def ParseConfig(self):
Filepath = os.path.normpath(self.Filename)
if not os.path.isfile(Filepath):
ErrorMsg = "Can't find configuration file '%s'" % Filepath
EdkLogger.error("Ecc", EdkLogger.ECC_ERROR, ErrorMsg, File = Filepath)
LineNo = 0
for Line in open(Filepath, 'r'):
LineNo = LineNo + 1
Line = CleanString(Line)
if Line != '':
List = GetSplitValueList(Line, TAB_EQUAL_SPLIT)
if List[0] not in self.__dict__:
ErrorMsg = "Invalid configuration option '%s' was found" % List[0]
EdkLogger.error("Ecc", EdkLogger.ECC_ERROR, ErrorMsg, File = Filepath, Line = LineNo)
if List[0] == 'ModifierList':
List[1] = GetSplitValueList(List[1], TAB_COMMA_SPLIT)
if List[0] == 'MetaDataFileCheckPathOfGenerateFileList' and List[1] == "":
continue
if List[0] == 'SkipDirList':
List[1] = GetSplitValueList(List[1], TAB_COMMA_SPLIT)
self.__dict__[List[0]] = List[1]
def ShowMe(self):
print self.Filename
for Key in self.__dict__.keys():
print Key, '=', self.__dict__[Key]

View File

@@ -0,0 +1,344 @@
## @file
# This file is used to create a database used by ECC tool
#
# Copyright (c) 2007 ~ 2008, Intel Corporation
# All rights reserved. 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
#
import sqlite3
import os, time
import Common.EdkLogger as EdkLogger
import CommonDataClass.DataClass as DataClass
from Table.TableDataModel import TableDataModel
from Table.TableFile import TableFile
from Table.TableFunction import TableFunction
from Table.TablePcd import TablePcd
from Table.TableIdentifier import TableIdentifier
from Table.TableReport import TableReport
from Table.TableInf import TableInf
from Table.TableDec import TableDec
from Table.TableDsc import TableDsc
from Table.TableFdf import TableFdf
##
# Static definitions
#
DATABASE_PATH = "Ecc.db"
## Database
#
# This class defined the ECC databse
# During the phase of initialization, the database will create all tables and
# insert all records of table DataModel
#
# @param object: Inherited from object class
# @param DbPath: A string for the path of the ECC database
#
# @var Conn: Connection of the ECC database
# @var Cur: Cursor of the connection
# @var TblDataModel: Local instance for TableDataModel
#
class Database(object):
def __init__(self, DbPath):
self.DbPath = DbPath
self.Conn = None
self.Cur = None
self.TblDataModel = None
self.TblFile = None
self.TblFunction = None
self.TblIdentifier = None
self.TblPcd = None
self.TblReport = None
self.TblInf = None
self.TblDec = None
self.TblDsc = None
self.TblFdf = None
## Initialize ECC database
#
# 1. Delete all old existing tables
# 2. Create new tables
# 3. Initialize table DataModel
#
def InitDatabase(self, NewDatabase = True):
EdkLogger.verbose("\nInitialize ECC database started ...")
#
# Drop all old existing tables
#
if NewDatabase:
if os.path.exists(self.DbPath):
os.remove(self.DbPath)
self.Conn = sqlite3.connect(self.DbPath, isolation_level = 'DEFERRED')
self.Conn.execute("PRAGMA page_size=4096")
self.Conn.execute("PRAGMA synchronous=OFF")
# to avoid non-ascii charater conversion error
self.Conn.text_factory = str
self.Cur = self.Conn.cursor()
self.TblDataModel = TableDataModel(self.Cur)
self.TblFile = TableFile(self.Cur)
self.TblFunction = TableFunction(self.Cur)
self.TblIdentifier = TableIdentifier(self.Cur)
self.TblPcd = TablePcd(self.Cur)
self.TblReport = TableReport(self.Cur)
self.TblInf = TableInf(self.Cur)
self.TblDec = TableDec(self.Cur)
self.TblDsc = TableDsc(self.Cur)
self.TblFdf = TableFdf(self.Cur)
#
# Create new tables
#
if NewDatabase:
self.TblDataModel.Create()
self.TblFile.Create()
self.TblFunction.Create()
self.TblPcd.Create()
self.TblReport.Create()
self.TblInf.Create()
self.TblDec.Create()
self.TblDsc.Create()
self.TblFdf.Create()
#
# Init each table's ID
#
self.TblDataModel.InitID()
self.TblFile.InitID()
self.TblFunction.InitID()
self.TblPcd.InitID()
self.TblReport.InitID()
self.TblInf.InitID()
self.TblDec.InitID()
self.TblDsc.InitID()
self.TblFdf.InitID()
#
# Initialize table DataModel
#
if NewDatabase:
self.TblDataModel.InitTable()
EdkLogger.verbose("Initialize ECC database ... DONE!")
## Query a table
#
# @param Table: The instance of the table to be queried
#
def QueryTable(self, Table):
Table.Query()
## Close entire database
#
# Commit all first
# Close the connection and cursor
#
def Close(self):
#
# Commit to file
#
self.Conn.commit()
#
# Close connection and cursor
#
self.Cur.close()
self.Conn.close()
## Insert one file information
#
# Insert one file's information to the database
# 1. Create a record in TableFile
# 2. Create functions one by one
# 2.1 Create variables of function one by one
# 2.2 Create pcds of function one by one
# 3. Create variables one by one
# 4. Create pcds one by one
#
def InsertOneFile(self, File):
#
# Insert a record for file
#
FileID = self.TblFile.Insert(File.Name, File.ExtName, File.Path, File.FullPath, Model = File.Model, TimeStamp = File.TimeStamp)
IdTable = TableIdentifier(self.Cur)
IdTable.Table = "Identifier%s" % FileID
IdTable.Create()
#
# Insert function of file
#
for Function in File.FunctionList:
FunctionID = self.TblFunction.Insert(Function.Header, Function.Modifier, Function.Name, Function.ReturnStatement, \
Function.StartLine, Function.StartColumn, Function.EndLine, Function.EndColumn, \
Function.BodyStartLine, Function.BodyStartColumn, FileID, \
Function.FunNameStartLine, Function.FunNameStartColumn)
#
# Insert Identifier of function
#
for Identifier in Function.IdentifierList:
IdentifierID = IdTable.Insert(Identifier.Modifier, Identifier.Type, Identifier.Name, Identifier.Value, Identifier.Model, \
FileID, FunctionID, Identifier.StartLine, Identifier.StartColumn, Identifier.EndLine, Identifier.EndColumn)
#
# Insert Pcd of function
#
for Pcd in Function.PcdList:
PcdID = self.TblPcd.Insert(Pcd.CName, Pcd.TokenSpaceGuidCName, Pcd.Token, Pcd.DatumType, Pcd.Model, \
FileID, FunctionID, Pcd.StartLine, Pcd.StartColumn, Pcd.EndLine, Pcd.EndColumn)
#
# Insert Identifier of file
#
for Identifier in File.IdentifierList:
IdentifierID = IdTable.Insert(Identifier.Modifier, Identifier.Type, Identifier.Name, Identifier.Value, Identifier.Model, \
FileID, -1, Identifier.StartLine, Identifier.StartColumn, Identifier.EndLine, Identifier.EndColumn)
#
# Insert Pcd of file
#
for Pcd in File.PcdList:
PcdID = self.TblPcd.Insert(Pcd.CName, Pcd.TokenSpaceGuidCName, Pcd.Token, Pcd.DatumType, Pcd.Model, \
FileID, -1, Pcd.StartLine, Pcd.StartColumn, Pcd.EndLine, Pcd.EndColumn)
EdkLogger.verbose("Insert information from file %s ... DONE!" % File.FullPath)
## UpdateIdentifierBelongsToFunction
#
# Update the field "BelongsToFunction" for each Indentifier
#
#
def UpdateIdentifierBelongsToFunction_disabled(self):
EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers started ...")
SqlCommand = """select ID, BelongsToFile, StartLine, EndLine, Model from Identifier"""
EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
self.Cur.execute(SqlCommand)
Records = self.Cur.fetchall()
for Record in Records:
IdentifierID = Record[0]
BelongsToFile = Record[1]
StartLine = Record[2]
EndLine = Record[3]
Model = Record[4]
#
# Check whether an identifier belongs to a function
#
EdkLogger.debug(4, "For common identifiers ... ")
SqlCommand = """select ID from Function
where StartLine < %s and EndLine > %s
and BelongsToFile = %s""" % (StartLine, EndLine, BelongsToFile)
EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
self.Cur.execute(SqlCommand)
IDs = self.Cur.fetchall()
for ID in IDs:
SqlCommand = """Update Identifier set BelongsToFunction = %s where ID = %s""" % (ID[0], IdentifierID)
EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
self.Cur.execute(SqlCommand)
#
# Check whether the identifier is a function header
#
EdkLogger.debug(4, "For function headers ... ")
if Model == DataClass.MODEL_IDENTIFIER_COMMENT:
SqlCommand = """select ID from Function
where StartLine = %s + 1
and BelongsToFile = %s""" % (EndLine, BelongsToFile)
EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
self.Cur.execute(SqlCommand)
IDs = self.Cur.fetchall()
for ID in IDs:
SqlCommand = """Update Identifier set BelongsToFunction = %s, Model = %s where ID = %s""" % (ID[0], DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER, IdentifierID)
EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
self.Cur.execute(SqlCommand)
EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers ... DONE")
## UpdateIdentifierBelongsToFunction
#
# Update the field "BelongsToFunction" for each Indentifier
#
#
def UpdateIdentifierBelongsToFunction(self):
EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers started ...")
SqlCommand = """select ID, BelongsToFile, StartLine, EndLine from Function"""
Records = self.TblFunction.Exec(SqlCommand)
Data1 = []
Data2 = []
for Record in Records:
FunctionID = Record[0]
BelongsToFile = Record[1]
StartLine = Record[2]
EndLine = Record[3]
#Data1.append(("'file%s'" % BelongsToFile, FunctionID, BelongsToFile, StartLine, EndLine))
#Data2.append(("'file%s'" % BelongsToFile, FunctionID, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER, BelongsToFile, DataClass.MODEL_IDENTIFIER_COMMENT, StartLine - 1))
SqlCommand = """Update Identifier%s set BelongsToFunction = %s where BelongsToFile = %s and StartLine > %s and EndLine < %s""" % \
(BelongsToFile, FunctionID, BelongsToFile, StartLine, EndLine)
self.TblIdentifier.Exec(SqlCommand)
SqlCommand = """Update Identifier%s set BelongsToFunction = %s, Model = %s where BelongsToFile = %s and Model = %s and EndLine = %s""" % \
(BelongsToFile, FunctionID, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER, BelongsToFile, DataClass.MODEL_IDENTIFIER_COMMENT, StartLine - 1)
self.TblIdentifier.Exec(SqlCommand)
# #
# # Check whether an identifier belongs to a function
# #
# print Data1
# SqlCommand = """Update ? set BelongsToFunction = ? where BelongsToFile = ? and StartLine > ? and EndLine < ?"""
# print SqlCommand
# EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
# self.Cur.executemany(SqlCommand, Data1)
#
# #
# # Check whether the identifier is a function header
# #
# EdkLogger.debug(4, "For function headers ... ")
# SqlCommand = """Update ? set BelongsToFunction = ?, Model = ? where BelongsToFile = ? and Model = ? and EndLine = ?"""
# EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
# self.Cur.executemany(SqlCommand, Data2)
#
# EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers ... DONE")
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
EdkLogger.Initialize()
#EdkLogger.SetLevel(EdkLogger.VERBOSE)
EdkLogger.SetLevel(EdkLogger.DEBUG_0)
EdkLogger.verbose("Start at " + time.strftime('%H:%M:%S', time.localtime()))
Db = Database(DATABASE_PATH)
Db.InitDatabase()
Db.QueryTable(Db.TblDataModel)
identifier1 = DataClass.IdentifierClass(-1, '', '', "i''1", 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 32, 43, 54, 43)
identifier2 = DataClass.IdentifierClass(-1, '', '', 'i1', 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 15, 43, 20, 43)
identifier3 = DataClass.IdentifierClass(-1, '', '', 'i1', 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 55, 43, 58, 43)
identifier4 = DataClass.IdentifierClass(-1, '', '', "i1'", 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 77, 43, 88, 43)
fun1 = DataClass.FunctionClass(-1, '', '', 'fun1', '', 21, 2, 60, 45, 1, 23, 0, [], [])
file = DataClass.FileClass(-1, 'F1', 'c', 'C:\\', 'C:\\F1.exe', DataClass.MODEL_FILE_C, '2007-12-28', [fun1], [identifier1, identifier2, identifier3, identifier4], [])
Db.InsertOneFile(file)
Db.UpdateIdentifierBelongsToFunction()
Db.QueryTable(Db.TblFile)
Db.QueryTable(Db.TblFunction)
Db.QueryTable(Db.TblPcd)
Db.QueryTable(Db.TblIdentifier)
Db.Close()
EdkLogger.verbose("End at " + time.strftime('%H:%M:%S', time.localtime()))

View File

@@ -0,0 +1,329 @@
## @file
# This file is used to be the main entrance of ECC tool
#
# Copyright (c) 2009, Intel Corporation
# All rights reserved. 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
#
import os, time, glob, sys
import Common.EdkLogger as EdkLogger
import Database
import EccGlobalData
from MetaDataParser import *
from optparse import OptionParser
from Configuration import Configuration
from Check import Check
from Common.InfClassObject import Inf
from Common.DecClassObject import Dec
from Common.DscClassObject import Dsc
from Common.FdfClassObject import Fdf
from Common.String import NormPath
from Common import BuildToolError
import c
from Exception import *
## Ecc
#
# This class is used to define Ecc main entrance
#
# @param object: Inherited from object class
#
class Ecc(object):
def __init__(self):
# Version and Copyright
self.VersionNumber = "0.01"
self.Version = "%prog Version " + self.VersionNumber
self.Copyright = "Copyright (c) 2009, Intel Corporation All rights reserved."
self.InitDefaultConfigIni()
self.OutputFile = 'output.txt'
self.ReportFile = 'Report.csv'
self.ExceptionFile = 'exception.xml'
self.IsInit = True
self.ScanSourceCode = True
self.ScanMetaData = True
# Parse the options and args
self.ParseOption()
# Generate checkpoints list
EccGlobalData.gConfig = Configuration(self.ConfigFile)
# Generate exception list
EccGlobalData.gException = ExceptionCheck(self.ExceptionFile)
# Init Ecc database
EccGlobalData.gDb = Database.Database(Database.DATABASE_PATH)
EccGlobalData.gDb.InitDatabase(self.IsInit)
# Build ECC database
self.BuildDatabase()
# Start to check
self.Check()
# Show report
self.GenReport()
# Close Database
EccGlobalData.gDb.Close()
def InitDefaultConfigIni(self):
paths = map(lambda p: os.path.join(p, 'Ecc', 'config.ini'), sys.path)
paths = (os.path.realpath('config.ini'),) + tuple(paths)
for path in paths:
if os.path.exists(path):
self.ConfigFile = path
return
self.ConfigFile = 'config.ini'
## BuildDatabase
#
# Build the database for target
#
def BuildDatabase(self):
# Clean report table
EccGlobalData.gDb.TblReport.Drop()
EccGlobalData.gDb.TblReport.Create()
# Build database
if self.IsInit:
if self.ScanSourceCode:
EdkLogger.quiet("Building database for source code ...")
c.CollectSourceCodeDataIntoDB(EccGlobalData.gTarget)
if self.ScanMetaData:
EdkLogger.quiet("Building database for source code done!")
self.BuildMetaDataFileDatabase()
EccGlobalData.gIdentifierTableList = GetTableList((MODEL_FILE_C, MODEL_FILE_H), 'Identifier', EccGlobalData.gDb)
## BuildMetaDataFileDatabase
#
# Build the database for meta data files
#
def BuildMetaDataFileDatabase(self):
EdkLogger.quiet("Building database for meta data files ...")
Op = open(EccGlobalData.gConfig.MetaDataFileCheckPathOfGenerateFileList, 'w+')
#SkipDirs = Read from config file
SkipDirs = EccGlobalData.gConfig.SkipDirList
for Root, Dirs, Files in os.walk(EccGlobalData.gTarget):
for Dir in Dirs:
if Dir.upper() in SkipDirs:
Dirs.remove(Dir)
for Dir in Dirs:
Dirname = os.path.join(Root, Dir)
if os.path.islink(Dirname):
Dirname = os.path.realpath(Dirname)
if os.path.isdir(Dirname):
# symlinks to directories are treated as directories
Dirs.remove(Dir)
Dirs.append(Dirname)
for File in Files:
if len(File) > 4 and File[-4:].upper() == ".DEC":
Filename = os.path.normpath(os.path.join(Root, File))
EdkLogger.quiet("Parsing %s" % Filename)
Op.write("%s\r" % Filename)
Dec(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)
continue
if len(File) > 4 and File[-4:].upper() == ".DSC":
Filename = os.path.normpath(os.path.join(Root, File))
EdkLogger.quiet("Parsing %s" % Filename)
Op.write("%s\r" % Filename)
Dsc(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)
continue
if len(File) > 4 and File[-4:].upper() == ".INF":
Filename = os.path.normpath(os.path.join(Root, File))
EdkLogger.quiet("Parsing %s" % Filename)
Op.write("%s\r" % Filename)
Inf(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)
continue
if len(File) > 4 and File[-4:].upper() == ".FDF":
Filename = os.path.normpath(os.path.join(Root, File))
EdkLogger.quiet("Parsing %s" % Filename)
Op.write("%s\r" % Filename)
Fdf(Filename, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)
continue
Op.close()
# Commit to database
EccGlobalData.gDb.Conn.commit()
EdkLogger.quiet("Building database for meta data files done!")
##
#
# Check each checkpoint
#
def Check(self):
EdkLogger.quiet("Checking ...")
EccCheck = Check()
EccCheck.Check()
EdkLogger.quiet("Checking done!")
##
#
# Generate the scan report
#
def GenReport(self):
EdkLogger.quiet("Generating report ...")
EccGlobalData.gDb.TblReport.ToCSV(self.ReportFile)
EdkLogger.quiet("Generating report done!")
def GetRealPathCase(self, path):
TmpPath = path.rstrip(os.sep)
PathParts = TmpPath.split(os.sep)
if len(PathParts) == 0:
return path
if len(PathParts) == 1:
if PathParts[0].strip().endswith(':'):
return PathParts[0].upper()
# Relative dir, list . current dir
Dirs = os.listdir('.')
for Dir in Dirs:
if Dir.upper() == PathParts[0].upper():
return Dir
if PathParts[0].strip().endswith(':'):
PathParts[0] = PathParts[0].upper()
ParentDir = PathParts[0]
RealPath = ParentDir
if PathParts[0] == '':
RealPath = os.sep
ParentDir = os.sep
PathParts.remove(PathParts[0]) # need to remove the parent
for Part in PathParts:
Dirs = os.listdir(ParentDir + os.sep)
for Dir in Dirs:
if Dir.upper() == Part.upper():
RealPath += os.sep
RealPath += Dir
break
ParentDir += os.sep
ParentDir += Dir
return RealPath
## ParseOption
#
# Parse options
#
def ParseOption(self):
EdkLogger.quiet("Loading ECC configuration ... done")
(Options, Target) = self.EccOptionParser()
# Check workspace envirnoment
if "WORKSPACE" not in os.environ:
EdkLogger.error("ECC", BuildToolError.ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",
ExtraData="WORKSPACE")
else:
EccGlobalData.gWorkspace = os.path.normpath(os.getenv("WORKSPACE"))
if not os.path.exists(EccGlobalData.gWorkspace):
EdkLogger.error("ECC", BuildToolError.FILE_NOT_FOUND, ExtraData="WORKSPACE = %s" % EccGlobalData.gWorkspace)
os.environ["WORKSPACE"] = EccGlobalData.gWorkspace
# Set log level
self.SetLogLevel(Options)
# Set other options
if Options.ConfigFile != None:
self.ConfigFile = Options.ConfigFile
if Options.OutputFile != None:
self.OutputFile = Options.OutputFile
if Options.ReportFile != None:
self.ReportFile = Options.ReportFile
if Options.Target != None:
if not os.path.isdir(Options.Target):
EdkLogger.error("ECC", BuildToolError.OPTION_VALUE_INVALID, ExtraData="Target [%s] does NOT exist" % Options.Target)
else:
EccGlobalData.gTarget = self.GetRealPathCase(os.path.normpath(Options.Target))
else:
EdkLogger.warn("Ecc", EdkLogger.ECC_ERROR, "The target source tree was not specified, using current WORKSPACE instead!")
EccGlobalData.gTarget = os.path.normpath(os.getenv("WORKSPACE"))
if Options.keepdatabase != None:
self.IsInit = False
if Options.metadata != None and Options.sourcecode != None:
EdkLogger.error("ECC", BuildToolError.OPTION_CONFLICT, ExtraData="-m and -s can't be specified at one time")
if Options.metadata != None:
self.ScanSourceCode = False
if Options.sourcecode != None:
self.ScanMetaData = False
## SetLogLevel
#
# Set current log level of the tool based on args
#
# @param Option: The option list including log level setting
#
def SetLogLevel(self, Option):
if Option.verbose != None:
EdkLogger.SetLevel(EdkLogger.VERBOSE)
elif Option.quiet != None:
EdkLogger.SetLevel(EdkLogger.QUIET)
elif Option.debug != None:
EdkLogger.SetLevel(Option.debug + 1)
else:
EdkLogger.SetLevel(EdkLogger.INFO)
## Parse command line options
#
# Using standard Python module optparse to parse command line option of this tool.
#
# @retval Opt A optparse.Values object containing the parsed options
# @retval Args Target of build command
#
def EccOptionParser(self):
Parser = OptionParser(description = self.Copyright, version = self.Version, prog = "Ecc.exe", usage = "%prog [options]")
Parser.add_option("-t", "--target sourcepath", action="store", type="string", dest='Target',
help="Check all files under the target workspace.")
Parser.add_option("-c", "--config filename", action="store", type="string", dest="ConfigFile",
help="Specify a configuration file. Defaultly use config.ini under ECC tool directory.")
Parser.add_option("-o", "--outfile filename", action="store", type="string", dest="OutputFile",
help="Specify the name of an output file, if and only if one filename was specified.")
Parser.add_option("-r", "--reportfile filename", action="store", type="string", dest="ReportFile",
help="Specify the name of an report file, if and only if one filename was specified.")
Parser.add_option("-m", "--metadata", action="store_true", type=None, help="Only scan meta-data files information if this option is specified.")
Parser.add_option("-s", "--sourcecode", action="store_true", type=None, help="Only scan source code files information if this option is specified.")
Parser.add_option("-k", "--keepdatabase", action="store_true", type=None, help="The existing Ecc database will not be cleaned except report information if this option is specified.")
Parser.add_option("-l", "--log filename", action="store", dest="LogFile", help="""If specified, the tool should emit the changes that
were made by the tool after printing the result message.
If filename, the emit to the file, otherwise emit to
standard output. If no modifications were made, then do not
create a log file, or output a log message.""")
Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed, "\
"including library instances selected, final dependency expression, "\
"and warning messages, etc.")
Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")
(Opt, Args)=Parser.parse_args()
return (Opt, Args)
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
# Initialize log system
EdkLogger.Initialize()
EdkLogger.IsRaiseError = False
EdkLogger.quiet(time.strftime("%H:%M:%S, %b.%d %Y ", time.localtime()) + "[00:00]" + "\n")
StartTime = time.clock()
Ecc = Ecc()
FinishTime = time.clock()
BuildDuration = time.strftime("%M:%S", time.gmtime(int(round(FinishTime - StartTime))))
EdkLogger.quiet("\n%s [%s]" % (time.strftime("%H:%M:%S, %b.%d %Y", time.localtime()), BuildDuration))

View File

@@ -0,0 +1,24 @@
## @file
# This file is used to save global datas used by ECC tool
#
# Copyright (c) 2008, Intel Corporation
# All rights reserved. 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
#
import os
gWorkspace = ''
gTarget = ''
gConfig = None
gDb = None
gIdentifierTableList = []
gException = None

View File

@@ -0,0 +1,179 @@
## @file
# Standardized Error Hanlding infrastructures.
#
# Copyright (c) 20087, Intel Corporation
# All rights reserved. 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.
#
ERROR_GENERAL_CHECK_ALL = 1000
ERROR_GENERAL_CHECK_NO_TAB = 1001
ERROR_GENERAL_CHECK_INDENTATION = 1002
ERROR_GENERAL_CHECK_LINE = 1003
ERROR_GENERAL_CHECK_NO_ASM = 1004
ERROR_GENERAL_CHECK_NO_PROGMA = 1005
ERROR_GENERAL_CHECK_CARRIAGE_RETURN = 1006
ERROR_GENERAL_CHECK_FILE_EXISTENCE = 1007
ERROR_SPACE_CHECK_ALL = 2000
ERROR_PREDICATE_EXPRESSION_CHECK_ALL = 3000
ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE = 3001
ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR = 3002
ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE = 3003
ERROR_HEADER_CHECK_ALL = 4000
ERROR_HEADER_CHECK_FILE = 4001
ERROR_HEADER_CHECK_FUNCTION = 4002
ERROR_C_FUNCTION_LAYOUT_CHECK_ALL = 5000
ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE = 5001
ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER = 5002
ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME = 5003
ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE = 5004
ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY = 5005
ERROR_C_FUNCTION_LAYOUT_CHECK_DATA_DECLARATION = 5006
ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE = 5007
ERROR_C_FUNCTION_LAYOUT_CHECK_NO_STATIC = 5008
ERROR_INCLUDE_FILE_CHECK_ALL = 6000
ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_1 = 6001
ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_2 = 6002
ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_3 = 6003
ERROR_INCLUDE_FILE_CHECK_DATA = 6004
ERROR_INCLUDE_FILE_CHECK_NAME = 6005
ERROR_DECLARATION_DATA_TYPE_CHECK_ALL = 7000
ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE = 7001
ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER = 7002
ERROR_DECLARATION_DATA_TYPE_CHECK_EFI_API_MODIFIER = 7003
ERROR_DECLARATION_DATA_TYPE_CHECK_ENUMERATED_TYPE = 7004
ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION = 7005
ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE = 7007
ERROR_DECLARATION_DATA_TYPE_CHECK_UNION_TYPE = 7006
ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE = 7008
ERROR_NAMING_CONVENTION_CHECK_ALL = 8000
ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT = 8001
ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT = 8002
ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT = 8003
ERROR_NAMING_CONVENTION_CHECK_PATH_NAME = 8004
ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME = 8005
ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME = 8006
ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE = 8007
ERROR_DOXYGEN_CHECK_ALL = 9000
ERROR_DOXYGEN_CHECK_FILE_HEADER = 9001
ERROR_DOXYGEN_CHECK_FUNCTION_HEADER = 9002
ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION = 9003
ERROR_DOXYGEN_CHECK_COMMENT_FORMAT = 9004
ERROR_DOXYGEN_CHECK_COMMAND = 9005
ERROR_META_DATA_FILE_CHECK_ALL = 10000
ERROR_META_DATA_FILE_CHECK_PATH_NAME = 10001
ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1 = 10002
ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_2 = 10003
ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT = 10004
ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_ORDER = 10005
ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE = 10006
ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF = 10007
ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE = 10008
ERROR_META_DATA_FILE_CHECK_PCD_FLASH = 10009
ERROR_META_DATA_FILE_CHECK_PCD_NO_USE = 10010
ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID = 10011
ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL = 10012
ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI = 10013
ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE = 10014
ERROR_META_DATA_FILE_CHECK_PCD_TYPE = 10015
ERROR_SPELLING_CHECK_ALL = 11000
gEccErrorMessage = {
ERROR_GENERAL_CHECK_ALL : "",
ERROR_GENERAL_CHECK_NO_TAB : "'TAB' character is not allowed in source code, please replace each 'TAB' with two spaces",
ERROR_GENERAL_CHECK_INDENTATION : "Indentation does not follow coding style",
ERROR_GENERAL_CHECK_LINE : "The width of each line does not follow coding style",
ERROR_GENERAL_CHECK_NO_ASM : "There should be no use of _asm in the source file",
ERROR_GENERAL_CHECK_NO_PROGMA : """There should be no use of "#progma" in source file except "#pragma pack(#)\"""",
ERROR_GENERAL_CHECK_CARRIAGE_RETURN : "There should be a carriage return at the end of the file",
ERROR_GENERAL_CHECK_FILE_EXISTENCE : "File not found",
ERROR_SPACE_CHECK_ALL : "",
ERROR_PREDICATE_EXPRESSION_CHECK_ALL : "",
ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE : "Boolean values and variable type BOOLEAN should not use explicit comparisons to TRUE or FALSE",
ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR : "Non-Boolean comparisons should use a compare operator (==, !=, >, < >=, <=)",
ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE : "A comparison of any pointer to zero must be done via the NULL type",
ERROR_HEADER_CHECK_ALL : "",
ERROR_HEADER_CHECK_FILE : "File header doesn't exist",
ERROR_HEADER_CHECK_FUNCTION : "Function header doesn't exist",
ERROR_C_FUNCTION_LAYOUT_CHECK_ALL : "",
ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE : "Return type of a function should exist and in the first line",
ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER : "Any optional functional modifiers should exist and next to the return type",
ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME : """Function name should be left justified, followed by the beginning of the parameter list, with the closing parenthesis on its own line, indented two spaces""",
ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE : "Function prototypes in include files have the same form as function definitions",
ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY : "The body of a function should be contained by open and close braces that must be in the first column",
ERROR_C_FUNCTION_LAYOUT_CHECK_DATA_DECLARATION : "The data declarations should be the first code in a module",
ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE : "There should be no initialization of a variable as part of its declaration",
ERROR_C_FUNCTION_LAYOUT_CHECK_NO_STATIC : "There should be no use of STATIC for functions",
ERROR_INCLUDE_FILE_CHECK_ALL : "",
ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_1 : "All include file contents should be guarded by a #ifndef statement.",
ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_2 : "The #ifndef must be the first line of code following the file header comment",
ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_3 : "The #endif must appear on the last line in the file",
ERROR_INCLUDE_FILE_CHECK_DATA : "Include files should contain only public or only private data and cannot contain code or define data variables",
ERROR_INCLUDE_FILE_CHECK_NAME : "No permission for the inlcude file with same names",
ERROR_DECLARATION_DATA_TYPE_CHECK_ALL : "",
ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE : "There should be no use of int, unsigned, char, void, static, long in any .c, .h or .asl files",
ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER : """The modifiers IN, OUT, OPTIONAL, and UNALIGNED should be used only to qualify arguments to a function and should not appear in a data type declaration""",
ERROR_DECLARATION_DATA_TYPE_CHECK_EFI_API_MODIFIER : "The EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols",
ERROR_DECLARATION_DATA_TYPE_CHECK_ENUMERATED_TYPE : "Enumerated Type should have a 'typedef' and the name must be in capital letters",
ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION : "Structure Type should have a 'typedef' and the name must be in capital letters",
ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE : "No permission for the structure with same names",
ERROR_DECLARATION_DATA_TYPE_CHECK_UNION_TYPE : "Union Type should have a 'typedef' and the name must be in capital letters",
ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE : "Complex types should be typedef-ed",
ERROR_NAMING_CONVENTION_CHECK_ALL : "",
ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT : "Only capital letters are allowed to be used for #define declarations",
ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT : "Only capital letters are allowed to be used for typedef declarations",
ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT : "The #ifndef at the start of an include file should use both prefix and postfix underscore characters, '_'",
ERROR_NAMING_CONVENTION_CHECK_PATH_NAME : """Path name does not follow the rules: 1. First character should be upper case 2. Must contain lower case characters 3. No white space characters""",
ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME : """Variable name does not follow the rules: 1. First character should be upper case 2. Must contain lower case characters 3. No white space characters 4. Global variable name must start with a 'g'""",
ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME : """Function name does not follow the rules: 1. First character should be upper case 2. Must contain lower case characters 3. No white space characters""",
ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE : "There should be no use of short (single character) variable names",
ERROR_DOXYGEN_CHECK_ALL : "",
ERROR_DOXYGEN_CHECK_FILE_HEADER : "The file headers should follow Doxygen special documentation blocks in section 2.3.5",
ERROR_DOXYGEN_CHECK_FUNCTION_HEADER : "The function headers should follow Doxygen special documentation blocks in section 2.3.5",
ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION : """The first line of text in a comment block should be a brief description of the element being documented and the brief description must end with a period.""",
ERROR_DOXYGEN_CHECK_COMMENT_FORMAT : "For comment line with '///< ... text ...' format, if it is used, it should be after the code section",
ERROR_DOXYGEN_CHECK_COMMAND : "Only Doxygen commands @bug and @todo are allowed to mark the code",
ERROR_META_DATA_FILE_CHECK_ALL : "",
ERROR_META_DATA_FILE_CHECK_PATH_NAME : "The file defined in meta-data does not exist",
ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1 : "A library instances defined for a given module (or dependent library instance) doesn't match the module's type.",
ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_2 : "A library instance must specify the Supported Module Types in its INF file",
ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT : "A library instance must be defined for all dependent library classes",
ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_ORDER : "The library Instances specified by the LibraryClasses sections should be listed in order of dependencies",
ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE : "There should be no unnecessary inclusion of library classes in the INF file",
ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF : "An INF file is specified in the FDF file, but not in the DSC file, therefore the INF file must be for a Binary module only",
ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE : "Duplicate PCDs found",
ERROR_META_DATA_FILE_CHECK_PCD_FLASH : "PCD settings in the FDF file should only be related to flash",
ERROR_META_DATA_FILE_CHECK_PCD_NO_USE : "There should be no PCDs declared in INF files that are not specified in in either a DSC or FDF file",
ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID : "Duplicate GUID found",
ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL : "Duplicate PROTOCOL found",
ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI : "Duplicate PPI found",
ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE : "No used module files found",
ERROR_META_DATA_FILE_CHECK_PCD_TYPE : "Wrong C code function used for this kind of PCD",
ERROR_SPELLING_CHECK_ALL : "",
}

View File

@@ -0,0 +1,87 @@
## @file
# This file is used to parse exception items found by ECC tool
#
# Copyright (c) 2009, Intel Corporation
# All rights reserved. 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 Common.XmlRoutines import *
import os.path
# ExceptionXml to parse Exception Node of XML file
class ExceptionXml(object):
def __init__(self):
self.KeyWord = ''
self.ErrorID = ''
self.FilePath = ''
def FromXml(self, Item, Key):
self.KeyWord = XmlElement(Item, '%s/KeyWord' % Key)
self.ErrorID = XmlElement(Item, '%s/ErrorID' % Key)
self.FilePath = os.path.normpath(XmlElement(Item, '%s/FilePath' % Key))
def __str__(self):
return 'ErrorID = %s KeyWord = %s FilePath = %s' %(self.ErrorID, self.KeyWord, self.FilePath)
# ExceptionListXml to parse Exception Node List of XML file
class ExceptionListXml(object):
def __init__(self):
self.List = []
def FromXmlFile(self, FilePath):
XmlContent = XmlParseFile(FilePath)
for Item in XmlList(XmlContent, '/ExceptionList/Exception'):
Exp = ExceptionXml()
Exp.FromXml(Item, 'Exception')
self.List.append(Exp)
def ToList(self):
RtnList = []
for Item in self.List:
#RtnList.append((Item.ErrorID, Item.KeyWord, Item.FilePath))
RtnList.append((Item.ErrorID, Item.KeyWord))
return RtnList
def __str__(self):
RtnStr = ''
if self.List:
for Item in self.List:
RtnStr = RtnStr + str(Item) + '\n'
return RtnStr
# A class to check exception
class ExceptionCheck(object):
def __init__(self, FilePath = None):
self.ExceptionList = []
self.ExceptionListXml = ExceptionListXml()
self.LoadExceptionListXml(FilePath)
def LoadExceptionListXml(self, FilePath):
if FilePath and os.path.isfile(FilePath):
self.ExceptionListXml.FromXmlFile(FilePath)
self.ExceptionList = self.ExceptionListXml.ToList()
def IsException(self, ErrorID, KeyWord, FileID=-1):
if (str(ErrorID), KeyWord) in self.ExceptionList:
return True
else:
return False
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
El = ExceptionCheck('C:\\Hess\\Project\\BuildTool\\src\\Ecc\\exception.xml')
print El.ExceptionList

View File

@@ -0,0 +1,57 @@
## @file
# fragments of source file
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import re
import os
from ParserWarning import Warning
CommentList = []
PPDirectiveList = []
PredicateExpressionList = []
FunctionDefinitionList = []
VariableDeclarationList = []
EnumerationDefinitionList = []
StructUnionDefinitionList = []
TypedefDefinitionList = []
FunctionCallingList = []
## record file data when parsing source
#
# May raise Exception when opening file.
#
class FileProfile :
## The constructor
#
# @param self The object pointer
# @param FileName The file that to be parsed
#
def __init__(self, FileName):
self.FileLinesList = []
self.FileLinesListFromFile = []
try:
fsock = open(FileName, "rb", 0)
try:
self.FileLinesListFromFile = fsock.readlines()
finally:
fsock.close()
except IOError:
raise Warning("Error when opening file %s" % FileName)

View File

@@ -0,0 +1,65 @@
## @file
# This file is used to define common parser functions for meta-data
#
# Copyright (c) 2008, Intel Corporation
# All rights reserved. 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 os
from CommonDataClass.DataClass import *
## Get the inlcude path list for a source file
#
# 1. Find the source file belongs to which inf file
# 2. Find the inf's package
# 3. Return the include path list of the package
#
def GetIncludeListOfFile(WorkSpace, Filepath, Db):
IncludeList = []
Filepath = os.path.normpath(Filepath)
SqlCommand = """
select Value1, FullPath from Inf, File where Inf.Model = %s and Inf.BelongsToFile in(
select distinct B.BelongsToFile from File as A left join Inf as B
where A.ID = B.BelongsToFile and B.Model = %s and (A.Path || '%s' || B.Value1) = '%s')
and Inf.BelongsToFile = File.ID""" \
% (MODEL_META_DATA_PACKAGE, MODEL_EFI_SOURCE_FILE, '\\', Filepath)
RecordSet = Db.TblFile.Exec(SqlCommand)
for Record in RecordSet:
DecFullPath = os.path.normpath(os.path.join(WorkSpace, Record[0]))
InfFullPath = os.path.normpath(os.path.join(WorkSpace, Record[1]))
(DecPath, DecName) = os.path.split(DecFullPath)
(InfPath, InfName) = os.path.split(InfFullPath)
SqlCommand = """select Value1 from Dec where BelongsToFile =
(select ID from File where FullPath = '%s') and Model = %s""" \
% (DecFullPath, MODEL_EFI_INCLUDE)
NewRecordSet = Db.TblDec.Exec(SqlCommand)
if InfPath not in IncludeList:
IncludeList.append(InfPath)
for NewRecord in NewRecordSet:
IncludePath = os.path.normpath(os.path.join(DecPath, NewRecord[0]))
if IncludePath not in IncludeList:
IncludeList.append(IncludePath)
return IncludeList
## Get the table list
#
# Search table file and find all small tables
#
def GetTableList(FileModelList, Table, Db):
TableList = []
SqlCommand = """select ID from File where Model in %s""" % str(FileModelList)
RecordSet = Db.TblFile.Exec(SqlCommand)
for Record in RecordSet:
TableName = Table + str(Record[0])
TableList.append(TableName)
return TableList

View File

@@ -0,0 +1,17 @@
## The exception class that used to report error messages when preprocessing
#
# Currently the "ToolName" is set to be "ECC PP".
#
class Warning (Exception):
## The constructor
#
# @param self The object pointer
# @param Str The message to record
# @param File The FDF name
# @param Line The Line number that error occurs
#
def __init__(self, Str, File = None, Line = None):
self.message = Str
self.FileName = File
self.LineNumber = Line
self.ToolName = 'ECC PP'

View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,242 @@
## @file
# This file is used to set configuration of ECC tool
# For the items listed below, 1 means valid, 0 means invalid
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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.
#
#
# Identify the version of current configuration
#
Version = 0.1
#
# Identify to if check all items
# 1 - Check all items and ignore all other detailed items
# 0 - Not check all items, the tool will go through all other detailed items to decide to check or not
#
CheckAll = 0
#
# Identify to if automatically correct mistakes
# 1 - Automatically correct
# 0 - Not automatically correct
# Only the following check points can be automatically corrected, others not listed below are not supported even it is 1
#
# GeneralCheckTab
# GeneralCheckIndentation
# GeneralCheckLine
# GeneralCheckCarriageReturn
# SpaceCheckAll
#
AutoCorrect = 1
#
# List customized Modifer here, split with ','
#
ModifierList = IN, OUT, OPTIONAL, UNALIGNED, EFI_RUNTIMESERVICE, EFI_BOOTSERVICE, EFIAPI, TPMINTERNALAPI
#
# General Checking
#
GeneralCheckAll = 0
# Check whether NO Tab is used, replaced with spaces
GeneralCheckNoTab = 1
# The width of Tab
GeneralCheckTabWidth = 2
# Check whether the indentation is followed coding style
GeneralCheckIndentation = 1
# The width of indentation
GeneralCheckIndentationWidth = 2
# Check whether no line is exceeding defined widty
GeneralCheckLine = 1
# The width of a line
GeneralCheckLineWidth = 120
# Check whether no use of _asm in the source file
GeneralCheckNo_Asm = 1
# Check whether no use of "#progma" in source file except "#pragma pack(#)".
GeneralCheckNoProgma = 1
# Check whether there is a carriage return at the end of the file
GeneralCheckCarriageReturn = 1
# Check whether the file exists
GeneralCheckFileExistence = 1
#
# Space Checking
#
SpaceCheckAll = 1
#
# Predicate Expression Checking
#
PredicateExpressionCheckAll = 0
# Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE
PredicateExpressionCheckBooleanValue = 1
# Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=).
PredicateExpressionCheckNonBooleanOperator = 1
# Check whether a comparison of any pointer to zero must be done via the NULL type
PredicateExpressionCheckComparisonNullType = 1
#
# Headers Checking
#
HeaderCheckAll = 0
# Check whether File header exists
HeaderCheckFile = 1
# Check whether Function header exists
HeaderCheckFunction = 1
#
# C Function Layout Checking
#
CFunctionLayoutCheckAll = 0
# Check whether return type exists and in the first line
CFunctionLayoutCheckReturnType = 1
# Check whether any optional functional modifiers exist and next to the return type
CFunctionLayoutCheckOptionalFunctionalModifier = 1
# Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list
# Check whether the closing parenthesis is on its own line and also indented two spaces
CFunctionLayoutCheckFunctionName = 1
# Check whether the function prototypes in include files have the same form as function definitions
CFunctionLayoutCheckFunctionPrototype = 1
# Check whether the body of a function is contained by open and close braces that must be in the first column
CFunctionLayoutCheckFunctionBody = 1
# Check whether the data declarations is the first code in a module.
CFunctionLayoutCheckDataDeclaration = 1
# Check whether no initialization of a variable as part of its declaration
CFunctionLayoutCheckNoInitOfVariable = 1
# Check whether no use of STATIC for functions
CFunctionLayoutCheckNoStatic = 1
#
# Include Files Checking
#
IncludeFileCheckAll = 0
#Check whether having include files with same name
IncludeFileCheckSameName = 1
# Check whether all include file contents is guarded by a #ifndef statement.
# the #ifndef must be the first line of code following the file header comment
# the #endif must appear on the last line in the file
IncludeFileCheckIfndefStatement = 1
# Check whether include files contain only public or only private data
# Check whether include files NOT contain code or define data variables
IncludeFileCheckData = 1
#
# Declarations and Data Types Checking
#
DeclarationDataTypeCheckAll = 0
# Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files.
DeclarationDataTypeCheckNoUseCType = 1
# Check whether the modifiers IN, OUT, OPTIONAL, and UNALIGNED are used only to qualify arguments to a function and should not appear in a data type declaration
DeclarationDataTypeCheckInOutModifier = 1
# Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols
DeclarationDataTypeCheckEFIAPIModifier = 1
# Check whether Enumerated Type has a 'typedef' and the name is capital
DeclarationDataTypeCheckEnumeratedType = 1
# Check whether Structure Type has a 'typedef' and the name is capital
DeclarationDataTypeCheckStructureDeclaration = 1
# Check whether having same Structure
DeclarationDataTypeCheckSameStructure = 1
# Check whether Union Type has a 'typedef' and the name is capital
DeclarationDataTypeCheckUnionType = 1
#
# Naming Conventions Checking
#
NamingConventionCheckAll = 0
# Check whether only capital letters are used for #define declarations
NamingConventionCheckDefineStatement = 1
# Check whether only capital letters are used for typedef declarations
NamingConventionCheckTypedefStatement = 1
# Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.
NamingConventionCheckIfndefStatement = 1
# Rule for path name, variable name and function name
# 1. First character should be upper case
# 2. Existing lower case in a word
# 3. No space existence
# 4. Global variable name must start by a 'g'
# Check whether the path name followed the rule
NamingConventionCheckPathName = 1
# Check whether the variable name followed the rule
NamingConventionCheckVariableName = 1
# Check whether the function name followed the rule
NamingConventionCheckFunctionName = 1
# Check whether NO use short variable name with single character
NamingConventionCheckSingleCharacterVariable = 1
#
# Doxygen Checking
#
DoxygenCheckAll = 0
# Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5
DoxygenCheckFileHeader = 1
# Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5
DoxygenCheckFunctionHeader = 1
# Check whether the first line of text in a comment block is a brief description of the element being documented.
# The brief description must end with a period.
DoxygenCheckCommentDescription = 1
# Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.
DoxygenCheckCommentFormat = 1
# Check whether only Doxygen commands allowed to mark the code are @bug and @todo.
DoxygenCheckCommand = 1
#
# Meta-Data File Processing Checking
#
MetaDataFileCheckAll = 0
# Check whether each file defined in meta-data exists
MetaDataFileCheckPathName = 1
# Generate a list for all files defined in meta-data files
MetaDataFileCheckGenerateFileList = 1
# The path of log file
MetaDataFileCheckPathOfGenerateFileList = File.log
# Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.
# Each Library Instance must specify the Supported Module Types in its INF file,
# and any module specifying the library instance must be one of the supported types.
MetaDataFileCheckLibraryInstance = 1
# Check whether a Library Instance has been defined for all dependent library classes
MetaDataFileCheckLibraryInstanceDependent = 1
# Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies
MetaDataFileCheckLibraryInstanceOrder = 1
# Check whether the unnecessary inclusion of library classes in the INF file
MetaDataFileCheckLibraryNoUse = 1
# Check whether an INF file is specified in the FDF file, but not in the DSC file, then the INF file must be for a Binary module only
MetaDataFileCheckBinaryInfInFdf = 1
# Not to report error and warning related OS include file such as "windows.h" and "stdio.h".
# Check whether a PCD is set in a DSC file or the FDF file, but not in both.
MetaDataFileCheckPcdDuplicate = 1
# Check whether PCD settings in the FDF file can only be related to flash.
MetaDataFileCheckPcdFlash = 1
# Check whether PCDs used in INF files but not specified in DSC or FDF files
MetaDataFileCheckPcdNoUse = 1
# Check whether having duplicate guids defined for Guid/Protocol/Ppi
MetaDataFileCheckGuidDuplicate = 1
# Check whether all files under module directory are described in INF files
MetaDataFileCheckModuleFileNoUse = 1
# Check whether the PCD is correctly used in C function via its type
MetaDataFileCheckPcdType = 1
#
# The check points in this section are reserved
#
# GotoStatementCheckAll = 0
# SpellingCheckAll = 0
#

View File

@@ -0,0 +1,310 @@
<ExceptionList xmlns="http://www.uefi.org/2008/2.1" xmlns:xsi="http:/www.w3.org/2001/XMLSchema-instance">
<Exception>
<KeyWord>__debugbreak</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>__readmsr</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>__writemsr</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>_InterlockedCompareExchange</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>_InterlockedCompareExchange64</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>_InterlockedDecrement</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>_InterlockedIncrement</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>_break</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>_inp</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>_inpw</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>_inpd</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>_outp</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>_outpw</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>_outpd</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>_ReadWriteBarrier</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>InternalX86DisablePaging32</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>InternalX86EnablePaging32</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>InternalLongJump</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>SetJump</KeyWord>
<ErrorID>4002</ErrorID>
</Exception>
<Exception>
<KeyWord>__debugbreak</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>__readmsr</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>__writemsr</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>_InterlockedCompareExchange</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>_InterlockedCompareExchange64</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>_InterlockedDecrement</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>_InterlockedIncrement</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>_inp</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>_inpw</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>_inpd</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>_outp</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>_outpw</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>_outpd</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>_ReadWriteBarrier</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>IoRead8</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>IoWrite8</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>IoRead16</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>IoWrite16</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>IoRead32</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>IoWrite32</KeyWord>
<ErrorID>5001</ErrorID>
</Exception>
<Exception>
<KeyWord>__debugbreak</KeyWord>
<ErrorID>5003</ErrorID>
</Exception>
<Exception>
<KeyWord>__readmsr</KeyWord>
<ErrorID>5003</ErrorID>
</Exception>
<Exception>
<KeyWord>__writemsr</KeyWord>
<ErrorID>5003</ErrorID>
</Exception>
<Exception>
<KeyWord>_InterlockedCompareExchange</KeyWord>
<ErrorID>5003</ErrorID>
</Exception>
<Exception>
<KeyWord>_InterlockedCompareExchange64</KeyWord>
<ErrorID>5003</ErrorID>
</Exception>
<Exception>
<KeyWord>_InterlockedDecrement</KeyWord>
<ErrorID>5003</ErrorID>
</Exception>
<Exception>
<KeyWord>_InterlockedIncrement</KeyWord>
<ErrorID>5003</ErrorID>
</Exception>
<Exception>
<KeyWord>_inp</KeyWord>
<ErrorID>5003</ErrorID>
</Exception>
<Exception>
<KeyWord>_inpw</KeyWord>
<ErrorID>5003</ErrorID>
</Exception>
<Exception>
<KeyWord>_inpd</KeyWord>
<ErrorID>5003</ErrorID>
</Exception>
<Exception>
<KeyWord>_outp</KeyWord>
<ErrorID>5003</ErrorID>
</Exception>
<Exception>
<KeyWord>_outpw</KeyWord>
<ErrorID>5003</ErrorID>
</Exception>
<Exception>
<KeyWord>_outpd</KeyWord>
<ErrorID>5003</ErrorID>
</Exception>
<Exception>
<KeyWord>_ReadWriteBarrier</KeyWord>
<ErrorID>5003</ErrorID>
</Exception>
<Exception>
<KeyWord>__debugbreak</KeyWord>
<ErrorID>7001</ErrorID>
</Exception>
<Exception>
<KeyWord>__readmsr</KeyWord>
<ErrorID>7001</ErrorID>
</Exception>
<Exception>
<KeyWord>__writemsr</KeyWord>
<ErrorID>7001</ErrorID>
</Exception>
<Exception>
<KeyWord>_InterlockedCompareExchange</KeyWord>
<ErrorID>7001</ErrorID>
</Exception>
<Exception>
<KeyWord>_InterlockedCompareExchange64</KeyWord>
<ErrorID>7001</ErrorID>
</Exception>
<Exception>
<KeyWord>_InterlockedDecrement</KeyWord>
<ErrorID>7001</ErrorID>
</Exception>
<Exception>
<KeyWord>_InterlockedIncrement</KeyWord>
<ErrorID>7001</ErrorID>
</Exception>
<Exception>
<KeyWord>_inp</KeyWord>
<ErrorID>7001</ErrorID>
</Exception>
<Exception>
<KeyWord>_inpw</KeyWord>
<ErrorID>7001</ErrorID>
</Exception>
<Exception>
<KeyWord>_inpd</KeyWord>
<ErrorID>7001</ErrorID>
</Exception>
<Exception>
<KeyWord>_outp</KeyWord>
<ErrorID>7001</ErrorID>
</Exception>
<Exception>
<KeyWord>_outpw</KeyWord>
<ErrorID>7001</ErrorID>
</Exception>
<Exception>
<KeyWord>_outpd</KeyWord>
<ErrorID>7001</ErrorID>
</Exception>
<Exception>
<KeyWord>_ReadWriteBarrier</KeyWord>
<ErrorID>7001</ErrorID>
</Exception>
<Exception>
<KeyWord>@</KeyWord>
<ErrorID>9005</ErrorID>
</Exception>
<Exception>
<KeyWord>@R1</KeyWord>
<ErrorID>9005</ErrorID>
</Exception>
<Exception>
<KeyWord>@R2</KeyWord>
<ErrorID>9005</ErrorID>
</Exception>
<Exception>
<KeyWord>@Rx</KeyWord>
<ErrorID>9005</ErrorID>
</Exception>
<Exception>
<KeyWord>@R2.</KeyWord>
<ErrorID>9005</ErrorID>
</Exception>
<Exception>
<KeyWord>_DriverUnloadHandler</KeyWord>
<ErrorID>8006</ErrorID>
</Exception>
<Exception>
<KeyWord>ASSERT</KeyWord>
<ErrorID>10015</ErrorID>
</Exception>
<Exception>
<KeyWord>REPORT_STATUS_CODE</KeyWord>
<ErrorID>10015</ErrorID>
</Exception>
<Exception>
<KeyWord>REPORT_STATUS_CODE_WITH_EXTENDED_DATA</KeyWord>
<ErrorID>10015</ErrorID>
</Exception>
<Exception>
<KeyWord>REPORT_STATUS_CODE_WITH_DEVICE_PATH</KeyWord>
<ErrorID>10015</ErrorID>
</Exception>
</ExceptionList>

View File

View File

@@ -0,0 +1,6 @@
all:
clean:
find . -name '*.pyc' -exec rm '{}' ';'

View File

@@ -0,0 +1,118 @@
## @file
# process APRIORI file data and generate PEI/DXE APRIORI file
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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 struct import *
import os
import StringIO
import FfsFileStatement
from GenFdsGlobalVariable import GenFdsGlobalVariable
from CommonDataClass.FdfClass import AprioriSectionClassObject
from Common.String import *
from Common.Misc import SaveFileOnChange,PathClass
from Common import EdkLogger
from Common.BuildToolError import *
## process APRIORI file data and generate PEI/DXE APRIORI file
#
#
class AprioriSection (AprioriSectionClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
AprioriSectionClassObject.__init__(self)
self.AprioriType = ""
## GenFfs() method
#
# Generate FFS for APRIORI file
#
# @param self The object pointer
# @param FvName for whom apriori file generated
# @param Dict dictionary contains macro and its value
# @retval string Generated file name
#
def GenFfs (self, FvName, Dict = {}):
DXE_GUID = "FC510EE7-FFDC-11D4-BD41-0080C73C8881"
PEI_GUID = "1B45CC0A-156A-428A-AF62-49864DA0E6E6"
Buffer = StringIO.StringIO('')
AprioriFileGuid = DXE_GUID
if self.AprioriType == "PEI":
AprioriFileGuid = PEI_GUID
OutputAprFilePath = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, \
GenFdsGlobalVariable.FfsDir,\
AprioriFileGuid + FvName)
if not os.path.exists(OutputAprFilePath) :
os.makedirs(OutputAprFilePath)
OutputAprFileName = os.path.join( OutputAprFilePath, \
AprioriFileGuid + FvName + '.Apri' )
AprFfsFileName = os.path.join (OutputAprFilePath,\
AprioriFileGuid + FvName + '.Ffs')
Dict.update(self.DefineVarDict)
for FfsObj in self.FfsList :
Guid = ""
if isinstance(FfsObj, FfsFileStatement.FileStatement):
Guid = FfsObj.NameGuid
else:
InfFileName = NormPath(FfsObj.InfFileName)
Arch = FfsObj.GetCurrentArch()
if Arch != None:
Dict['$(ARCH)'] = Arch
InfFileName = GenFdsGlobalVariable.MacroExtend(InfFileName, Dict, Arch)
if Arch != None:
Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), Arch]
Guid = Inf.Guid
else:
Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), 'COMMON']
Guid = Inf.Guid
self.BinFileList = Inf.Module.Binaries
if self.BinFileList == []:
EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE,
"INF %s not found in build ARCH %s!" \
% (InfFileName, GenFdsGlobalVariable.ArchList))
GuidPart = Guid.split('-')
Buffer.write(pack('I', long(GuidPart[0], 16)))
Buffer.write(pack('H', int(GuidPart[1], 16)))
Buffer.write(pack('H', int(GuidPart[2], 16)))
for Num in range(2):
Char = GuidPart[3][Num*2:Num*2+2]
Buffer.write(pack('B', int(Char, 16)))
for Num in range(6):
Char = GuidPart[4][Num*2:Num*2+2]
Buffer.write(pack('B', int(Char, 16)))
SaveFileOnChange(OutputAprFileName, Buffer.getvalue())
RawSectionFileName = os.path.join( OutputAprFilePath, \
AprioriFileGuid + FvName + '.raw' )
GenFdsGlobalVariable.GenerateSection(RawSectionFileName, [OutputAprFileName], 'EFI_SECTION_RAW')
GenFdsGlobalVariable.GenerateFfs(AprFfsFileName, [RawSectionFileName],
'EFI_FV_FILETYPE_FREEFORM', AprioriFileGuid)
return AprFfsFileName

View File

@@ -0,0 +1,28 @@
## @file
# name value pair
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
## name value pair
#
#
class Attribute:
## The constructor
#
# @param self The object pointer
def __init__(self):
self.Name = None
self.Value = None

View File

@@ -0,0 +1,89 @@
## @file
# generate capsule
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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 GenFdsGlobalVariable import GenFdsGlobalVariable
from CommonDataClass.FdfClass import CapsuleClassObject
import os
import subprocess
import StringIO
from Common.Misc import SaveFileOnChange
T_CHAR_LF = '\n'
## create inf file describes what goes into capsule and call GenFv to generate capsule
#
#
class Capsule (CapsuleClassObject) :
## The constructor
#
# @param self The object pointer
#
def __init__(self):
CapsuleClassObject.__init__(self)
# For GenFv
self.BlockSize = None
# For GenFv
self.BlockNum = None
## Generate capsule
#
# @param self The object pointer
#
def GenCapsule(self):
CapInfFile = self.GenCapInf()
CapInfFile.writelines("[files]" + T_CHAR_LF)
for CapsuleDataObj in self.CapsuleDataList :
FileName = CapsuleDataObj.GenCapsuleSubItem()
CapInfFile.writelines("EFI_FILE_NAME = " + \
FileName + \
T_CHAR_LF)
SaveFileOnChange(self.CapInfFileName, CapInfFile.getvalue(), False)
CapInfFile.close()
#
# Call GenFv tool to generate capsule
#
CapOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiCapsuleName)
CapOutputFile = CapOutputFile + '.Cap'
GenFdsGlobalVariable.GenerateFirmwareVolume(
CapOutputFile,
[self.CapInfFileName],
Capsule=True
)
GenFdsGlobalVariable.SharpCounter = 0
## Generate inf file for capsule
#
# @param self The object pointer
# @retval file inf file object
#
def GenCapInf(self):
self.CapInfFileName = os.path.join(GenFdsGlobalVariable.FvDir,
self.UiCapsuleName + "_Cap" + '.inf')
CapInfFile = StringIO.StringIO() #open (self.CapInfFileName , 'w+')
CapInfFile.writelines("[options]" + T_CHAR_LF)
for Item in self.TokensDict.keys():
CapInfFile.writelines("EFI_" + \
Item + \
' = ' + \
self.TokensDict.get(Item) + \
T_CHAR_LF)
return CapInfFile

View File

@@ -0,0 +1,84 @@
## @file
# generate capsule
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import Ffs
from GenFdsGlobalVariable import GenFdsGlobalVariable
import StringIO
## base class for capsule data
#
#
class CapsuleData:
## The constructor
#
# @param self The object pointer
def __init__(self):
pass
## generate capsule data
#
# @param self The object pointer
def GenCapsuleSubItem(self):
pass
## FFS class for capsule data
#
#
class CapsuleFfs (CapsuleData):
## The constructor
#
# @param self The object pointer
#
def __init_(self) :
self.Ffs = None
## generate FFS capsule data
#
# @param self The object pointer
# @retval string Generated file name
#
def GenCapsuleSubItem(self):
FfsFile = self.Ffs.GenFfs()
return FfsFile
## FV class for capsule data
#
#
class CapsuleFv (CapsuleData):
## The constructor
#
# @param self The object pointer
#
def __init__(self) :
self.FvName = None
## generate FV capsule data
#
# @param self The object pointer
# @retval string Generated file name
#
def GenCapsuleSubItem(self):
if self.FvName.find('.fv') == -1:
if self.FvName.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName.upper())
FdBuffer = StringIO.StringIO('')
FvFile = FvObj.AddToBuffer(FdBuffer)
return FvFile
else:
FvFile = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FvName)
return FvFile

View File

@@ -0,0 +1,29 @@
## @file
# VTF components
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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 CommonDataClass.FdfClass import ComponentStatementClassObject
## VTF components
#
#
class ComponentStatement (ComponentStatementClassObject) :
## The constructor
#
# @param self The object pointer
#
def __init__(self):
ComponentStatementClassObject.__init__(self)

View File

@@ -0,0 +1,87 @@
## @file
# process compress section generation
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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 Ffs import Ffs
import Section
import subprocess
import os
from GenFdsGlobalVariable import GenFdsGlobalVariable
from CommonDataClass.FdfClass import CompressSectionClassObject
## generate compress section
#
#
class CompressSection (CompressSectionClassObject) :
## compress types: PI standard and non PI standard
CompTypeDict = {
'PI_STD' : 'PI_STD',
'NON_PI_STD' : 'NON_PI_STD'
}
## The constructor
#
# @param self The object pointer
#
def __init__(self):
CompressSectionClassObject.__init__(self)
## GenSection() method
#
# Generate compressed section
#
# @param self The object pointer
# @param OutputPath Where to place output file
# @param ModuleName Which module this section belongs to
# @param SecNum Index of section
# @param KeyStringList Filter for inputs of section generation
# @param FfsInf FfsInfStatement object that contains this section data
# @param Dict dictionary contains macro and its value
# @retval tuple (Generated file name, section alignment)
#
def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}):
if FfsInf != None:
self.CompType = FfsInf.__ExtendMacro__(self.CompType)
self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
SectFiles = tuple()
Index = 0
for Sect in self.SectionList:
Index = Index + 1
SecIndex = '%s.%d' %(SecNum, Index)
ReturnSectList, AlignValue = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict)
if ReturnSectList != []:
for FileData in ReturnSectList:
SectFiles += (FileData,)
OutputFile = OutputPath + \
os.sep + \
ModuleName + \
'SEC' + \
SecNum + \
Ffs.SectionSuffix['COMPRESS']
OutputFile = os.path.normpath(OutputFile)
GenFdsGlobalVariable.GenerateSection(OutputFile, SectFiles, Section.Section.SectionType['COMPRESS'],
CompressionType=self.CompTypeDict[self.CompType])
OutputFileList = []
OutputFileList.append(OutputFile)
return OutputFileList, self.Alignment

View File

@@ -0,0 +1,109 @@
## @file
# process data section generation
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import Section
from GenFdsGlobalVariable import GenFdsGlobalVariable
import subprocess
from Ffs import Ffs
import os
from CommonDataClass.FdfClass import DataSectionClassObject
import shutil
## generate data section
#
#
class DataSection (DataSectionClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
DataSectionClassObject.__init__(self)
## GenSection() method
#
# Generate compressed section
#
# @param self The object pointer
# @param OutputPath Where to place output file
# @param ModuleName Which module this section belongs to
# @param SecNum Index of section
# @param KeyStringList Filter for inputs of section generation
# @param FfsInf FfsInfStatement object that contains this section data
# @param Dict dictionary contains macro and its value
# @retval tuple (Generated file name list, section alignment)
#
def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}):
#
# Prepare the parameter of GenSection
#
if FfsFile != None:
self.SectFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.SectFileName)
self.SectFileName = GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict, FfsFile.CurrentArch)
else:
self.SectFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.SectFileName)
self.SectFileName = GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)
"""Check Section file exist or not !"""
if not os.path.exists(self.SectFileName):
self.SectFileName = os.path.join (GenFdsGlobalVariable.WorkSpaceDir,
self.SectFileName)
"""Copy Map file to Ffs output"""
Filename = GenFdsGlobalVariable.MacroExtend(self.SectFileName)
if Filename[(len(Filename)-4):] == '.efi':
MapFile = Filename.replace('.efi', '.map')
if os.path.exists(MapFile):
CopyMapFile = os.path.join(OutputPath, ModuleName + '.map')
if not os.path.exists(CopyMapFile) or \
(os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)):
shutil.copyfile(MapFile, CopyMapFile)
NoStrip = True
if self.SecType in ('TE', 'PE32'):
if self.KeepReloc != None:
NoStrip = self.KeepReloc
if not NoStrip:
FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi')
if not os.path.exists(FileBeforeStrip) or \
(os.path.getmtime(self.SectFileName) > os.path.getmtime(FileBeforeStrip)):
shutil.copyfile(self.SectFileName, FileBeforeStrip)
StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped')
GenFdsGlobalVariable.GenerateFirmwareImage(
StrippedFile,
[GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)],
Strip=True
)
self.SectFileName = StrippedFile
if self.SecType == 'TE':
TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw')
GenFdsGlobalVariable.GenerateFirmwareImage(
TeFile,
[GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)],
Type='te'
)
self.SectFileName = TeFile
OutputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get(self.SecType))
OutputFile = os.path.normpath(OutputFile)
GenFdsGlobalVariable.GenerateSection(OutputFile, [self.SectFileName], Section.Section.SectionType.get(self.SecType))
FileList = [OutputFile]
return FileList, self.Alignment

View File

@@ -0,0 +1,102 @@
## @file
# process depex section generation
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import Section
from GenFdsGlobalVariable import GenFdsGlobalVariable
import subprocess
from Ffs import Ffs
import os
from CommonDataClass.FdfClass import DepexSectionClassObject
from AutoGen.GenDepex import DependencyExpression
import shutil
from Common import EdkLogger
from Common.BuildToolError import *
## generate data section
#
#
class DepexSection (DepexSectionClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
DepexSectionClassObject.__init__(self)
def __FindGuidValue(self, CName):
for Arch in GenFdsGlobalVariable.ArchList:
for PkgDb in GenFdsGlobalVariable.WorkSpace.PackageList:
if CName in PkgDb.Ppis:
return PkgDb.Ppis[CName]
if CName in PkgDb.Protocols:
return PkgDb.Protocols[CName]
if CName in PkgDb.Guids:
return PkgDb.Guids[CName]
return None
## GenSection() method
#
# Generate compressed section
#
# @param self The object pointer
# @param OutputPath Where to place output file
# @param ModuleName Which module this section belongs to
# @param SecNum Index of section
# @param KeyStringList Filter for inputs of section generation
# @param FfsInf FfsInfStatement object that contains this section data
# @param Dict dictionary contains macro and its value
# @retval tuple (Generated file name list, section alignment)
#
def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}):
self.Expression = self.Expression.replace("\n", " ").replace("\r", " ")
ExpList = self.Expression.split()
ExpGuidDict = {}
for Exp in ExpList:
if Exp.upper() not in ('AND', 'OR', 'NOT', 'TRUE', 'FALSE', 'SOR', 'BEFORE', 'AFTER', 'END'):
GuidStr = self.__FindGuidValue(Exp)
if GuidStr == None:
EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE,
"Depex GUID %s could not be found in build DB! (ModuleName: %s)" % (Exp, ModuleName))
ExpGuidDict[Exp] = GuidStr
for Item in ExpGuidDict:
self.Expression = self.Expression.replace(Item, ExpGuidDict[Item])
self.Expression = self.Expression.strip()
ModuleType = (self.DepexType.startswith('PEI') and ['PEIM'] or ['DXE_DRIVER'])[0]
if self.DepexType.startswith('SMM'):
ModuleType = 'SMM_DRIVER'
InputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + '.dpx')
InputFile = os.path.normpath(InputFile)
Dpx = DependencyExpression(self.Expression, ModuleType)
Dpx.Generate(InputFile)
OutputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + '.depex')
if self.DepexType.startswith('SMM'):
OutputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + '.smm')
OutputFile = os.path.normpath(OutputFile)
SecType = (self.DepexType.startswith('PEI') and ['PEI_DEPEX'] or ['DXE_DEPEX'])[0]
if self.DepexType.startswith('SMM'):
SecType = 'SMM_DEPEX'
GenFdsGlobalVariable.GenerateSection(OutputFile, [InputFile], Section.Section.SectionType.get (SecType))
FileList = [OutputFile]
return FileList, self.Alignment

View File

@@ -0,0 +1,262 @@
## @file
# process rule section generation
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import Section
from GenFdsGlobalVariable import GenFdsGlobalVariable
import subprocess
from Ffs import Ffs
import os
from CommonDataClass.FdfClass import EfiSectionClassObject
import shutil
from Common import EdkLogger
from Common.BuildToolError import *
## generate rule section
#
#
class EfiSection (EfiSectionClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
EfiSectionClassObject.__init__(self)
## GenSection() method
#
# Generate rule section
#
# @param self The object pointer
# @param OutputPath Where to place output file
# @param ModuleName Which module this section belongs to
# @param SecNum Index of section
# @param KeyStringList Filter for inputs of section generation
# @param FfsInf FfsInfStatement object that contains this section data
# @param Dict dictionary contains macro and its value
# @retval tuple (Generated file name list, section alignment)
#
def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}) :
if self.FileName != None and self.FileName.startswith('PCD('):
self.FileName = GenFdsGlobalVariable.GetPcdValue(self.FileName)
"""Prepare the parameter of GenSection"""
if FfsInf != None :
InfFileName = FfsInf.InfFileName
SectionType = FfsInf.__ExtendMacro__(self.SectionType)
Filename = FfsInf.__ExtendMacro__(self.FileName)
BuildNum = FfsInf.__ExtendMacro__(self.BuildNum)
StringData = FfsInf.__ExtendMacro__(self.StringData)
NoStrip = True
if FfsInf.ModuleType in ('SEC', 'PEI_CORE', 'PEIM') and SectionType in ('TE', 'PE32'):
if FfsInf.KeepReloc != None:
NoStrip = FfsInf.KeepReloc
elif FfsInf.KeepRelocFromRule != None:
NoStrip = FfsInf.KeepRelocFromRule
elif self.KeepReloc != None:
NoStrip = self.KeepReloc
elif FfsInf.ShadowFromInfFile != None:
NoStrip = FfsInf.ShadowFromInfFile
else:
EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s apply rule for None!" %ModuleName)
"""If the file name was pointed out, add it in FileList"""
FileList = []
if Filename != None:
Filename = GenFdsGlobalVariable.MacroExtend(Filename, Dict)
if not self.Optional:
FileList.append(Filename)
elif os.path.exists(Filename):
FileList.append(Filename)
else:
FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FileType, self.FileExtension, Dict)
if IsSect :
return FileList, self.Alignment
Index = 0
""" If Section type is 'VERSION'"""
OutputFileList = []
if SectionType == 'VERSION':
InfOverrideVerString = False
if FfsInf.Version != None:
#StringData = FfsInf.Version
BuildNum = FfsInf.Version
InfOverrideVerString = True
if InfOverrideVerString:
#VerTuple = ('-n', '"' + StringData + '"')
if BuildNum != None and BuildNum != '':
BuildNumTuple = ('-j', BuildNum)
else:
BuildNumTuple = tuple()
Num = SecNum
OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType))
GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
#Ui=StringData,
Ver=BuildNum)
OutputFileList.append(OutputFile)
elif FileList != []:
for File in FileList:
Index = Index + 1
Num = '%s.%d' %(SecNum , Index)
OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get(SectionType))
f = open(File, 'r')
VerString = f.read()
f.close()
# VerTuple = ('-n', '"' + VerString + '"')
BuildNum = VerString
if BuildNum != None and BuildNum != '':
BuildNumTuple = ('-j', BuildNum)
GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
#Ui=VerString,
Ver=BuildNum)
OutputFileList.append(OutputFile)
else:
# if StringData != None and len(StringData) > 0:
# VerTuple = ('-n', '"' + StringData + '"')
# else:
# VerTuple = tuple()
# VerString = ' ' + ' '.join(VerTuple)
BuildNum = StringData
if BuildNum != None and BuildNum != '':
BuildNumTuple = ('-j', BuildNum)
else:
BuildNumTuple = tuple()
BuildNumString = ' ' + ' '.join(BuildNumTuple)
#if VerString == '' and
if BuildNumString == '':
if self.Optional == True :
GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!")
return [], None
else:
EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss Version Section value" %InfFileName)
Num = SecNum
OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType))
GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
#Ui=VerString,
Ver=BuildNum)
OutputFileList.append(OutputFile)
#
# If Section Type is 'UI'
#
elif SectionType == 'UI':
InfOverrideUiString = False
if FfsInf.Ui != None:
StringData = FfsInf.Ui
InfOverrideUiString = True
if InfOverrideUiString:
Num = SecNum
OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType))
GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
Ui=StringData)
OutputFileList.append(OutputFile)
elif FileList != []:
for File in FileList:
Index = Index + 1
Num = '%s.%d' %(SecNum , Index)
OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get(SectionType))
f = open(File, 'r')
UiString = f.read()
f.close()
GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
Ui=UiString)
OutputFileList.append(OutputFile)
else:
if StringData != None and len(StringData) > 0:
UiTuple = ('-n', '"' + StringData + '"')
else:
UiTuple = tuple()
if self.Optional == True :
GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!")
return '', None
else:
EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss UI Section value" %InfFileName)
Num = SecNum
OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType))
GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
Ui=StringData)
OutputFileList.append(OutputFile)
else:
"""If File List is empty"""
if FileList == [] :
if self.Optional == True:
GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!")
return [], None
else:
EdkLogger.error("GenFds", GENFDS_ERROR, "Output file for %s section could not be found for %s" % (SectionType, InfFileName))
else:
"""Convert the File to Section file one by one """
for File in FileList:
""" Copy Map file to FFS output path """
Index = Index + 1
Num = '%s.%d' %(SecNum , Index)
OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get(SectionType))
File = GenFdsGlobalVariable.MacroExtend(File, Dict)
if File[(len(File)-4):] == '.efi':
MapFile = File.replace('.efi', '.map')
if os.path.exists(MapFile):
CopyMapFile = os.path.join(OutputPath, ModuleName + '.map')
if not os.path.exists(CopyMapFile) or \
(os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)):
shutil.copyfile(MapFile, CopyMapFile)
if not NoStrip:
FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi')
if not os.path.exists(FileBeforeStrip) or \
(os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
shutil.copyfile(File, FileBeforeStrip)
StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped')
GenFdsGlobalVariable.GenerateFirmwareImage(
StrippedFile,
[GenFdsGlobalVariable.MacroExtend(File, Dict)],
Strip=True
)
File = StrippedFile
"""For TE Section call GenFw to generate TE image"""
if SectionType == 'TE':
TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw')
GenFdsGlobalVariable.GenerateFirmwareImage(
TeFile,
[GenFdsGlobalVariable.MacroExtend(File, Dict)],
Type='te'
)
File = TeFile
"""Call GenSection"""
GenFdsGlobalVariable.GenerateSection(OutputFile,
[GenFdsGlobalVariable.MacroExtend(File)],
Section.Section.SectionType.get (SectionType)
)
OutputFileList.append(OutputFile)
return OutputFileList, self.Alignment

View File

@@ -0,0 +1,169 @@
## @file
# process FD generation
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import Region
import Fv
import os
import StringIO
import sys
from struct import *
from GenFdsGlobalVariable import GenFdsGlobalVariable
from CommonDataClass.FdfClass import FDClassObject
from Common import EdkLogger
from Common.BuildToolError import *
from Common.Misc import SaveFileOnChange
## generate FD
#
#
class FD(FDClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
FDClassObject.__init__(self)
## GenFd() method
#
# Generate FD
#
# @param self The object pointer
# @param FvBinDict dictionary contains generated FV name and its file name
# @retval string Generated FD file name
#
def GenFd (self, FvBinDict):
#
# Print Information
#
GenFdsGlobalVariable.InfLogger("Fd File Name:%s" %self.FdUiName)
Offset = 0x00
for item in self.BlockSizeList:
Offset = Offset + item[0] * item[1]
if Offset != self.Size:
EdkLogger.error("GenFds", GENFDS_ERROR, 'FD %s Size not consistent with block array' % self.FdUiName)
GenFdsGlobalVariable.VerboseLogger('Following Fv will be add to Fd !!!')
for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict:
GenFdsGlobalVariable.VerboseLogger(FvObj)
GenFdsGlobalVariable.VerboseLogger('################### Gen VTF ####################')
self.GenVtfFile()
FdBuffer = StringIO.StringIO('')
PreviousRegionStart = -1
PreviousRegionSize = 1
for RegionObj in self.RegionList :
if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart:
EdkLogger.error("GenFds", GENFDS_ERROR,
'Region offset 0x%X in wrong order with Region starting from 0x%X, size 0x%X\nRegions in FDF must have offsets appear in ascending order.'\
% (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize))
elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize):
EdkLogger.error("GenFds", GENFDS_ERROR,
'Region offset 0x%X overlaps with Region starting from 0x%X, size 0x%X' \
% (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize))
elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize:
GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
PadRegion = Region.Region()
PadRegion.Offset = PreviousRegionStart + PreviousRegionSize
PadRegion.Size = RegionObj.Offset - PadRegion.Offset
PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, FvBinDict, self.vtfRawDict, self.DefineVarDict)
PreviousRegionStart = RegionObj.Offset
PreviousRegionSize = RegionObj.Size
#
# Call each region's AddToBuffer function
#
if PreviousRegionSize > self.Size:
EdkLogger.error("GenFds", GENFDS_ERROR, 'FD %s size too small' % self.FdUiName)
GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function')
RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, FvBinDict, self.vtfRawDict, self.DefineVarDict)
#
# Create a empty Fd file
#
GenFdsGlobalVariable.VerboseLogger ('Create an empty Fd file')
FdFileName = os.path.join(GenFdsGlobalVariable.FvDir,
self.FdUiName + '.fd')
#FdFile = open(FdFileName, 'wb')
#
# Write the buffer contents to Fd file
#
GenFdsGlobalVariable.VerboseLogger('Write the buffer contents to Fd file')
SaveFileOnChange(FdFileName, FdBuffer.getvalue())
#FdFile.write(FdBuffer.getvalue());
#FdFile.close();
FdBuffer.close();
return FdFileName
## generate VTF
#
# @param self The object pointer
#
def GenVtfFile (self) :
#
# Get this Fd's all Fv name
#
FvAddDict ={}
FvList = []
for RegionObj in self.RegionList:
if RegionObj.RegionType == 'FV':
if len(RegionObj.RegionDataList) == 1:
RegionData = RegionObj.RegionDataList[0]
FvList.append(RegionData.upper())
FvAddDict[RegionData.upper()] = (int(self.BaseAddress,16) + \
RegionObj.Offset, RegionObj.Size)
else:
Offset = RegionObj.Offset
for RegionData in RegionObj.RegionDataList:
FvList.append(RegionData.upper())
FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(RegionData.upper())
if len(FvObj.BlockSizeList) < 1:
EdkLogger.error("GenFds", GENFDS_ERROR,
'FV.%s must point out FVs blocksize and Fv BlockNum' \
% FvObj.UiFvName)
else:
Size = 0
for blockStatement in FvObj.BlockSizeList:
Size = Size + blockStatement[0] * blockStatement[1]
FvAddDict[RegionData.upper()] = (int(self.BaseAddress,16) + \
Offset, Size)
Offset = Offset + Size
#
# Check whether this Fd need VTF
#
Flag = False
for VtfObj in GenFdsGlobalVariable.FdfParser.Profile.VtfList:
compLocList = VtfObj.GetFvList()
if set(compLocList).issubset(FvList):
Flag = True
break
if Flag == True:
self.vtfRawDict = VtfObj.GenVtf(FvAddDict)
## generate flash map file
#
# @param self The object pointer
#
def GenFlashMap (self):
pass

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,81 @@
## @file
# process FFS generation
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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 CommonDataClass.FdfClass import FDClassObject
## generate FFS
#
#
class Ffs(FDClassObject):
# mapping between MODULE type in FDF (from INF) and file type for GenFfs
ModuleTypeToFileType = {
'SEC' : 'EFI_FV_FILETYPE_SECURITY_CORE',
'PEI_CORE' : 'EFI_FV_FILETYPE_PEI_CORE',
'PEIM' : 'EFI_FV_FILETYPE_PEIM',
'DXE_CORE' : 'EFI_FV_FILETYPE_DXE_CORE',
'DXE_DRIVER' : 'EFI_FV_FILETYPE_DRIVER',
'DXE_SAL_DRIVER' : 'EFI_FV_FILETYPE_DRIVER',
'DXE_SMM_DRIVER' : 'EFI_FV_FILETYPE_DRIVER',
'DXE_RUNTIME_DRIVER': 'EFI_FV_FILETYPE_DRIVER',
'UEFI_DRIVER' : 'EFI_FV_FILETYPE_DRIVER',
'UEFI_APPLICATION' : 'EFI_FV_FILETYPE_APPLICATION',
'SMM_DRIVER' : 'EFI_FV_FILETYPE_SMM',
'SMM_CORE' : 'EFI_FV_FILETYPE_SMM_CORE'
}
# mapping between FILE type in FDF and file type for GenFfs
FdfFvFileTypeToFileType = {
'SEC' : 'EFI_FV_FILETYPE_SECURITY_CORE',
'PEI_CORE' : 'EFI_FV_FILETYPE_PEI_CORE',
'PEIM' : 'EFI_FV_FILETYPE_PEIM',
'DXE_CORE' : 'EFI_FV_FILETYPE_DXE_CORE',
'FREEFORM' : 'EFI_FV_FILETYPE_FREEFORM',
'DRIVER' : 'EFI_FV_FILETYPE_DRIVER',
'APPLICATION' : 'EFI_FV_FILETYPE_APPLICATION',
'FV_IMAGE' : 'EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE',
'RAW' : 'EFI_FV_FILETYPE_RAW',
'PEI_DXE_COMBO' : 'EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER',
'SMM_DXE_COMBO' : 'EFI_FV_FILETYPE_COMBINED_SMM_DXE',
'SMM' : 'EFI_FV_FILETYPE_SMM',
'SMM_CORE' : 'EFI_FV_FILETYPE_SMM_CORE'
}
# mapping between section type in FDF and file suffix
SectionSuffix = {
'PE32' : '.pe32',
'PIC' : '.pic',
'TE' : '.te',
'DXE_DEPEX' : '.dpx',
'VERSION' : '.ver',
'UI' : '.ui',
'COMPAT16' : '.com16',
'RAW' : '.raw',
'FREEFORM_SUBTYPE_GUID': '.guid',
'FV_IMAGE' : 'fv.sec',
'COMPRESS' : '.com',
'GUIDED' : '.guided',
'PEI_DEPEX' : '.dpx',
'SMM_DEPEX' : '.smm'
}
## The constructor
#
# @param self The object pointer
#
def __init__(self):
FfsClassObject.__init__(self)

View File

@@ -0,0 +1,118 @@
## @file
# process FFS generation from FILE statement
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import Ffs
import Rule
from GenFdsGlobalVariable import GenFdsGlobalVariable
import os
import StringIO
import subprocess
from CommonDataClass.FdfClass import FileStatementClassObject
from Common import EdkLogger
from Common.BuildToolError import *
from Common.Misc import GuidStructureByteArrayToGuidString
## generate FFS from FILE
#
#
class FileStatement (FileStatementClassObject) :
## The constructor
#
# @param self The object pointer
#
def __init__(self):
FileStatementClassObject.__init__(self)
## GenFfs() method
#
# Generate FFS
#
# @param self The object pointer
# @param Dict dictionary contains macro and value pair
# @retval string Generated FFS file name
#
def GenFfs(self, Dict = {}):
if self.NameGuid != None and self.NameGuid.startswith('PCD('):
PcdValue = GenFdsGlobalVariable.GetPcdValue(self.NameGuid)
if len(PcdValue) == 0:
EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
% (self.NameGuid))
if PcdValue.startswith('{'):
PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
RegistryGuidStr = PcdValue
if len(RegistryGuidStr) == 0:
EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
% (self.NameGuid))
self.NameGuid = RegistryGuidStr
OutputDir = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid)
if not os.path.exists(OutputDir):
os.makedirs(OutputDir)
Dict.update(self.DefineVarDict)
SectionAlignments = None
if self.FvName != None :
Buffer = StringIO.StringIO('')
if self.FvName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (self.FvName))
Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName.upper())
FileName = Fv.AddToBuffer(Buffer)
SectionFiles = [FileName]
elif self.FdName != None:
if self.FdName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
EdkLogger.error("GenFds", GENFDS_ERROR, "FD (%s) is NOT described in FDF file!" % (self.FdName))
Fd = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(self.FdName.upper())
FvBin = {}
FileName = Fd.GenFd(FvBin)
SectionFiles = [FileName]
elif self.FileName != None:
self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
SectionFiles = [GenFdsGlobalVariable.MacroExtend(self.FileName, Dict)]
else:
SectionFiles = []
Index = 0
SectionAlignments = []
for section in self.SectionList :
Index = Index + 1
SecIndex = '%d' %Index
sectList, align = section.GenSection(OutputDir, self.NameGuid, SecIndex, self.KeyStringList, None, Dict)
if sectList != []:
for sect in sectList:
SectionFiles.append(sect)
SectionAlignments.append(align)
#
# Prepare the parameter
#
FfsFileOutput = os.path.join(OutputDir, self.NameGuid + '.ffs')
GenFdsGlobalVariable.GenerateFfs(FfsFileOutput, SectionFiles,
Ffs.Ffs.FdfFvFileTypeToFileType.get(self.FvFileType),
self.NameGuid,
Fixed=self.Fixed,
CheckSum=self.CheckSum,
Align=self.Alignment,
SectionAlign=SectionAlignments
)
return FfsFileOutput

View File

@@ -0,0 +1,582 @@
## @file
# process FFS generation from INF statement
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import Rule
import os
import shutil
from GenFdsGlobalVariable import GenFdsGlobalVariable
import Ffs
import subprocess
import sys
import Section
import RuleSimpleFile
import RuleComplexFile
from CommonDataClass.FdfClass import FfsInfStatementClassObject
from Common.String import *
from Common.Misc import PathClass
from Common.Misc import GuidStructureByteArrayToGuidString
from Common import EdkLogger
from Common.BuildToolError import *
## generate FFS from INF
#
#
class FfsInfStatement(FfsInfStatementClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
FfsInfStatementClassObject.__init__(self)
self.TargetOverrideList = []
self.ShadowFromInfFile = None
self.KeepRelocFromRule = None
self.InDsc = True
self.OptRomDefs = {}
## __InfParse() method
#
# Parse inf file to get module information
#
# @param self The object pointer
# @param Dict dictionary contains macro and value pair
#
def __InfParse__(self, Dict = {}):
GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName)
self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '')
if self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' :
self.InfFileName = self.InfFileName[1:]
if self.InfFileName.find('$') == -1:
InfPath = NormPath(self.InfFileName)
if not os.path.exists(InfPath):
InfPath = GenFdsGlobalVariable.ReplaceWorkspaceMacro(InfPath)
if not os.path.exists(InfPath):
EdkLogger.error("GenFds", GENFDS_ERROR, "Non-existant Module %s !" % (self.InfFileName))
self.CurrentArch = self.GetCurrentArch()
#
# Get the InfClass object
#
PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)
ErrorCode, ErrorInfo = PathClassObj.Validate()
if ErrorCode != 0:
EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
if self.CurrentArch != None:
Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch]
#
# Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath
#
self.BaseName = Inf.BaseName
self.ModuleGuid = Inf.Guid
self.ModuleType = Inf.ModuleType
if Inf.AutoGenVersion < 0x00010005:
self.ModuleType = Inf.ComponentType
self.VersionString = Inf.Version
self.BinFileList = Inf.Binaries
self.SourceFileList = Inf.Sources
if self.KeepReloc == None and Inf.Shadow:
self.ShadowFromInfFile = Inf.Shadow
else:
Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON']
self.BaseName = Inf.BaseName
self.ModuleGuid = Inf.Guid
self.ModuleType = Inf.ModuleType
self.VersionString = Inf.Version
self.BinFileList = Inf.Binaries
self.SourceFileList = Inf.Sources
if self.BinFileList == []:
EdkLogger.error("GenFds", GENFDS_ERROR,
"INF %s specified in FDF could not be found in build ARCH %s!" \
% (self.InfFileName, GenFdsGlobalVariable.ArchList))
if len(self.SourceFileList) != 0 and not self.InDsc:
EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName))
if Inf._Defs != None and len(Inf._Defs) > 0:
self.OptRomDefs.update(Inf._Defs)
GenFdsGlobalVariable.VerboseLogger( "BaseName : %s" %self.BaseName)
GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" %self.ModuleGuid)
GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" %self.ModuleType)
GenFdsGlobalVariable.VerboseLogger("VersionString : %s" %self.VersionString)
GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" %self.InfFileName)
#
# Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\
#
self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \
self.ModuleGuid + self.BaseName)
if not os.path.exists(self.OutputPath) :
os.makedirs(self.OutputPath)
self.EfiOutputPath = self.__GetEFIOutPutPath__()
GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)
## GenFfs() method
#
# Generate FFS
#
# @param self The object pointer
# @param Dict dictionary contains macro and value pair
# @retval string Generated FFS file name
#
def GenFfs(self, Dict = {}):
#
# Parse Inf file get Module related information
#
self.__InfParse__(Dict)
#
# Get the rule of how to generate Ffs file
#
Rule = self.__GetRule__()
GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName)
#FileType = Ffs.Ffs.ModuleTypeToFileType[Rule.ModuleType]
#
# For the rule only has simpleFile
#
if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) :
SectionOutputList = self.__GenSimpleFileSection__(Rule)
FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList)
return FfsOutput
#
# For Rule has ComplexFile
#
elif isinstance(Rule, RuleComplexFile.RuleComplexFile):
InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule)
FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments)
return FfsOutput
## __ExtendMacro__() method
#
# Replace macro with its value
#
# @param self The object pointer
# @param String The string to be replaced
# @retval string Macro replaced string
#
def __ExtendMacro__ (self, String):
MacroDict = {
'$(INF_OUTPUT)' : self.EfiOutputPath,
'$(MODULE_NAME)' : self.BaseName,
'$(BUILD_NUMBER)': self.BuildNum,
'$(INF_VERSION)' : self.VersionString,
'$(NAMED_GUID)' : self.ModuleGuid
}
String = GenFdsGlobalVariable.MacroExtend(String, MacroDict)
return String
## __GetRule__() method
#
# Get correct rule for generating FFS for this INF
#
# @param self The object pointer
# @retval Rule Rule object
#
def __GetRule__ (self) :
CurrentArchList = []
if self.CurrentArch == None:
CurrentArchList = ['common']
else:
CurrentArchList.append(self.CurrentArch)
for CurrentArch in CurrentArchList:
RuleName = 'RULE' + \
'.' + \
CurrentArch.upper() + \
'.' + \
self.ModuleType.upper()
if self.Rule != None:
RuleName = RuleName + \
'.' + \
self.Rule.upper()
Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)
if Rule != None:
GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)
return Rule
RuleName = 'RULE' + \
'.' + \
'COMMON' + \
'.' + \
self.ModuleType.upper()
if self.Rule != None:
RuleName = RuleName + \
'.' + \
self.Rule.upper()
GenFdsGlobalVariable.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName, self.InfFileName))
Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)
if Rule != None:
GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)
return Rule
if Rule == None :
EdkLogger.error("GenFds", GENFDS_ERROR, 'Don\'t Find common rule %s for INF %s' \
% (RuleName, self.InfFileName))
## __GetPlatformArchList__() method
#
# Get Arch list this INF built under
#
# @param self The object pointer
# @retval list Arch list
#
def __GetPlatformArchList__(self):
InfFileKey = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName))
DscArchList = []
PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IA32']
if PlatformDataBase != None:
if InfFileKey in PlatformDataBase.Modules:
DscArchList.append ('IA32')
PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'X64']
if PlatformDataBase != None:
if InfFileKey in PlatformDataBase.Modules:
DscArchList.append ('X64')
PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IPF']
if PlatformDataBase != None:
if InfFileKey in (PlatformDataBase.Modules):
DscArchList.append ('IPF')
PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'ARM']
if PlatformDataBase != None:
if InfFileKey in (PlatformDataBase.Modules):
DscArchList.append ('ARM')
PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'EBC']
if PlatformDataBase != None:
if InfFileKey in (PlatformDataBase.Modules):
DscArchList.append ('EBC')
return DscArchList
## GetCurrentArch() method
#
# Get Arch list of the module from this INF is to be placed into flash
#
# @param self The object pointer
# @retval list Arch list
#
def GetCurrentArch(self) :
TargetArchList = GenFdsGlobalVariable.ArchList
PlatformArchList = self.__GetPlatformArchList__()
CurArchList = TargetArchList
if PlatformArchList != []:
CurArchList = list(set (TargetArchList) & set (PlatformArchList))
GenFdsGlobalVariable.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList))
ArchList = []
if self.KeyStringList != []:
for Key in self.KeyStringList:
Key = GenFdsGlobalVariable.MacroExtend(Key)
Target, Tag, Arch = Key.split('_')
if Arch in CurArchList:
ArchList.append(Arch)
if Target not in self.TargetOverrideList:
self.TargetOverrideList.append(Target)
else:
ArchList = CurArchList
UseArchList = TargetArchList
if self.UseArch != None:
UseArchList = []
UseArchList.append(self.UseArch)
ArchList = list(set (UseArchList) & set (ArchList))
self.InfFileName = NormPath(self.InfFileName)
if len(PlatformArchList) == 0:
self.InDsc = False
PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)
ErrorCode, ErrorInfo = PathClassObj.Validate()
if ErrorCode != 0:
EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
if len(ArchList) == 1:
Arch = ArchList[0]
return Arch
elif len(ArchList) > 1:
if len(PlatformArchList) == 0:
EdkLogger.error("GenFds", GENFDS_ERROR, "GenFds command line option has multiple ARCHs %s. Not able to determine which ARCH is valid for Module %s !" % (str(ArchList), self.InfFileName))
else:
EdkLogger.error("GenFds", GENFDS_ERROR, "Module built under multiple ARCHs %s. Not able to determine which output to put into flash for Module %s !" % (str(ArchList), self.InfFileName))
else:
EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s appears under ARCH %s in platform %s, but current deduced ARCH is %s, so NO build output could be put into flash." \
% (self.InfFileName, str(PlatformArchList), GenFdsGlobalVariable.ActivePlatform, str(set (UseArchList) & set (TargetArchList))))
## __GetEFIOutPutPath__() method
#
# Get the output path for generated files
#
# @param self The object pointer
# @retval string Path that output files from this INF go to
#
def __GetEFIOutPutPath__(self):
Arch = ''
OutputPath = ''
(ModulePath, FileName) = os.path.split(self.InfFileName)
Index = FileName.find('.')
FileName = FileName[0:Index]
Arch = "NoneArch"
if self.CurrentArch != None:
Arch = self.CurrentArch
OutputPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch],
Arch ,
ModulePath,
FileName,
'OUTPUT'
)
OutputPath = os.path.realpath(OutputPath)
return OutputPath
## __GenSimpleFileSection__() method
#
# Generate section by specified file name or a list of files with file extension
#
# @param self The object pointer
# @param Rule The rule object used to generate section
# @retval string File name of the generated section file
#
def __GenSimpleFileSection__(self, Rule):
#
# Prepare the parameter of GenSection
#
FileList = []
OutputFileList = []
if Rule.FileName != None:
GenSecInputFile = self.__ExtendMacro__(Rule.FileName)
else:
FileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension)
Index = 1
SectionType = Rule.SectionType
NoStrip = True
if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):
if self.KeepReloc != None:
NoStrip = self.KeepReloc
elif Rule.KeepReloc != None:
NoStrip = Rule.KeepReloc
elif self.ShadowFromInfFile != None:
NoStrip = self.ShadowFromInfFile
if FileList != [] :
for File in FileList:
SecNum = '%d' %Index
GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \
Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum
Index = Index + 1
OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)
if not NoStrip:
FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
if not os.path.exists(FileBeforeStrip) or \
(os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
shutil.copyfile(File, FileBeforeStrip)
StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
GenFdsGlobalVariable.GenerateFirmwareImage(
StrippedFile,
[GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)],
Strip=True
)
File = StrippedFile
if SectionType == 'TE':
TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
GenFdsGlobalVariable.GenerateFirmwareImage(
TeFile,
[GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)],
Type='te'
)
File = TeFile
GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType])
OutputFileList.append(OutputFile)
else:
SecNum = '%d' %Index
GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \
Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum
OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)
if not NoStrip:
FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
if not os.path.exists(FileBeforeStrip) or \
(os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)):
shutil.copyfile(GenSecInputFile, FileBeforeStrip)
StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
GenFdsGlobalVariable.GenerateFirmwareImage(
StrippedFile,
[GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch)],
Strip=True
)
GenSecInputFile = StrippedFile
if SectionType == 'TE':
TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
GenFdsGlobalVariable.GenerateFirmwareImage(
TeFile,
[GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)],
Type='te'
)
GenSecInputFile = TeFile
GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType])
OutputFileList.append(OutputFile)
return OutputFileList
## __GenSimpleFileFfs__() method
#
# Generate FFS
#
# @param self The object pointer
# @param Rule The rule object used to generate section
# @param InputFileList The output file list from GenSection
# @retval string Generated FFS file name
#
def __GenSimpleFileFfs__(self, Rule, InputFileList):
FfsOutput = self.OutputPath + \
os.sep + \
self.__ExtendMacro__(Rule.NameGuid) + \
'.ffs'
GenFdsGlobalVariable.VerboseLogger(self.__ExtendMacro__(Rule.NameGuid))
InputSection = []
SectionAlignments = []
for InputFile in InputFileList:
InputSection.append(InputFile)
SectionAlignments.append(Rule.Alignment)
if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):
PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)
if len(PcdValue) == 0:
EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
% (Rule.NameGuid))
if PcdValue.startswith('{'):
PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
RegistryGuidStr = PcdValue
if len(RegistryGuidStr) == 0:
EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
% (Rule.NameGuid))
self.ModuleGuid = RegistryGuidStr
GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection,
Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
self.ModuleGuid, Fixed=Rule.Fixed,
CheckSum=Rule.CheckSum, Align=Rule.Alignment,
SectionAlign=SectionAlignments
)
return FfsOutput
## __GenComplexFileSection__() method
#
# Generate section by sections in Rule
#
# @param self The object pointer
# @param Rule The rule object used to generate section
# @retval string File name of the generated section file
#
def __GenComplexFileSection__(self, Rule):
if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):
if Rule.KeepReloc != None:
self.KeepRelocFromRule = Rule.KeepReloc
SectFiles = []
SectAlignments = []
Index = 1
for Sect in Rule.SectionList:
SecIndex = '%d' %Index
SectList = []
if Rule.KeyStringList != []:
SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self)
else :
SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self)
for SecName in SectList :
SectFiles.append(SecName)
SectAlignments.append(Align)
Index = Index + 1
return SectFiles, SectAlignments
## __GenComplexFileFfs__() method
#
# Generate FFS
#
# @param self The object pointer
# @param Rule The rule object used to generate section
# @param InputFileList The output file list from GenSection
# @retval string Generated FFS file name
#
def __GenComplexFileFfs__(self, Rule, InputFile, Alignments):
if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):
PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)
if len(PcdValue) == 0:
EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
% (Rule.NameGuid))
if PcdValue.startswith('{'):
PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
RegistryGuidStr = PcdValue
if len(RegistryGuidStr) == 0:
EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
% (Rule.NameGuid))
self.ModuleGuid = RegistryGuidStr
FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')
GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile,
Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
self.ModuleGuid, Fixed=Rule.Fixed,
CheckSum=Rule.CheckSum, Align=Rule.Alignment,
SectionAlign=Alignments
)
return FfsOutput
## __GetGenFfsCmdParameter__() method
#
# Create parameter string for GenFfs
#
# @param self The object pointer
# @param Rule The rule object used to generate section
# @retval tuple (FileType, Fixed, CheckSum, Alignment)
#
def __GetGenFfsCmdParameter__(self, Rule):
result = tuple()
result += ('-t', Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType])
if Rule.Fixed != False:
result += ('-x',)
if Rule.CheckSum != False:
result += ('-s',)
if Rule.Alignment != None and Rule.Alignment != '':
result += ('-a', Rule.Alignment)
return result

View File

@@ -0,0 +1,215 @@
## @file
# process FV generation
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import os
import shutil
import subprocess
import StringIO
import Ffs
import AprioriSection
from GenFdsGlobalVariable import GenFdsGlobalVariable
from GenFds import GenFds
from CommonDataClass.FdfClass import FvClassObject
from Common.Misc import SaveFileOnChange
T_CHAR_LF = '\n'
## generate FV
#
#
class FV (FvClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
FvClassObject.__init__(self)
self.FvInfFile = None
self.FvAddressFile = None
self.BaseAddress = None
self.InfFileName = None
self.FvAddressFileName = None
## AddToBuffer()
#
# Generate Fv and add it to the Buffer
#
# @param self The object pointer
# @param Buffer The buffer generated FV data will be put
# @param BaseAddress base address of FV
# @param BlockSize block size of FV
# @param BlockNum How many blocks in FV
# @param ErasePolarity Flash erase polarity
# @param VtfDict VTF objects
# @param MacroDict macro value pair
# @retval string Generated FV file path
#
def AddToBuffer (self, Buffer, BaseAddress=None, BlockSize= None, BlockNum=None, ErasePloarity='1', VtfDict=None, MacroDict = {}) :
if self.UiFvName.upper() in GenFds.FvBinDict.keys():
return GenFds.FvBinDict[self.UiFvName.upper()]
GenFdsGlobalVariable.InfLogger( "\nGenerating %s FV ..." %self.UiFvName)
self.__InitializeInf__(BaseAddress, BlockSize, BlockNum, ErasePloarity, VtfDict)
#
# First Process the Apriori section
#
MacroDict.update(self.DefineVarDict)
GenFdsGlobalVariable.VerboseLogger('First generate Apriori file !')
FfsFileList = []
for AprSection in self.AprioriSectionList:
FileName = AprSection.GenFfs (self.UiFvName, MacroDict)
FfsFileList.append(FileName)
# Add Apriori file name to Inf file
self.FvInfFile.writelines("EFI_FILE_NAME = " + \
FileName + \
T_CHAR_LF)
# Process Modules in FfsList
for FfsFile in self.FfsList :
FileName = FfsFile.GenFfs(MacroDict)
FfsFileList.append(FileName)
self.FvInfFile.writelines("EFI_FILE_NAME = " + \
FileName + \
T_CHAR_LF)
SaveFileOnChange(self.InfFileName, self.FvInfFile.getvalue(), False)
self.FvInfFile.close()
#
# Call GenFv tool
#
FvOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiFvName)
FvOutputFile = FvOutputFile + '.Fv'
# BUGBUG: FvOutputFile could be specified from FDF file (FV section, CreateFile statement)
if self.CreateFileName != None:
FvOutputFile = self.CreateFileName
FvInfoFileName = os.path.join(GenFdsGlobalVariable.FfsDir, self.UiFvName + '.inf')
shutil.copy(GenFdsGlobalVariable.FvAddressFileName, FvInfoFileName)
GenFdsGlobalVariable.GenerateFirmwareVolume(
FvOutputFile,
[self.InfFileName],
AddressFile=FvInfoFileName,
FfsList=FfsFileList
)
#
# Write the Fv contents to Buffer
#
FvFileObj = open ( FvOutputFile,'r+b')
GenFdsGlobalVariable.InfLogger( "\nGenerate %s FV Successfully" %self.UiFvName)
GenFdsGlobalVariable.SharpCounter = 0
Buffer.write(FvFileObj.read())
FvFileObj.close()
GenFds.FvBinDict[self.UiFvName.upper()] = FvOutputFile
return FvOutputFile
## __InitializeInf__()
#
# Initilize the inf file to create FV
#
# @param self The object pointer
# @param BaseAddress base address of FV
# @param BlockSize block size of FV
# @param BlockNum How many blocks in FV
# @param ErasePolarity Flash erase polarity
# @param VtfDict VTF objects
#
def __InitializeInf__ (self, BaseAddress = None, BlockSize= None, BlockNum = None, ErasePloarity='1', VtfDict=None) :
#
# Create FV inf file
#
self.InfFileName = os.path.join(GenFdsGlobalVariable.FvDir,
self.UiFvName + '.inf')
self.FvInfFile = StringIO.StringIO()
#
# Add [Options]
#
self.FvInfFile.writelines("[options]" + T_CHAR_LF)
if BaseAddress != None :
self.FvInfFile.writelines("EFI_BASE_ADDRESS = " + \
BaseAddress + \
T_CHAR_LF)
if BlockSize != None:
self.FvInfFile.writelines("EFI_BLOCK_SIZE = " + \
'0x%X' %BlockSize + \
T_CHAR_LF)
if BlockNum != None:
self.FvInfFile.writelines("EFI_NUM_BLOCKS = " + \
' 0x%X' %BlockNum + \
T_CHAR_LF)
else:
for BlockSize in self.BlockSizeList :
if BlockSize[0] != None:
self.FvInfFile.writelines("EFI_BLOCK_SIZE = " + \
'0x%X' %BlockSize[0] + \
T_CHAR_LF)
if BlockSize[1] != None:
self.FvInfFile.writelines("EFI_NUM_BLOCKS = " + \
' 0x%X' %BlockSize[1] + \
T_CHAR_LF)
if self.BsBaseAddress != None:
self.FvInfFile.writelines('EFI_BOOT_DRIVER_BASE_ADDRESS = ' + \
'0x%X' %self.BsBaseAddress)
if self.RtBaseAddress != None:
self.FvInfFile.writelines('EFI_RUNTIME_DRIVER_BASE_ADDRESS = ' + \
'0x%X' %self.RtBaseAddress)
#
# Add attribute
#
self.FvInfFile.writelines("[attributes]" + T_CHAR_LF)
self.FvInfFile.writelines("EFI_ERASE_POLARITY = " + \
' %s' %ErasePloarity + \
T_CHAR_LF)
if not (self.FvAttributeDict == None):
for FvAttribute in self.FvAttributeDict.keys() :
self.FvInfFile.writelines("EFI_" + \
FvAttribute + \
' = ' + \
self.FvAttributeDict[FvAttribute] + \
T_CHAR_LF )
if self.FvAlignment != None:
self.FvInfFile.writelines("EFI_FVB2_ALIGNMENT_" + \
self.FvAlignment.strip() + \
" = TRUE" + \
T_CHAR_LF)
if self.FvNameGuid != None:
self.FvInfFile.writelines("EFI_FVNAME_GUID" + \
" = %s" % self.FvNameGuid + \
T_CHAR_LF)
#
# Add [Files]
#
self.FvInfFile.writelines("[files]" + T_CHAR_LF)
if VtfDict != None and self.UiFvName in VtfDict.keys():
self.FvInfFile.writelines("EFI_FILE_NAME = " + \
VtfDict.get(self.UiFvName) + \
T_CHAR_LF)

View File

@@ -0,0 +1,90 @@
## @file
# process FV image section generation
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import Section
import StringIO
from Ffs import Ffs
import subprocess
from GenFdsGlobalVariable import GenFdsGlobalVariable
import os
from CommonDataClass.FdfClass import FvImageSectionClassObject
from Common import EdkLogger
from Common.BuildToolError import *
## generate FV image section
#
#
class FvImageSection(FvImageSectionClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
FvImageSectionClassObject.__init__(self)
## GenSection() method
#
# Generate FV image section
#
# @param self The object pointer
# @param OutputPath Where to place output file
# @param ModuleName Which module this section belongs to
# @param SecNum Index of section
# @param KeyStringList Filter for inputs of section generation
# @param FfsInf FfsInfStatement object that contains this section data
# @param Dict dictionary contains macro and its value
# @retval tuple (Generated file name, section alignment)
#
def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}):
OutputFileList = []
if self.FvFileType != None:
FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FvFileType, self.FvFileExtension)
if IsSect :
return FileList, self.Alignment
Num = SecNum
for FileName in FileList:
OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get("FV_IMAGE"))
GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE')
OutputFileList.append(OutputFile)
return OutputFileList, self.Alignment
#
# Generate Fv
#
if self.FvName != None:
Buffer = StringIO.StringIO('')
Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName)
if Fv != None:
self.Fv = Fv
FvFileName = self.Fv.AddToBuffer(Buffer, MacroDict = Dict)
else:
if self.FvFileName != None:
FvFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FvFileName)
else:
EdkLogger.error("GenFds", GENFDS_ERROR, "FvImageSection Failed! %s NOT found in FDF" % self.FvName)
#
# Prepare the parameter of GenSection
#
OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get("FV_IMAGE"))
GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE')
OutputFileList.append(OutputFile)
return OutputFileList, self.Alignment

View File

@@ -0,0 +1,486 @@
## @file
# generate flash image
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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 optparse import OptionParser
import sys
import os
import linecache
import FdfParser
from Common.BuildToolError import *
from GenFdsGlobalVariable import GenFdsGlobalVariable
from Workspace.WorkspaceDatabase import WorkspaceDatabase
from Workspace.BuildClassObject import PcdClassObject
from Workspace.BuildClassObject import ModuleBuildClassObject
import RuleComplexFile
from EfiSection import EfiSection
import StringIO
import Common.TargetTxtClassObject as TargetTxtClassObject
import Common.ToolDefClassObject as ToolDefClassObject
import Common.DataType
import Common.GlobalData as GlobalData
from Common import EdkLogger
from Common.String import *
from Common.Misc import DirCache,PathClass
## Version and Copyright
versionNumber = "1.0"
__version__ = "%prog Version " + versionNumber
__copyright__ = "Copyright (c) 2007, Intel Corporation All rights reserved."
## Tool entrance method
#
# This method mainly dispatch specific methods per the command line options.
# If no error found, return zero value so the caller of this tool can know
# if it's executed successfully or not.
#
# @retval 0 Tool was successful
# @retval 1 Tool failed
#
def main():
global Options
Options = myOptionParser()
global Workspace
Workspace = ""
ArchList = None
ReturnCode = 0
EdkLogger.Initialize()
try:
if Options.verbose != None:
EdkLogger.SetLevel(EdkLogger.VERBOSE)
GenFdsGlobalVariable.VerboseMode = True
if Options.FixedAddress != None:
GenFdsGlobalVariable.FixedLoadAddress = True
if Options.quiet != None:
EdkLogger.SetLevel(EdkLogger.QUIET)
if Options.debug != None:
EdkLogger.SetLevel(Options.debug + 1)
GenFdsGlobalVariable.DebugLevel = Options.debug
else:
EdkLogger.SetLevel(EdkLogger.INFO)
if (Options.Workspace == None):
EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "WORKSPACE not defined",
ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")
elif not os.path.exists(Options.Workspace):
EdkLogger.error("GenFds", BuildToolError.PARAMETER_INVALID, "WORKSPACE is invalid",
ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")
else:
Workspace = os.path.normcase(Options.Workspace)
GenFdsGlobalVariable.WorkSpaceDir = Workspace
if 'EDK_SOURCE' in os.environ.keys():
GenFdsGlobalVariable.EdkSourceDir = os.path.normcase(os.environ['EDK_SOURCE'])
if (Options.debug):
GenFdsGlobalVariable.VerboseLogger( "Using Workspace:" + Workspace)
os.chdir(GenFdsGlobalVariable.WorkSpaceDir)
if (Options.filename):
FdfFilename = Options.filename
FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename)
else:
EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing FDF filename")
if (Options.BuildTarget):
GenFdsGlobalVariable.TargetName = Options.BuildTarget
else:
EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing build target")
if (Options.ToolChain):
GenFdsGlobalVariable.ToolChainTag = Options.ToolChain
else:
EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing tool chain tag")
if FdfFilename[0:2] == '..':
FdfFilename = os.path.realpath(FdfFilename)
if FdfFilename[1] != ':':
FdfFilename = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename)
if not os.path.exists(FdfFilename):
EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=FdfFilename)
GenFdsGlobalVariable.FdfFile = FdfFilename
GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime(FdfFilename)
if (Options.activePlatform):
ActivePlatform = Options.activePlatform
ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform)
if ActivePlatform[0:2] == '..':
ActivePlatform = os.path.realpath(ActivePlatform)
if ActivePlatform[1] != ':':
ActivePlatform = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform)
if not os.path.exists(ActivePlatform) :
EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist!")
if ActivePlatform.find(Workspace) == -1:
EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist in Workspace!")
ActivePlatform = ActivePlatform.replace(Workspace, '')
if len(ActivePlatform) > 0 :
if ActivePlatform[0] == '\\' or ActivePlatform[0] == '/':
ActivePlatform = ActivePlatform[1:]
else:
EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist!")
else :
EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing active platform")
GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform), Workspace)
BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, "Conf/target.txt"))
if os.path.isfile(BuildConfigurationFile) == True:
TargetTxtClassObject.TargetTxtClassObject(BuildConfigurationFile)
else:
EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=BuildConfigurationFile)
if Options.Macros:
for Pair in Options.Macros:
Pair.strip('"')
List = Pair.split('=')
if len(List) == 2:
FdfParser.InputMacroDict[List[0].strip()] = List[1].strip()
if List[0].strip() == "EFI_SOURCE":
GlobalData.gEfiSource = List[1].strip()
elif List[0].strip() == "EDK_SOURCE":
GlobalData.gEdkSource = List[1].strip()
else:
GlobalData.gEdkGlobal[List[0].strip()] = List[1].strip()
else:
FdfParser.InputMacroDict[List[0].strip()] = None
"""call Workspace build create database"""
os.environ["WORKSPACE"] = Workspace
BuildWorkSpace = WorkspaceDatabase(':memory:', GlobalData.gGlobalDefines)
BuildWorkSpace.InitDatabase()
#
# Get files real name in workspace dir
#
GlobalData.gAllFiles = DirCache(Workspace)
GlobalData.gWorkspace = Workspace
if (Options.archList) :
ArchList = Options.archList.split(',')
else:
# EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing build ARCH")
ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList
TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList) & set(ArchList)
if len(TargetArchList) == 0:
EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList)))
for Arch in ArchList:
GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].OutputDirectory)
if (Options.outputDir):
OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(Options.outputDir)
for Arch in ArchList:
GenFdsGlobalVariable.OutputDirDict[Arch] = OutputDirFromCommandLine
else:
for Arch in ArchList:
GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag)
for Key in GenFdsGlobalVariable.OutputDirDict:
OutputDir = GenFdsGlobalVariable.OutputDirDict[Key]
if OutputDir[0:2] == '..':
OutputDir = os.path.realpath(OutputDir)
if OutputDir[1] != ':':
OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir)
if not os.path.exists(OutputDir):
EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=OutputDir)
GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir
""" Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """
FdfParserObj = FdfParser.FdfParser(FdfFilename)
FdfParserObj.ParseFile()
if FdfParserObj.CycleReferenceCheck():
EdkLogger.error("GenFds", BuildToolError.FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file")
if (Options.uiFdName) :
if Options.uiFdName.upper() in FdfParserObj.Profile.FdDict.keys():
GenFds.OnlyGenerateThisFd = Options.uiFdName
else:
EdkLogger.error("GenFds", BuildToolError.OPTION_VALUE_INVALID,
"No such an FD in FDF file: %s" % Options.uiFdName)
if (Options.uiFvName) :
if Options.uiFvName.upper() in FdfParserObj.Profile.FvDict.keys():
GenFds.OnlyGenerateThisFv = Options.uiFvName
else:
EdkLogger.error("GenFds", BuildToolError.OPTION_VALUE_INVALID,
"No such an FV in FDF file: %s" % Options.uiFvName)
"""Modify images from build output if the feature of loading driver at fixed address is on."""
if GenFdsGlobalVariable.FixedLoadAddress:
GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform)
"""Call GenFds"""
GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)
"""Display FV space info."""
GenFds.DisplayFvSpaceInfo(FdfParserObj)
except FdfParser.Warning, X:
EdkLogger.error(X.ToolName, BuildToolError.FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError = False)
ReturnCode = BuildToolError.FORMAT_INVALID
except FatalError, X:
if Options.debug != None:
import traceback
EdkLogger.quiet(traceback.format_exc())
ReturnCode = X.args[0]
except:
import traceback
EdkLogger.error(
"\nPython",
CODE_ERROR,
"Tools code failure",
ExtraData="Please submit bug report in www.TianoCore.org, attaching following call stack trace!\n",
RaiseError=False
)
EdkLogger.quiet(traceback.format_exc())
ReturnCode = CODE_ERROR
return ReturnCode
gParamCheck = []
def SingleCheckCallback(option, opt_str, value, parser):
if option not in gParamCheck:
setattr(parser.values, option.dest, value)
gParamCheck.append(option)
else:
parser.error("Option %s only allows one instance in command line!" % option)
## Parse command line options
#
# Using standard Python module optparse to parse command line option of this tool.
#
# @retval Opt A optparse.Values object containing the parsed options
# @retval Args Target of build command
#
def myOptionParser():
usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\""
Parser = OptionParser(usage=usage,description=__copyright__,version="%prog " + str(versionNumber))
Parser.add_option("-f", "--file", dest="filename", type="string", help="Name of FDF file to convert", action="callback", callback=SingleCheckCallback)
Parser.add_option("-a", "--arch", dest="archList", help="comma separated list containing one or more of: IA32, X64, IPF, ARM or EBC which should be built, overrides target.txt?s TARGET_ARCH")
Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")
Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")
Parser.add_option("-p", "--platform", type="string", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.",
action="callback", callback=SingleCheckCallback)
Parser.add_option("-w", "--workspace", type="string", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE",
action="callback", callback=SingleCheckCallback)
Parser.add_option("-o", "--outputDir", type="string", dest="outputDir", help="Name of Build Output directory",
action="callback", callback=SingleCheckCallback)
Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.")
Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Buld the FV image using the [FV] section named by UiFvName")
Parser.add_option("-b", "--buildtarget", type="choice", choices=['DEBUG','RELEASE'], dest="BuildTarget", help="Build TARGET is one of list: DEBUG, RELEASE.",
action="callback", callback=SingleCheckCallback)
Parser.add_option("-t", "--tagname", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.",
action="callback", callback=SingleCheckCallback)
Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")
Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.")
(Options, args) = Parser.parse_args()
return Options
## The class implementing the EDK2 flash image generation process
#
# This process includes:
# 1. Collect workspace information, includes platform and module information
# 2. Call methods of Fd class to generate FD
# 3. Call methods of Fv class to generate FV that not belong to FD
#
class GenFds :
FdfParsef = None
# FvName in FDF, FvBinFile name
FvBinDict = {}
OnlyGenerateThisFd = None
OnlyGenerateThisFv = None
## GenFd()
#
# @param OutputDir Output directory
# @param FdfParser FDF contents parser
# @param Workspace The directory of workspace
# @param ArchList The Arch list of platform
#
def GenFd (OutputDir, FdfParser, WorkSpace, ArchList):
GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList)
GenFdsGlobalVariable.VerboseLogger(" Gen Fd !")
if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(GenFds.OnlyGenerateThisFd.upper())
if FdObj != None:
FdObj.GenFd(GenFds.FvBinDict)
elif GenFds.OnlyGenerateThisFv == None:
for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]
FdObj.GenFd(GenFds.FvBinDict)
GenFdsGlobalVariable.VerboseLogger(" Gen FV ! ")
if GenFds.OnlyGenerateThisFv != None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(GenFds.OnlyGenerateThisFv.upper())
if FvObj != None:
Buffer = StringIO.StringIO()
# Get FV base Address
FvObj.AddToBuffer(Buffer, None, GenFds.GetFvBlockSize(FvObj))
Buffer.close()
return
elif GenFds.OnlyGenerateThisFd == None:
for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
Buffer = StringIO.StringIO('')
FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]
# Get FV base Address
FvObj.AddToBuffer(Buffer, None, GenFds.GetFvBlockSize(FvObj))
Buffer.close()
if GenFds.OnlyGenerateThisFv == None and GenFds.OnlyGenerateThisFd == None:
GenFdsGlobalVariable.VerboseLogger(" Gen Capsule !")
for CapsuleObj in GenFdsGlobalVariable.FdfParser.Profile.CapsuleList:
CapsuleObj.GenCapsule()
if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:
GenFdsGlobalVariable.VerboseLogger(" Gen Option ROM !")
for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():
OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]
OptRomObj.AddToBuffer(None)
## GetFvBlockSize()
#
# @param FvObj Whose block size to get
# @retval int Block size value
#
def GetFvBlockSize(FvObj):
DefaultBlockSize = 0x10000
FdObj = None
if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]
if FdObj == None:
for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():
for ElementRegion in ElementFd.RegionList:
if ElementRegion.RegionType == 'FV':
for ElementRegionData in ElementRegion.RegionDataList:
if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:
if FvObj.BlockSizeList != []:
return FvObj.BlockSizeList[0][0]
else:
return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)
if FvObj.BlockSizeList != []:
return FvObj.BlockSizeList[0][0]
return DefaultBlockSize
else:
for ElementRegion in FdObj.RegionList:
if ElementRegion.RegionType == 'FV':
for ElementRegionData in ElementRegion.RegionDataList:
if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:
if FvObj.BlockSizeList != []:
return FvObj.BlockSizeList[0][0]
else:
return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)
return DefaultBlockSize
## DisplayFvSpaceInfo()
#
# @param FvObj Whose block size to get
# @retval None
#
def DisplayFvSpaceInfo(FdfParser):
FvSpaceInfoList = []
MaxFvNameLength = 0
for FvName in FdfParser.Profile.FvDict:
if len(FvName) > MaxFvNameLength:
MaxFvNameLength = len(FvName)
FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map')
if os.path.exists(FvSpaceInfoFileName):
FileLinesList = linecache.getlines(FvSpaceInfoFileName)
TotalFound = False
Total = ''
UsedFound = False
Used = ''
FreeFound = False
Free = ''
for Line in FileLinesList:
NameValue = Line.split('=')
if len(NameValue) == 2:
if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE':
TotalFound = True
Total = NameValue[1].strip()
if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE':
UsedFound = True
Used = NameValue[1].strip()
if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE':
FreeFound = True
Free = NameValue[1].strip()
if TotalFound and UsedFound and FreeFound:
FvSpaceInfoList.append((FvName, Total, Used, Free))
GenFdsGlobalVariable.InfLogger('\nFV Space Information')
for FvSpaceInfo in FvSpaceInfoList:
Name = FvSpaceInfo[0]
TotalSizeValue = long(FvSpaceInfo[1], 0)
UsedSizeValue = long(FvSpaceInfo[2], 0)
FreeSizeValue = long(FvSpaceInfo[3], 0)
GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + str((UsedSizeValue+0.0)/TotalSizeValue)[0:4].lstrip('0.') + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free')
## PreprocessImage()
#
# @param BuildDb Database from build meta data files
# @param DscFile modules from dsc file will be preprocessed
# @retval None
#
def PreprocessImage(BuildDb, DscFile):
PcdDict = BuildDb.BuildObject[DscFile, 'COMMON'].Pcds
PcdValue = ''
for Key in PcdDict:
PcdObj = PcdDict[Key]
if PcdObj.TokenCName == 'PcdBsBaseAddress':
PcdValue = PcdObj.DefaultValue
break
if PcdValue == '':
return
Int64PcdValue = long(PcdValue, 0)
if Int64PcdValue == 0 or Int64PcdValue < -1:
return
TopAddress = 0
if Int64PcdValue > 0:
TopAddress = Int64PcdValue
ModuleDict = BuildDb.BuildObject[DscFile, 'COMMON'].Modules
for Key in ModuleDict:
ModuleObj = BuildDb.BuildObject[Key, 'COMMON']
print ModuleObj.BaseName + ' ' + ModuleObj.ModuleType
##Define GenFd as static function
GenFd = staticmethod(GenFd)
GetFvBlockSize = staticmethod(GetFvBlockSize)
DisplayFvSpaceInfo = staticmethod(DisplayFvSpaceInfo)
PreprocessImage = staticmethod(PreprocessImage)
if __name__ == '__main__':
r = main()
## 0-127 is a safe return range, and 1 is a standard default error
if r < 0 or r > 127: r = 1
sys.exit(r)

View File

@@ -0,0 +1,472 @@
## @file
# Global variables for GenFds
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import os
import sys
import subprocess
import struct
import array
from Common.BuildToolError import *
from Common import EdkLogger
from Common.Misc import SaveFileOnChange
## Global variables
#
#
class GenFdsGlobalVariable:
FvDir = ''
OutputDirDict = {}
BinDir = ''
# will be FvDir + os.sep + 'Ffs'
FfsDir = ''
FdfParser = None
LibDir = ''
WorkSpace = None
WorkSpaceDir = ''
EdkSourceDir = ''
OutputDirFromDscDict = {}
TargetName = ''
ToolChainTag = ''
RuleDict = {}
ArchList = None
VtfDict = {}
ActivePlatform = None
FvAddressFileName = ''
VerboseMode = False
DebugLevel = -1
SharpCounter = 0
SharpNumberPerLine = 40
FdfFile = ''
FdfFileTimeStamp = 0
FixedLoadAddress = False
SectionHeader = struct.Struct("3B 1B")
## SetDir()
#
# @param OutputDir Output directory
# @param FdfParser FDF contents parser
# @param Workspace The directory of workspace
# @param ArchList The Arch list of platform
#
def SetDir (OutputDir, FdfParser, WorkSpace, ArchList):
GenFdsGlobalVariable.VerboseLogger( "GenFdsGlobalVariable.OutputDir :%s" %OutputDir)
# GenFdsGlobalVariable.OutputDirDict = OutputDir
GenFdsGlobalVariable.FdfParser = FdfParser
GenFdsGlobalVariable.WorkSpace = WorkSpace
GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], 'FV')
if not os.path.exists(GenFdsGlobalVariable.FvDir) :
os.makedirs(GenFdsGlobalVariable.FvDir)
GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')
if not os.path.exists(GenFdsGlobalVariable.FfsDir) :
os.makedirs(GenFdsGlobalVariable.FfsDir)
if ArchList != None:
GenFdsGlobalVariable.ArchList = ArchList
T_CHAR_LF = '\n'
#
# Create FV Address inf file
#
GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')
FvAddressFile = open (GenFdsGlobalVariable.FvAddressFileName, 'w')
#
# Add [Options]
#
FvAddressFile.writelines("[options]" + T_CHAR_LF)
BsAddress = '0'
for Arch in ArchList:
if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].BsBaseAddress:
BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].BsBaseAddress
break
FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
BsAddress + \
T_CHAR_LF)
RtAddress = '0'
for Arch in ArchList:
if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].RtBaseAddress:
RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].RtBaseAddress
FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
RtAddress + \
T_CHAR_LF)
FvAddressFile.close()
## ReplaceWorkspaceMacro()
#
# @param String String that may contain macro
#
def ReplaceWorkspaceMacro(String):
Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir)
if os.path.exists(Str):
if not os.path.isabs(Str):
Str = os.path.abspath(Str)
else:
Str = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, String)
return os.path.normpath(Str)
## Check if the input files are newer than output files
#
# @param Output Path of output file
# @param Input Path list of input files
#
# @retval True if Output doesn't exist, or any Input is newer
# @retval False if all Input is older than Output
#
@staticmethod
def NeedsUpdate(Output, Input):
if not os.path.exists(Output):
return True
# always update "Output" if no "Input" given
if Input == None or len(Input) == 0:
return True
# if fdf file is changed after the 'Output" is generated, update the 'Output'
OutputTime = os.path.getmtime(Output)
if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime:
return True
for F in Input:
# always update "Output" if any "Input" doesn't exist
if not os.path.exists(F):
return True
# always update "Output" if any "Input" is newer than "Output"
if os.path.getmtime(F) > OutputTime:
return True
return False
@staticmethod
def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,
GuidHdrLen=None, GuidAttr=None, Ui=None, Ver=None):
if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
return
GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
Cmd = ["GenSec"]
if Type not in [None, '']:
Cmd += ["-s", Type]
if CompressionType not in [None, '']:
Cmd += ["-c", CompressionType]
if Guid != None:
Cmd += ["-g", Guid]
if GuidHdrLen not in [None, '']:
Cmd += ["-l", GuidHdrLen]
if GuidAttr not in [None, '']:
Cmd += ["-r", GuidAttr]
if Ui not in [None, '']:
#Cmd += ["-n", '"' + Ui + '"']
SectionData = array.array('B', [0,0,0,0])
SectionData.fromstring(Ui.encode("utf_16_le"))
SectionData.append(0)
SectionData.append(0)
Len = len(SectionData)
GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15)
SaveFileOnChange(Output, SectionData.tostring())
elif Ver not in [None, '']:
#Cmd += ["-j", Ver]
SectionData = array.array('B', [0,0,0,0])
SectionData.fromstring(Ver.encode("utf_16_le"))
SectionData.append(0)
SectionData.append(0)
Len = len(SectionData)
GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x14)
SaveFileOnChange(Output, SectionData.tostring())
else:
Cmd += ["-o", Output]
Cmd += Input
GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
@staticmethod
def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,
SectionAlign=None):
if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
return
GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
Cmd = ["GenFfs", "-t", Type, "-g", Guid]
if Fixed == True:
Cmd += ["-x"]
if CheckSum:
Cmd += ["-s"]
if Align not in [None, '']:
Cmd += ["-a", Align]
Cmd += ["-o", Output]
for I in range(0, len(Input)):
Cmd += ("-i", Input[I])
if SectionAlign not in [None, '', []] and SectionAlign[I] not in [None, '']:
Cmd += ("-n", SectionAlign[I])
GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")
@staticmethod
def GenerateFirmwareVolume(Output, Input, BaseAddress=None, Capsule=False, Dump=False,
AddressFile=None, MapFile=None, FfsList=[]):
if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList):
return
GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
Cmd = ["GenFv"]
if BaseAddress not in [None, '']:
Cmd += ["-r", BaseAddress]
if Capsule:
Cmd += ["-c"]
if Dump:
Cmd += ["-p"]
if AddressFile not in [None, '']:
Cmd += ["-a", AddressFile]
if MapFile not in [None, '']:
Cmd += ["-m", MapFile]
Cmd += ["-o", Output]
for I in Input:
Cmd += ["-i", I]
GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV")
@staticmethod
def GenerateVtf(Output, Input, BaseAddress=None, FvSize=None):
if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
return
GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
Cmd = ["GenVtf"]
if BaseAddress not in [None, ''] and FvSize not in [None, ''] \
and len(BaseAddress) == len(FvSize):
for I in range(0, len(BaseAddress)):
Cmd += ["-r", BaseAddress[I], "-s", FvSize[I]]
Cmd += ["-o", Output]
for F in Input:
Cmd += ["-f", F]
GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate VTF")
@staticmethod
def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False,
Strip=False, Replace=False, TimeStamp=None, Join=False,
Align=None, Padding=None, Convert=False):
if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
return
GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
Cmd = ["GenFw"]
if Type.lower() == "te":
Cmd += ["-t"]
if SubType not in [None, '']:
Cmd += ["-e", SubType]
if TimeStamp not in [None, '']:
Cmd += ["-s", TimeStamp]
if Align not in [None, '']:
Cmd += ["-a", Align]
if Padding not in [None, '']:
Cmd += ["-p", Padding]
if Zero:
Cmd += ["-z"]
if Strip:
Cmd += ["-l"]
if Replace:
Cmd += ["-r"]
if Join:
Cmd += ["-j"]
if Convert:
Cmd += ["-m"]
Cmd += ["-o", Output]
Cmd += Input
GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")
@staticmethod
def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None,
Revision=None, DeviceId=None, VendorId=None):
# if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
# return
# GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
Cmd = ["EfiRom"]
if len(EfiInput) > 0:
if Compress:
Cmd += ["-ec"]
else:
Cmd += ["-e"]
for EfiFile in EfiInput:
Cmd += [EfiFile]
if len(BinaryInput) > 0:
Cmd += ["-b"]
for BinFile in BinaryInput:
Cmd += [BinFile]
if ClassCode != None:
Cmd += ["-l", ClassCode]
if Revision != None:
Cmd += ["-r", Revision]
if DeviceId != None:
Cmd += ["-i", DeviceId]
if VendorId != None:
Cmd += ["-f", VendorId]
Cmd += ["-o", Output]
GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom")
@staticmethod
def GuidTool(Output, Input, ToolPath, Options=''):
if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
return
GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
Cmd = [ToolPath, Options]
Cmd += ["-o", Output]
Cmd += Input
GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath)
def CallExternalTool (cmd, errorMess):
if type(cmd) not in (tuple, list):
GenFdsGlobalVariable.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool")
if GenFdsGlobalVariable.DebugLevel != -1:
cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel))
GenFdsGlobalVariable.InfLogger (cmd)
if GenFdsGlobalVariable.VerboseMode:
cmd += ('-v',)
GenFdsGlobalVariable.InfLogger (cmd)
else:
sys.stdout.write ('#')
sys.stdout.flush()
GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1
if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0:
sys.stdout.write('\n')
try:
PopenObject = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr= subprocess.PIPE)
except Exception, X:
EdkLogger.error("GenFds", BuildToolError.COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))
(out, error) = PopenObject.communicate()
while PopenObject.returncode == None :
PopenObject.wait()
if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1:
GenFdsGlobalVariable.InfLogger ("Return Value = %d" %PopenObject.returncode)
GenFdsGlobalVariable.InfLogger (out)
GenFdsGlobalVariable.InfLogger (error)
if PopenObject.returncode != 0:
print "###", cmd
EdkLogger.error("GenFds", BuildToolError.COMMAND_FAILURE, errorMess)
def VerboseLogger (msg):
EdkLogger.verbose(msg)
def InfLogger (msg):
EdkLogger.info(msg)
def ErrorLogger (msg, File = None, Line = None, ExtraData = None):
EdkLogger.error('GenFds', BuildToolError.GENFDS_ERROR, msg, File, Line, ExtraData)
def DebugLogger (Level, msg):
EdkLogger.debug(Level, msg)
## ReplaceWorkspaceMacro()
#
# @param Str String that may contain macro
# @param MacroDict Dictionary that contains macro value pair
#
def MacroExtend (Str, MacroDict = {}, Arch = 'COMMON'):
if Str == None :
return None
Dict = {'$(WORKSPACE)' : GenFdsGlobalVariable.WorkSpaceDir,
'$(EDK_SOURCE)' : GenFdsGlobalVariable.EdkSourceDir,
# '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,
'$(TARGET)' : GenFdsGlobalVariable.TargetName,
'$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable.ToolChainTag
}
OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]]
if Arch != 'COMMON' and Arch in GenFdsGlobalVariable.ArchList:
OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch]
Dict['$(OUTPUT_DIRECTORY)'] = OutputDir
if MacroDict != None and len (MacroDict) != 0:
Dict.update(MacroDict)
for key in Dict.keys():
if Str.find(key) >= 0 :
Str = Str.replace (key, Dict[key])
if Str.find('$(ARCH)') >= 0:
if len(GenFdsGlobalVariable.ArchList) == 1:
Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0])
else:
EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str)
return Str
## GetPcdValue()
#
# @param PcdPattern pattern that labels a PCD.
#
def GetPcdValue (PcdPattern):
if PcdPattern == None :
return None
PcdPair = PcdPattern.lstrip('PCD(').rstrip(')').strip().split('.')
TokenSpace = PcdPair[0]
TokenCName = PcdPair[1]
PcdValue = ''
for Platform in GenFdsGlobalVariable.WorkSpace.PlatformList:
PcdDict = Platform.Pcds
for Key in PcdDict:
PcdObj = PcdDict[Key]
if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
if PcdObj.Type != 'FixedAtBuild':
EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
if PcdObj.DatumType != 'VOID*':
EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)
PcdValue = PcdObj.DefaultValue
return PcdValue
for Package in GenFdsGlobalVariable.WorkSpace.PackageList:
PcdDict = Package.Pcds
for Key in PcdDict:
PcdObj = PcdDict[Key]
if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
if PcdObj.Type != 'FixedAtBuild':
EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
if PcdObj.DatumType != 'VOID*':
EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)
PcdValue = PcdObj.DefaultValue
return PcdValue
return PcdValue
SetDir = staticmethod(SetDir)
ReplaceWorkspaceMacro = staticmethod(ReplaceWorkspaceMacro)
CallExternalTool = staticmethod(CallExternalTool)
VerboseLogger = staticmethod(VerboseLogger)
InfLogger = staticmethod(InfLogger)
ErrorLogger = staticmethod(ErrorLogger)
DebugLogger = staticmethod(DebugLogger)
MacroExtend = staticmethod (MacroExtend)
GetPcdValue = staticmethod(GetPcdValue)

View File

@@ -0,0 +1,190 @@
## @file
# process GUIDed section generation
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import Section
import subprocess
from Ffs import Ffs
import os
from GenFdsGlobalVariable import GenFdsGlobalVariable
from CommonDataClass.FdfClass import GuidSectionClassObject
from Common import ToolDefClassObject
import sys
from Common import EdkLogger
from Common.BuildToolError import *
## generate GUIDed section
#
#
class GuidSection(GuidSectionClassObject) :
## The constructor
#
# @param self The object pointer
#
def __init__(self):
GuidSectionClassObject.__init__(self)
## GenSection() method
#
# Generate GUIDed section
#
# @param self The object pointer
# @param OutputPath Where to place output file
# @param ModuleName Which module this section belongs to
# @param SecNum Index of section
# @param KeyStringList Filter for inputs of section generation
# @param FfsInf FfsInfStatement object that contains this section data
# @param Dict dictionary contains macro and its value
# @retval tuple (Generated file name, section alignment)
#
def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}):
#
# Generate all section
#
self.KeyStringList = KeyStringList
self.CurrentArchList = GenFdsGlobalVariable.ArchList
if FfsInf != None:
self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
self.NameGuid = FfsInf.__ExtendMacro__(self.NameGuid)
self.SectionType = FfsInf.__ExtendMacro__(self.SectionType)
self.CurrentArchList = [FfsInf.CurrentArch]
SectFile = tuple()
Index = 0
for Sect in self.SectionList:
Index = Index + 1
SecIndex = '%s.%d' %(SecNum,Index)
ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList,FfsInf, Dict)
if ReturnSectList != []:
for file in ReturnSectList:
SectFile += (file,)
OutputFile = OutputPath + \
os.sep + \
ModuleName + \
'SEC' + \
SecNum + \
Ffs.SectionSuffix['GUIDED']
OutputFile = os.path.normpath(OutputFile)
ExternalTool = None
if self.NameGuid != None:
ExternalTool = self.__FindExtendTool__()
#
# If not have GUID , call default
# GENCRC32 section
#
if self.NameGuid == None :
GenFdsGlobalVariable.VerboseLogger( "Use GenSection function Generate CRC32 Section")
GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType])
OutputFileList = []
OutputFileList.append(OutputFile)
return OutputFileList, self.Alignment
#or GUID not in External Tool List
elif ExternalTool == None:
EdkLogger.error("GenFds", GENFDS_ERROR, "No tool found with GUID %s" % self.NameGuid)
else:
#
# Call GenSection with DUMMY section type.
#
GenFdsGlobalVariable.GenerateSection(OutputFile+".dummy", SectFile)
#
# Use external tool process the Output
#
InputFile = OutputFile+".dummy"
TempFile = OutputPath + \
os.sep + \
ModuleName + \
'SEC' + \
SecNum + \
'.tmp'
TempFile = os.path.normpath(TempFile)
ExternalToolCmd = (
ExternalTool,
'-e',
'-o', TempFile,
InputFile,
)
#
# Call external tool
#
GenFdsGlobalVariable.GuidTool(TempFile, [InputFile], ExternalTool, '-e')
#
# Call Gensection Add Secntion Header
#
Attribute = None
if self.ProcessRequired == True:
Attribute = 'PROCSSING_REQUIRED'
if self.AuthStatusValid == True:
Attribute = 'AUTH_STATUS_VALID'
GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
Guid=self.NameGuid, GuidAttr=Attribute)
OutputFileList = []
OutputFileList.append(OutputFile)
return OutputFileList, self.Alignment
## __FindExtendTool()
#
# Find location of tools to process section data
#
# @param self The object pointer
#
def __FindExtendTool__(self):
# if user not specify filter, try to deduce it from global data.
if self.KeyStringList == None or self.KeyStringList == []:
Target = GenFdsGlobalVariable.TargetName
ToolChain = GenFdsGlobalVariable.ToolChainTag
ToolDb = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.WorkSpaceDir).ToolsDefTxtDatabase
if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:
EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain)
self.KeyStringList = [Target+'_'+ToolChain+'_'+self.CurrentArchList[0]]
for Arch in self.CurrentArchList:
if Target+'_'+ToolChain+'_'+Arch not in self.KeyStringList:
self.KeyStringList.append(Target+'_'+ToolChain+'_'+Arch)
ToolDefinition = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.WorkSpaceDir).ToolsDefTxtDictionary
ToolPathTmp = None
for ToolDef in ToolDefinition.items():
if self.NameGuid == ToolDef[1]:
KeyList = ToolDef[0].split('_')
Key = KeyList[0] + \
'_' + \
KeyList[1] + \
'_' + \
KeyList[2]
if Key in self.KeyStringList and KeyList[4] == 'GUID':
ToolPath = ToolDefinition.get( Key + \
'_' + \
KeyList[3] + \
'_' + \
'PATH')
if ToolPathTmp == None:
ToolPathTmp = ToolPath
else:
if ToolPathTmp != ToolPath:
EdkLogger.error("GenFds", GENFDS_ERROR, "Don't know which tool to use, %s or %s ?" % (ToolPathTmp, ToolPath))
return ToolPathTmp

View File

@@ -0,0 +1,50 @@
## @file
# process OptionROM generation from FILE statement
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import os
from GenFdsGlobalVariable import GenFdsGlobalVariable
##
#
#
class OptRomFileStatement:
## The constructor
#
# @param self The object pointer
#
def __init__(self):
self.FileName = None
self.FileType = None
self.OverrideAttribs = None
## GenFfs() method
#
# Generate FFS
#
# @param self The object pointer
# @param Dict dictionary contains macro and value pair
# @retval string Generated FFS file name
#
def GenFfs(self, Dict = {}):
if self.FileName != None:
self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
return self.FileName

View File

@@ -0,0 +1,147 @@
## @file
# process OptionROM generation from INF statement
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import RuleSimpleFile
import RuleComplexFile
import Section
import OptionRom
import Common.GlobalData as GlobalData
from Common.DataType import *
from Common.String import *
from FfsInfStatement import FfsInfStatement
from GenFdsGlobalVariable import GenFdsGlobalVariable
##
#
#
class OptRomInfStatement (FfsInfStatement):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
FfsInfStatement.__init__(self)
self.OverrideAttribs = None
## __GetOptRomParams() method
#
# Parse inf file to get option ROM related parameters
#
# @param self The object pointer
#
def __GetOptRomParams(self):
if self.OverrideAttribs == None:
self.OverrideAttribs = OptionRom.OverrideAttribs()
if self.OverrideAttribs.PciVendorId == None:
self.OverrideAttribs.PciVendorId = self.OptRomDefs.get ('PCI_VENDOR_ID')
if self.OverrideAttribs.PciClassCode == None:
self.OverrideAttribs.PciClassCode = self.OptRomDefs.get ('PCI_CLASS_CODE')
if self.OverrideAttribs.PciDeviceId == None:
self.OverrideAttribs.PciDeviceId = self.OptRomDefs.get ('PCI_DEVICE_ID')
if self.OverrideAttribs.PciRevision == None:
self.OverrideAttribs.PciRevision = self.OptRomDefs.get ('PCI_REVISION')
# InfObj = GenFdsGlobalVariable.WorkSpace.BuildObject[self.PathClassObj, self.CurrentArch]
# RecordList = InfObj._RawData[MODEL_META_DATA_HEADER, InfObj._Arch, InfObj._Platform]
# for Record in RecordList:
# Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
# Name = Record[0]
## GenFfs() method
#
# Generate FFS
#
# @param self The object pointer
# @retval string Generated .efi file name
#
def GenFfs(self):
#
# Parse Inf file get Module related information
#
self.__InfParse__()
self.__GetOptRomParams()
#
# Get the rule of how to generate Ffs file
#
Rule = self.__GetRule__()
GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName)
#FileType = Ffs.Ffs.ModuleTypeToFileType[Rule.ModuleType]
#
# For the rule only has simpleFile
#
if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) :
EfiOutputList = self.__GenSimpleFileSection__(Rule)
return EfiOutputList
#
# For Rule has ComplexFile
#
elif isinstance(Rule, RuleComplexFile.RuleComplexFile):
EfiOutputList = self.__GenComplexFileSection__(Rule)
return EfiOutputList
## __GenSimpleFileSection__() method
#
# Get .efi files according to simple rule.
#
# @param self The object pointer
# @param Rule The rule object used to generate section
# @retval string File name of the generated section file
#
def __GenSimpleFileSection__(self, Rule):
#
# Prepare the parameter of GenSection
#
OutputFileList = []
if Rule.FileName != None:
GenSecInputFile = self.__ExtendMacro__(Rule.FileName)
OutputFileList.append(GenSecInputFile)
else:
OutputFileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension)
return OutputFileList
## __GenComplexFileSection__() method
#
# Get .efi by sections in complex Rule
#
# @param self The object pointer
# @param Rule The rule object used to generate section
# @retval string File name of the generated section file
#
def __GenComplexFileSection__(self, Rule):
OutputFileList = []
for Sect in Rule.SectionList:
if Sect.SectionType == 'PE32':
if Sect.FileName != None:
GenSecInputFile = self.__ExtendMacro__(Sect.FileName)
OutputFileList.append(GenSecInputFile)
else:
FileList, IsSect = Section.Section.GetFileList(self, '', Sect.FileExtension)
OutputFileList.extend(FileList)
return OutputFileList

View File

@@ -0,0 +1,140 @@
## @file
# process OptionROM generation
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import os
import shutil
import subprocess
import StringIO
import OptRomInfStatement
from GenFdsGlobalVariable import GenFdsGlobalVariable
from GenFds import GenFds
from CommonDataClass.FdfClass import OptionRomClassObject
from Common.Misc import SaveFileOnChange
from Common import EdkLogger
from Common.BuildToolError import *
T_CHAR_LF = '\n'
##
#
#
class OPTIONROM (OptionRomClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
OptionRomClassObject.__init__(self)
## AddToBuffer()
#
# Generate Option ROM
#
# @param self The object pointer
# @param Buffer The buffer generated OptROM data will be put
# @retval string Generated OptROM file path
#
def AddToBuffer (self, Buffer) :
GenFdsGlobalVariable.InfLogger( "\nGenerating %s Option ROM ..." %self.DriverName)
EfiFileList = []
BinFileList = []
# Process Modules in FfsList
for FfsFile in self.FfsList :
if isinstance(FfsFile, OptRomInfStatement.OptRomInfStatement):
FilePathNameList = FfsFile.GenFfs()
if len(FilePathNameList) == 0:
EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s not produce .efi files, so NO file could be put into option ROM." % (FfsFile.InfFileName))
if FfsFile.OverrideAttribs == None:
EfiFileList.extend(FilePathNameList)
else:
FileName = os.path.basename(FilePathNameList[0])
TmpOutputDir = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName)
if not os.path.exists(TmpOutputDir) :
os.makedirs(TmpOutputDir)
TmpOutputFile = os.path.join(TmpOutputDir, FileName+'.tmp')
GenFdsGlobalVariable.GenerateOptionRom(TmpOutputFile,
FilePathNameList,
[],
FfsFile.OverrideAttribs.NeedCompress,
FfsFile.OverrideAttribs.PciClassCode,
FfsFile.OverrideAttribs.PciRevision,
FfsFile.OverrideAttribs.PciDeviceId,
FfsFile.OverrideAttribs.PciVendorId)
BinFileList.append(TmpOutputFile)
else:
FilePathName = FfsFile.GenFfs()
if FfsFile.OverrideAttribs != None:
FileName = os.path.basename(FilePathName)
TmpOutputDir = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName)
if not os.path.exists(TmpOutputDir) :
os.makedirs(TmpOutputDir)
TmpOutputFile = os.path.join(TmpOutputDir, FileName+'.tmp')
GenFdsGlobalVariable.GenerateOptionRom(TmpOutputFile,
[FilePathName],
[],
FfsFile.OverrideAttribs.NeedCompress,
FfsFile.OverrideAttribs.PciClassCode,
FfsFile.OverrideAttribs.PciRevision,
FfsFile.OverrideAttribs.PciDeviceId,
FfsFile.OverrideAttribs.PciVendorId)
BinFileList.append(TmpOutputFile)
else:
if FfsFile.FileType == 'EFI':
EfiFileList.append(FilePathName)
else:
BinFileList.append(FilePathName)
#
# Call EfiRom tool
#
OutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName)
OutputFile = OutputFile + '.rom'
GenFdsGlobalVariable.GenerateOptionRom(
OutputFile,
EfiFileList,
BinFileList
)
GenFdsGlobalVariable.InfLogger( "\nGenerate %s Option ROM Successfully" %self.DriverName)
GenFdsGlobalVariable.SharpCounter = 0
return OutputFile
class OverrideAttribs:
## The constructor
#
# @param self The object pointer
#
def __init__(self):
self.PciVendorId = None
self.PciClassCode = None
self.PciDeviceId = None
self.PciRevision = None
self.NeedCompress = False

View File

@@ -0,0 +1,240 @@
## @file
# process FD Region generation
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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 struct import *
from GenFdsGlobalVariable import GenFdsGlobalVariable
import StringIO
from CommonDataClass.FdfClass import RegionClassObject
import os
from Common import EdkLogger
from Common.BuildToolError import *
## generate Region
#
#
class Region(RegionClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
RegionClassObject.__init__(self)
## AddToBuffer()
#
# Add region data to the Buffer
#
# @param self The object pointer
# @param Buffer The buffer generated region data will be put
# @param BaseAddress base address of region
# @param BlockSize block size of region
# @param BlockNum How many blocks in region
# @param ErasePolarity Flash erase polarity
# @param VtfDict VTF objects
# @param MacroDict macro value pair
# @retval string Generated FV file path
#
def AddToBuffer(self, Buffer, BaseAddress, BlockSizeList, ErasePolarity, FvBinDict, vtfDict = None, MacroDict = {}):
Size = self.Size
GenFdsGlobalVariable.InfLogger('Generate Region at Offset 0x%X' % self.Offset)
GenFdsGlobalVariable.InfLogger(" Region Size = 0x%X" %Size)
GenFdsGlobalVariable.SharpCounter = 0
if self.RegionType == 'FV':
#
# Get Fv from FvDict
#
FvBuffer = StringIO.StringIO('')
RegionBlockSize = self.BlockSizeOfRegion(BlockSizeList)
RegionBlockNum = self.BlockNumOfRegion(RegionBlockSize)
self.FvAddress = int(BaseAddress, 16) + self.Offset
FvBaseAddress = '0x%X' %self.FvAddress
for RegionData in self.RegionDataList:
if RegionData.endswith(".fv"):
RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict)
GenFdsGlobalVariable.InfLogger(' Region FV File Name = .fv : %s'%RegionData)
if RegionData[1] != ':' :
RegionData = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData)
if not os.path.exists(RegionData):
EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData)
BinFile = open (RegionData, 'r+b')
FvBuffer.write(BinFile.read())
if FvBuffer.len > Size:
EdkLogger.error("GenFds", GENFDS_ERROR,
"Size of FV File (%s) is larger than Region Size 0x%X specified." \
% (RegionData, Size))
break
if RegionData.upper() in FvBinDict.keys():
continue
FvObj = None
if RegionData.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(RegionData.upper())
if FvObj != None :
GenFdsGlobalVariable.InfLogger(' Region Name = FV')
#
# Call GenFv tool
#
BlockSize = RegionBlockSize
BlockNum = RegionBlockNum
if FvObj.BlockSizeList != []:
if FvObj.BlockSizeList[0][0] != None:
BlockSize = FvObj.BlockSizeList[0][0]
if FvObj.BlockSizeList[0][1] != None:
BlockNum = FvObj.BlockSizeList[0][1]
self.FvAddress = self.FvAddress + FvBuffer.len
FvAlignValue = self.GetFvAlignValue(FvObj.FvAlignment)
if self.FvAddress % FvAlignValue != 0:
EdkLogger.error("GenFds", GENFDS_ERROR,
"FV (%s) is NOT %s Aligned!" % (FvObj.UiFvName, FvObj.FvAlignment))
FvBaseAddress = '0x%X' %self.FvAddress
FileName = FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, vtfDict)
if FvBuffer.len > Size:
EdkLogger.error("GenFds", GENFDS_ERROR,
"Size of FV (%s) is larger than Region Size 0x%X specified." % (RegionData, Size))
else:
EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (RegionData))
if FvBuffer.len > 0:
Buffer.write(FvBuffer.getvalue())
else:
BinFile = open (FileName, 'rb')
Buffer.write(BinFile.read())
FvBuffer.close()
if self.RegionType == 'FILE':
FvBuffer = StringIO.StringIO('')
for RegionData in self.RegionDataList:
RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict)
GenFdsGlobalVariable.InfLogger(' Region File Name = FILE: %s'%RegionData)
if RegionData[1] != ':' :
RegionData = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData)
if not os.path.exists(RegionData):
EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData)
BinFile = open (RegionData, 'r+b')
FvBuffer.write(BinFile.read())
if FvBuffer.len > Size :
EdkLogger.error("GenFds", GENFDS_ERROR,
"Size of File (%s) large than Region Size " % RegionData)
#
# If File contents less than region size, append "0xff" after it
#
if FvBuffer.len < Size:
for index in range(0, (Size-FvBuffer.len)):
if (ErasePolarity == '1'):
FvBuffer.write(pack('B', int('0xFF', 16)))
else:
FvBuffer.write(pack('B', int('0x00', 16)))
Buffer.write(FvBuffer.getvalue())
FvBuffer.close()
if self.RegionType == 'DATA' :
GenFdsGlobalVariable.InfLogger(' Region Name = DATA')
DataSize = 0
for RegionData in self.RegionDataList:
Data = RegionData.split(',')
DataSize = DataSize + len(Data)
if DataSize > Size:
EdkLogger.error("GenFds", GENFDS_ERROR, "Size of DATA is larger than Region Size ")
else:
for item in Data :
Buffer.write(pack('B', int(item, 16)))
if DataSize < Size:
if (ErasePolarity == '1'):
PadData = 0xFF
else:
PadData = 0
for i in range(Size - DataSize):
Buffer.write(pack('B', PadData))
if self.RegionType == None:
GenFdsGlobalVariable.InfLogger(' Region Name = None')
if (ErasePolarity == '1') :
PadData = 0xFF
else :
PadData = 0
for i in range(0, Size):
Buffer.write(pack('B', PadData))
def GetFvAlignValue(self, Str):
AlignValue = 1
Granu = 1
Str = Str.strip().upper()
if Str.endswith('K'):
Granu = 1024
Str = Str[:-1]
elif Str.endswith('M'):
Granu = 1024*1024
Str = Str[:-1]
elif Str.endswith('G'):
Granu = 1024*1024*1024
Str = Str[:-1]
else:
pass
AlignValue = int(Str)*Granu
return AlignValue
## BlockSizeOfRegion()
#
# @param BlockSizeList List of block information
# @retval int Block size of region
#
def BlockSizeOfRegion(self, BlockSizeList):
Offset = 0x00
BlockSize = 0
for item in BlockSizeList:
Offset = Offset + item[0] * item[1]
GenFdsGlobalVariable.VerboseLogger ("Offset = 0x%X" %Offset)
GenFdsGlobalVariable.VerboseLogger ("self.Offset 0x%X" %self.Offset)
if self.Offset < Offset :
if Offset - self.Offset < self.Size:
EdkLogger.error("GenFds", GENFDS_ERROR,
"Region at Offset 0x%X can NOT fit into Block array with BlockSize %X" \
% (self.Offset, item[0]))
BlockSize = item[0]
GenFdsGlobalVariable.VerboseLogger ("BlockSize = %X" %BlockSize)
return BlockSize
return BlockSize
## BlockNumOfRegion()
#
# @param BlockSize block size of region
# @retval int Block number of region
#
def BlockNumOfRegion (self, BlockSize):
if BlockSize == 0 :
EdkLogger.error("GenFds", GENFDS_ERROR, "Region: %s is not in the FD address scope!" % self.Offset)
BlockNum = self.Size / BlockSize
GenFdsGlobalVariable.VerboseLogger ("BlockNum = 0x%X" %BlockNum)
return BlockNum

View File

@@ -0,0 +1,29 @@
## @file
# Rule object for generating FFS
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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 CommonDataClass.FdfClass import RuleClassObject
## Rule base class
#
#
class Rule(RuleClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
RuleClassObject.__init__(self)

View File

@@ -0,0 +1,30 @@
## @file
# Complex Rule object for generating FFS
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import Rule
from CommonDataClass.FdfClass import RuleComplexFileClassObject
## complex rule
#
#
class RuleComplexFile(RuleComplexFileClassObject) :
## The constructor
#
# @param self The object pointer
#
def __init__(self):
RuleComplexFileClassObject.__init__(self)

View File

@@ -0,0 +1,30 @@
## @file
# Simple Rule object for generating FFS
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import Rule
from CommonDataClass.FdfClass import RuleSimpleFileClassObject
## simple rule
#
#
class RuleSimpleFile (RuleSimpleFileClassObject) :
## The constructor
#
# @param self The object pointer
#
def __init__(self):
RuleSimpleFileClassObject.__init__(self)

View File

@@ -0,0 +1,153 @@
## @file
# section base class
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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 CommonDataClass.FdfClass import SectionClassObject
from GenFdsGlobalVariable import GenFdsGlobalVariable
import os, glob
from Common import EdkLogger
from Common.BuildToolError import *
## section base class
#
#
class Section (SectionClassObject):
SectionType = {
'RAW' : 'EFI_SECTION_RAW',
'FREEFORM' : 'EFI_SECTION_FREEFORM_SUBTYPE_GUID',
'PE32' : 'EFI_SECTION_PE32',
'PIC' : 'EFI_SECTION_PIC',
'TE' : 'EFI_SECTION_TE',
'FV_IMAGE' : 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE',
'DXE_DEPEX' : 'EFI_SECTION_DXE_DEPEX',
'PEI_DEPEX' : 'EFI_SECTION_PEI_DEPEX',
'GUIDED' : 'EFI_SECTION_GUID_DEFINED',
'COMPRESS' : 'EFI_SECTION_COMPRESSION',
'UI' : 'EFI_SECTION_USER_INTERFACE',
'SMM_DEPEX' : 'EFI_SECTION_SMM_DEPEX'
}
BinFileType = {
'GUID' : '.guid',
'ACPI' : '.acpi',
'ASL' : '.asl' ,
'UEFI_APP' : '.app',
'LIB' : '.lib',
'PE32' : '.pe32',
'PIC' : '.pic',
'PEI_DEPEX' : '.depex',
'SEC_PEI_DEPEX' : '.depex',
'TE' : '.te',
'UNI_VER' : '.ver',
'VER' : '.ver',
'UNI_UI' : '.ui',
'UI' : '.ui',
'BIN' : '.bin',
'RAW' : '.raw',
'COMPAT16' : '.comp16',
'FV' : '.fv'
}
SectFileType = {
'SEC_GUID' : '.sec' ,
'SEC_PE32' : '.sec' ,
'SEC_PIC' : '.sec',
'SEC_TE' : '.sec',
'SEC_VER' : '.sec',
'SEC_UI' : '.sec',
'SEC_COMPAT16' : '.sec',
'SEC_BIN' : '.sec'
}
ToolGuid = {
'0xa31280ad-0x481e-0x41b6-0x95e8-0x127f-0x4c984779' : 'TianoCompress',
'0xee4e5898-0x3914-0x4259-0x9d6e-0xdc7b-0xd79403cf' : 'LzmaCompress'
}
## The constructor
#
# @param self The object pointer
#
def __init__(self):
SectionClassObject.__init__(self)
## GenSection() method
#
# virtual function
#
# @param self The object pointer
# @param OutputPath Where to place output file
# @param ModuleName Which module this section belongs to
# @param SecNum Index of section
# @param KeyStringList Filter for inputs of section generation
# @param FfsInf FfsInfStatement object that contains this section data
# @param Dict dictionary contains macro and its value
#
def GenSection(self, OutputPath, GuidName, SecNum, keyStringList, FfsInf = None, Dict = {}):
pass
## GetFileList() method
#
# Generate compressed section
#
# @param self The object pointer
# @param FfsInf FfsInfStatement object that contains file list
# @param FileType File type to get
# @param FileExtension File extension to get
# @param Dict dictionary contains macro and its value
# @retval tuple (File list, boolean)
#
def GetFileList(FfsInf, FileType, FileExtension, Dict = {}):
if FileType in Section.SectFileType.keys() :
IsSect = True
else :
IsSect = False
if FileExtension != None:
Suffix = FileExtension
elif IsSect :
Suffix = Section.SectionType.get(FileType)
else:
Suffix = Section.BinFileType.get(FileType)
if FfsInf == None:
EdkLogger.error("GenFds", GENFDS_ERROR, 'Inf File does not exist!')
FileList = []
if FileType != None:
for File in FfsInf.BinFileList:
if File.Arch == "COMMON" or FfsInf.CurrentArch == File.Arch:
if File.Type == FileType:
if '*' in FfsInf.TargetOverrideList or File.Target == '*' or File.Target in FfsInf.TargetOverrideList or FfsInf.TargetOverrideList == []:
FileList.append(File.Path)
else:
GenFdsGlobalVariable.InfLogger ("\nBuild Target \'%s\' of File %s is not in the Scope of %s specified by INF %s in FDF" %(File.Target, File.File, FfsInf.TargetOverrideList, FfsInf.InfFileName))
else:
GenFdsGlobalVariable.VerboseLogger ("\nFile Type \'%s\' of File %s in %s is not same with file type \'%s\' from Rule in FDF" %(File.Type, File.File, FfsInf.InfFileName, FileType))
else:
GenFdsGlobalVariable.InfLogger ("\nCurrent ARCH \'%s\' of File %s is not in the Support Arch Scope of %s specified by INF %s in FDF" %(FfsInf.CurrentArch, File.File, File.Arch, FfsInf.InfFileName))
if Suffix != None and os.path.exists(FfsInf.EfiOutputPath):
# FileList.extend(glob.glob(os.path.join(FfsInf.EfiOutputPath, "*" + Suffix)))
# Update to search files with suffix in all sub-dirs.
Tuple = os.walk(FfsInf.EfiOutputPath)
for Dirpath, Dirnames, Filenames in Tuple:
for F in Filenames:
if os.path.splitext(F)[1] in (Suffix):
FullName = os.path.join(Dirpath, F)
FileList.append(FullName)
return FileList, IsSect
GetFileList = staticmethod(GetFileList)

View File

@@ -0,0 +1,77 @@
## @file
# process UI section generation
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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
#
import Section
from Ffs import Ffs
import subprocess
import os
from GenFdsGlobalVariable import GenFdsGlobalVariable
from CommonDataClass.FdfClass import UiSectionClassObject
## generate UI section
#
#
class UiSection (UiSectionClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
UiSectionClassObject.__init__(self)
## GenSection() method
#
# Generate UI section
#
# @param self The object pointer
# @param OutputPath Where to place output file
# @param ModuleName Which module this section belongs to
# @param SecNum Index of section
# @param KeyStringList Filter for inputs of section generation
# @param FfsInf FfsInfStatement object that contains this section data
# @param Dict dictionary contains macro and its value
# @retval tuple (Generated file name, section alignment)
#
def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}):
#
# Prepare the parameter of GenSection
#
if FfsInf != None:
self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
self.StringData = FfsInf.__ExtendMacro__(self.StringData)
self.FileName = FfsInf.__ExtendMacro__(self.FileName)
OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get('UI'))
if self.StringData != None :
NameString = self.StringData
elif self.FileName != None:
FileNameStr = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
FileNameStr = GenFdsGlobalVariable.MacroExtend(FileNameStr, Dict)
FileObj = open(FileNameStr, 'r')
NameString = FileObj.read()
NameString = '\"' + NameString + "\""
FileObj.close()
else:
NameString = ''
GenFdsGlobalVariable.GenerateSection(OutputFile, None, 'EFI_SECTION_USER_INTERFACE', Ui=NameString)
OutputFileList = []
OutputFileList.append(OutputFile)
return OutputFileList, self.Alignment

View File

@@ -0,0 +1,82 @@
## @file
# process Version section generation
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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 Ffs import Ffs
import Section
import os
import subprocess
from GenFdsGlobalVariable import GenFdsGlobalVariable
from CommonDataClass.FdfClass import VerSectionClassObject
## generate version section
#
#
class VerSection (VerSectionClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
VerSectionClassObject.__init__(self)
## GenSection() method
#
# Generate version section
#
# @param self The object pointer
# @param OutputPath Where to place output file
# @param ModuleName Which module this section belongs to
# @param SecNum Index of section
# @param KeyStringList Filter for inputs of section generation
# @param FfsInf FfsInfStatement object that contains this section data
# @param Dict dictionary contains macro and its value
# @retval tuple (Generated file name, section alignment)
#
def GenSection(self,OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}):
#
# Prepare the parameter of GenSection
#
if FfsInf != None:
self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
self.BuildNum = FfsInf.__ExtendMacro__(self.BuildNum)
self.StringData = FfsInf.__ExtendMacro__(self.StringData)
self.FileName = FfsInf.__ExtendMacro__(self.FileName)
OutputFile = os.path.join(OutputPath,
ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get('VERSION'))
OutputFile = os.path.normpath(OutputFile)
# Get String Data
StringData = ''
if self.StringData != None:
StringData = self.StringData
elif self.FileName != None:
FileNameStr = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
FileNameStr = GenFdsGlobalVariable.MacroExtend(FileNameStr, Dict)
FileObj = open(FileNameStr, 'r')
StringData = FileObj.read()
StringData = '"' + StringData + '"'
FileObj.close()
else:
StringData = ''
GenFdsGlobalVariable.GenerateSection(OutputFile, None, 'EFI_SECTION_VERSION',
Ui=StringData, Ver=self.BuildNum)
OutputFileList = []
OutputFileList.append(OutputFile)
return OutputFileList, self.Alignment

View File

@@ -0,0 +1,188 @@
## @file
# process VTF generation
#
# Copyright (c) 2007, Intel Corporation
#
# All rights reserved. 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 GenFdsGlobalVariable import GenFdsGlobalVariable
import os
from CommonDataClass.FdfClass import VtfClassObject
T_CHAR_LF = '\n'
## generate VTF
#
#
class Vtf (VtfClassObject):
## The constructor
#
# @param self The object pointer
#
def __init__(self):
VtfClassObject.__init__(self)
## GenVtf() method
#
# Generate VTF
#
# @param self The object pointer
# @param FdAddressDict dictionary contains FV name and its base address
# @retval Dict FV and corresponding VTF file name
#
def GenVtf(self, FdAddressDict) :
self.GenBsfInf()
OutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiName + '.Vtf')
BaseAddArg = self.GetBaseAddressArg(FdAddressDict)
OutputArg, VtfRawDict = self.GenOutputArg()
Cmd = (
'GenVtf',
) + OutputArg + (
'-f', self.BsfInfName,
) + BaseAddArg
GenFdsGlobalVariable.CallExternalTool(Cmd, "GenFv -Vtf Failed!")
GenFdsGlobalVariable.SharpCounter = 0
return VtfRawDict
## GenBsfInf() method
#
# Generate inf used to generate VTF
#
# @param self The object pointer
#
def GenBsfInf (self):
FvList = self.GetFvList()
self.BsfInfName = os.path.join(GenFdsGlobalVariable.FvDir, self.UiName + '.inf')
BsfInf = open (self.BsfInfName, 'w+')
BsfInf.writelines ("[COMPONENTS]" + T_CHAR_LF)
for ComponentObj in self.ComponentStatementList :
BsfInf.writelines ("COMP_NAME" + \
" = " + \
ComponentObj.CompName + \
T_CHAR_LF )
if ComponentObj.CompLoc.upper() == 'NONE':
BsfInf.writelines ("COMP_LOC" + \
" = " + \
'N' + \
T_CHAR_LF )
elif ComponentObj.FilePos != None:
BsfInf.writelines ("COMP_LOC" + \
" = " + \
ComponentObj.FilePos + \
T_CHAR_LF )
else:
Index = FvList.index(ComponentObj.CompLoc.upper())
if Index == 0:
BsfInf.writelines ("COMP_LOC" + \
" = " + \
'F' + \
T_CHAR_LF )
elif Index == 1:
BsfInf.writelines ("COMP_LOC" + \
" = " + \
'S' + \
T_CHAR_LF )
BsfInf.writelines ("COMP_TYPE" + \
" = " + \
ComponentObj.CompType + \
T_CHAR_LF )
BsfInf.writelines ("COMP_VER" + \
" = " + \
ComponentObj.CompVer + \
T_CHAR_LF )
BsfInf.writelines ("COMP_CS" + \
" = " + \
ComponentObj.CompCs + \
T_CHAR_LF )
BinPath = ComponentObj.CompBin
if BinPath != '-':
BinPath = GenFdsGlobalVariable.MacroExtend(GenFdsGlobalVariable.ReplaceWorkspaceMacro(BinPath))
BsfInf.writelines ("COMP_BIN" + \
" = " + \
BinPath + \
T_CHAR_LF )
SymPath = ComponentObj.CompSym
if SymPath != '-':
SymPath = GenFdsGlobalVariable.MacroExtend(GenFdsGlobalVariable.ReplaceWorkspaceMacro(SymPath))
BsfInf.writelines ("COMP_SYM" + \
" = " + \
SymPath + \
T_CHAR_LF )
BsfInf.writelines ("COMP_SIZE" + \
" = " + \
ComponentObj.CompSize + \
T_CHAR_LF )
BsfInf.writelines (T_CHAR_LF )
BsfInf.close()
## GenFvList() method
#
# Get FV list referenced by VTF components
#
# @param self The object pointer
#
def GetFvList(self):
FvList = []
for component in self.ComponentStatementList :
if component.CompLoc.upper() != 'NONE' and not (component.CompLoc.upper() in FvList):
FvList.append(component.CompLoc.upper())
return FvList
## GetBaseAddressArg() method
#
# Get base address arguments for GenVtf
#
# @param self The object pointer
#
def GetBaseAddressArg(self, FdAddressDict):
FvList = self.GetFvList()
CmdStr = tuple()
for i in FvList:
(BaseAddress, Size) = FdAddressDict.get(i)
CmdStr += (
'-r', '0x%x' % BaseAddress,
'-s', '0x%x' %Size,
)
return CmdStr
## GenOutputArg() method
#
# Get output arguments for GenVtf
#
# @param self The object pointer
#
def GenOutputArg(self):
FvVtfDict = {}
OutputFileName = ''
FvList = self.GetFvList()
Index = 0
Arg = tuple()
for FvObj in FvList:
Index = Index + 1
OutputFileName = 'Vtf%d.raw' % Index
OutputFileName = os.path.join(GenFdsGlobalVariable.FvDir, OutputFileName)
Arg += ('-o', OutputFileName)
FvVtfDict[FvObj.upper()] = OutputFileName
return Arg, FvVtfDict

View File

@@ -0,0 +1,89 @@
!IFNDEF PYTHON_FREEZER_PATH
!ERROR PYTHON_FREEZER_PATH must be defined!
!ENDIF
FREEZE=$(PYTHON_FREEZER_PATH)\FreezePython.exe
MODULES=encodings.cp437,encodings.gbk,encodings.utf_16,encodings.utf_8,encodings.utf_16_le,encodings.latin_1
BIN_DIR=$(EDK_TOOLS_PATH)\Bin\Win32
APPLICATIONS=$(BIN_DIR)\build.exe $(BIN_DIR)\GenFds.exe $(BIN_DIR)\Trim.exe $(BIN_DIR)\MigrationMsa2Inf.exe $(BIN_DIR)\Fpd2Dsc.exe $(BIN_DIR)\TargetTool.exe $(BIN_DIR)\spd2dec.exe $(BIN_DIR)\GenDepex.exe
COMMON_PYTHON=$(BASE_TOOLS_PATH)\Source\Python\Common\BuildToolError.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\Database.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\DataType.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\DecClassObject.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\DecClassObjectLight.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\Dictionary.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\DscClassObject.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\EdkIIWorkspace.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\EdkIIWorkspaceBuild.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\EdkLogger.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\FdfClassObject.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\FdfParserLite.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\GlobalData.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\Identification.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\InfClassObject.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\InfClassObjectLight.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\MigrationUtilities.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\Misc.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\Parsing.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\String.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\TargetTxtClassObject.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\ToolDefClassObject.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\XmlParser.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\XmlRoutines.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\__init__.py \
$(BASE_TOOLS_PATH)\Source\Python\Workspace\BuildClassObject.py \
$(BASE_TOOLS_PATH)\Source\Python\Workspace\MetaDataTable.py \
$(BASE_TOOLS_PATH)\Source\Python\Workspace\MetaFileParser.py \
$(BASE_TOOLS_PATH)\Source\Python\Workspace\MetaFileTable.py \
$(BASE_TOOLS_PATH)\Source\Python\Workspace\WorkspaceDatabase.py \
$(BASE_TOOLS_PATH)\Source\Python\Workspace\__init__.py \
$(BASE_TOOLS_PATH)\Source\Python\Autogen\AutoGen.py \
$(BASE_TOOLS_PATH)\Source\Python\Autogen\BuildEngine.py \
$(BASE_TOOLS_PATH)\Source\Python\Autogen\GenC.py \
$(BASE_TOOLS_PATH)\Source\Python\Autogen\GenDepex.py \
$(BASE_TOOLS_PATH)\Source\Python\Autogen\GenMake.py \
$(BASE_TOOLS_PATH)\Source\Python\Autogen\StrGather.py \
$(BASE_TOOLS_PATH)\Source\Python\Autogen\UniClassObject.py \
$(BASE_TOOLS_PATH)\Source\Python\Autogen\__init__.py
all: SetPythonPath $(APPLICATIONS)
SetPythonPath:
set PYTHONPATH=$(BASE_TOOLS_PATH)\Source\Python
$(BIN_DIR)\build.exe: $(BASE_TOOLS_PATH)\Source\Python\build\build.py $(COMMON_PYTHON)
@pushd . & @cd build & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) build.py & @popd
$(BIN_DIR)\GenFds.exe: $(BASE_TOOLS_PATH)\Source\Python\GenFds\GenFds.py $(COMMON_PYTHON)
@pushd . & @cd GenFds & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) GenFds.py & @popd
$(BIN_DIR)\Trim.exe: $(BASE_TOOLS_PATH)\Source\Python\Trim\Trim.py $(COMMON_PYTHON)
@pushd . & @cd Trim & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) Trim.py & @popd
$(BIN_DIR)\MigrationMsa2Inf.exe: $(BASE_TOOLS_PATH)\Source\Python\MigrationMsa2Inf\MigrationMsa2Inf.py
@pushd . & @cd MigrationMsa2Inf & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) MigrationMsa2Inf.py & @popd
$(BIN_DIR)\Fpd2Dsc.exe: $(BASE_TOOLS_PATH)\Source\Python\Fpd2Dsc\Fpd2Dsc.py $(COMMON_PYTHON)
@pushd . & @cd Fpd2Dsc & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) Fpd2Dsc.py & @popd
$(BIN_DIR)\spd2dec.exe: $(BASE_TOOLS_PATH)\Source\Python\spd2dec\Spd2Dec.py $(COMMON_PYTHON)
@pushd . & @cd Spd2Dec & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) Spd2Dec.py & @popd
$(BIN_DIR)\GenDepex.exe: $(BASE_TOOLS_PATH)\Source\Python\AutoGen\GenDepex.py $(COMMON_PYTHON)
@pushd . & @cd AutoGen & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) GenDepex.py & @popd
$(BIN_DIR)\TargetTool.exe: $(BASE_TOOLS_PATH)\Source\Python\TargetTool\TargetTool.py $(COMMON_PYTHON)
@pushd . & @cd TargetTool & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) TargetTool.py & @popd
clean:
cleanall:
@del /f /q $(BIN_DIR)\*.pyd $(BIN_DIR)\*.dll
@for %%i in ($(APPLICATIONS)) do @del /f /q %%i

View File

@@ -0,0 +1,369 @@
#!/usr/bin/env python
#
#
# Copyright (c) 2007, Intel Corporation
# All rights reserved. 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
#
import re, os, glob
from Common.XmlRoutines import *
#"ModuleType"=>(PackageGuid, headerFileName) List
HeaderFiles = {}
GuidList = []
GuidMap = {}
HeaderFileContents = {}
gTest = {}
GuidMacro2CName = {}
GuidAliasList = []
def collectIncludeFolder(pkgDirName, guidType, pkgName):
includeFolder = os.path.join(pkgDirName, "Include", guidType)
if os.path.exists(includeFolder) and os.path.isdir(includeFolder):
for headerFileName in os.listdir(includeFolder):
if headerFileName[-2:] == ".h":
headerFile = open(os.path.join(includeFolder, headerFileName))
HeaderFileContents[(guidType, headerFileName, pkgName)] = headerFile.read()
headerFile.close()
GuidMacroReg = re.compile(r"\b(?!EFI_GUID\b)[A-Z0-9_]+_GUID\b")
GuidCNameReg = re.compile(r"\bg\w+Guid\b")
GuidAliasReg = re.compile(r"#define\s+([A-Z0-9_]+_GUID)\s+([A-Z0-9_]+_GUID)\b")
def collectPackageInfo(spdFileName):
pkgDirName = os.path.dirname(spdFileName)
spd = XmlParseFile(spdFileName)
pkgName = XmlElement(spd, "/PackageSurfaceArea/SpdHeader/PackageName")
pkgGuid = XmlElement(spd, "/PackageSurfaceArea/SpdHeader/GuidValue")
for IncludePkgHeader in XmlList(spd, "/PackageSurfaceArea/PackageHeaders/IncludePkgHeader"):
moduleType = XmlAttribute(IncludePkgHeader, "ModuleType")
headerFilePath = XmlElementData(IncludePkgHeader)
headerFilePath = re.sub("Include/", "", headerFilePath, 1)
headerTuple = HeaderFiles.get(moduleType, [])
headerTuple.append((pkgGuid, headerFilePath))
HeaderFiles[moduleType] = headerTuple
guidTypes = ["Guid", "Protocol", "Ppi"]
for guidType in guidTypes:
for guidEntry in XmlList(spd, "/PackageSurfaceArea/" + guidType + "Declarations/Entry"):
guidCName = XmlElement(guidEntry, "Entry/C_Name")
GuidList.append(guidCName)
collectIncludeFolder(pkgDirName, guidType, pkgName)
for DecFile in glob.glob(os.path.join(pkgDirName, "*.dec")):
fileContents = open(DecFile).read()
for GuidCNameMatch in GuidCNameReg.finditer(fileContents):
GuidCName = GuidCNameMatch.group(0)
if GuidCName not in GuidList:
GuidList.append(GuidCName)
def AddGuidMacro2GuidCName(GuidMacros, GuidCNames):
for GuidMacro in GuidMacros:
GuessGuidCName = "g" + GuidMacro.lower().title().replace("_", "")
if GuessGuidCName in GuidCNames:
GuidMacro2CName[GuidMacro] = GuessGuidCName
elif len(GuidCNames) == 1:
GuidMacro2CName[GuidMacro] = GuidCNames[0]
else:
for GuidCName in GuidCNames:
if GuidCName.lower() == GuessGuidCName.lower():
GuidMacro2CName[GuidMacro] = GuidCName
break
else:
pass
#print "No matching GuidMacro %s" % GuidMacro
def TranslateGuid(GuidMacroMatch):
GuidMacro = GuidMacroMatch.group(0)
return GuidMacro2CName.get(GuidMacro, GuidMacro)
DepexReg = re.compile(r"DEPENDENCY_START(.*?)DEPENDENCY_END", re.DOTALL)
def TranslateDpxSection(fileContents):
DepexMatch = DepexReg.search(fileContents)
if not DepexMatch:
return "", []
fileContents = DepexMatch.group(1)
fileContents = re.sub(r"\s+", " ", fileContents).strip()
fileContents = GuidMacroReg.sub(TranslateGuid, fileContents)
return fileContents, GuidMacroReg.findall(fileContents)
def InitializeAutoGen(workspace, db):
for spdFile in XmlList(db, "/FrameworkDatabase/PackageList/Filename"):
spdFileName = XmlElementData(spdFile)
collectPackageInfo(os.path.join(workspace, spdFileName))
BlockCommentReg = re.compile(r"/\*.*?\*/", re.DOTALL)
LineCommentReg = re.compile(r"//.*")
GuidReg = re.compile(r"\b(" + '|'.join(GuidList) + r")\b")
for headerFile in HeaderFileContents:
Contents = HeaderFileContents[headerFile]
Contents = BlockCommentReg.sub("", Contents)
Contents = LineCommentReg.sub("", Contents)
FoundGuids = GuidReg.findall(Contents)
for FoundGuid in FoundGuids:
GuidMap[FoundGuid] = "%s/%s" % (headerFile[0], headerFile[1])
#print "%-40s %s/%s" % (FoundGuid, headerFile[0], headerFile[1])
GuidMacros = GuidMacroReg.findall(Contents)
GuidCNames = GuidCNameReg.findall(Contents)
for GuidAliasMatch in GuidAliasReg.finditer(Contents):
Name1, Name2 = GuidAliasMatch.group(1), GuidAliasMatch.group(2)
GuidAliasList.append((Name1, Name2))
AddGuidMacro2GuidCName(GuidMacros, GuidCNames)
def AddSystemIncludeStatement(moduleType, PackageList):
IncludeStatement = "\n"
headerList = HeaderFiles.get(moduleType, [])
for pkgGuid in PackageList:
for pkgTuple in headerList:
if pkgTuple[0] == pkgGuid:
IncludeStatement += "#include <%s>\n" % pkgTuple[1]
return IncludeStatement
def AddLibraryClassStatement(LibraryClassList):
IncludeStatement = "\n"
for LibraryClass in LibraryClassList:
IncludeStatement += "#include <Library/%s.h>\n" % LibraryClass
return IncludeStatement
def AddGuidStatement(GuidList):
IncludeStatement = "\n"
GuidIncludeSet = {}
for Guid in GuidList:
if Guid in GuidMap:
GuidIncludeSet[GuidMap[Guid]] = 1
else:
print "GUID CName: %s cannot be found in any public header file" % Guid
for GuidInclude in GuidIncludeSet:
IncludeStatement += "#include <%s>\n" % GuidInclude
return IncludeStatement
DriverBindingMap = {
"gEfiDriverBindingProtocolGuid" : "EFI_DRIVER_BINDING_PROTOCOL",
"gEfiComponentNameProtocolGuid" : "EFI_COMPONENT_NAME_PROTOCOL",
"gEfiDriverConfigurationProtocolGuid" : "EFI_DRIVER_CONFIGURATION_PROTOCOL",
"gEfiDriverDiagnosticProtocolGuid" : "EFI_DRIVER_CONFIGURATION_PROTOCOL"
}
def AddDriverBindingProtocolStatement(AutoGenDriverModel):
InstallStatement = "\n"
DBindingHandle = "ImageHandle"
GlobalDeclaration = "\n"
for DriverModelItem in AutoGenDriverModel:
if DriverModelItem[1] == "NULL" and DriverModelItem[2] == "NULL" and DriverModelItem[3] == "NULL":
InstallStatement += " Status = EfiLibInstallDriverBinding (\n"
InstallStatement += " ImageHandle,\n"
InstallStatement += " SystemTable,\n"
InstallStatement += " %s,\n" % DriverModelItem[0]
InstallStatement += " %s\n" % DBindingHandle
InstallStatement += " );\n"
else:
InstallStatement += " Status = EfiLibInstallAllDriverProtocols (\n"
InstallStatement += " ImageHandle,\n"
InstallStatement += " SystemTable,\n"
InstallStatement += " %s,\n" % DriverModelItem[0]
InstallStatement += " %s,\n" % DBindingHandle
InstallStatement += " %s,\n" % DriverModelItem[1]
InstallStatement += " %s,\n" % DriverModelItem[2]
InstallStatement += " %s\n" % DriverModelItem[3]
InstallStatement += " );\n"
InstallStatement += " ASSERT_EFI_ERROR (Status);\n\n"
GlobalDeclaration += "extern EFI_DRIVER_BINDING_PROTOCOL %s;\n" % DriverModelItem[0][1:]
if (DriverModelItem[1] != "NULL"):
GlobalDeclaration += "extern EFI_COMPONENT_NAME_PROTOCOL %s;\n" % DriverModelItem[1][1:]
if (DriverModelItem[2] != "NULL"):
GlobalDeclaration += "extern EFI_DRIVER_CONFIGURATION_PROTOCOL %s;\n" % DriverModelItem[2][1:]
if (DriverModelItem[3] != "NULL"):
GlobalDeclaration += "extern EFI_DRIVER_CONFIGURATION_PROTOCOL %s;\n" % DriverModelItem[3][1:]
DBindingHandle = "NULL"
return (InstallStatement, "", "", GlobalDeclaration)
EventDeclarationTemplate = """
//
// Declaration for callback Event.
//
VOID
EFIAPI
%s (
IN EFI_EVENT Event,
IN VOID *Context
);
"""
def AddBootServiceEventStatement(EventList):
FinalEvent = ""
if len(EventList) > 1:
print "Current prototype does not support multi boot service event"
else:
FinalEvent = EventList[0]
CreateStatement = "\n"
CreateStatement += " Status = gBS->CreateEvent (\n"
CreateStatement += " EVT_SIGNAL_EXIT_BOOT_SERVICES,\n"
CreateStatement += " EFI_TPL_NOTIFY,\n"
CreateStatement += " " + FinalEvent + ",\n"
CreateStatement += " NULL,\n"
CreateStatement += " &mExitBootServicesEvent\n"
CreateStatement += " );\n"
CreateStatement += " ASSERT_EFI_ERROR (Status);\n"
GlobalDefinition = "\n"
GlobalDefinition += "STATIC EFI_EVENT mExitBootServicesEvent = NULL;\n"
GlobalDeclaration = EventDeclarationTemplate % FinalEvent
DestroyStatement = "\n"
DestroyStatement += " Status = gBS->CloseEvent (mExitBootServicesEvent);\n"
DestroyStatement += " ASSERT_EFI_ERROR (Status);\n"
return (CreateStatement, "", GlobalDefinition, GlobalDeclaration)
def AddVirtualAddressEventStatement(EventList):
FinalEvent = ""
if len(EventList) > 1:
print "Current prototype does not support multi virtual address change event"
else:
FinalEvent = EventList[0]
CreateStatement = "\n"
CreateStatement += " Status = gBS->CreateEvent (\n"
CreateStatement += " EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,\n"
CreateStatement += " TPL_NOTIFY,\n"
CreateStatement += " " + FinalEvent + ",\n"
CreateStatement += " NULL,\n"
CreateStatement += " &mVirtualAddressChangedEvent\n"
CreateStatement += " );\n"
CreateStatement += " ASSERT_EFI_ERROR (Status);\n"
GlobalDefinition = "\n"
GlobalDefinition += "STATIC EFI_EVENT mVirtualAddressChangedEvent = NULL;\n"
GlobalDeclaration = EventDeclarationTemplate % FinalEvent
DestroyStatement = "\n"
DestroyStatement += " Status = gBS->CloseEvent (mVirtualAddressChangedEvent);\n"
DestroyStatement += " ASSERT_EFI_ERROR (Status);\n"
return (CreateStatement, "", GlobalDefinition, GlobalDeclaration)
EntryPointDeclarationTemplate = """
//
// Declaration for original Entry Point.
//
EFI_STATUS
EFIAPI
%s (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
"""
EntryPointHeader = r"""
/**
The user Entry Point for module %s. The user code starts with this function.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully.
@retval other Some error occurs when executing this entry point.
**/
"""
def AddNewEntryPointContentsStatement (moduleName, EntryPoint, InstallStatement = ""):
if EntryPoint != "Initialize%s" % moduleName:
NewEntryPoint = "Initialize%s" % moduleName
else:
NewEntryPoint = "NewInitialize%s" % moduleName
EntryPointContents = EntryPointHeader % moduleName
EntryPointContents += "EFI_STATUS\n"
EntryPointContents += "EFIAPI\n"
EntryPointContents += NewEntryPoint + "(\n"
EntryPointContents += " IN EFI_HANDLE ImageHandle,\n"
EntryPointContents += " IN EFI_SYSTEM_TABLE *SystemTable\n"
EntryPointContents += " )\n"
EntryPointContents += "{\n"
EntryPointContents += " EFI_STATUS Status;\n"
EntryPointContents += InstallStatement + "\n"
GlobalDeclaration = ""
if EntryPoint != "":
EntryPointContents += " //\n // Call the original Entry Point\n //\n"
EntryPointContents += " Status = %s (ImageHandle, SystemTable);\n\n" % EntryPoint
GlobalDeclaration += EntryPointDeclarationTemplate % EntryPoint
EntryPointContents += " return Status;\n"
EntryPointContents += "}\n"
return (NewEntryPoint, EntryPointContents, GlobalDeclaration)
reFileHeader = re.compile(r"^\s*/\*.*?\*/\s*", re.DOTALL)
reNext = re.compile(r"#ifndef\s*(\w+)\s*#define\s*\1\s*")
def AddCommonInclusionStatement(fileContents, includeStatement):
if includeStatement in fileContents:
return fileContents
insertPos = 0
matchFileHeader = reFileHeader.search(fileContents)
if matchFileHeader:
insertPos = matchFileHeader.end()
matchFileHeader = reNext.search(fileContents, insertPos)
if matchFileHeader:
insertPos = matchFileHeader.end()
includeStatement = "\n%s\n\n" % includeStatement
fileContents = fileContents[0:insertPos] + includeStatement + fileContents[insertPos:]
return fileContents
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
if __name__ == '__main__':
pass

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More