diff options
Diffstat (limited to 'BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel')
6 files changed, 1595 insertions, 1595 deletions
diff --git a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/__init__.py b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/__init__.py index 57dfebde59..a7909346f3 100644 --- a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/__init__.py +++ b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/__init__.py @@ -1,6 +1,6 @@ -## @file
-#
-# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
+## @file +# +# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# diff --git a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/doxygen.py b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/doxygen.py index a8f87751a0..b3198d5bc9 100644 --- a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/doxygen.py +++ b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/doxygen.py @@ -1,445 +1,445 @@ -## @file
-#
-# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-from __future__ import print_function
-from __future__ import absolute_import
-import os
-
-from .message import *
-
-class BaseDoxygeItem:
- def __init__(self, name, tag=''):
- self.mName = name
- self.mTag = tag
- self.mDescription = ''
- self.mText = []
-
- def AddDescription(self, desc):
- self.mDescription = '%s%s' % (self.mDescription, desc)
-
- def __str__(self):
- return '\n'.join(self.mText)
-
- def Generate(self):
- """This interface need to be override"""
-
-class Section(BaseDoxygeItem):
- def Generate(self):
- """This interface need to be override"""
- if len(self.mTag) != 0:
- self.mText.append(' \section %s %s' % (self.mName, self.mTag))
- else:
- self.mText.append(' \section %s' % self.mName)
-
- self.mText.append(self.mDescription)
- return self.mText
-
-class Page(BaseDoxygeItem):
- def __init__(self, name, tag=None, isSort=True):
- BaseDoxygeItem.__init__(self, name, tag)
- self.mSubPages = []
- self.mIsMainPage = False
- self.mSections = []
- self.mIsSort = isSort
-
- def GetSubpageCount(self):
- return len(self.mSubPages)
-
- def AddPage(self, subpage):
- self.mSubPages.append(subpage)
- return subpage
-
- def AddPages(self, pageArray):
- if pageArray is None:
- return
- for page in pageArray:
- self.AddPage(page)
-
- def AddSection(self, section):
- self.mSections.append(section)
- self.mSections.sort(key=lambda x: x.mName.lower())
-
- def Generate(self):
- if self.mIsMainPage:
- self.mText.append('/** \mainpage %s' % self.mName)
- self.mIsSort = False
- else:
- self.mText.append('/** \page %s %s' % (self.mTag, self.mName))
-
- if len(self.mDescription) != 0:
- self.mText.append(self.mDescription)
- endIndex = len(self.mText)
-
- self.mSections.sort(key=lambda x: x.mName.lower())
- for sect in self.mSections:
- self.mText += sect.Generate()
-
- endIndex = len(self.mText)
-
- if len(self.mSubPages) != 0:
- self.mText.insert(endIndex, "<p> \section content_index INDEX")
- endIndex = len(self.mText)
- self.mText.insert(endIndex, '<ul>')
- endIndex += 1
- if self.mIsSort:
- self.mSubPages.sort(key=lambda x: x.mName.lower())
- for page in self.mSubPages:
- self.mText.insert(endIndex, '<li>\subpage %s \"%s\" </li>' % (page.mTag, page.mName))
- endIndex += 1
- self.mText += page.Generate()
- self.mText.insert(endIndex, '</ul>')
- endIndex += 1
- self.mText.insert(endIndex, ' **/')
- return self.mText
-
-class DoxygenFile(Page):
- def __init__(self, name, file):
- Page.__init__(self, name)
- self.mFilename = file
- self.mIsMainPage = True
-
- def GetFilename(self):
- return self.mFilename.replace('/', '\\')
-
- def Save(self):
- str = self.Generate()
- try:
- f = open(self.mFilename, 'w')
- f.write('\n'.join(str))
- f.close()
- except IOError as e:
- ErrorMsg ('Fail to write file %s' % self.mFilename)
- return False
-
- return True
-
-doxygenConfigTemplate = """
-DOXYFILE_ENCODING = UTF-8
-PROJECT_NAME = %(ProjectName)s
-PROJECT_NUMBER = %(ProjectVersion)s
-OUTPUT_DIRECTORY = %(OutputDir)s
-CREATE_SUBDIRS = YES
-OUTPUT_LANGUAGE = English
-BRIEF_MEMBER_DESC = YES
-REPEAT_BRIEF = YES
-ABBREVIATE_BRIEF = "The $name class " \\
- "The $name widget " \\
- "The $name file " \\
- is \\
- provides \\
- specifies \\
- contains \\
- represents \\
- a \\
- an \\
- the
-ALWAYS_DETAILED_SEC = NO
-INLINE_INHERITED_MEMB = NO
-FULL_PATH_NAMES = YES
-STRIP_FROM_PATH = %(StripPath)s
-STRIP_FROM_INC_PATH =
-SHORT_NAMES = YES
-JAVADOC_AUTOBRIEF = NO
-QT_AUTOBRIEF = NO
-MULTILINE_CPP_IS_BRIEF = NO
-DETAILS_AT_TOP = YES
-INHERIT_DOCS = YES
-SEPARATE_MEMBER_PAGES = NO
-TAB_SIZE = 1
-ALIASES =
-OPTIMIZE_OUTPUT_FOR_C = YES
-OPTIMIZE_OUTPUT_JAVA = NO
-BUILTIN_STL_SUPPORT = NO
-CPP_CLI_SUPPORT = NO
-SIP_SUPPORT = NO
-DISTRIBUTE_GROUP_DOC = YES
-SUBGROUPING = YES
-TYPEDEF_HIDES_STRUCT = NO
-
-EXTRACT_ALL = YES
-EXTRACT_PRIVATE = NO
-EXTRACT_STATIC = NO
-EXTRACT_LOCAL_CLASSES = NO
-EXTRACT_LOCAL_METHODS = NO
-EXTRACT_ANON_NSPACES = NO
-HIDE_UNDOC_MEMBERS = NO
-HIDE_UNDOC_CLASSES = NO
-HIDE_FRIEND_COMPOUNDS = NO
-HIDE_IN_BODY_DOCS = NO
-INTERNAL_DOCS = NO
-CASE_SENSE_NAMES = NO
-HIDE_SCOPE_NAMES = NO
-SHOW_INCLUDE_FILES = NO
-INLINE_INFO = YES
-SORT_MEMBER_DOCS = YES
-SORT_BRIEF_DOCS = NO
-SORT_BY_SCOPE_NAME = YES
-GENERATE_TODOLIST = YES
-GENERATE_TESTLIST = YES
-GENERATE_BUGLIST = YES
-GENERATE_DEPRECATEDLIST= YES
-ENABLED_SECTIONS =
-MAX_INITIALIZER_LINES = 30
-SHOW_USED_FILES = NO
-SHOW_DIRECTORIES = NO
-FILE_VERSION_FILTER =
-
-QUIET = NO
-WARNINGS = YES
-WARN_IF_UNDOCUMENTED = YES
-WARN_IF_DOC_ERROR = YES
-WARN_NO_PARAMDOC = YES
-WARN_FORMAT = "$file:$line: $text "
-WARN_LOGFILE = %(WarningFile)s
-
-INPUT = %(FileList)s
-INPUT_ENCODING = UTF-8
-FILE_PATTERNS = %(Pattern)s
-RECURSIVE = NO
-EXCLUDE = *.svn
-EXCLUDE_SYMLINKS = NO
-EXCLUDE_PATTERNS = .svn
-EXCLUDE_SYMBOLS =
-EXAMPLE_PATH = %(ExamplePath)s
-EXAMPLE_PATTERNS = *
-EXAMPLE_RECURSIVE = NO
-IMAGE_PATH =
-INPUT_FILTER =
-FILTER_PATTERNS =
-FILTER_SOURCE_FILES = NO
-
-SOURCE_BROWSER = NO
-INLINE_SOURCES = NO
-STRIP_CODE_COMMENTS = YES
-REFERENCED_BY_RELATION = YES
-REFERENCES_RELATION = YES
-REFERENCES_LINK_SOURCE = NO
-USE_HTAGS = NO
-VERBATIM_HEADERS = NO
-
-ALPHABETICAL_INDEX = NO
-COLS_IN_ALPHA_INDEX = 5
-IGNORE_PREFIX =
-
-GENERATE_HTML = YES
-HTML_OUTPUT = html
-HTML_FILE_EXTENSION = .html
-HTML_HEADER =
-HTML_FOOTER =
-HTML_STYLESHEET =
-HTML_ALIGN_MEMBERS = YES
-GENERATE_HTMLHELP = %(WhetherGenerateHtmlHelp)s
-HTML_DYNAMIC_SECTIONS = NO
-CHM_FILE = index.chm
-HHC_LOCATION =
-GENERATE_CHI = NO
-BINARY_TOC = NO
-TOC_EXPAND = NO
-DISABLE_INDEX = NO
-ENUM_VALUES_PER_LINE = 4
-GENERATE_TREEVIEW = %(WhetherGenerateTreeView)s
-TREEVIEW_WIDTH = 250
-
-GENERATE_LATEX = NO
-LATEX_OUTPUT = latex
-LATEX_CMD_NAME = latex
-MAKEINDEX_CMD_NAME = makeindex
-COMPACT_LATEX = NO
-PAPER_TYPE = a4wide
-EXTRA_PACKAGES =
-LATEX_HEADER =
-PDF_HYPERLINKS = YES
-USE_PDFLATEX = YES
-LATEX_BATCHMODE = NO
-LATEX_HIDE_INDICES = NO
-
-GENERATE_RTF = NO
-RTF_OUTPUT = rtf
-COMPACT_RTF = NO
-RTF_HYPERLINKS = NO
-RTF_STYLESHEET_FILE =
-RTF_EXTENSIONS_FILE =
-
-GENERATE_MAN = NO
-MAN_OUTPUT = man
-MAN_EXTENSION = .3
-MAN_LINKS = NO
-
-GENERATE_XML = NO
-XML_OUTPUT = xml
-XML_SCHEMA =
-XML_DTD =
-XML_PROGRAMLISTING = YES
-
-GENERATE_AUTOGEN_DEF = NO
-
-GENERATE_PERLMOD = NO
-PERLMOD_LATEX = NO
-PERLMOD_PRETTY = YES
-PERLMOD_MAKEVAR_PREFIX =
-
-ENABLE_PREPROCESSING = YES
-MACRO_EXPANSION = YES
-EXPAND_ONLY_PREDEF = YES
-SEARCH_INCLUDES = YES
-INCLUDE_PATH = %(IncludePath)s
-INCLUDE_FILE_PATTERNS = *.h
-PREDEFINED = %(PreDefined)s
-EXPAND_AS_DEFINED =
-SKIP_FUNCTION_MACROS = NO
-
-TAGFILES =
-GENERATE_TAGFILE =
-ALLEXTERNALS = NO
-EXTERNAL_GROUPS = YES
-PERL_PATH = /usr/bin/perl
-
-CLASS_DIAGRAMS = NO
-MSCGEN_PATH =
-HIDE_UNDOC_RELATIONS = YES
-HAVE_DOT = NO
-CLASS_GRAPH = YES
-COLLABORATION_GRAPH = YES
-GROUP_GRAPHS = YES
-UML_LOOK = NO
-TEMPLATE_RELATIONS = NO
-INCLUDE_GRAPH = YES
-INCLUDED_BY_GRAPH = YES
-CALL_GRAPH = NO
-CALLER_GRAPH = NO
-GRAPHICAL_HIERARCHY = YES
-DIRECTORY_GRAPH = YES
-DOT_IMAGE_FORMAT = png
-DOT_PATH =
-DOTFILE_DIRS =
-DOT_GRAPH_MAX_NODES = 50
-MAX_DOT_GRAPH_DEPTH = 1000
-DOT_TRANSPARENT = YES
-DOT_MULTI_TARGETS = NO
-GENERATE_LEGEND = YES
-DOT_CLEANUP = YES
-
-SEARCHENGINE = NO
-
-"""
-class DoxygenConfigFile:
- def __init__(self):
- self.mProjectName = ''
- self.mOutputDir = ''
- self.mFileList = []
- self.mIncludeList = []
- self.mStripPath = ''
- self.mExamplePath = ''
- self.mPattern = ['*.c', '*.h',
- '*.asm', '*.s', '.nasm', '*.html', '*.dox']
- self.mMode = 'HTML'
- self.mWarningFile = ''
- self.mPreDefined = []
- self.mProjectVersion = 0.1
-
- def SetChmMode(self):
- self.mMode = 'CHM'
-
- def SetHtmlMode(self):
- self.mMode = 'HTML'
-
- def SetProjectName(self, str):
- self.mProjectName = str
-
- def SetProjectVersion(self, str):
- self.mProjectVersion = str
-
- def SetOutputDir(self, str):
- self.mOutputDir = str
-
- def SetStripPath(self, str):
- self.mStripPath = str
-
- def SetExamplePath(self, str):
- self.mExamplePath = str
-
- def SetWarningFilePath(self, str):
- self.mWarningFile = str.replace('\\', '/')
-
- def FileExists(self, path):
- if path is None:
- return False
- if len(path) == 0:
- return False
-
- for p in self.mFileList:
- if path.lower() == p.lower():
- return True
-
- return False
-
- def AddFile(self, path):
- if path is None:
- return
-
- if len(path) == 0:
- return
- path = path.replace('\\', '/')
- if not self.FileExists(path):
- self.mFileList.append(path)
-
- def AddIncludePath(self, path):
- path = path.replace('\\', '/')
- if path not in self.mIncludeList:
- self.mIncludeList.append(path)
-
- def AddPattern(self, pattern):
- self.mPattern.append(pattern)
-
- def AddPreDefined(self, macro):
- self.mPreDefined.append(macro)
-
- def Generate(self, path):
- files = ' \\\n'.join(self.mFileList)
- includes = ' \\\n'.join(self.mIncludeList)
- patterns = ' \\\n'.join(self.mPattern)
- if self.mMode.lower() == 'html':
- sHtmlHelp = 'NO'
- sTreeView = 'YES'
- else:
- sHtmlHelp = 'YES'
- sTreeView = 'NO'
-
- text = doxygenConfigTemplate % {'ProjectName':self.mProjectName,
- 'OutputDir':self.mOutputDir,
- 'StripPath':self.mStripPath,
- 'ExamplePath':self.mExamplePath,
- 'FileList':files,
- 'Pattern':patterns,
- 'WhetherGenerateHtmlHelp':sHtmlHelp,
- 'WhetherGenerateTreeView':sTreeView,
- 'IncludePath':includes,
- 'WarningFile':self.mWarningFile,
- 'PreDefined':' '.join(self.mPreDefined),
- 'ProjectVersion':self.mProjectVersion}
- try:
- f = open(path, 'w')
- f.write(text)
- f.close()
- except IOError as e:
- ErrorMsg ('Fail to generate doxygen config file %s' % path)
- return False
-
- return True
-
-########################################################################
-# TEST CODE
-########################################################################
-if __name__== '__main__':
- df = DoxygenFile('Platform Document', 'm:\tree')
- df.AddPage(Page('Module', 'module'))
- p = df.AddPage(Page('Library', 'library'))
- p.AddDescription(desc)
- p.AddPage(Page('PCD', 'pcds'))
-
- df.Generate()
- print(df)
+## @file +# +# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +from __future__ import print_function +from __future__ import absolute_import +import os + +from .message import * + +class BaseDoxygeItem: + def __init__(self, name, tag=''): + self.mName = name + self.mTag = tag + self.mDescription = '' + self.mText = [] + + def AddDescription(self, desc): + self.mDescription = '%s%s' % (self.mDescription, desc) + + def __str__(self): + return '\n'.join(self.mText) + + def Generate(self): + """This interface need to be override""" + +class Section(BaseDoxygeItem): + def Generate(self): + """This interface need to be override""" + if len(self.mTag) != 0: + self.mText.append(' \section %s %s' % (self.mName, self.mTag)) + else: + self.mText.append(' \section %s' % self.mName) + + self.mText.append(self.mDescription) + return self.mText + +class Page(BaseDoxygeItem): + def __init__(self, name, tag=None, isSort=True): + BaseDoxygeItem.__init__(self, name, tag) + self.mSubPages = [] + self.mIsMainPage = False + self.mSections = [] + self.mIsSort = isSort + + def GetSubpageCount(self): + return len(self.mSubPages) + + def AddPage(self, subpage): + self.mSubPages.append(subpage) + return subpage + + def AddPages(self, pageArray): + if pageArray is None: + return + for page in pageArray: + self.AddPage(page) + + def AddSection(self, section): + self.mSections.append(section) + self.mSections.sort(key=lambda x: x.mName.lower()) + + def Generate(self): + if self.mIsMainPage: + self.mText.append('/** \mainpage %s' % self.mName) + self.mIsSort = False + else: + self.mText.append('/** \page %s %s' % (self.mTag, self.mName)) + + if len(self.mDescription) != 0: + self.mText.append(self.mDescription) + endIndex = len(self.mText) + + self.mSections.sort(key=lambda x: x.mName.lower()) + for sect in self.mSections: + self.mText += sect.Generate() + + endIndex = len(self.mText) + + if len(self.mSubPages) != 0: + self.mText.insert(endIndex, "<p> \section content_index INDEX") + endIndex = len(self.mText) + self.mText.insert(endIndex, '<ul>') + endIndex += 1 + if self.mIsSort: + self.mSubPages.sort(key=lambda x: x.mName.lower()) + for page in self.mSubPages: + self.mText.insert(endIndex, '<li>\subpage %s \"%s\" </li>' % (page.mTag, page.mName)) + endIndex += 1 + self.mText += page.Generate() + self.mText.insert(endIndex, '</ul>') + endIndex += 1 + self.mText.insert(endIndex, ' **/') + return self.mText + +class DoxygenFile(Page): + def __init__(self, name, file): + Page.__init__(self, name) + self.mFilename = file + self.mIsMainPage = True + + def GetFilename(self): + return self.mFilename.replace('/', '\\') + + def Save(self): + str = self.Generate() + try: + f = open(self.mFilename, 'w') + f.write('\n'.join(str)) + f.close() + except IOError as e: + ErrorMsg ('Fail to write file %s' % self.mFilename) + return False + + return True + +doxygenConfigTemplate = """ +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = %(ProjectName)s +PROJECT_NUMBER = %(ProjectVersion)s +OUTPUT_DIRECTORY = %(OutputDir)s +CREATE_SUBDIRS = YES +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class " \\ + "The $name widget " \\ + "The $name file " \\ + is \\ + provides \\ + specifies \\ + contains \\ + represents \\ + a \\ + an \\ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = %(StripPath)s +STRIP_FROM_INC_PATH = +SHORT_NAMES = YES +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = YES +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 1 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = YES +SUBGROUPING = YES +TYPEDEF_HIDES_STRUCT = NO + +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = NO +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = YES +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = NO +SHOW_DIRECTORIES = NO +FILE_VERSION_FILTER = + +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = YES +WARN_FORMAT = "$file:$line: $text " +WARN_LOGFILE = %(WarningFile)s + +INPUT = %(FileList)s +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = %(Pattern)s +RECURSIVE = NO +EXCLUDE = *.svn +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = .svn +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = %(ExamplePath)s +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO + +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +REFERENCES_LINK_SOURCE = NO +USE_HTAGS = NO +VERBATIM_HEADERS = NO + +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = + +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = %(WhetherGenerateHtmlHelp)s +HTML_DYNAMIC_SECTIONS = NO +CHM_FILE = index.chm +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = %(WhetherGenerateTreeView)s +TREEVIEW_WIDTH = 250 + +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO + +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = + +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO + +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES + +GENERATE_AUTOGEN_DEF = NO + +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = + +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +SEARCH_INCLUDES = YES +INCLUDE_PATH = %(IncludePath)s +INCLUDE_FILE_PATTERNS = *.h +PREDEFINED = %(PreDefined)s +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = NO + +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl + +CLASS_DIAGRAMS = NO +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = YES +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES + +SEARCHENGINE = NO + +""" +class DoxygenConfigFile: + def __init__(self): + self.mProjectName = '' + self.mOutputDir = '' + self.mFileList = [] + self.mIncludeList = [] + self.mStripPath = '' + self.mExamplePath = '' + self.mPattern = ['*.c', '*.h', + '*.asm', '*.s', '.nasm', '*.html', '*.dox'] + self.mMode = 'HTML' + self.mWarningFile = '' + self.mPreDefined = [] + self.mProjectVersion = 0.1 + + def SetChmMode(self): + self.mMode = 'CHM' + + def SetHtmlMode(self): + self.mMode = 'HTML' + + def SetProjectName(self, str): + self.mProjectName = str + + def SetProjectVersion(self, str): + self.mProjectVersion = str + + def SetOutputDir(self, str): + self.mOutputDir = str + + def SetStripPath(self, str): + self.mStripPath = str + + def SetExamplePath(self, str): + self.mExamplePath = str + + def SetWarningFilePath(self, str): + self.mWarningFile = str.replace('\\', '/') + + def FileExists(self, path): + if path is None: + return False + if len(path) == 0: + return False + + for p in self.mFileList: + if path.lower() == p.lower(): + return True + + return False + + def AddFile(self, path): + if path is None: + return + + if len(path) == 0: + return + path = path.replace('\\', '/') + if not self.FileExists(path): + self.mFileList.append(path) + + def AddIncludePath(self, path): + path = path.replace('\\', '/') + if path not in self.mIncludeList: + self.mIncludeList.append(path) + + def AddPattern(self, pattern): + self.mPattern.append(pattern) + + def AddPreDefined(self, macro): + self.mPreDefined.append(macro) + + def Generate(self, path): + files = ' \\\n'.join(self.mFileList) + includes = ' \\\n'.join(self.mIncludeList) + patterns = ' \\\n'.join(self.mPattern) + if self.mMode.lower() == 'html': + sHtmlHelp = 'NO' + sTreeView = 'YES' + else: + sHtmlHelp = 'YES' + sTreeView = 'NO' + + text = doxygenConfigTemplate % {'ProjectName':self.mProjectName, + 'OutputDir':self.mOutputDir, + 'StripPath':self.mStripPath, + 'ExamplePath':self.mExamplePath, + 'FileList':files, + 'Pattern':patterns, + 'WhetherGenerateHtmlHelp':sHtmlHelp, + 'WhetherGenerateTreeView':sTreeView, + 'IncludePath':includes, + 'WarningFile':self.mWarningFile, + 'PreDefined':' '.join(self.mPreDefined), + 'ProjectVersion':self.mProjectVersion} + try: + f = open(path, 'w') + f.write(text) + f.close() + except IOError as e: + ErrorMsg ('Fail to generate doxygen config file %s' % path) + return False + + return True + +######################################################################## +# TEST CODE +######################################################################## +if __name__== '__main__': + df = DoxygenFile('Platform Document', 'm:\tree') + df.AddPage(Page('Module', 'module')) + p = df.AddPage(Page('Library', 'library')) + p.AddDescription(desc) + p.AddPage(Page('PCD', 'pcds')) + + df.Generate() + print(df) diff --git a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/efibinary.py b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/efibinary.py index 1bc4938bfc..44ab75114b 100644 --- a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/efibinary.py +++ b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/efibinary.py @@ -1,606 +1,606 @@ -## @file
-#
-# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-from __future__ import print_function
-import array
-import uuid
-import re
-import os
-import logging
-import core.pe as pe
-
-def GetLogger():
- return logging.getLogger('EFI Binary File')
-
-class EFIBinaryError(Exception):
- def __init__(self, message):
- Exception.__init__(self)
- self._message = message
-
- def GetMessage(self):
- return self._message
-
-class EfiFd(object):
- EFI_FV_HEADER_SIZE = 0x48
-
- def __init__(self):
- self._fvs = []
-
- def Load(self, fd, size):
- index = fd.tell()
- while (index + self.EFI_FV_HEADER_SIZE < size):
- fv = EfiFv(self)
- fv.Load(fd)
- self._fvs.append(fv)
- index += fv.GetHeader().GetFvLength()
- index = align(index, 8)
- fd.seek(index)
-
- def GetFvs(self):
- return self._fvs
-
-class EfiFv(object):
- FILE_SYSTEM_GUID = uuid.UUID('{8c8ce578-8a3d-4f1c-9935-896185c32dd3}')
-
- def __init__(self, parent=None):
- self._size = 0
- self._filename = None
- self._fvheader = None
- self._blockentries = []
- self._ffs = []
-
- # following field is for FV in FD
- self._parent = parent
- self._offset = 0
- self._raw = array.array('B')
-
- def Load(self, fd):
- self._offset = fd.tell()
- self._filename = fd.name
-
- # get file header
- self._fvheader = EfiFirmwareVolumeHeader.Read(fd)
- #self._fvheader.Dump()
-
- self._size = self._fvheader.GetFvLength()
-
- if self._fvheader.GetFileSystemGuid() != self.FILE_SYSTEM_GUID:
- fd.seek(self._offset)
- self._raw.fromfile(fd, self.GetHeader().GetFvLength())
- return
-
- # read block map
- blockentry = BlockMapEntry.Read(fd)
- self._blockentries.append(blockentry)
- while (blockentry.GetNumberBlocks() != 0 and blockentry.GetLength() != 0):
- self._blockentries.append(blockentry)
- blockentry = BlockMapEntry.Read(fd)
-
-
- if self._fvheader.GetSize() + (len(self._blockentries)) * 8 != \
- self._fvheader.GetHeaderLength():
- raise EFIBinaryError("Volume Header length not consistent with block map!")
-
- index = align(fd.tell(), 8)
- count = 0
- while ((index + EfiFfs.FFS_HEADER_SIZE) < self._size):
- ffs = EfiFfs.Read(fd, self)
- if not isValidGuid(ffs.GetNameGuid()):
- break
- self._ffs.append(ffs)
- count += 1
- index = align(fd.tell(), 8)
-
- fd.seek(self._offset)
- self._raw.fromfile(fd, self.GetHeader().GetFvLength())
-
- def GetFfs(self):
- return self._ffs
-
- def GetHeader(self):
- return self._fvheader
-
- def GetBlockEntries(self):
- return self._blockentries
-
- def GetHeaderRawData(self):
- ret = []
- ret += self._fvheader.GetRawData()
- for block in self._blockentries:
- ret += block.GetRawData()
- return ret
-
- def GetOffset(self):
- return 0
-
- def GetRawData(self):
- return self._raw.tolist()
-
-class BinaryItem(object):
- def __init__(self, parent=None):
- self._size = 0
- self._arr = array.array('B')
- self._parent = parent
-
- @classmethod
- def Read(cls, fd, parent=None):
- item = cls(parent)
- item.fromfile(fd)
- return item
-
- def Load(self, fd):
- self.fromfile(fd)
-
- def GetSize(self):
- """should be implemented by inherited class"""
-
- def fromfile(self, fd):
- self._arr.fromfile(fd, self.GetSize())
-
- def GetParent(self):
- return self._parent
-
-class EfiFirmwareVolumeHeader(BinaryItem):
- def GetSize(self):
- return 56
-
- def GetSigunature(self):
- list = self._arr.tolist()
- sig = ''
- for x in list[40:44]:
- sig += chr(x)
- return sig
-
- def GetAttribute(self):
- return list2int(self._arr.tolist()[44:48])
-
- def GetErasePolarity(self):
- list = self.GetAttrStrings()
- if 'EFI_FVB2_ERASE_POLARITY' in list:
- return True
- return False
-
- def GetAttrStrings(self):
- list = []
- value = self.GetAttribute()
- if (value & 0x01) != 0:
- list.append('EFI_FVB2_READ_DISABLED_CAP')
- if (value & 0x02) != 0:
- list.append('EFI_FVB2_READ_ENABLED_CAP')
- if (value & 0x04) != 0:
- list.append('EFI_FVB2_READ_STATUS')
- if (value & 0x08) != 0:
- list.append('EFI_FVB2_WRITE_DISABLED_CAP')
- if (value & 0x10) != 0:
- list.append('EFI_FVB2_WRITE_ENABLED_CAP')
- if (value & 0x20) != 0:
- list.append('EFI_FVB2_WRITE_STATUS')
- if (value & 0x40) != 0:
- list.append('EFI_FVB2_LOCK_CAP')
- if (value & 0x80) != 0:
- list.append('EFI_FVB2_LOCK_STATUS')
- if (value & 0x200) != 0:
- list.append('EFI_FVB2_STICKY_WRITE')
- if (value & 0x400) != 0:
- list.append('EFI_FVB2_MEMORY_MAPPED')
- if (value & 0x800) != 0:
- list.append('EFI_FVB2_ERASE_POLARITY')
- if (value & 0x1000) != 0:
- list.append('EFI_FVB2_READ_LOCK_CAP')
- if (value & 0x00002000) != 0:
- list.append('EFI_FVB2_READ_LOCK_STATUS')
- if (value & 0x00004000) != 0:
- list.append('EFI_FVB2_WRITE_LOCK_CAP')
- if (value & 0x00008000) != 0:
- list.append('EFI_FVB2_WRITE_LOCK_STATUS')
-
- if (value == 0):
- list.append('EFI_FVB2_ALIGNMENT_1')
- if (value & 0x001F0000) == 0x00010000:
- list.append('EFI_FVB2_ALIGNMENT_2')
- if (value & 0x001F0000) == 0x00020000:
- list.append('EFI_FVB2_ALIGNMENT_4')
- if (value & 0x001F0000) == 0x00030000:
- list.append('EFI_FVB2_ALIGNMENT_8')
- if (value & 0x001F0000) == 0x00040000:
- list.append('EFI_FVB2_ALIGNMENT_16')
- if (value & 0x001F0000) == 0x00050000:
- list.append('EFI_FVB2_ALIGNMENT_32')
- if (value & 0x001F0000) == 0x00060000:
- list.append('EFI_FVB2_ALIGNMENT_64')
- if (value & 0x001F0000) == 0x00070000:
- list.append('EFI_FVB2_ALIGNMENT_128')
- if (value & 0x001F0000) == 0x00080000:
- list.append('EFI_FVB2_ALIGNMENT_256')
- if (value & 0x001F0000) == 0x00090000:
- list.append('EFI_FVB2_ALIGNMENT_512')
- if (value & 0x001F0000) == 0x000A0000:
- list.append('EFI_FVB2_ALIGNMENT_1K')
- if (value & 0x001F0000) == 0x000B0000:
- list.append('EFI_FVB2_ALIGNMENT_2K')
- if (value & 0x001F0000) == 0x000C0000:
- list.append('EFI_FVB2_ALIGNMENT_4K')
- if (value & 0x001F0000) == 0x000D0000:
- list.append('EFI_FVB2_ALIGNMENT_8K')
- if (value & 0x001F0000) == 0x000E0000:
- list.append('EFI_FVB2_ALIGNMENT_16K')
- if (value & 0x001F0000) == 0x000F0000:
- list.append('EFI_FVB2_ALIGNMENT_32K')
- if (value & 0x001F0000) == 0x00100000:
- list.append('EFI_FVB2_ALIGNMENT_64K')
- if (value & 0x001F0000) == 0x00110000:
- list.append('EFI_FVB2_ALIGNMENT_128K')
- if (value & 0x001F0000) == 0x00120000:
- list.append('EFI_FVB2_ALIGNMENT_256K')
- if (value & 0x001F0000) == 0x00130000:
- list.append('EFI_FVB2_ALIGNMENT_512K')
-
- return list
-
- def GetHeaderLength(self):
- return list2int(self._arr.tolist()[48:50])
-
- def Dump(self):
- print('Signature: %s' % self.GetSigunature())
- print('Attribute: 0x%X' % self.GetAttribute())
- print('Header Length: 0x%X' % self.GetHeaderLength())
- print('File system Guid: ', self.GetFileSystemGuid())
- print('Revision: 0x%X' % self.GetRevision())
- print('FvLength: 0x%X' % self.GetFvLength())
-
- def GetFileSystemGuid(self):
- list = self._arr.tolist()
- return list2guid(list[16:32])
-
- def GetRevision(self):
- list = self._arr.tolist()
- return int(list[55])
-
- def GetFvLength(self):
- list = self._arr.tolist()
- return list2int(list[32:40])
-
- def GetRawData(self):
- return self._arr.tolist()
-
-class BlockMapEntry(BinaryItem):
- def GetSize(self):
- return 8
-
- def GetNumberBlocks(self):
- list = self._arr.tolist()
- return list2int(list[0:4])
-
- def GetLength(self):
- list = self._arr.tolist()
- return list2int(list[4:8])
-
- def GetRawData(self):
- return self._arr.tolist()
-
- def __str__(self):
- return '[BlockEntry] Number = 0x%X, length=0x%X' % (self.GetNumberBlocks(), self.GetLength())
-
-class EfiFfs(object):
- FFS_HEADER_SIZE = 24
-
- def __init__(self, parent=None):
- self._header = None
-
- # following field is for FFS in FV file.
- self._parent = parent
- self._offset = 0
- self._sections = []
-
- def Load(self, fd):
- self._offset = align(fd.tell(), 8)
-
- self._header = EfiFfsHeader.Read(fd, self)
-
- if not isValidGuid(self.GetNameGuid()):
- return
-
- index = self._offset
- fileend = self._offset + self.GetSize()
- while (index + EfiSection.EFI_SECTION_HEADER_SIZE < fileend):
- section = EfiSection(self)
- section.Load(fd)
- if section.GetSize() == 0 and section.GetHeader().GetType() == 0:
- break
- self._sections.append(section)
- index = fd.tell()
-
- # rebase file pointer to next ffs file
- index = self._offset + self._header.GetFfsSize()
- index = align(index, 8)
- fd.seek(index)
-
- def GetOffset(self):
- return self._offset
-
- def GetSize(self):
- return self._header.GetFfsSize()
-
- @classmethod
- def Read(cls, fd, parent=None):
- item = cls(parent)
- item.Load(fd)
- return item
-
- def GetNameGuid(self):
- return self._header.GetNameGuid()
-
- def DumpContent(self):
- list = self._content.tolist()
- line = []
- count = 0
- for item in list:
- if count < 32:
- line.append('0x%X' % int(item))
- count += 1
- else:
- print(' '.join(line))
- count = 0
- line = []
- line.append('0x%X' % int(item))
- count += 1
-
- def GetHeader(self):
- return self._header
-
- def GetParent(self):
- return self._parent
-
- def GetSections(self):
- return self._sections
-
-class EfiFfsHeader(BinaryItem):
- ffs_state_map = {0x01:'EFI_FILE_HEADER_CONSTRUCTION',
- 0x02:'EFI_FILE_HEADER_VALID',
- 0x04:'EFI_FILE_DATA_VALID',
- 0x08:'EFI_FILE_MARKED_FOR_UPDATE',
- 0x10:'EFI_FILE_DELETED',
- 0x20:'EFI_FILE_HEADER_INVALID'}
-
- def GetSize(self):
- return 24
-
- def GetNameGuid(self):
- list = self._arr.tolist()
- return list2guid(list[0:16])
-
- def GetType(self):
- list = self._arr.tolist()
- return int(list[18])
-
-
- def GetTypeString(self):
- value = self.GetType()
- if value == 0x01:
- return 'EFI_FV_FILETYPE_RAW'
- if value == 0x02:
- return 'EFI_FV_FILETYPE_FREEFORM'
- if value == 0x03:
- return 'EFI_FV_FILETYPE_SECURITY_CORE'
- if value == 0x04:
- return 'EFI_FV_FILETYPE_PEI_CORE'
- if value == 0x05:
- return 'EFI_FV_FILETYPE_DXE_CORE'
- if value == 0x06:
- return 'EFI_FV_FILETYPE_PEIM'
- if value == 0x07:
- return 'EFI_FV_FILETYPE_DRIVER'
- if value == 0x08:
- return 'EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER'
- if value == 0x09:
- return 'EFI_FV_FILETYPE_APPLICATION'
- if value == 0x0B:
- return 'EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE'
- if value == 0xc0:
- return 'EFI_FV_FILETYPE_OEM_MIN'
- if value == 0xdf:
- return 'EFI_FV_FILETYPE_OEM_MAX'
- if value == 0xe0:
- return 'EFI_FV_FILETYPE_DEBUG_MIN'
- if value == 0xef:
- return 'EFI_FV_FILETYPE_DEBUG_MAX'
- if value == 0xf0:
- return 'EFI_FV_FILETYPE_FFS_PAD'
- if value == 0xff:
- return 'EFI_FV_FILETYPE_FFS_MAX'
- return 'Unknown FFS Type'
-
- def GetAttributes(self):
- list = self._arr.tolist()
- return int(list[19])
-
- def GetFfsSize(self):
- list = self._arr.tolist()
- return list2int(list[20:23])
-
- def GetState(self):
- list = self._arr.tolist()
- state = int(list[23])
- polarity = self.GetParent().GetParent().GetHeader().GetErasePolarity()
- if polarity:
- state = (~state) & 0xFF
- HighestBit = 0x80
- while (HighestBit != 0) and (HighestBit & state) == 0:
- HighestBit = HighestBit >> 1
- return HighestBit
-
- def GetStateString(self):
- state = self.GetState()
- if state in self.ffs_state_map.keys():
- return self.ffs_state_map[state]
- return 'Unknown Ffs State'
-
- def Dump(self):
- print("FFS name: ", self.GetNameGuid())
- print("FFS type: ", self.GetType())
- print("FFS attr: 0x%X" % self.GetAttributes())
- print("FFS size: 0x%X" % self.GetFfsSize())
- print("FFS state: 0x%X" % self.GetState())
-
- def GetRawData(self):
- return self._arr.tolist()
-
-
-class EfiSection(object):
- EFI_SECTION_HEADER_SIZE = 4
-
- def __init__(self, parent=None):
- self._size = 0
- self._parent = parent
- self._offset = 0
- self._contents = array.array('B')
-
- def Load(self, fd):
- self._offset = align(fd.tell(), 4)
-
- self._header = EfiSectionHeader.Read(fd, self)
-
- if self._header.GetTypeString() == "EFI_SECTION_PE32":
- pefile = pe.PEFile(self)
- pefile.Load(fd, self.GetContentSize())
-
- fd.seek(self._offset)
- self._contents.fromfile(fd, self.GetContentSize())
-
- # rebase file pointer to next section
- index = self._offset + self.GetSize()
- index = align(index, 4)
- fd.seek(index)
-
- def GetContentSize(self):
- return self.GetSize() - self.EFI_SECTION_HEADER_SIZE
-
- def GetContent(self):
- return self._contents.tolist()
-
- def GetSize(self):
- return self._header.GetSectionSize()
-
- def GetHeader(self):
- return self._header
-
- def GetSectionOffset(self):
- return self._offset + self.EFI_SECTION_HEADER_SIZE
-
-class EfiSectionHeader(BinaryItem):
- section_type_map = {0x01: 'EFI_SECTION_COMPRESSION',
- 0x02: 'EFI_SECTION_GUID_DEFINED',
- 0x10: 'EFI_SECTION_PE32',
- 0x11: 'EFI_SECTION_PIC',
- 0x12: 'EFI_SECTION_TE',
- 0x13: 'EFI_SECTION_DXE_DEPEX',
- 0x14: 'EFI_SECTION_VERSION',
- 0x15: 'EFI_SECTION_USER_INTERFACE',
- 0x16: 'EFI_SECTION_COMPATIBILITY16',
- 0x17: 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE',
- 0x18: 'EFI_SECTION_FREEFORM_SUBTYPE_GUID',
- 0x19: 'EFI_SECTION_RAW',
- 0x1B: 'EFI_SECTION_PEI_DEPEX'}
- def GetSize(self):
- return 4
-
- def GetSectionSize(self):
- list = self._arr.tolist()
- return list2int(list[0:3])
-
- def GetType(self):
- list = self._arr.tolist()
- return int(list[3])
-
- def GetTypeString(self):
- type = self.GetType()
- if type not in self.section_type_map.keys():
- return 'Unknown Section Type'
- return self.section_type_map[type]
-
- def Dump(self):
- print('size = 0x%X' % self.GetSectionSize())
- print('type = 0x%X' % self.GetType())
-
-
-
-rMapEntry = re.compile('^(\w+)[ \(\w\)]* \(BaseAddress=([0-9a-fA-F]+), EntryPoint=([0-9a-fA-F]+), GUID=([0-9a-fA-F\-]+)')
-class EfiFvMapFile(object):
- def __init__(self):
- self._mapentries = {}
-
- def Load(self, path):
- if not os.path.exists(path):
- return False
-
- try:
- file = open(path, 'r')
- lines = file.readlines()
- file.close()
- except:
- return False
-
- for line in lines:
- if line[0] != ' ':
- # new entry
- ret = rMapEntry.match(line)
- if ret is not None:
- name = ret.groups()[0]
- baseaddr = int(ret.groups()[1], 16)
- entry = int(ret.groups()[2], 16)
- guidstr = '{' + ret.groups()[3] + '}'
- guid = uuid.UUID(guidstr)
- self._mapentries[guid] = EfiFvMapFileEntry(name, baseaddr, entry, guid)
- return True
-
- def GetEntry(self, guid):
- if guid in self._mapentries.keys():
- return self._mapentries[guid]
- return None
-
-class EfiFvMapFileEntry(object):
- def __init__(self, name, baseaddr, entry, guid):
- self._name = name
- self._baseaddr = baseaddr
- self._entry = entry
- self._guid = guid
-
- def GetName(self):
- return self._name
-
- def GetBaseAddress(self):
- return self._baseaddr
-
- def GetEntryPoint(self):
- return self._entry
-
-def list2guid(list):
- val1 = list2int(list[0:4])
- val2 = list2int(list[4:6])
- val3 = list2int(list[6:8])
- val4 = 0
- for item in list[8:16]:
- val4 = (val4 << 8) | int(item)
-
- val = val1 << 12 * 8 | val2 << 10 * 8 | val3 << 8 * 8 | val4
- guid = uuid.UUID(int=val)
- return guid
-
-def list2int(list):
- val = 0
- for index in range(len(list) - 1, -1, -1):
- val = (val << 8) | int(list[index])
- return val
-
-def align(value, alignment):
- return (value + ((alignment - value) & (alignment - 1)))
-
-gInvalidGuid = uuid.UUID(int=0xffffffffffffffffffffffffffffffff)
-def isValidGuid(guid):
- if guid == gInvalidGuid:
- return False
- return True
+## @file +# +# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +from __future__ import print_function +import array +import uuid +import re +import os +import logging +import core.pe as pe + +def GetLogger(): + return logging.getLogger('EFI Binary File') + +class EFIBinaryError(Exception): + def __init__(self, message): + Exception.__init__(self) + self._message = message + + def GetMessage(self): + return self._message + +class EfiFd(object): + EFI_FV_HEADER_SIZE = 0x48 + + def __init__(self): + self._fvs = [] + + def Load(self, fd, size): + index = fd.tell() + while (index + self.EFI_FV_HEADER_SIZE < size): + fv = EfiFv(self) + fv.Load(fd) + self._fvs.append(fv) + index += fv.GetHeader().GetFvLength() + index = align(index, 8) + fd.seek(index) + + def GetFvs(self): + return self._fvs + +class EfiFv(object): + FILE_SYSTEM_GUID = uuid.UUID('{8c8ce578-8a3d-4f1c-9935-896185c32dd3}') + + def __init__(self, parent=None): + self._size = 0 + self._filename = None + self._fvheader = None + self._blockentries = [] + self._ffs = [] + + # following field is for FV in FD + self._parent = parent + self._offset = 0 + self._raw = array.array('B') + + def Load(self, fd): + self._offset = fd.tell() + self._filename = fd.name + + # get file header + self._fvheader = EfiFirmwareVolumeHeader.Read(fd) + #self._fvheader.Dump() + + self._size = self._fvheader.GetFvLength() + + if self._fvheader.GetFileSystemGuid() != self.FILE_SYSTEM_GUID: + fd.seek(self._offset) + self._raw.fromfile(fd, self.GetHeader().GetFvLength()) + return + + # read block map + blockentry = BlockMapEntry.Read(fd) + self._blockentries.append(blockentry) + while (blockentry.GetNumberBlocks() != 0 and blockentry.GetLength() != 0): + self._blockentries.append(blockentry) + blockentry = BlockMapEntry.Read(fd) + + + if self._fvheader.GetSize() + (len(self._blockentries)) * 8 != \ + self._fvheader.GetHeaderLength(): + raise EFIBinaryError("Volume Header length not consistent with block map!") + + index = align(fd.tell(), 8) + count = 0 + while ((index + EfiFfs.FFS_HEADER_SIZE) < self._size): + ffs = EfiFfs.Read(fd, self) + if not isValidGuid(ffs.GetNameGuid()): + break + self._ffs.append(ffs) + count += 1 + index = align(fd.tell(), 8) + + fd.seek(self._offset) + self._raw.fromfile(fd, self.GetHeader().GetFvLength()) + + def GetFfs(self): + return self._ffs + + def GetHeader(self): + return self._fvheader + + def GetBlockEntries(self): + return self._blockentries + + def GetHeaderRawData(self): + ret = [] + ret += self._fvheader.GetRawData() + for block in self._blockentries: + ret += block.GetRawData() + return ret + + def GetOffset(self): + return 0 + + def GetRawData(self): + return self._raw.tolist() + +class BinaryItem(object): + def __init__(self, parent=None): + self._size = 0 + self._arr = array.array('B') + self._parent = parent + + @classmethod + def Read(cls, fd, parent=None): + item = cls(parent) + item.fromfile(fd) + return item + + def Load(self, fd): + self.fromfile(fd) + + def GetSize(self): + """should be implemented by inherited class""" + + def fromfile(self, fd): + self._arr.fromfile(fd, self.GetSize()) + + def GetParent(self): + return self._parent + +class EfiFirmwareVolumeHeader(BinaryItem): + def GetSize(self): + return 56 + + def GetSigunature(self): + list = self._arr.tolist() + sig = '' + for x in list[40:44]: + sig += chr(x) + return sig + + def GetAttribute(self): + return list2int(self._arr.tolist()[44:48]) + + def GetErasePolarity(self): + list = self.GetAttrStrings() + if 'EFI_FVB2_ERASE_POLARITY' in list: + return True + return False + + def GetAttrStrings(self): + list = [] + value = self.GetAttribute() + if (value & 0x01) != 0: + list.append('EFI_FVB2_READ_DISABLED_CAP') + if (value & 0x02) != 0: + list.append('EFI_FVB2_READ_ENABLED_CAP') + if (value & 0x04) != 0: + list.append('EFI_FVB2_READ_STATUS') + if (value & 0x08) != 0: + list.append('EFI_FVB2_WRITE_DISABLED_CAP') + if (value & 0x10) != 0: + list.append('EFI_FVB2_WRITE_ENABLED_CAP') + if (value & 0x20) != 0: + list.append('EFI_FVB2_WRITE_STATUS') + if (value & 0x40) != 0: + list.append('EFI_FVB2_LOCK_CAP') + if (value & 0x80) != 0: + list.append('EFI_FVB2_LOCK_STATUS') + if (value & 0x200) != 0: + list.append('EFI_FVB2_STICKY_WRITE') + if (value & 0x400) != 0: + list.append('EFI_FVB2_MEMORY_MAPPED') + if (value & 0x800) != 0: + list.append('EFI_FVB2_ERASE_POLARITY') + if (value & 0x1000) != 0: + list.append('EFI_FVB2_READ_LOCK_CAP') + if (value & 0x00002000) != 0: + list.append('EFI_FVB2_READ_LOCK_STATUS') + if (value & 0x00004000) != 0: + list.append('EFI_FVB2_WRITE_LOCK_CAP') + if (value & 0x00008000) != 0: + list.append('EFI_FVB2_WRITE_LOCK_STATUS') + + if (value == 0): + list.append('EFI_FVB2_ALIGNMENT_1') + if (value & 0x001F0000) == 0x00010000: + list.append('EFI_FVB2_ALIGNMENT_2') + if (value & 0x001F0000) == 0x00020000: + list.append('EFI_FVB2_ALIGNMENT_4') + if (value & 0x001F0000) == 0x00030000: + list.append('EFI_FVB2_ALIGNMENT_8') + if (value & 0x001F0000) == 0x00040000: + list.append('EFI_FVB2_ALIGNMENT_16') + if (value & 0x001F0000) == 0x00050000: + list.append('EFI_FVB2_ALIGNMENT_32') + if (value & 0x001F0000) == 0x00060000: + list.append('EFI_FVB2_ALIGNMENT_64') + if (value & 0x001F0000) == 0x00070000: + list.append('EFI_FVB2_ALIGNMENT_128') + if (value & 0x001F0000) == 0x00080000: + list.append('EFI_FVB2_ALIGNMENT_256') + if (value & 0x001F0000) == 0x00090000: + list.append('EFI_FVB2_ALIGNMENT_512') + if (value & 0x001F0000) == 0x000A0000: + list.append('EFI_FVB2_ALIGNMENT_1K') + if (value & 0x001F0000) == 0x000B0000: + list.append('EFI_FVB2_ALIGNMENT_2K') + if (value & 0x001F0000) == 0x000C0000: + list.append('EFI_FVB2_ALIGNMENT_4K') + if (value & 0x001F0000) == 0x000D0000: + list.append('EFI_FVB2_ALIGNMENT_8K') + if (value & 0x001F0000) == 0x000E0000: + list.append('EFI_FVB2_ALIGNMENT_16K') + if (value & 0x001F0000) == 0x000F0000: + list.append('EFI_FVB2_ALIGNMENT_32K') + if (value & 0x001F0000) == 0x00100000: + list.append('EFI_FVB2_ALIGNMENT_64K') + if (value & 0x001F0000) == 0x00110000: + list.append('EFI_FVB2_ALIGNMENT_128K') + if (value & 0x001F0000) == 0x00120000: + list.append('EFI_FVB2_ALIGNMENT_256K') + if (value & 0x001F0000) == 0x00130000: + list.append('EFI_FVB2_ALIGNMENT_512K') + + return list + + def GetHeaderLength(self): + return list2int(self._arr.tolist()[48:50]) + + def Dump(self): + print('Signature: %s' % self.GetSigunature()) + print('Attribute: 0x%X' % self.GetAttribute()) + print('Header Length: 0x%X' % self.GetHeaderLength()) + print('File system Guid: ', self.GetFileSystemGuid()) + print('Revision: 0x%X' % self.GetRevision()) + print('FvLength: 0x%X' % self.GetFvLength()) + + def GetFileSystemGuid(self): + list = self._arr.tolist() + return list2guid(list[16:32]) + + def GetRevision(self): + list = self._arr.tolist() + return int(list[55]) + + def GetFvLength(self): + list = self._arr.tolist() + return list2int(list[32:40]) + + def GetRawData(self): + return self._arr.tolist() + +class BlockMapEntry(BinaryItem): + def GetSize(self): + return 8 + + def GetNumberBlocks(self): + list = self._arr.tolist() + return list2int(list[0:4]) + + def GetLength(self): + list = self._arr.tolist() + return list2int(list[4:8]) + + def GetRawData(self): + return self._arr.tolist() + + def __str__(self): + return '[BlockEntry] Number = 0x%X, length=0x%X' % (self.GetNumberBlocks(), self.GetLength()) + +class EfiFfs(object): + FFS_HEADER_SIZE = 24 + + def __init__(self, parent=None): + self._header = None + + # following field is for FFS in FV file. + self._parent = parent + self._offset = 0 + self._sections = [] + + def Load(self, fd): + self._offset = align(fd.tell(), 8) + + self._header = EfiFfsHeader.Read(fd, self) + + if not isValidGuid(self.GetNameGuid()): + return + + index = self._offset + fileend = self._offset + self.GetSize() + while (index + EfiSection.EFI_SECTION_HEADER_SIZE < fileend): + section = EfiSection(self) + section.Load(fd) + if section.GetSize() == 0 and section.GetHeader().GetType() == 0: + break + self._sections.append(section) + index = fd.tell() + + # rebase file pointer to next ffs file + index = self._offset + self._header.GetFfsSize() + index = align(index, 8) + fd.seek(index) + + def GetOffset(self): + return self._offset + + def GetSize(self): + return self._header.GetFfsSize() + + @classmethod + def Read(cls, fd, parent=None): + item = cls(parent) + item.Load(fd) + return item + + def GetNameGuid(self): + return self._header.GetNameGuid() + + def DumpContent(self): + list = self._content.tolist() + line = [] + count = 0 + for item in list: + if count < 32: + line.append('0x%X' % int(item)) + count += 1 + else: + print(' '.join(line)) + count = 0 + line = [] + line.append('0x%X' % int(item)) + count += 1 + + def GetHeader(self): + return self._header + + def GetParent(self): + return self._parent + + def GetSections(self): + return self._sections + +class EfiFfsHeader(BinaryItem): + ffs_state_map = {0x01:'EFI_FILE_HEADER_CONSTRUCTION', + 0x02:'EFI_FILE_HEADER_VALID', + 0x04:'EFI_FILE_DATA_VALID', + 0x08:'EFI_FILE_MARKED_FOR_UPDATE', + 0x10:'EFI_FILE_DELETED', + 0x20:'EFI_FILE_HEADER_INVALID'} + + def GetSize(self): + return 24 + + def GetNameGuid(self): + list = self._arr.tolist() + return list2guid(list[0:16]) + + def GetType(self): + list = self._arr.tolist() + return int(list[18]) + + + def GetTypeString(self): + value = self.GetType() + if value == 0x01: + return 'EFI_FV_FILETYPE_RAW' + if value == 0x02: + return 'EFI_FV_FILETYPE_FREEFORM' + if value == 0x03: + return 'EFI_FV_FILETYPE_SECURITY_CORE' + if value == 0x04: + return 'EFI_FV_FILETYPE_PEI_CORE' + if value == 0x05: + return 'EFI_FV_FILETYPE_DXE_CORE' + if value == 0x06: + return 'EFI_FV_FILETYPE_PEIM' + if value == 0x07: + return 'EFI_FV_FILETYPE_DRIVER' + if value == 0x08: + return 'EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER' + if value == 0x09: + return 'EFI_FV_FILETYPE_APPLICATION' + if value == 0x0B: + return 'EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE' + if value == 0xc0: + return 'EFI_FV_FILETYPE_OEM_MIN' + if value == 0xdf: + return 'EFI_FV_FILETYPE_OEM_MAX' + if value == 0xe0: + return 'EFI_FV_FILETYPE_DEBUG_MIN' + if value == 0xef: + return 'EFI_FV_FILETYPE_DEBUG_MAX' + if value == 0xf0: + return 'EFI_FV_FILETYPE_FFS_PAD' + if value == 0xff: + return 'EFI_FV_FILETYPE_FFS_MAX' + return 'Unknown FFS Type' + + def GetAttributes(self): + list = self._arr.tolist() + return int(list[19]) + + def GetFfsSize(self): + list = self._arr.tolist() + return list2int(list[20:23]) + + def GetState(self): + list = self._arr.tolist() + state = int(list[23]) + polarity = self.GetParent().GetParent().GetHeader().GetErasePolarity() + if polarity: + state = (~state) & 0xFF + HighestBit = 0x80 + while (HighestBit != 0) and (HighestBit & state) == 0: + HighestBit = HighestBit >> 1 + return HighestBit + + def GetStateString(self): + state = self.GetState() + if state in self.ffs_state_map.keys(): + return self.ffs_state_map[state] + return 'Unknown Ffs State' + + def Dump(self): + print("FFS name: ", self.GetNameGuid()) + print("FFS type: ", self.GetType()) + print("FFS attr: 0x%X" % self.GetAttributes()) + print("FFS size: 0x%X" % self.GetFfsSize()) + print("FFS state: 0x%X" % self.GetState()) + + def GetRawData(self): + return self._arr.tolist() + + +class EfiSection(object): + EFI_SECTION_HEADER_SIZE = 4 + + def __init__(self, parent=None): + self._size = 0 + self._parent = parent + self._offset = 0 + self._contents = array.array('B') + + def Load(self, fd): + self._offset = align(fd.tell(), 4) + + self._header = EfiSectionHeader.Read(fd, self) + + if self._header.GetTypeString() == "EFI_SECTION_PE32": + pefile = pe.PEFile(self) + pefile.Load(fd, self.GetContentSize()) + + fd.seek(self._offset) + self._contents.fromfile(fd, self.GetContentSize()) + + # rebase file pointer to next section + index = self._offset + self.GetSize() + index = align(index, 4) + fd.seek(index) + + def GetContentSize(self): + return self.GetSize() - self.EFI_SECTION_HEADER_SIZE + + def GetContent(self): + return self._contents.tolist() + + def GetSize(self): + return self._header.GetSectionSize() + + def GetHeader(self): + return self._header + + def GetSectionOffset(self): + return self._offset + self.EFI_SECTION_HEADER_SIZE + +class EfiSectionHeader(BinaryItem): + section_type_map = {0x01: 'EFI_SECTION_COMPRESSION', + 0x02: 'EFI_SECTION_GUID_DEFINED', + 0x10: 'EFI_SECTION_PE32', + 0x11: 'EFI_SECTION_PIC', + 0x12: 'EFI_SECTION_TE', + 0x13: 'EFI_SECTION_DXE_DEPEX', + 0x14: 'EFI_SECTION_VERSION', + 0x15: 'EFI_SECTION_USER_INTERFACE', + 0x16: 'EFI_SECTION_COMPATIBILITY16', + 0x17: 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', + 0x18: 'EFI_SECTION_FREEFORM_SUBTYPE_GUID', + 0x19: 'EFI_SECTION_RAW', + 0x1B: 'EFI_SECTION_PEI_DEPEX'} + def GetSize(self): + return 4 + + def GetSectionSize(self): + list = self._arr.tolist() + return list2int(list[0:3]) + + def GetType(self): + list = self._arr.tolist() + return int(list[3]) + + def GetTypeString(self): + type = self.GetType() + if type not in self.section_type_map.keys(): + return 'Unknown Section Type' + return self.section_type_map[type] + + def Dump(self): + print('size = 0x%X' % self.GetSectionSize()) + print('type = 0x%X' % self.GetType()) + + + +rMapEntry = re.compile('^(\w+)[ \(\w\)]* \(BaseAddress=([0-9a-fA-F]+), EntryPoint=([0-9a-fA-F]+), GUID=([0-9a-fA-F\-]+)') +class EfiFvMapFile(object): + def __init__(self): + self._mapentries = {} + + def Load(self, path): + if not os.path.exists(path): + return False + + try: + file = open(path, 'r') + lines = file.readlines() + file.close() + except: + return False + + for line in lines: + if line[0] != ' ': + # new entry + ret = rMapEntry.match(line) + if ret is not None: + name = ret.groups()[0] + baseaddr = int(ret.groups()[1], 16) + entry = int(ret.groups()[2], 16) + guidstr = '{' + ret.groups()[3] + '}' + guid = uuid.UUID(guidstr) + self._mapentries[guid] = EfiFvMapFileEntry(name, baseaddr, entry, guid) + return True + + def GetEntry(self, guid): + if guid in self._mapentries.keys(): + return self._mapentries[guid] + return None + +class EfiFvMapFileEntry(object): + def __init__(self, name, baseaddr, entry, guid): + self._name = name + self._baseaddr = baseaddr + self._entry = entry + self._guid = guid + + def GetName(self): + return self._name + + def GetBaseAddress(self): + return self._baseaddr + + def GetEntryPoint(self): + return self._entry + +def list2guid(list): + val1 = list2int(list[0:4]) + val2 = list2int(list[4:6]) + val3 = list2int(list[6:8]) + val4 = 0 + for item in list[8:16]: + val4 = (val4 << 8) | int(item) + + val = val1 << 12 * 8 | val2 << 10 * 8 | val3 << 8 * 8 | val4 + guid = uuid.UUID(int=val) + return guid + +def list2int(list): + val = 0 + for index in range(len(list) - 1, -1, -1): + val = (val << 8) | int(list[index]) + return val + +def align(value, alignment): + return (value + ((alignment - value) & (alignment - 1))) + +gInvalidGuid = uuid.UUID(int=0xffffffffffffffffffffffffffffffff) +def isValidGuid(guid): + if guid == gInvalidGuid: + return False + return True diff --git a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/ini.py b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/ini.py index 7facb9aa24..6d61b7a289 100644 --- a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/ini.py +++ b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/ini.py @@ -1,475 +1,475 @@ -## @file
-#
-# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-from __future__ import absolute_import
-from .message import *
-import re
-import os
-
-section_re = re.compile(r'^\[([\w., "]+)\]')
-
-class BaseINIFile(object):
- _objs = {}
- def __new__(cls, *args, **kwargs):
- """Maintain only a single instance of this object
- @return: instance of this class
-
- """
- if len(args) == 0: return object.__new__(cls)
- filename = args[0]
- parent = None
- if len(args) > 1:
- parent = args[1]
-
- key = os.path.normpath(filename)
- if key not in cls._objs.keys():
- cls._objs[key] = object.__new__(cls)
-
- if parent is not None:
- cls._objs[key].AddParent(parent)
-
- return cls._objs[key]
-
- def __init__(self, filename=None, parent=None):
- self._lines = []
- self._sections = {}
- self._filename = filename
- self._globals = []
- self._isModify = True
-
- def AddParent(self, parent):
- if parent is None: return
- if not hasattr(self, "_parents"):
- self._parents = []
-
- if parent in self._parents:
- ErrorMsg("Duplicate parent is found for INI file %s" % self._filename)
- return
- self._parents.append(parent)
-
- def GetFilename(self):
- return os.path.normpath(self._filename)
-
- def IsModified(self):
- return self._isModify
-
- def Modify(self, modify=True, obj=None):
- if modify == self._isModify: return
- self._isModify = modify
- if modify:
- for parent in self._parents:
- parent.Modify(True, self)
-
- def _ReadLines(self, filename):
- #
- # try to open file
- #
- if not os.path.exists(filename):
- return False
-
- try:
- handle = open(filename, 'r')
- self._lines = handle.readlines()
- handle.close()
- except:
- raise EdkException("Fail to open file %s" % filename)
-
- return True
-
- def GetSectionInstance(self, parent, name, isCombined=False):
- return BaseINISection(parent, name, isCombined)
-
- def GetSectionByName(self, name):
- arr = []
- for key in self._sections.keys():
- if '.private' in key:
- continue
- for item in self._sections[key]:
- if item.GetBaseName().lower().find(name.lower()) != -1:
- arr.append(item)
- return arr
-
- def GetSectionObjectsByName(self, name):
- arr = []
- sects = self.GetSectionByName(name)
- for sect in sects:
- for obj in sect.GetObjects():
- arr.append(obj)
- return arr
-
- def Parse(self):
- if not self._isModify: return True
- if not self._ReadLines(self._filename): return False
-
- sObjs = []
- inGlobal = True
- # process line
- for index in range(len(self._lines)):
- templine = self._lines[index].strip()
- # skip comments
- if len(templine) == 0: continue
- if re.match("^\[=*\]", templine) or re.match("^#", templine) or \
- re.match("\*+/", templine):
- continue
-
- m = section_re.match(templine)
- if m is not None: # found a section
- inGlobal = False
- # Finish the latest section first
- if len(sObjs) != 0:
- for sObj in sObjs:
- sObj._end = index - 1
- if not sObj.Parse():
- ErrorMsg("Fail to parse section %s" % sObj.GetBaseName(),
- self._filename,
- sObj._start)
-
- # start new section
- sname_arr = m.groups()[0].split(',')
- sObjs = []
- for name in sname_arr:
- sObj = self.GetSectionInstance(self, name, (len(sname_arr) > 1))
- sObj._start = index
- sObjs.append(sObj)
- if name.lower() not in self._sections:
- self._sections[name.lower()] = [sObj]
- else:
- self._sections[name.lower()].append(sObj)
- elif inGlobal: # not start any section and find global object
- gObj = BaseINIGlobalObject(self)
- gObj._start = index
- gObj.Parse()
- self._globals.append(gObj)
-
- # Finish the last section
- if len(sObjs) != 0:
- for sObj in sObjs:
- sObj._end = index
- if not sObj.Parse():
- ErrorMsg("Fail to parse section %s" % sObj.GetBaseName(),
- self._filename,
- sObj._start)
-
- self._isModify = False
- return True
-
- def Destroy(self, parent):
-
- # check referenced parent
- if parent is not None:
- assert parent in self._parents, "when destory ini object, can not found parent reference!"
- self._parents.remove(parent)
-
- if len(self._parents) != 0: return
-
- for sects in self._sections.values():
- for sect in sects:
- sect.Destroy()
-
- # dereference from _objs array
- assert self.GetFilename() in self._objs.keys(), "When destroy ini object, can not find obj reference!"
- assert self in self._objs.values(), "When destroy ini object, can not find obj reference!"
- del self._objs[self.GetFilename()]
-
- # dereference self
- self.Clear()
-
- def GetDefine(self, name):
- sects = self.GetSectionByName('Defines')
- for sect in sects:
- for obj in sect.GetObjects():
- line = obj.GetLineByOffset(obj._start).split('#')[0].strip()
- arr = line.split('=')
- if arr[0].strip().lower() == name.strip().lower():
- return arr[1].strip()
- return None
-
- def Clear(self):
- for sects in self._sections.values():
- for sect in sects:
- del sect
- self._sections.clear()
- for gObj in self._globals:
- del gObj
-
- del self._globals[:]
- del self._lines[:]
-
- def Reload(self):
- self.Clear()
- ret = self.Parse()
- if ret:
- self._isModify = False
- return ret
-
- def AddNewSection(self, sectName):
- if sectName.lower() in self._sections.keys():
- ErrorMsg('Section %s can not be created for conflict with existing section')
- return None
-
- sectionObj = self.GetSectionInstance(self, sectName)
- sectionObj._start = len(self._lines)
- sectionObj._end = len(self._lines) + 1
- self._lines.append('[%s]\n' % sectName)
- self._lines.append('\n\n')
- self._sections[sectName.lower()] = sectionObj
- return sectionObj
-
- def CopySectionsByName(self, oldDscObj, nameStr):
- sects = oldDscObj.GetSectionByName(nameStr)
- for sect in sects:
- sectObj = self.AddNewSection(sect.GetName())
- sectObj.Copy(sect)
-
- def __str__(self):
- return ''.join(self._lines)
-
- ## Get file header's comment from basic INI file.
- # The file comments has two style:
- # 1) #/** @file
- # 2) ## @file
- #
- def GetFileHeader(self):
- desc = []
- lineArr = self._lines
- inHeader = False
- for num in range(len(self._lines)):
- line = lineArr[num].strip()
- if not inHeader and (line.startswith("#/**") or line.startswith("##")) and \
- line.find("@file") != -1:
- inHeader = True
- continue
- if inHeader and (line.startswith("#**/") or line.startswith('##')):
- inHeader = False
- break
- if inHeader:
- prefixIndex = line.find('#')
- if prefixIndex == -1:
- desc.append(line)
- else:
- desc.append(line[prefixIndex + 1:])
- return '<br>\n'.join(desc)
-
-class BaseINISection(object):
- def __init__(self, parent, name, isCombined=False):
- self._parent = parent
- self._name = name
- self._isCombined = isCombined
- self._start = 0
- self._end = 0
- self._objs = []
-
- def __del__(self):
- for obj in self._objs:
- del obj
- del self._objs[:]
-
- def GetName(self):
- return self._name
-
- def GetObjects(self):
- return self._objs
-
- def GetParent(self):
- return self._parent
-
- def GetStartLinenumber(self):
- return self._start
-
- def GetEndLinenumber(self):
- return self._end
-
- def GetLine(self, linenumber):
- return self._parent._lines[linenumber]
-
- def GetFilename(self):
- return self._parent.GetFilename()
-
- def GetSectionINIObject(self, parent):
- return BaseINISectionObject(parent)
-
- def Parse(self):
- # skip first line in section, it is used by section name
- visit = self._start + 1
- iniObj = None
- while (visit <= self._end):
- line = self.GetLine(visit).strip()
- if re.match("^\[=*\]", line) or re.match("^#", line) or len(line) == 0:
- visit += 1
- continue
- line = line.split('#')[0].strip()
- if iniObj is not None:
- if line.endswith('}'):
- iniObj._end = visit - self._start
- if not iniObj.Parse():
- ErrorMsg("Fail to parse ini object",
- self.GetFilename(),
- iniObj.GetStartLinenumber())
- else:
- self._objs.append(iniObj)
- iniObj = None
- else:
- iniObj = self.GetSectionINIObject(self)
- iniObj._start = visit - self._start
- if not line.endswith('{'):
- iniObj._end = visit - self._start
- if not iniObj.Parse():
- ErrorMsg("Fail to parse ini object",
- self.GetFilename(),
- iniObj.GetStartLinenumber())
- else:
- self._objs.append(iniObj)
- iniObj = None
- visit += 1
- return True
-
- def Destroy(self):
- for obj in self._objs:
- obj.Destroy()
-
- def GetBaseName(self):
- return self._name
-
- def AddLine(self, line):
- end = self.GetEndLinenumber()
- self._parent._lines.insert(end, line)
- self._end += 1
-
- def Copy(self, sectObj):
- index = sectObj.GetStartLinenumber() + 1
- while index < sectObj.GetEndLinenumber():
- line = sectObj.GetLine(index)
- if not line.strip().startswith('#'):
- self.AddLine(line)
- index += 1
-
- def AddObject(self, obj):
- lines = obj.GenerateLines()
- for line in lines:
- self.AddLine(line)
-
- def GetComment(self):
- comments = []
- start = self._start - 1
- bFound = False
-
- while (start > 0):
- line = self.GetLine(start).strip()
- if len(line) == 0:
- start -= 1
- continue
- if line.startswith('##'):
- bFound = True
- index = line.rfind('#')
- if (index + 1) < len(line):
- comments.append(line[index + 1:])
- break
- if line.startswith('#'):
- start -= 1
- continue
- break
- if bFound:
- end = start + 1
- while (end < self._start):
- line = self.GetLine(end).strip()
- if len(line) == 0: break
- if not line.startswith('#'): break
- index = line.rfind('#')
- if (index + 1) < len(line):
- comments.append(line[index + 1:])
- end += 1
- return comments
-
-class BaseINIGlobalObject(object):
- def __init__(self, parent):
- self._start = 0
- self._end = 0
-
- def Parse(self):
- return True
-
- def __str__(self):
- return parent._lines[self._start]
-
- def __del__(self):
- pass
-
-class BaseINISectionObject(object):
- def __init__(self, parent):
- self._start = 0
- self._end = 0
- self._parent = parent
-
- def __del__(self):
- self._parent = None
-
- def GetParent(self):
- return self._parent
-
- def GetFilename(self):
- return self.GetParent().GetFilename()
-
- def GetPackageName(self):
- return self.GetFilename()
-
- def GetFileObj(self):
- return self.GetParent().GetParent()
-
- def GetStartLinenumber(self):
- return self.GetParent()._start + self._start
-
- def GetLineByOffset(self, offset):
- sect_start = self._parent.GetStartLinenumber()
- linenumber = sect_start + offset
- return self._parent.GetLine(linenumber)
-
- def GetLinenumberByOffset(self, offset):
- return offset + self._parent.GetStartLinenumber()
-
- def Parse(self):
- return True
-
- def Destroy(self):
- pass
-
- def __str__(self):
- return self.GetLineByOffset(self._start).strip()
-
- def GenerateLines(self):
- return ['default setion object string\n']
-
- def GetComment(self):
- comments = []
- start = self.GetStartLinenumber() - 1
- bFound = False
-
- while (start > 0):
- line = self.GetParent().GetLine(start).strip()
- if len(line) == 0:
- start -= 1
- continue
- if line.startswith('##'):
- bFound = True
- index = line.rfind('#')
- if (index + 1) < len(line):
- comments.append(line[index + 1:])
- break
- if line.startswith('#'):
- start -= 1
- continue
- break
- if bFound:
- end = start + 1
- while (end <= self.GetStartLinenumber() - 1):
- line = self.GetParent().GetLine(end).strip()
- if len(line) == 0: break
- if not line.startswith('#'): break
- index = line.rfind('#')
- if (index + 1) < len(line):
- comments.append(line[index + 1:])
- end += 1
- return comments
+## @file +# +# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +from __future__ import absolute_import +from .message import * +import re +import os + +section_re = re.compile(r'^\[([\w., "]+)\]') + +class BaseINIFile(object): + _objs = {} + def __new__(cls, *args, **kwargs): + """Maintain only a single instance of this object + @return: instance of this class + + """ + if len(args) == 0: return object.__new__(cls) + filename = args[0] + parent = None + if len(args) > 1: + parent = args[1] + + key = os.path.normpath(filename) + if key not in cls._objs.keys(): + cls._objs[key] = object.__new__(cls) + + if parent is not None: + cls._objs[key].AddParent(parent) + + return cls._objs[key] + + def __init__(self, filename=None, parent=None): + self._lines = [] + self._sections = {} + self._filename = filename + self._globals = [] + self._isModify = True + + def AddParent(self, parent): + if parent is None: return + if not hasattr(self, "_parents"): + self._parents = [] + + if parent in self._parents: + ErrorMsg("Duplicate parent is found for INI file %s" % self._filename) + return + self._parents.append(parent) + + def GetFilename(self): + return os.path.normpath(self._filename) + + def IsModified(self): + return self._isModify + + def Modify(self, modify=True, obj=None): + if modify == self._isModify: return + self._isModify = modify + if modify: + for parent in self._parents: + parent.Modify(True, self) + + def _ReadLines(self, filename): + # + # try to open file + # + if not os.path.exists(filename): + return False + + try: + handle = open(filename, 'r') + self._lines = handle.readlines() + handle.close() + except: + raise EdkException("Fail to open file %s" % filename) + + return True + + def GetSectionInstance(self, parent, name, isCombined=False): + return BaseINISection(parent, name, isCombined) + + def GetSectionByName(self, name): + arr = [] + for key in self._sections.keys(): + if '.private' in key: + continue + for item in self._sections[key]: + if item.GetBaseName().lower().find(name.lower()) != -1: + arr.append(item) + return arr + + def GetSectionObjectsByName(self, name): + arr = [] + sects = self.GetSectionByName(name) + for sect in sects: + for obj in sect.GetObjects(): + arr.append(obj) + return arr + + def Parse(self): + if not self._isModify: return True + if not self._ReadLines(self._filename): return False + + sObjs = [] + inGlobal = True + # process line + for index in range(len(self._lines)): + templine = self._lines[index].strip() + # skip comments + if len(templine) == 0: continue + if re.match("^\[=*\]", templine) or re.match("^#", templine) or \ + re.match("\*+/", templine): + continue + + m = section_re.match(templine) + if m is not None: # found a section + inGlobal = False + # Finish the latest section first + if len(sObjs) != 0: + for sObj in sObjs: + sObj._end = index - 1 + if not sObj.Parse(): + ErrorMsg("Fail to parse section %s" % sObj.GetBaseName(), + self._filename, + sObj._start) + + # start new section + sname_arr = m.groups()[0].split(',') + sObjs = [] + for name in sname_arr: + sObj = self.GetSectionInstance(self, name, (len(sname_arr) > 1)) + sObj._start = index + sObjs.append(sObj) + if name.lower() not in self._sections: + self._sections[name.lower()] = [sObj] + else: + self._sections[name.lower()].append(sObj) + elif inGlobal: # not start any section and find global object + gObj = BaseINIGlobalObject(self) + gObj._start = index + gObj.Parse() + self._globals.append(gObj) + + # Finish the last section + if len(sObjs) != 0: + for sObj in sObjs: + sObj._end = index + if not sObj.Parse(): + ErrorMsg("Fail to parse section %s" % sObj.GetBaseName(), + self._filename, + sObj._start) + + self._isModify = False + return True + + def Destroy(self, parent): + + # check referenced parent + if parent is not None: + assert parent in self._parents, "when destory ini object, can not found parent reference!" + self._parents.remove(parent) + + if len(self._parents) != 0: return + + for sects in self._sections.values(): + for sect in sects: + sect.Destroy() + + # dereference from _objs array + assert self.GetFilename() in self._objs.keys(), "When destroy ini object, can not find obj reference!" + assert self in self._objs.values(), "When destroy ini object, can not find obj reference!" + del self._objs[self.GetFilename()] + + # dereference self + self.Clear() + + def GetDefine(self, name): + sects = self.GetSectionByName('Defines') + for sect in sects: + for obj in sect.GetObjects(): + line = obj.GetLineByOffset(obj._start).split('#')[0].strip() + arr = line.split('=') + if arr[0].strip().lower() == name.strip().lower(): + return arr[1].strip() + return None + + def Clear(self): + for sects in self._sections.values(): + for sect in sects: + del sect + self._sections.clear() + for gObj in self._globals: + del gObj + + del self._globals[:] + del self._lines[:] + + def Reload(self): + self.Clear() + ret = self.Parse() + if ret: + self._isModify = False + return ret + + def AddNewSection(self, sectName): + if sectName.lower() in self._sections.keys(): + ErrorMsg('Section %s can not be created for conflict with existing section') + return None + + sectionObj = self.GetSectionInstance(self, sectName) + sectionObj._start = len(self._lines) + sectionObj._end = len(self._lines) + 1 + self._lines.append('[%s]\n' % sectName) + self._lines.append('\n\n') + self._sections[sectName.lower()] = sectionObj + return sectionObj + + def CopySectionsByName(self, oldDscObj, nameStr): + sects = oldDscObj.GetSectionByName(nameStr) + for sect in sects: + sectObj = self.AddNewSection(sect.GetName()) + sectObj.Copy(sect) + + def __str__(self): + return ''.join(self._lines) + + ## Get file header's comment from basic INI file. + # The file comments has two style: + # 1) #/** @file + # 2) ## @file + # + def GetFileHeader(self): + desc = [] + lineArr = self._lines + inHeader = False + for num in range(len(self._lines)): + line = lineArr[num].strip() + if not inHeader and (line.startswith("#/**") or line.startswith("##")) and \ + line.find("@file") != -1: + inHeader = True + continue + if inHeader and (line.startswith("#**/") or line.startswith('##')): + inHeader = False + break + if inHeader: + prefixIndex = line.find('#') + if prefixIndex == -1: + desc.append(line) + else: + desc.append(line[prefixIndex + 1:]) + return '<br>\n'.join(desc) + +class BaseINISection(object): + def __init__(self, parent, name, isCombined=False): + self._parent = parent + self._name = name + self._isCombined = isCombined + self._start = 0 + self._end = 0 + self._objs = [] + + def __del__(self): + for obj in self._objs: + del obj + del self._objs[:] + + def GetName(self): + return self._name + + def GetObjects(self): + return self._objs + + def GetParent(self): + return self._parent + + def GetStartLinenumber(self): + return self._start + + def GetEndLinenumber(self): + return self._end + + def GetLine(self, linenumber): + return self._parent._lines[linenumber] + + def GetFilename(self): + return self._parent.GetFilename() + + def GetSectionINIObject(self, parent): + return BaseINISectionObject(parent) + + def Parse(self): + # skip first line in section, it is used by section name + visit = self._start + 1 + iniObj = None + while (visit <= self._end): + line = self.GetLine(visit).strip() + if re.match("^\[=*\]", line) or re.match("^#", line) or len(line) == 0: + visit += 1 + continue + line = line.split('#')[0].strip() + if iniObj is not None: + if line.endswith('}'): + iniObj._end = visit - self._start + if not iniObj.Parse(): + ErrorMsg("Fail to parse ini object", + self.GetFilename(), + iniObj.GetStartLinenumber()) + else: + self._objs.append(iniObj) + iniObj = None + else: + iniObj = self.GetSectionINIObject(self) + iniObj._start = visit - self._start + if not line.endswith('{'): + iniObj._end = visit - self._start + if not iniObj.Parse(): + ErrorMsg("Fail to parse ini object", + self.GetFilename(), + iniObj.GetStartLinenumber()) + else: + self._objs.append(iniObj) + iniObj = None + visit += 1 + return True + + def Destroy(self): + for obj in self._objs: + obj.Destroy() + + def GetBaseName(self): + return self._name + + def AddLine(self, line): + end = self.GetEndLinenumber() + self._parent._lines.insert(end, line) + self._end += 1 + + def Copy(self, sectObj): + index = sectObj.GetStartLinenumber() + 1 + while index < sectObj.GetEndLinenumber(): + line = sectObj.GetLine(index) + if not line.strip().startswith('#'): + self.AddLine(line) + index += 1 + + def AddObject(self, obj): + lines = obj.GenerateLines() + for line in lines: + self.AddLine(line) + + def GetComment(self): + comments = [] + start = self._start - 1 + bFound = False + + while (start > 0): + line = self.GetLine(start).strip() + if len(line) == 0: + start -= 1 + continue + if line.startswith('##'): + bFound = True + index = line.rfind('#') + if (index + 1) < len(line): + comments.append(line[index + 1:]) + break + if line.startswith('#'): + start -= 1 + continue + break + if bFound: + end = start + 1 + while (end < self._start): + line = self.GetLine(end).strip() + if len(line) == 0: break + if not line.startswith('#'): break + index = line.rfind('#') + if (index + 1) < len(line): + comments.append(line[index + 1:]) + end += 1 + return comments + +class BaseINIGlobalObject(object): + def __init__(self, parent): + self._start = 0 + self._end = 0 + + def Parse(self): + return True + + def __str__(self): + return parent._lines[self._start] + + def __del__(self): + pass + +class BaseINISectionObject(object): + def __init__(self, parent): + self._start = 0 + self._end = 0 + self._parent = parent + + def __del__(self): + self._parent = None + + def GetParent(self): + return self._parent + + def GetFilename(self): + return self.GetParent().GetFilename() + + def GetPackageName(self): + return self.GetFilename() + + def GetFileObj(self): + return self.GetParent().GetParent() + + def GetStartLinenumber(self): + return self.GetParent()._start + self._start + + def GetLineByOffset(self, offset): + sect_start = self._parent.GetStartLinenumber() + linenumber = sect_start + offset + return self._parent.GetLine(linenumber) + + def GetLinenumberByOffset(self, offset): + return offset + self._parent.GetStartLinenumber() + + def Parse(self): + return True + + def Destroy(self): + pass + + def __str__(self): + return self.GetLineByOffset(self._start).strip() + + def GenerateLines(self): + return ['default setion object string\n'] + + def GetComment(self): + comments = [] + start = self.GetStartLinenumber() - 1 + bFound = False + + while (start > 0): + line = self.GetParent().GetLine(start).strip() + if len(line) == 0: + start -= 1 + continue + if line.startswith('##'): + bFound = True + index = line.rfind('#') + if (index + 1) < len(line): + comments.append(line[index + 1:]) + break + if line.startswith('#'): + start -= 1 + continue + break + if bFound: + end = start + 1 + while (end <= self.GetStartLinenumber() - 1): + line = self.GetParent().GetLine(end).strip() + if len(line) == 0: break + if not line.startswith('#'): break + index = line.rfind('#') + if (index + 1) < len(line): + comments.append(line[index + 1:]) + end += 1 + return comments diff --git a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/inidocview.py b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/inidocview.py index 849d0fc91a..46015d54e5 100644 --- a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/inidocview.py +++ b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/inidocview.py @@ -1,17 +1,17 @@ -## @file
-#
-# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-import core.editor
-
-class INIDoc(core.editor.EditorDocument):
- def __init__(self):
- core.editor.EditorDocument.__init__(self)
- self._iniobj = None
-
-
-class INIView(core.editor.EditorView):
- pass
+## @file +# +# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +import core.editor + +class INIDoc(core.editor.EditorDocument): + def __init__(self): + core.editor.EditorDocument.__init__(self) + self._iniobj = None + + +class INIView(core.editor.EditorView): + pass diff --git a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/message.py b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/message.py index 882538a171..e36930ef61 100644 --- a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/message.py +++ b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/message.py @@ -1,46 +1,46 @@ -## @file
-#
-# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-def GetEdkLogger():
- import logging
- return logging.getLogger('edk')
-
-class EdkException(Exception):
- def __init__(self, message, fName=None, fNo=None):
- self._message = message
- ErrorMsg(message, fName, fNo)
-
- def GetMessage(self):
- return '[EDK Failure]: %s' %self._message
-
-def ErrorMsg(mess, fName=None, fNo=None):
- GetEdkLogger().error(NormalMessage('#ERR#', mess, fName, fNo))
-
-def LogMsg(mess, fName=None, fNo=None):
- GetEdkLogger().info(NormalMessage('@LOG@', mess, fName, fNo))
-
-def WarnMsg(mess, fName=None, fNo=None):
- GetEdkLogger().warning(NormalMessage('!WAR!', mess, fName, fNo))
-
-def NormalMessage(type, mess, fName=None, fNo=None):
- strMsg = type
-
- if fName is not None:
- strMsg += ' %s' % fName.replace('/', '\\')
- if fNo is not None:
- strMsg += '(%d):' % fNo
- else:
- strMsg += ' :'
-
- if fName is None and fNo is None:
- strMsg += ' '
- strMsg += mess
-
- return strMsg
-
-
-
+## @file +# +# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +def GetEdkLogger(): + import logging + return logging.getLogger('edk') + +class EdkException(Exception): + def __init__(self, message, fName=None, fNo=None): + self._message = message + ErrorMsg(message, fName, fNo) + + def GetMessage(self): + return '[EDK Failure]: %s' %self._message + +def ErrorMsg(mess, fName=None, fNo=None): + GetEdkLogger().error(NormalMessage('#ERR#', mess, fName, fNo)) + +def LogMsg(mess, fName=None, fNo=None): + GetEdkLogger().info(NormalMessage('@LOG@', mess, fName, fNo)) + +def WarnMsg(mess, fName=None, fNo=None): + GetEdkLogger().warning(NormalMessage('!WAR!', mess, fName, fNo)) + +def NormalMessage(type, mess, fName=None, fNo=None): + strMsg = type + + if fName is not None: + strMsg += ' %s' % fName.replace('/', '\\') + if fNo is not None: + strMsg += '(%d):' % fNo + else: + strMsg += ' :' + + if fName is None and fNo is None: + strMsg += ' ' + strMsg += mess + + return strMsg + + + |
