summaryrefslogtreecommitdiff
path: root/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins
diff options
context:
space:
mode:
Diffstat (limited to 'BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins')
-rw-r--r--BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/__init__.py12
-rw-r--r--BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/__init__.py12
-rw-r--r--BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/doxygen.py890
-rw-r--r--BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/efibinary.py1212
-rw-r--r--BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/ini.py950
-rw-r--r--BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/inidocview.py34
-rw-r--r--BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/message.py92
-rw-r--r--BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/__init__.py12
-rw-r--r--BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/__init__.py12
-rw-r--r--BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/baseobject.py1856
-rw-r--r--BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/dec.py626
-rw-r--r--BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/doxygengen.py2168
-rw-r--r--BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/doxygengen_spec.py2172
-rw-r--r--BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/dsc.py390
-rw-r--r--BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/inf.py670
15 files changed, 5554 insertions, 5554 deletions
diff --git a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/__init__.py b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/__init__.py
index 57dfebde59..a7909346f3 100644
--- a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/__init__.py
+++ b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/__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/__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
+
+
+
diff --git a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/__init__.py b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/__init__.py
index 57dfebde59..a7909346f3 100644
--- a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/__init__.py
+++ b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/__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/edk2/model/__init__.py b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/__init__.py
index 57dfebde59..a7909346f3 100644
--- a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/__init__.py
+++ b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/__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/edk2/model/baseobject.py b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/baseobject.py
index ee00529f46..0bafe2dce2 100644
--- a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/baseobject.py
+++ b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/baseobject.py
@@ -1,928 +1,928 @@
-## @file
-#
-# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-
-from plugins.EdkPlugins.basemodel import ini
-from plugins.EdkPlugins.edk2.model import dsc
-from plugins.EdkPlugins.edk2.model import inf
-from plugins.EdkPlugins.edk2.model import dec
-import os
-from plugins.EdkPlugins.basemodel.message import *
-
-class SurfaceObject(object):
- _objs = {}
-
- def __new__(cls, *args, **kwargs):
- """Maintain only a single instance of this object
- @return: instance of this class
-
- """
- obj = object.__new__(cls)
- if "None" not in cls._objs:
- cls._objs["None"] = []
- cls._objs["None"].append(obj)
-
- return obj
-
- def __init__(self, parent, workspace):
- self._parent = parent
- self._fileObj = None
- self._workspace = workspace
- self._isModify = False
- self._modifiedObjs = []
-
- def __del__(self):
- pass
-
- def Destroy(self):
- key = self.GetRelativeFilename()
- self.GetFileObj().Destroy(self)
- del self._fileObj
- # dereference self from _objs arrary
- assert key in self._objs, "when destory, object is not in obj list"
- assert self in self._objs[key], "when destory, object is not in obj list"
- self._objs[key].remove(self)
- if len(self._objs[key]) == 0:
- del self._objs[key]
-
- def GetParent(self):
- return self._parent
-
- def GetWorkspace(self):
- return self._workspace
-
- def GetFileObjectClass(self):
- return ini.BaseINIFile
-
- def GetFilename(self):
- return self.GetFileObj().GetFilename()
-
- def GetFileObj(self):
- return self._fileObj
-
- def GetRelativeFilename(self):
- fullPath = self.GetFilename()
- return fullPath[len(self._workspace) + 1:]
-
- def Load(self, relativePath):
- # if has been loaded, directly return
- if self._fileObj is not None: return True
-
- relativePath = os.path.normpath(relativePath)
- fullPath = os.path.join(self._workspace, relativePath)
- fullPath = os.path.normpath(fullPath)
-
- if not os.path.exists(fullPath):
- ErrorMsg("file does not exist!", fullPath)
- return False
-
- self._fileObj = self.GetFileObjectClass()(fullPath, self)
-
- if not self._fileObj.Parse():
- ErrorMsg("Fail to parse file!", fullPath)
- return False
-
- # remove self from None list to list with filename as key
- cls = self.__class__
- if self not in cls._objs["None"]:
- ErrorMsg("Sufrace object does not be create into None list")
- cls._objs["None"].remove(self)
- if relativePath not in cls._objs:
- cls._objs[relativePath] = []
- cls._objs[relativePath].append(self)
-
- return True
-
- def Reload(self, force=False):
- ret = True
- # whether require must be update
- if force:
- ret = self.GetFileObj().Reload(True)
- else:
- if self.IsModified():
- if self.GetFileObj().IsModified():
- ret = self.GetFileObj().Reload()
- return ret
-
- def Modify(self, modify=True, modifiedObj=None):
- if modify:
- #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj))
- if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify:
- return
- self._isModify = modify
- self.GetParent().Modify(modify, self)
- else:
- self._isModify = modify
-
- def IsModified(self):
- return self._isModify
-
- def GetModifiedObjs(self):
- return self._modifiedObjs
-
- def FilterObjsByArch(self, objs, arch):
- arr = []
- for obj in objs:
- if obj.GetArch().lower() == 'common':
- arr.append(obj)
- continue
- if obj.GetArch().lower() == arch.lower():
- arr.append(obj)
- continue
- return arr
-
-class Platform(SurfaceObject):
- def __init__(self, parent, workspace):
- SurfaceObject.__init__(self, parent, workspace)
- self._modules = []
- self._packages = []
-
- def Destroy(self):
- for module in self._modules:
- module.Destroy()
- del self._modules[:]
-
- del self._packages[:]
- SurfaceObject.Destroy(self)
-
- def GetName(self):
- return self.GetFileObj().GetDefine("PLATFORM_NAME")
-
- def GetFileObjectClass(self):
- return dsc.DSCFile
-
- def GetModuleCount(self):
- if self.GetFileObj() is None:
- ErrorMsg("Fail to get module count because DSC file has not been load!")
-
- return len(self.GetFileObj().GetComponents())
-
- def GetSupportArchs(self):
- return self.GetFileObj().GetDefine("SUPPORTED_ARCHITECTURES").strip().split('#')[0].split('|')
-
- def LoadModules(self, precallback=None, postcallback=None):
- for obj in self.GetFileObj().GetComponents():
- mFilename = obj.GetFilename()
- if precallback is not None:
- precallback(self, mFilename)
- arch = obj.GetArch()
- if arch.lower() == 'common':
- archarr = self.GetSupportArchs()
- else:
- archarr = [arch]
- for arch in archarr:
- module = Module(self, self.GetWorkspace())
- if module.Load(mFilename, arch, obj.GetOveridePcds(), obj.GetOverideLibs()):
- self._modules.append(module)
- if postcallback is not None:
- postcallback(self, module)
- else:
- del module
- ErrorMsg("Fail to load module %s" % mFilename)
-
- def GetModules(self):
- return self._modules
-
- def GetLibraryPath(self, classname, arch, type):
- objs = self.GetFileObj().GetSectionObjectsByName("libraryclasses")
-
- for obj in objs:
- if classname.lower() != obj.GetClass().lower():
- continue
- if obj.GetArch().lower() != 'common' and \
- obj.GetArch().lower() != arch.lower():
- continue
-
- if obj.GetModuleType().lower() != 'common' and \
- obj.GetModuleType().lower() != type.lower():
- continue
-
- return obj.GetInstance()
-
- ErrorMsg("Fail to get library class %s [%s][%s] from platform %s" % (classname, arch, type, self.GetFilename()))
- return None
-
- def GetPackage(self, path):
- package = self.GetParent().GetPackage(path)
- if package not in self._packages:
- self._packages.append(package)
- return package
-
- def GetPcdBuildObjs(self, name, arch=None):
- arr = []
- objs = self.GetFileObj().GetSectionObjectsByName('pcds')
- for obj in objs:
- if obj.GetPcdName().lower() == name.lower():
- arr.append(obj)
- if arch is not None:
- arr = self.FilterObjsByArch(arr, arch)
- return arr
-
- def Reload(self, callback=None):
- # do not care force paramter for platform object
- isFileChanged = self.GetFileObj().IsModified()
- ret = SurfaceObject.Reload(self, False)
- if not ret: return False
- if isFileChanged:
- # destroy all modules and reload them again
- for obj in self._modules:
- obj.Destroy()
- del self._modules[:]
- del self._packages[:]
- self.LoadModules(callback)
- else:
- for obj in self._modules:
- callback(self, obj.GetFilename())
- obj.Reload()
-
- self.Modify(False)
- return True
-
- def Modify(self, modify=True, modifiedObj=None):
- if modify:
- #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj))
- if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify:
- return
- self._isModify = modify
- self.GetParent().Modify(modify, self)
- else:
- if self.GetFileObj().IsModified():
- return
- for obj in self._modules:
- if obj.IsModified():
- return
-
- self._isModify = modify
- self.GetParent().Modify(modify, self)
-
- def GetModuleObject(self, relativePath, arch):
- path = os.path.normpath(relativePath)
- for obj in self._modules:
- if obj.GetRelativeFilename() == path:
- if arch.lower() == 'common':
- return obj
- if obj.GetArch() == arch:
- return obj
- return None
-
- def GenerateFullReferenceDsc(self):
- oldDsc = self.GetFileObj()
- newDsc = dsc.DSCFile()
- newDsc.CopySectionsByName(oldDsc, 'defines')
- newDsc.CopySectionsByName(oldDsc, 'SkuIds')
-
- #
- # Dynamic common section should also be copied
- #
- newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicDefault')
- newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicHii')
- newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicVpd')
- newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicEx')
-
- sects = oldDsc.GetSectionByName('Components')
- for oldSect in sects:
- newSect = newDsc.AddNewSection(oldSect.GetName())
- for oldComObj in oldSect.GetObjects():
- module = self.GetModuleObject(oldComObj.GetFilename(), oldSect.GetArch())
- if module is None: continue
-
- newComObj = dsc.DSCComponentObject(newSect)
- newComObj.SetFilename(oldComObj.GetFilename())
-
- # add all library instance for override section
- libdict = module.GetLibraries()
- for libclass in libdict.keys():
- if libdict[libclass] is not None:
- newComObj.AddOverideLib(libclass, libdict[libclass].GetRelativeFilename().replace('\\', '/'))
-
- # add all pcds for override section
- pcddict = module.GetPcds()
- for pcd in pcddict.values():
- buildPcd = pcd.GetBuildObj()
- buildType = buildPcd.GetPcdType()
- buildValue = None
- if buildType.lower() == 'pcdsdynamichii' or \
- buildType.lower() == 'pcdsdynamicvpd' or \
- buildType.lower() == 'pcdsdynamicdefault':
- buildType = 'PcdsDynamic'
- if buildType != 'PcdsDynamic':
- buildValue = buildPcd.GetPcdValue()
- newComObj.AddOveridePcd(buildPcd.GetPcdName(),
- buildType,
- buildValue)
- newSect.AddObject(newComObj)
- return newDsc
-
-class Module(SurfaceObject):
- def __init__(self, parent, workspace):
- SurfaceObject.__init__(self, parent, workspace)
- self._arch = 'common'
- self._parent = parent
- self._overidePcds = {}
- self._overideLibs = {}
- self._libs = {}
- self._pcds = {}
- self._ppis = []
- self._protocols = []
- self._depexs = []
- self._guids = []
- self._packages = []
-
- def Destroy(self):
- for lib in self._libs.values():
- if lib is not None:
- lib.Destroy()
- self._libs.clear()
-
- for pcd in self._pcds.values():
- pcd.Destroy()
- self._pcds.clear()
-
- for ppi in self._ppis:
- ppi.DeRef(self)
- del self._ppis[:]
-
- for protocol in self._protocols:
- if protocol is not None:
- protocol.DeRef(self)
- del self._protocols[:]
-
- for guid in self._guids:
- if guid is not None:
- guid.DeRef(self)
- del self._guids[:]
-
- del self._packages[:]
- del self._depexs[:]
- SurfaceObject.Destroy(self)
-
- def GetFileObjectClass(self):
- return inf.INFFile
-
- def GetLibraries(self):
- return self._libs
-
- def Load(self, filename, arch='common', overidePcds=None, overideLibs=None):
- if not SurfaceObject.Load(self, filename):
- return False
-
- self._arch = arch
- if overidePcds is not None:
- self._overideLibs = overideLibs
- if overideLibs is not None:
- self._overidePcds = overidePcds
-
- self._SearchLibraries()
- self._SearchPackage()
- self._SearchSurfaceItems()
- return True
-
- def GetArch(self):
- return self._arch
-
- def GetModuleName(self):
- return self.GetFileObj().GetDefine("BASE_NAME")
-
- def GetModuleType(self):
- return self.GetFileObj().GetDefine("MODULE_TYPE")
-
- def GetPlatform(self):
- return self.GetParent()
-
- def GetModuleObj(self):
- return self
-
- def GetPcds(self):
- pcds = self._pcds.copy()
- for lib in self._libs.values():
- if lib is None: continue
- for name in lib._pcds.keys():
- pcds[name] = lib._pcds[name]
- return pcds
-
- def GetPpis(self):
- ppis = []
- ppis += self._ppis
- for lib in self._libs.values():
- if lib is None: continue
- ppis += lib._ppis
- return ppis
-
- def GetProtocols(self):
- pros = []
- pros = self._protocols
- for lib in self._libs.values():
- if lib is None: continue
- pros += lib._protocols
- return pros
-
- def GetGuids(self):
- guids = []
- guids += self._guids
- for lib in self._libs.values():
- if lib is None: continue
- guids += lib._guids
- return guids
-
- def GetDepexs(self):
- deps = []
- deps += self._depexs
- for lib in self._libs.values():
- if lib is None: continue
- deps += lib._depexs
- return deps
-
- def IsLibrary(self):
- return self.GetFileObj().GetDefine("LIBRARY_CLASS") is not None
-
- def GetLibraryInstance(self, classname, arch, type):
- if classname not in self._libs.keys():
- # find in overide lib firstly
- if classname in self._overideLibs.keys():
- self._libs[classname] = Library(self, self.GetWorkspace())
- self._libs[classname].Load(self._overideLibs[classname])
- return self._libs[classname]
-
- parent = self.GetParent()
- if issubclass(parent.__class__, Platform):
- path = parent.GetLibraryPath(classname, arch, type)
- if path is None:
- ErrorMsg('Fail to get library instance for %s' % classname, self.GetFilename())
- return None
- self._libs[classname] = Library(self, self.GetWorkspace())
- if not self._libs[classname].Load(path, self.GetArch()):
- self._libs[classname] = None
- else:
- self._libs[classname] = parent.GetLibraryInstance(classname, arch, type)
- return self._libs[classname]
-
- def GetSourceObjs(self):
- return self.GetFileObj().GetSectionObjectsByName('source')
-
- def _SearchLibraries(self):
- objs = self.GetFileObj().GetSectionObjectsByName('libraryclasses')
- arch = self.GetArch()
- type = self.GetModuleType()
- for obj in objs:
- if obj.GetArch().lower() != 'common' and \
- obj.GetArch().lower() not in self.GetPlatform().GetSupportArchs():
- continue
- classname = obj.GetClass()
- instance = self.GetLibraryInstance(classname, arch, type)
- if not self.IsLibrary() and instance is not None:
- instance._isInherit = False
-
- if classname not in self._libs.keys():
- self._libs[classname] = instance
-
- def _SearchSurfaceItems(self):
- # get surface item from self's inf
- pcds = []
- ppis = []
- pros = []
- deps = []
- guids = []
- if self.GetFileObj() is not None:
- pcds = self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('pcd'),
- self.GetArch())
- for pcd in pcds:
- if pcd.GetPcdName() not in self._pcds.keys():
- pcdItem = PcdItem(pcd.GetPcdName(), self, pcd)
- self._pcds[pcd.GetPcdName()] = ModulePcd(self,
- pcd.GetPcdName(),
- pcd,
- pcdItem)
-
- ppis += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('ppis'),
- self.GetArch())
-
- for ppi in ppis:
- item = PpiItem(ppi.GetName(), self, ppi)
- if item not in self._ppis:
- self._ppis.append(item)
-
- pros += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('protocols'),
- self.GetArch())
-
- for pro in pros:
- item = ProtocolItem(pro.GetName(), self, pro)
- if item not in self._protocols:
- self._protocols.append(item)
-
- deps += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('depex'),
- self.GetArch())
- for dep in deps:
- item = DepexItem(self, dep)
- self._depexs.append(item)
-
- guids += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('guids'),
- self.GetArch())
- for guid in guids:
- item = GuidItem(guid.GetName(), self, guid)
- if item not in self._guids:
- self._guids.append(item)
-
- def _SearchPackage(self):
- objs = self.GetFileObj().GetSectionObjectsByName('packages')
- for obj in objs:
- package = self.GetPlatform().GetPackage(obj.GetPath())
- if package is not None:
- self._packages.append(package)
-
- def GetPackages(self):
- return self._packages
-
- def GetPcdObjects(self):
- if self.GetFileObj() is None:
- return []
-
- return self.GetFileObj().GetSectionObjectsByName('pcd')
-
- def GetLibraryClassHeaderFilePath(self):
- lcname = self.GetFileObj().GetProduceLibraryClass()
- if lcname is None: return None
-
- pkgs = self.GetPackages()
- for package in pkgs:
- path = package.GetLibraryClassHeaderPathByName(lcname)
- if path is not None:
- return os.path.realpath(os.path.join(package.GetFileObj().GetPackageRootPath(), path))
- return None
-
- def Reload(self, force=False, callback=None):
- if callback is not None:
- callback(self, "Starting reload...")
-
- ret = SurfaceObject.Reload(self, force)
- if not ret: return False
-
- if not force and not self.IsModified():
- return True
-
- for lib in self._libs.values():
- if lib is not None:
- lib.Destroy()
- self._libs.clear()
-
- for pcd in self._pcds.values():
- pcd.Destroy()
- self._pcds.clear()
-
- for ppi in self._ppis:
- ppi.DeRef(self)
- del self._ppis[:]
-
- for protocol in self._protocols:
- protocol.DeRef(self)
- del self._protocols[:]
-
- for guid in self._guids:
- guid.DeRef(self)
- del self._guids[:]
-
- del self._packages[:]
- del self._depexs[:]
-
- if callback is not None:
- callback(self, "Searching libraries...")
- self._SearchLibraries()
- if callback is not None:
- callback(self, "Searching packages...")
- self._SearchPackage()
- if callback is not None:
- callback(self, "Searching surface items...")
- self._SearchSurfaceItems()
-
- self.Modify(False)
- return True
-
- def Modify(self, modify=True, modifiedObj=None):
- if modify:
- #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj))
- if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify:
- return
- self._isModify = modify
- self.GetParent().Modify(modify, self)
- else:
- if self.GetFileObj().IsModified():
- return
-
- self._isModify = modify
- self.GetParent().Modify(modify, self)
-
-class Library(Module):
- def __init__(self, parent, workspace):
- Module.__init__(self, parent, workspace)
- self._isInherit = True
-
- def IsInherit(self):
- return self._isInherit
-
- def GetModuleType(self):
- return self.GetParent().GetModuleType()
-
- def GetPlatform(self):
- return self.GetParent().GetParent()
-
- def GetModuleObj(self):
- return self.GetParent()
-
- def GetArch(self):
- return self.GetParent().GetArch()
-
- def Destroy(self):
- self._libs.clear()
- self._pcds.clear()
- SurfaceObject.Destroy(self)
-
-class Package(SurfaceObject):
- def __init__(self, parent, workspace):
- SurfaceObject.__init__(self, parent, workspace)
- self._pcds = {}
- self._guids = {}
- self._protocols = {}
- self._ppis = {}
-
- def GetPcds(self):
- return self._pcds
-
- def GetPpis(self):
- return list(self._ppis.values())
-
- def GetProtocols(self):
- return list(self._protocols.values())
-
- def GetGuids(self):
- return list(self._guids.values())
-
- def Destroy(self):
- for pcd in self._pcds.values():
- if pcd is not None:
- pcd.Destroy()
- for guid in self._guids.values():
- if guid is not None:
- guid.Destroy()
- for protocol in self._protocols.values():
- if protocol is not None:
- protocol.Destroy()
- for ppi in self._ppis.values():
- if ppi is not None:
- ppi.Destroy()
- self._pcds.clear()
- self._guids.clear()
- self._protocols.clear()
- self._ppis.clear()
- self._pcds.clear()
- SurfaceObject.Destroy(self)
-
- def Load(self, relativePath):
- ret = SurfaceObject.Load(self, relativePath)
- if not ret: return False
- pcds = self.GetFileObj().GetSectionObjectsByName('pcds')
- for pcd in pcds:
- if pcd.GetPcdName() in self._pcds.keys():
- if self._pcds[pcd.GetPcdName()] is not None:
- self._pcds[pcd.GetPcdName()].AddDecObj(pcd)
- else:
- self._pcds[pcd.GetPcdName()] = PcdItem(pcd.GetPcdName(), self, pcd)
-
- guids = self.GetFileObj().GetSectionObjectsByName('guids')
- for guid in guids:
- if guid.GetName() not in self._guids.keys():
- self._guids[guid.GetName()] = GuidItem(guid.GetName(), self, guid)
- else:
- WarnMsg("Duplicate definition for %s" % guid.GetName())
-
- ppis = self.GetFileObj().GetSectionObjectsByName('ppis')
- for ppi in ppis:
- if ppi.GetName() not in self._ppis.keys():
- self._ppis[ppi.GetName()] = PpiItem(ppi.GetName(), self, ppi)
- else:
- WarnMsg("Duplicate definition for %s" % ppi.GetName())
-
- protocols = self.GetFileObj().GetSectionObjectsByName('protocols')
- for protocol in protocols:
- if protocol.GetName() not in self._protocols.keys():
- self._protocols[protocol.GetName()] = ProtocolItem(protocol.GetName(), self, protocol)
- else:
- WarnMsg("Duplicate definition for %s" % protocol.GetName())
-
- return True
-
- def GetFileObjectClass(self):
- return dec.DECFile
-
- def GetName(self):
- return self.GetFileObj().GetDefine("PACKAGE_NAME")
-
- def GetPcdDefineObjs(self, name=None):
- arr = []
- objs = self.GetFileObj().GetSectionObjectsByName('pcds')
- if name is None: return objs
-
- for obj in objs:
- if obj.GetPcdName().lower() == name.lower():
- arr.append(obj)
- return arr
-
- def GetLibraryClassObjs(self):
- return self.GetFileObj().GetSectionObjectsByName('libraryclasses')
-
- def Modify(self, modify=True, modifiedObj=None):
- if modify:
- self._isModify = modify
- self.GetParent().Modify(modify, self)
- else:
- if self.GetFileObj().IsModified():
- return
-
- self._isModify = modify
- self.GetParent().Modify(modify, self)
-
- def GetLibraryClassHeaderPathByName(self, clsname):
- objs = self.GetLibraryClassObjs()
- for obj in objs:
- if obj.GetClassName() == clsname:
- return obj.GetHeaderFile()
- return None
-
-class DepexItem(object):
- def __init__(self, parent, infObj):
- self._parent = parent
- self._infObj = infObj
-
- def GetDepexString(self):
- return str(self._infObj)
-
- def GetInfObject(self):
- return self._infObj
-
-class ModulePcd(object):
- _type_mapping = {'FeaturePcd': 'PcdsFeatureFlag',
- 'FixedPcd': 'PcdsFixedAtBuild',
- 'PatchPcd': 'PcdsPatchableInModule'}
-
- def __init__(self, parent, name, infObj, pcdItem):
- assert issubclass(parent.__class__, Module), "Module's PCD's parent must be module!"
- assert pcdItem is not None, 'Pcd %s does not in some package!' % name
-
- self._name = name
- self._parent = parent
- self._pcdItem = pcdItem
- self._infObj = infObj
-
- def GetName(self):
- return self._name
-
- def GetParent(self):
- return self._name
-
- def GetArch(self):
- return self._parent.GetArch()
-
- def Destroy(self):
- self._pcdItem.DeRef(self._parent)
- self._infObj = None
-
- def GetBuildObj(self):
- platformInfos = self._parent.GetPlatform().GetPcdBuildObjs(self._name, self.GetArch())
- modulePcdType = self._infObj.GetPcdType()
-
- # if platform do not gives pcd's value, get default value from package
- if len(platformInfos) == 0:
- if modulePcdType.lower() == 'pcd':
- return self._pcdItem.GetDecObject()
- else:
- for obj in self._pcdItem.GetDecObjects():
- if modulePcdType not in self._type_mapping.keys():
- ErrorMsg("Invalid PCD type %s" % modulePcdType)
- return None
-
- if self._type_mapping[modulePcdType] == obj.GetPcdType():
- return obj
- ErrorMsg ('Module PCD type %s does not in valied range [%s] in package!' % \
- (modulePcdType))
- else:
- if modulePcdType.lower() == 'pcd':
- if len(platformInfos) > 1:
- WarnMsg("Find more than one value for PCD %s in platform %s" % \
- (self._name, self._parent.GetPlatform().GetFilename()))
- return platformInfos[0]
- else:
- for obj in platformInfos:
- if modulePcdType not in self._type_mapping.keys():
- ErrorMsg("Invalid PCD type %s" % modulePcdType)
- return None
-
- if self._type_mapping[modulePcdType] == obj.GetPcdType():
- return obj
-
- ErrorMsg('Can not find value for pcd %s in pcd type %s' % \
- (self._name, modulePcdType))
- return None
-
-
-class SurfaceItem(object):
- _objs = {}
-
- def __new__(cls, *args, **kwargs):
- """Maintain only a single instance of this object
- @return: instance of this class
-
- """
- name = args[0]
- parent = args[1]
- fileObj = args[2]
- if issubclass(parent.__class__, Package):
- if name in cls._objs.keys():
- ErrorMsg("%s item is duplicated defined in packages: %s and %s" %
- (name, parent.GetFilename(), cls._objs[name].GetParent().GetFilename()))
- return None
- obj = object.__new__(cls)
- cls._objs[name] = obj
- return obj
- elif issubclass(parent.__class__, Module):
- if name not in cls._objs.keys():
- ErrorMsg("%s item does not defined in any package! It is used by module %s" % \
- (name, parent.GetFilename()))
- return None
- return cls._objs[name]
-
- return None
-
-
- def __init__(self, name, parent, fileObj):
- if issubclass(parent.__class__, Package):
- self._name = name
- self._parent = parent
- self._decObj = [fileObj]
- self._refMods = {}
- else:
- self.RefModule(parent, fileObj)
-
- @classmethod
- def GetObjectDict(cls):
- return cls._objs
-
- def GetParent(self):
- return self._parent
-
- def GetReference(self):
- return self._refMods
-
- def RefModule(self, mObj, infObj):
- if mObj in self._refMods.keys():
- return
- self._refMods[mObj] = infObj
-
- def DeRef(self, mObj):
- if mObj not in self._refMods.keys():
- WarnMsg("%s is not referenced by module %s" % (self._name, mObj.GetFilename()))
- return
- del self._refMods[mObj]
-
- def Destroy(self):
- self._refMods.clear()
- cls = self.__class__
- del cls._objs[self._name]
-
- def GetName(self):
- return self._name
-
- def GetDecObject(self):
- return self._decObj[0]
-
- def GetDecObjects(self):
- return self._decObj
-
-class PcdItem(SurfaceItem):
- def AddDecObj(self, fileObj):
- for decObj in self._decObj:
- if decObj.GetFilename() != fileObj.GetFilename():
- ErrorMsg("Pcd %s defined in more than one packages : %s and %s" % \
- (self._name, decObj.GetFilename(), fileObj.GetFilename()))
- return
- if decObj.GetPcdType() == fileObj.GetPcdType() and \
- decObj.GetArch().lower() == fileObj.GetArch():
- ErrorMsg("Pcd %s is duplicated defined in pcd type %s in package %s" % \
- (self._name, decObj.GetPcdType(), decObj.GetFilename()))
- return
- self._decObj.append(fileObj)
-
- def GetValidPcdType(self):
- types = []
- for obj in self._decObj:
- if obj.GetPcdType() not in types:
- types += obj.GetPcdType()
- return types
-
-class GuidItem(SurfaceItem):
- pass
-
-class PpiItem(SurfaceItem):
- pass
-
-class ProtocolItem(SurfaceItem):
- pass
+## @file
+#
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+from plugins.EdkPlugins.basemodel import ini
+from plugins.EdkPlugins.edk2.model import dsc
+from plugins.EdkPlugins.edk2.model import inf
+from plugins.EdkPlugins.edk2.model import dec
+import os
+from plugins.EdkPlugins.basemodel.message import *
+
+class SurfaceObject(object):
+ _objs = {}
+
+ def __new__(cls, *args, **kwargs):
+ """Maintain only a single instance of this object
+ @return: instance of this class
+
+ """
+ obj = object.__new__(cls)
+ if "None" not in cls._objs:
+ cls._objs["None"] = []
+ cls._objs["None"].append(obj)
+
+ return obj
+
+ def __init__(self, parent, workspace):
+ self._parent = parent
+ self._fileObj = None
+ self._workspace = workspace
+ self._isModify = False
+ self._modifiedObjs = []
+
+ def __del__(self):
+ pass
+
+ def Destroy(self):
+ key = self.GetRelativeFilename()
+ self.GetFileObj().Destroy(self)
+ del self._fileObj
+ # dereference self from _objs arrary
+ assert key in self._objs, "when destory, object is not in obj list"
+ assert self in self._objs[key], "when destory, object is not in obj list"
+ self._objs[key].remove(self)
+ if len(self._objs[key]) == 0:
+ del self._objs[key]
+
+ def GetParent(self):
+ return self._parent
+
+ def GetWorkspace(self):
+ return self._workspace
+
+ def GetFileObjectClass(self):
+ return ini.BaseINIFile
+
+ def GetFilename(self):
+ return self.GetFileObj().GetFilename()
+
+ def GetFileObj(self):
+ return self._fileObj
+
+ def GetRelativeFilename(self):
+ fullPath = self.GetFilename()
+ return fullPath[len(self._workspace) + 1:]
+
+ def Load(self, relativePath):
+ # if has been loaded, directly return
+ if self._fileObj is not None: return True
+
+ relativePath = os.path.normpath(relativePath)
+ fullPath = os.path.join(self._workspace, relativePath)
+ fullPath = os.path.normpath(fullPath)
+
+ if not os.path.exists(fullPath):
+ ErrorMsg("file does not exist!", fullPath)
+ return False
+
+ self._fileObj = self.GetFileObjectClass()(fullPath, self)
+
+ if not self._fileObj.Parse():
+ ErrorMsg("Fail to parse file!", fullPath)
+ return False
+
+ # remove self from None list to list with filename as key
+ cls = self.__class__
+ if self not in cls._objs["None"]:
+ ErrorMsg("Sufrace object does not be create into None list")
+ cls._objs["None"].remove(self)
+ if relativePath not in cls._objs:
+ cls._objs[relativePath] = []
+ cls._objs[relativePath].append(self)
+
+ return True
+
+ def Reload(self, force=False):
+ ret = True
+ # whether require must be update
+ if force:
+ ret = self.GetFileObj().Reload(True)
+ else:
+ if self.IsModified():
+ if self.GetFileObj().IsModified():
+ ret = self.GetFileObj().Reload()
+ return ret
+
+ def Modify(self, modify=True, modifiedObj=None):
+ if modify:
+ #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj))
+ if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify:
+ return
+ self._isModify = modify
+ self.GetParent().Modify(modify, self)
+ else:
+ self._isModify = modify
+
+ def IsModified(self):
+ return self._isModify
+
+ def GetModifiedObjs(self):
+ return self._modifiedObjs
+
+ def FilterObjsByArch(self, objs, arch):
+ arr = []
+ for obj in objs:
+ if obj.GetArch().lower() == 'common':
+ arr.append(obj)
+ continue
+ if obj.GetArch().lower() == arch.lower():
+ arr.append(obj)
+ continue
+ return arr
+
+class Platform(SurfaceObject):
+ def __init__(self, parent, workspace):
+ SurfaceObject.__init__(self, parent, workspace)
+ self._modules = []
+ self._packages = []
+
+ def Destroy(self):
+ for module in self._modules:
+ module.Destroy()
+ del self._modules[:]
+
+ del self._packages[:]
+ SurfaceObject.Destroy(self)
+
+ def GetName(self):
+ return self.GetFileObj().GetDefine("PLATFORM_NAME")
+
+ def GetFileObjectClass(self):
+ return dsc.DSCFile
+
+ def GetModuleCount(self):
+ if self.GetFileObj() is None:
+ ErrorMsg("Fail to get module count because DSC file has not been load!")
+
+ return len(self.GetFileObj().GetComponents())
+
+ def GetSupportArchs(self):
+ return self.GetFileObj().GetDefine("SUPPORTED_ARCHITECTURES").strip().split('#')[0].split('|')
+
+ def LoadModules(self, precallback=None, postcallback=None):
+ for obj in self.GetFileObj().GetComponents():
+ mFilename = obj.GetFilename()
+ if precallback is not None:
+ precallback(self, mFilename)
+ arch = obj.GetArch()
+ if arch.lower() == 'common':
+ archarr = self.GetSupportArchs()
+ else:
+ archarr = [arch]
+ for arch in archarr:
+ module = Module(self, self.GetWorkspace())
+ if module.Load(mFilename, arch, obj.GetOveridePcds(), obj.GetOverideLibs()):
+ self._modules.append(module)
+ if postcallback is not None:
+ postcallback(self, module)
+ else:
+ del module
+ ErrorMsg("Fail to load module %s" % mFilename)
+
+ def GetModules(self):
+ return self._modules
+
+ def GetLibraryPath(self, classname, arch, type):
+ objs = self.GetFileObj().GetSectionObjectsByName("libraryclasses")
+
+ for obj in objs:
+ if classname.lower() != obj.GetClass().lower():
+ continue
+ if obj.GetArch().lower() != 'common' and \
+ obj.GetArch().lower() != arch.lower():
+ continue
+
+ if obj.GetModuleType().lower() != 'common' and \
+ obj.GetModuleType().lower() != type.lower():
+ continue
+
+ return obj.GetInstance()
+
+ ErrorMsg("Fail to get library class %s [%s][%s] from platform %s" % (classname, arch, type, self.GetFilename()))
+ return None
+
+ def GetPackage(self, path):
+ package = self.GetParent().GetPackage(path)
+ if package not in self._packages:
+ self._packages.append(package)
+ return package
+
+ def GetPcdBuildObjs(self, name, arch=None):
+ arr = []
+ objs = self.GetFileObj().GetSectionObjectsByName('pcds')
+ for obj in objs:
+ if obj.GetPcdName().lower() == name.lower():
+ arr.append(obj)
+ if arch is not None:
+ arr = self.FilterObjsByArch(arr, arch)
+ return arr
+
+ def Reload(self, callback=None):
+ # do not care force paramter for platform object
+ isFileChanged = self.GetFileObj().IsModified()
+ ret = SurfaceObject.Reload(self, False)
+ if not ret: return False
+ if isFileChanged:
+ # destroy all modules and reload them again
+ for obj in self._modules:
+ obj.Destroy()
+ del self._modules[:]
+ del self._packages[:]
+ self.LoadModules(callback)
+ else:
+ for obj in self._modules:
+ callback(self, obj.GetFilename())
+ obj.Reload()
+
+ self.Modify(False)
+ return True
+
+ def Modify(self, modify=True, modifiedObj=None):
+ if modify:
+ #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj))
+ if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify:
+ return
+ self._isModify = modify
+ self.GetParent().Modify(modify, self)
+ else:
+ if self.GetFileObj().IsModified():
+ return
+ for obj in self._modules:
+ if obj.IsModified():
+ return
+
+ self._isModify = modify
+ self.GetParent().Modify(modify, self)
+
+ def GetModuleObject(self, relativePath, arch):
+ path = os.path.normpath(relativePath)
+ for obj in self._modules:
+ if obj.GetRelativeFilename() == path:
+ if arch.lower() == 'common':
+ return obj
+ if obj.GetArch() == arch:
+ return obj
+ return None
+
+ def GenerateFullReferenceDsc(self):
+ oldDsc = self.GetFileObj()
+ newDsc = dsc.DSCFile()
+ newDsc.CopySectionsByName(oldDsc, 'defines')
+ newDsc.CopySectionsByName(oldDsc, 'SkuIds')
+
+ #
+ # Dynamic common section should also be copied
+ #
+ newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicDefault')
+ newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicHii')
+ newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicVpd')
+ newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicEx')
+
+ sects = oldDsc.GetSectionByName('Components')
+ for oldSect in sects:
+ newSect = newDsc.AddNewSection(oldSect.GetName())
+ for oldComObj in oldSect.GetObjects():
+ module = self.GetModuleObject(oldComObj.GetFilename(), oldSect.GetArch())
+ if module is None: continue
+
+ newComObj = dsc.DSCComponentObject(newSect)
+ newComObj.SetFilename(oldComObj.GetFilename())
+
+ # add all library instance for override section
+ libdict = module.GetLibraries()
+ for libclass in libdict.keys():
+ if libdict[libclass] is not None:
+ newComObj.AddOverideLib(libclass, libdict[libclass].GetRelativeFilename().replace('\\', '/'))
+
+ # add all pcds for override section
+ pcddict = module.GetPcds()
+ for pcd in pcddict.values():
+ buildPcd = pcd.GetBuildObj()
+ buildType = buildPcd.GetPcdType()
+ buildValue = None
+ if buildType.lower() == 'pcdsdynamichii' or \
+ buildType.lower() == 'pcdsdynamicvpd' or \
+ buildType.lower() == 'pcdsdynamicdefault':
+ buildType = 'PcdsDynamic'
+ if buildType != 'PcdsDynamic':
+ buildValue = buildPcd.GetPcdValue()
+ newComObj.AddOveridePcd(buildPcd.GetPcdName(),
+ buildType,
+ buildValue)
+ newSect.AddObject(newComObj)
+ return newDsc
+
+class Module(SurfaceObject):
+ def __init__(self, parent, workspace):
+ SurfaceObject.__init__(self, parent, workspace)
+ self._arch = 'common'
+ self._parent = parent
+ self._overidePcds = {}
+ self._overideLibs = {}
+ self._libs = {}
+ self._pcds = {}
+ self._ppis = []
+ self._protocols = []
+ self._depexs = []
+ self._guids = []
+ self._packages = []
+
+ def Destroy(self):
+ for lib in self._libs.values():
+ if lib is not None:
+ lib.Destroy()
+ self._libs.clear()
+
+ for pcd in self._pcds.values():
+ pcd.Destroy()
+ self._pcds.clear()
+
+ for ppi in self._ppis:
+ ppi.DeRef(self)
+ del self._ppis[:]
+
+ for protocol in self._protocols:
+ if protocol is not None:
+ protocol.DeRef(self)
+ del self._protocols[:]
+
+ for guid in self._guids:
+ if guid is not None:
+ guid.DeRef(self)
+ del self._guids[:]
+
+ del self._packages[:]
+ del self._depexs[:]
+ SurfaceObject.Destroy(self)
+
+ def GetFileObjectClass(self):
+ return inf.INFFile
+
+ def GetLibraries(self):
+ return self._libs
+
+ def Load(self, filename, arch='common', overidePcds=None, overideLibs=None):
+ if not SurfaceObject.Load(self, filename):
+ return False
+
+ self._arch = arch
+ if overidePcds is not None:
+ self._overideLibs = overideLibs
+ if overideLibs is not None:
+ self._overidePcds = overidePcds
+
+ self._SearchLibraries()
+ self._SearchPackage()
+ self._SearchSurfaceItems()
+ return True
+
+ def GetArch(self):
+ return self._arch
+
+ def GetModuleName(self):
+ return self.GetFileObj().GetDefine("BASE_NAME")
+
+ def GetModuleType(self):
+ return self.GetFileObj().GetDefine("MODULE_TYPE")
+
+ def GetPlatform(self):
+ return self.GetParent()
+
+ def GetModuleObj(self):
+ return self
+
+ def GetPcds(self):
+ pcds = self._pcds.copy()
+ for lib in self._libs.values():
+ if lib is None: continue
+ for name in lib._pcds.keys():
+ pcds[name] = lib._pcds[name]
+ return pcds
+
+ def GetPpis(self):
+ ppis = []
+ ppis += self._ppis
+ for lib in self._libs.values():
+ if lib is None: continue
+ ppis += lib._ppis
+ return ppis
+
+ def GetProtocols(self):
+ pros = []
+ pros = self._protocols
+ for lib in self._libs.values():
+ if lib is None: continue
+ pros += lib._protocols
+ return pros
+
+ def GetGuids(self):
+ guids = []
+ guids += self._guids
+ for lib in self._libs.values():
+ if lib is None: continue
+ guids += lib._guids
+ return guids
+
+ def GetDepexs(self):
+ deps = []
+ deps += self._depexs
+ for lib in self._libs.values():
+ if lib is None: continue
+ deps += lib._depexs
+ return deps
+
+ def IsLibrary(self):
+ return self.GetFileObj().GetDefine("LIBRARY_CLASS") is not None
+
+ def GetLibraryInstance(self, classname, arch, type):
+ if classname not in self._libs.keys():
+ # find in overide lib firstly
+ if classname in self._overideLibs.keys():
+ self._libs[classname] = Library(self, self.GetWorkspace())
+ self._libs[classname].Load(self._overideLibs[classname])
+ return self._libs[classname]
+
+ parent = self.GetParent()
+ if issubclass(parent.__class__, Platform):
+ path = parent.GetLibraryPath(classname, arch, type)
+ if path is None:
+ ErrorMsg('Fail to get library instance for %s' % classname, self.GetFilename())
+ return None
+ self._libs[classname] = Library(self, self.GetWorkspace())
+ if not self._libs[classname].Load(path, self.GetArch()):
+ self._libs[classname] = None
+ else:
+ self._libs[classname] = parent.GetLibraryInstance(classname, arch, type)
+ return self._libs[classname]
+
+ def GetSourceObjs(self):
+ return self.GetFileObj().GetSectionObjectsByName('source')
+
+ def _SearchLibraries(self):
+ objs = self.GetFileObj().GetSectionObjectsByName('libraryclasses')
+ arch = self.GetArch()
+ type = self.GetModuleType()
+ for obj in objs:
+ if obj.GetArch().lower() != 'common' and \
+ obj.GetArch().lower() not in self.GetPlatform().GetSupportArchs():
+ continue
+ classname = obj.GetClass()
+ instance = self.GetLibraryInstance(classname, arch, type)
+ if not self.IsLibrary() and instance is not None:
+ instance._isInherit = False
+
+ if classname not in self._libs.keys():
+ self._libs[classname] = instance
+
+ def _SearchSurfaceItems(self):
+ # get surface item from self's inf
+ pcds = []
+ ppis = []
+ pros = []
+ deps = []
+ guids = []
+ if self.GetFileObj() is not None:
+ pcds = self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('pcd'),
+ self.GetArch())
+ for pcd in pcds:
+ if pcd.GetPcdName() not in self._pcds.keys():
+ pcdItem = PcdItem(pcd.GetPcdName(), self, pcd)
+ self._pcds[pcd.GetPcdName()] = ModulePcd(self,
+ pcd.GetPcdName(),
+ pcd,
+ pcdItem)
+
+ ppis += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('ppis'),
+ self.GetArch())
+
+ for ppi in ppis:
+ item = PpiItem(ppi.GetName(), self, ppi)
+ if item not in self._ppis:
+ self._ppis.append(item)
+
+ pros += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('protocols'),
+ self.GetArch())
+
+ for pro in pros:
+ item = ProtocolItem(pro.GetName(), self, pro)
+ if item not in self._protocols:
+ self._protocols.append(item)
+
+ deps += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('depex'),
+ self.GetArch())
+ for dep in deps:
+ item = DepexItem(self, dep)
+ self._depexs.append(item)
+
+ guids += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('guids'),
+ self.GetArch())
+ for guid in guids:
+ item = GuidItem(guid.GetName(), self, guid)
+ if item not in self._guids:
+ self._guids.append(item)
+
+ def _SearchPackage(self):
+ objs = self.GetFileObj().GetSectionObjectsByName('packages')
+ for obj in objs:
+ package = self.GetPlatform().GetPackage(obj.GetPath())
+ if package is not None:
+ self._packages.append(package)
+
+ def GetPackages(self):
+ return self._packages
+
+ def GetPcdObjects(self):
+ if self.GetFileObj() is None:
+ return []
+
+ return self.GetFileObj().GetSectionObjectsByName('pcd')
+
+ def GetLibraryClassHeaderFilePath(self):
+ lcname = self.GetFileObj().GetProduceLibraryClass()
+ if lcname is None: return None
+
+ pkgs = self.GetPackages()
+ for package in pkgs:
+ path = package.GetLibraryClassHeaderPathByName(lcname)
+ if path is not None:
+ return os.path.realpath(os.path.join(package.GetFileObj().GetPackageRootPath(), path))
+ return None
+
+ def Reload(self, force=False, callback=None):
+ if callback is not None:
+ callback(self, "Starting reload...")
+
+ ret = SurfaceObject.Reload(self, force)
+ if not ret: return False
+
+ if not force and not self.IsModified():
+ return True
+
+ for lib in self._libs.values():
+ if lib is not None:
+ lib.Destroy()
+ self._libs.clear()
+
+ for pcd in self._pcds.values():
+ pcd.Destroy()
+ self._pcds.clear()
+
+ for ppi in self._ppis:
+ ppi.DeRef(self)
+ del self._ppis[:]
+
+ for protocol in self._protocols:
+ protocol.DeRef(self)
+ del self._protocols[:]
+
+ for guid in self._guids:
+ guid.DeRef(self)
+ del self._guids[:]
+
+ del self._packages[:]
+ del self._depexs[:]
+
+ if callback is not None:
+ callback(self, "Searching libraries...")
+ self._SearchLibraries()
+ if callback is not None:
+ callback(self, "Searching packages...")
+ self._SearchPackage()
+ if callback is not None:
+ callback(self, "Searching surface items...")
+ self._SearchSurfaceItems()
+
+ self.Modify(False)
+ return True
+
+ def Modify(self, modify=True, modifiedObj=None):
+ if modify:
+ #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj))
+ if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify:
+ return
+ self._isModify = modify
+ self.GetParent().Modify(modify, self)
+ else:
+ if self.GetFileObj().IsModified():
+ return
+
+ self._isModify = modify
+ self.GetParent().Modify(modify, self)
+
+class Library(Module):
+ def __init__(self, parent, workspace):
+ Module.__init__(self, parent, workspace)
+ self._isInherit = True
+
+ def IsInherit(self):
+ return self._isInherit
+
+ def GetModuleType(self):
+ return self.GetParent().GetModuleType()
+
+ def GetPlatform(self):
+ return self.GetParent().GetParent()
+
+ def GetModuleObj(self):
+ return self.GetParent()
+
+ def GetArch(self):
+ return self.GetParent().GetArch()
+
+ def Destroy(self):
+ self._libs.clear()
+ self._pcds.clear()
+ SurfaceObject.Destroy(self)
+
+class Package(SurfaceObject):
+ def __init__(self, parent, workspace):
+ SurfaceObject.__init__(self, parent, workspace)
+ self._pcds = {}
+ self._guids = {}
+ self._protocols = {}
+ self._ppis = {}
+
+ def GetPcds(self):
+ return self._pcds
+
+ def GetPpis(self):
+ return list(self._ppis.values())
+
+ def GetProtocols(self):
+ return list(self._protocols.values())
+
+ def GetGuids(self):
+ return list(self._guids.values())
+
+ def Destroy(self):
+ for pcd in self._pcds.values():
+ if pcd is not None:
+ pcd.Destroy()
+ for guid in self._guids.values():
+ if guid is not None:
+ guid.Destroy()
+ for protocol in self._protocols.values():
+ if protocol is not None:
+ protocol.Destroy()
+ for ppi in self._ppis.values():
+ if ppi is not None:
+ ppi.Destroy()
+ self._pcds.clear()
+ self._guids.clear()
+ self._protocols.clear()
+ self._ppis.clear()
+ self._pcds.clear()
+ SurfaceObject.Destroy(self)
+
+ def Load(self, relativePath):
+ ret = SurfaceObject.Load(self, relativePath)
+ if not ret: return False
+ pcds = self.GetFileObj().GetSectionObjectsByName('pcds')
+ for pcd in pcds:
+ if pcd.GetPcdName() in self._pcds.keys():
+ if self._pcds[pcd.GetPcdName()] is not None:
+ self._pcds[pcd.GetPcdName()].AddDecObj(pcd)
+ else:
+ self._pcds[pcd.GetPcdName()] = PcdItem(pcd.GetPcdName(), self, pcd)
+
+ guids = self.GetFileObj().GetSectionObjectsByName('guids')
+ for guid in guids:
+ if guid.GetName() not in self._guids.keys():
+ self._guids[guid.GetName()] = GuidItem(guid.GetName(), self, guid)
+ else:
+ WarnMsg("Duplicate definition for %s" % guid.GetName())
+
+ ppis = self.GetFileObj().GetSectionObjectsByName('ppis')
+ for ppi in ppis:
+ if ppi.GetName() not in self._ppis.keys():
+ self._ppis[ppi.GetName()] = PpiItem(ppi.GetName(), self, ppi)
+ else:
+ WarnMsg("Duplicate definition for %s" % ppi.GetName())
+
+ protocols = self.GetFileObj().GetSectionObjectsByName('protocols')
+ for protocol in protocols:
+ if protocol.GetName() not in self._protocols.keys():
+ self._protocols[protocol.GetName()] = ProtocolItem(protocol.GetName(), self, protocol)
+ else:
+ WarnMsg("Duplicate definition for %s" % protocol.GetName())
+
+ return True
+
+ def GetFileObjectClass(self):
+ return dec.DECFile
+
+ def GetName(self):
+ return self.GetFileObj().GetDefine("PACKAGE_NAME")
+
+ def GetPcdDefineObjs(self, name=None):
+ arr = []
+ objs = self.GetFileObj().GetSectionObjectsByName('pcds')
+ if name is None: return objs
+
+ for obj in objs:
+ if obj.GetPcdName().lower() == name.lower():
+ arr.append(obj)
+ return arr
+
+ def GetLibraryClassObjs(self):
+ return self.GetFileObj().GetSectionObjectsByName('libraryclasses')
+
+ def Modify(self, modify=True, modifiedObj=None):
+ if modify:
+ self._isModify = modify
+ self.GetParent().Modify(modify, self)
+ else:
+ if self.GetFileObj().IsModified():
+ return
+
+ self._isModify = modify
+ self.GetParent().Modify(modify, self)
+
+ def GetLibraryClassHeaderPathByName(self, clsname):
+ objs = self.GetLibraryClassObjs()
+ for obj in objs:
+ if obj.GetClassName() == clsname:
+ return obj.GetHeaderFile()
+ return None
+
+class DepexItem(object):
+ def __init__(self, parent, infObj):
+ self._parent = parent
+ self._infObj = infObj
+
+ def GetDepexString(self):
+ return str(self._infObj)
+
+ def GetInfObject(self):
+ return self._infObj
+
+class ModulePcd(object):
+ _type_mapping = {'FeaturePcd': 'PcdsFeatureFlag',
+ 'FixedPcd': 'PcdsFixedAtBuild',
+ 'PatchPcd': 'PcdsPatchableInModule'}
+
+ def __init__(self, parent, name, infObj, pcdItem):
+ assert issubclass(parent.__class__, Module), "Module's PCD's parent must be module!"
+ assert pcdItem is not None, 'Pcd %s does not in some package!' % name
+
+ self._name = name
+ self._parent = parent
+ self._pcdItem = pcdItem
+ self._infObj = infObj
+
+ def GetName(self):
+ return self._name
+
+ def GetParent(self):
+ return self._name
+
+ def GetArch(self):
+ return self._parent.GetArch()
+
+ def Destroy(self):
+ self._pcdItem.DeRef(self._parent)
+ self._infObj = None
+
+ def GetBuildObj(self):
+ platformInfos = self._parent.GetPlatform().GetPcdBuildObjs(self._name, self.GetArch())
+ modulePcdType = self._infObj.GetPcdType()
+
+ # if platform do not gives pcd's value, get default value from package
+ if len(platformInfos) == 0:
+ if modulePcdType.lower() == 'pcd':
+ return self._pcdItem.GetDecObject()
+ else:
+ for obj in self._pcdItem.GetDecObjects():
+ if modulePcdType not in self._type_mapping.keys():
+ ErrorMsg("Invalid PCD type %s" % modulePcdType)
+ return None
+
+ if self._type_mapping[modulePcdType] == obj.GetPcdType():
+ return obj
+ ErrorMsg ('Module PCD type %s does not in valied range [%s] in package!' % \
+ (modulePcdType))
+ else:
+ if modulePcdType.lower() == 'pcd':
+ if len(platformInfos) > 1:
+ WarnMsg("Find more than one value for PCD %s in platform %s" % \
+ (self._name, self._parent.GetPlatform().GetFilename()))
+ return platformInfos[0]
+ else:
+ for obj in platformInfos:
+ if modulePcdType not in self._type_mapping.keys():
+ ErrorMsg("Invalid PCD type %s" % modulePcdType)
+ return None
+
+ if self._type_mapping[modulePcdType] == obj.GetPcdType():
+ return obj
+
+ ErrorMsg('Can not find value for pcd %s in pcd type %s' % \
+ (self._name, modulePcdType))
+ return None
+
+
+class SurfaceItem(object):
+ _objs = {}
+
+ def __new__(cls, *args, **kwargs):
+ """Maintain only a single instance of this object
+ @return: instance of this class
+
+ """
+ name = args[0]
+ parent = args[1]
+ fileObj = args[2]
+ if issubclass(parent.__class__, Package):
+ if name in cls._objs.keys():
+ ErrorMsg("%s item is duplicated defined in packages: %s and %s" %
+ (name, parent.GetFilename(), cls._objs[name].GetParent().GetFilename()))
+ return None
+ obj = object.__new__(cls)
+ cls._objs[name] = obj
+ return obj
+ elif issubclass(parent.__class__, Module):
+ if name not in cls._objs.keys():
+ ErrorMsg("%s item does not defined in any package! It is used by module %s" % \
+ (name, parent.GetFilename()))
+ return None
+ return cls._objs[name]
+
+ return None
+
+
+ def __init__(self, name, parent, fileObj):
+ if issubclass(parent.__class__, Package):
+ self._name = name
+ self._parent = parent
+ self._decObj = [fileObj]
+ self._refMods = {}
+ else:
+ self.RefModule(parent, fileObj)
+
+ @classmethod
+ def GetObjectDict(cls):
+ return cls._objs
+
+ def GetParent(self):
+ return self._parent
+
+ def GetReference(self):
+ return self._refMods
+
+ def RefModule(self, mObj, infObj):
+ if mObj in self._refMods.keys():
+ return
+ self._refMods[mObj] = infObj
+
+ def DeRef(self, mObj):
+ if mObj not in self._refMods.keys():
+ WarnMsg("%s is not referenced by module %s" % (self._name, mObj.GetFilename()))
+ return
+ del self._refMods[mObj]
+
+ def Destroy(self):
+ self._refMods.clear()
+ cls = self.__class__
+ del cls._objs[self._name]
+
+ def GetName(self):
+ return self._name
+
+ def GetDecObject(self):
+ return self._decObj[0]
+
+ def GetDecObjects(self):
+ return self._decObj
+
+class PcdItem(SurfaceItem):
+ def AddDecObj(self, fileObj):
+ for decObj in self._decObj:
+ if decObj.GetFilename() != fileObj.GetFilename():
+ ErrorMsg("Pcd %s defined in more than one packages : %s and %s" % \
+ (self._name, decObj.GetFilename(), fileObj.GetFilename()))
+ return
+ if decObj.GetPcdType() == fileObj.GetPcdType() and \
+ decObj.GetArch().lower() == fileObj.GetArch():
+ ErrorMsg("Pcd %s is duplicated defined in pcd type %s in package %s" % \
+ (self._name, decObj.GetPcdType(), decObj.GetFilename()))
+ return
+ self._decObj.append(fileObj)
+
+ def GetValidPcdType(self):
+ types = []
+ for obj in self._decObj:
+ if obj.GetPcdType() not in types:
+ types += obj.GetPcdType()
+ return types
+
+class GuidItem(SurfaceItem):
+ pass
+
+class PpiItem(SurfaceItem):
+ pass
+
+class ProtocolItem(SurfaceItem):
+ pass
diff --git a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/dec.py b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/dec.py
index c25ab322ef..cff2f1278a 100644
--- a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/dec.py
+++ b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/dec.py
@@ -1,313 +1,313 @@
-## @file
-#
-# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-from plugins.EdkPlugins.basemodel import ini
-import re, os
-from plugins.EdkPlugins.basemodel.message import *
-
-class DECFile(ini.BaseINIFile):
-
- def GetSectionInstance(self, parent, name, isCombined=False):
- return DECSection(parent, name, isCombined)
-
- def GetComponents(self):
- return self.GetSectionByName('Components')
-
- def GetPackageRootPath(self):
- return os.path.dirname(self.GetFilename()).strip()
-
- def GetBaseName(self):
- return self.GetDefine("PACKAGE_NAME").strip()
-
- def GetVersion(self):
- return self.GetDefine("PACKAGE_VERSION").strip()
-
- def GetSectionObjectsByName(self, name, arch=None):
- arr = []
- sects = self.GetSectionByName(name)
- for sect in sects:
- # skip unmatched archtecture content
- if not sect.IsArchMatch(arch):
- continue
-
- for obj in sect.GetObjects():
- arr.append(obj)
-
- return arr
-
-class DECSection(ini.BaseINISection):
- def GetSectionINIObject(self, parent):
- type = self.GetType()
-
- if type.lower().find('defines') != -1:
- return DECDefineSectionObject(self)
- if type.lower().find('includes') != -1:
- return DECIncludeObject(self)
- if type.lower().find('pcd') != -1:
- return DECPcdObject(self)
- if type.lower() == 'libraryclasses':
- return DECLibraryClassObject(self)
- if type.lower() == 'guids':
- return DECGuidObject(self)
- if type.lower() == 'ppis':
- return DECPpiObject(self)
- if type.lower() == 'protocols':
- return DECProtocolObject(self)
-
- return DECSectionObject(self)
-
- def GetType(self):
- arr = self._name.split('.')
- return arr[0].strip()
-
- def GetArch(self):
- arr = self._name.split('.')
- if len(arr) == 1:
- return 'common'
- return arr[1]
-
- def IsArchMatch(self, arch):
- if arch is None or self.GetArch() == 'common':
- return True
-
- if self.GetArch().lower() != arch.lower():
- return False
-
- return True
-
-class DECSectionObject(ini.BaseINISectionObject):
- def GetArch(self):
- return self.GetParent().GetArch()
-
-class DECDefineSectionObject(DECSectionObject):
- def __init__(self, parent):
- DECSectionObject.__init__(self, parent)
- self._key = None
- self._value = None
-
- def Parse(self):
- assert (self._start == self._end), 'The object in define section must be in single line'
-
- line = self.GetLineByOffset(self._start).strip()
-
- line = line.split('#')[0]
- arr = line.split('=')
- if len(arr) != 2:
- ErrorMsg('Invalid define section object',
- self.GetFilename(),
- self.GetParent().GetName()
- )
- return False
-
- self._key = arr[0].strip()
- self._value = arr[1].strip()
-
- return True
-
- def GetKey(self):
- return self._key
-
- def GetValue(self):
- return self._value
-
-class DECGuidObject(DECSectionObject):
- _objs = {}
-
- def __init__(self, parent):
- DECSectionObject.__init__(self, parent)
- self._name = None
-
- def Parse(self):
- line = self.GetLineByOffset(self._start).strip().split('#')[0]
- self._name = line.split('=')[0].strip()
- self._guid = line.split('=')[1].strip()
- objdict = DECGuidObject._objs
- if self._name not in objdict.keys():
- objdict[self._name] = [self]
- else:
- objdict[self._name].append(self)
-
- return True
-
- def GetName(self):
- return self._name
-
- def GetGuid(self):
- return self._guid
-
- def Destroy(self):
- objdict = DECGuidObject._objs
- objdict[self._name].remove(self)
- if len(objdict[self._name]) == 0:
- del objdict[self._name]
-
- @staticmethod
- def GetObjectDict():
- return DECGuidObject._objs
-
-class DECPpiObject(DECSectionObject):
- _objs = {}
- def __init__(self, parent):
- DECSectionObject.__init__(self, parent)
- self._name = None
-
- def Parse(self):
- line = self.GetLineByOffset(self._start).strip().split('#')[0]
- self._name = line.split('=')[0].strip()
- self._guid = line.split('=')[1].strip()
- objdict = DECPpiObject._objs
- if self._name not in objdict.keys():
- objdict[self._name] = [self]
- else:
- objdict[self._name].append(self)
-
- return True
-
- def GetName(self):
- return self._name
-
- def GetGuid(self):
- return self._guid
-
- def Destroy(self):
- objdict = DECPpiObject._objs
- objdict[self._name].remove(self)
- if len(objdict[self._name]) == 0:
- del objdict[self._name]
-
- @staticmethod
- def GetObjectDict():
- return DECPpiObject._objs
-
-class DECProtocolObject(DECSectionObject):
- _objs = {}
-
- def __init__(self, parent):
- DECSectionObject.__init__(self, parent)
- self._name = None
-
- def Parse(self):
- line = self.GetLineByOffset(self._start).strip().split('#')[0]
- self._name = line.split('=')[0].strip()
- self._guid = line.split('=')[1].strip()
- objdict = DECProtocolObject._objs
- if self._name not in objdict.keys():
- objdict[self._name] = [self]
- else:
- objdict[self._name].append(self)
-
- return True
-
- def GetName(self):
- return self._name
-
- def GetGuid(self):
- return self._guid
-
- def Destroy(self):
- objdict = DECProtocolObject._objs
- objdict[self._name].remove(self)
- if len(objdict[self._name]) == 0:
- del objdict[self._name]
-
-
- @staticmethod
- def GetObjectDict():
- return DECProtocolObject._objs
-
-class DECLibraryClassObject(DECSectionObject):
- _objs = {}
-
- def __init__(self, parent):
- DECSectionObject.__init__(self, parent)
- self.mClassName = None
- self.mHeaderFile = None
-
- def Parse(self):
- line = self.GetLineByOffset(self._start).strip().split('#')[0]
- self.mClassName, self.mHeaderFile = line.split('|')
- objdict = DECLibraryClassObject._objs
- if self.mClassName not in objdict.keys():
- objdict[self.mClassName] = [self]
- else:
- objdict[self.mClassName].append(self)
- return True
-
- def GetClassName(self):
- return self.mClassName
-
- def GetName(self):
- return self.mClassName
-
- def GetHeaderFile(self):
- return self.mHeaderFile
-
- def Destroy(self):
- objdict = DECLibraryClassObject._objs
- objdict[self.mClassName].remove(self)
- if len(objdict[self.mClassName]) == 0:
- del objdict[self.mClassName]
-
- @staticmethod
- def GetObjectDict():
- return DECLibraryClassObject._objs
-
-class DECIncludeObject(DECSectionObject):
- def __init__(self, parent):
- DECSectionObject.__init__(self, parent)
-
- def GetPath(self):
- return self.GetLineByOffset(self._start).split('#')[0].strip()
-
-class DECPcdObject(DECSectionObject):
- _objs = {}
-
- def __init__(self, parent):
- DECSectionObject.__init__(self, parent)
- self.mPcdName = None
- self.mPcdDefaultValue = None
- self.mPcdDataType = None
- self.mPcdToken = None
-
- def Parse(self):
- line = self.GetLineByOffset(self._start).strip().split('#')[0]
- (self.mPcdName, self.mPcdDefaultValue, self.mPcdDataType, self.mPcdToken) = line.split('|')
- objdict = DECPcdObject._objs
- if self.mPcdName not in objdict.keys():
- objdict[self.mPcdName] = [self]
- else:
- objdict[self.mPcdName].append(self)
-
- return True
-
- def Destroy(self):
- objdict = DECPcdObject._objs
- objdict[self.mPcdName].remove(self)
- if len(objdict[self.mPcdName]) == 0:
- del objdict[self.mPcdName]
-
- def GetPcdType(self):
- return self.GetParent().GetType()
-
- def GetPcdName(self):
- return self.mPcdName
-
- def GetPcdValue(self):
- return self.mPcdDefaultValue
-
- def GetPcdDataType(self):
- return self.mPcdDataType
-
- def GetPcdToken(self):
- return self.mPcdToken
-
- def GetName(self):
- return self.GetPcdName().split('.')[1]
-
- @staticmethod
- def GetObjectDict():
- return DECPcdObject._objs
+## @file
+#
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+from plugins.EdkPlugins.basemodel import ini
+import re, os
+from plugins.EdkPlugins.basemodel.message import *
+
+class DECFile(ini.BaseINIFile):
+
+ def GetSectionInstance(self, parent, name, isCombined=False):
+ return DECSection(parent, name, isCombined)
+
+ def GetComponents(self):
+ return self.GetSectionByName('Components')
+
+ def GetPackageRootPath(self):
+ return os.path.dirname(self.GetFilename()).strip()
+
+ def GetBaseName(self):
+ return self.GetDefine("PACKAGE_NAME").strip()
+
+ def GetVersion(self):
+ return self.GetDefine("PACKAGE_VERSION").strip()
+
+ def GetSectionObjectsByName(self, name, arch=None):
+ arr = []
+ sects = self.GetSectionByName(name)
+ for sect in sects:
+ # skip unmatched archtecture content
+ if not sect.IsArchMatch(arch):
+ continue
+
+ for obj in sect.GetObjects():
+ arr.append(obj)
+
+ return arr
+
+class DECSection(ini.BaseINISection):
+ def GetSectionINIObject(self, parent):
+ type = self.GetType()
+
+ if type.lower().find('defines') != -1:
+ return DECDefineSectionObject(self)
+ if type.lower().find('includes') != -1:
+ return DECIncludeObject(self)
+ if type.lower().find('pcd') != -1:
+ return DECPcdObject(self)
+ if type.lower() == 'libraryclasses':
+ return DECLibraryClassObject(self)
+ if type.lower() == 'guids':
+ return DECGuidObject(self)
+ if type.lower() == 'ppis':
+ return DECPpiObject(self)
+ if type.lower() == 'protocols':
+ return DECProtocolObject(self)
+
+ return DECSectionObject(self)
+
+ def GetType(self):
+ arr = self._name.split('.')
+ return arr[0].strip()
+
+ def GetArch(self):
+ arr = self._name.split('.')
+ if len(arr) == 1:
+ return 'common'
+ return arr[1]
+
+ def IsArchMatch(self, arch):
+ if arch is None or self.GetArch() == 'common':
+ return True
+
+ if self.GetArch().lower() != arch.lower():
+ return False
+
+ return True
+
+class DECSectionObject(ini.BaseINISectionObject):
+ def GetArch(self):
+ return self.GetParent().GetArch()
+
+class DECDefineSectionObject(DECSectionObject):
+ def __init__(self, parent):
+ DECSectionObject.__init__(self, parent)
+ self._key = None
+ self._value = None
+
+ def Parse(self):
+ assert (self._start == self._end), 'The object in define section must be in single line'
+
+ line = self.GetLineByOffset(self._start).strip()
+
+ line = line.split('#')[0]
+ arr = line.split('=')
+ if len(arr) != 2:
+ ErrorMsg('Invalid define section object',
+ self.GetFilename(),
+ self.GetParent().GetName()
+ )
+ return False
+
+ self._key = arr[0].strip()
+ self._value = arr[1].strip()
+
+ return True
+
+ def GetKey(self):
+ return self._key
+
+ def GetValue(self):
+ return self._value
+
+class DECGuidObject(DECSectionObject):
+ _objs = {}
+
+ def __init__(self, parent):
+ DECSectionObject.__init__(self, parent)
+ self._name = None
+
+ def Parse(self):
+ line = self.GetLineByOffset(self._start).strip().split('#')[0]
+ self._name = line.split('=')[0].strip()
+ self._guid = line.split('=')[1].strip()
+ objdict = DECGuidObject._objs
+ if self._name not in objdict.keys():
+ objdict[self._name] = [self]
+ else:
+ objdict[self._name].append(self)
+
+ return True
+
+ def GetName(self):
+ return self._name
+
+ def GetGuid(self):
+ return self._guid
+
+ def Destroy(self):
+ objdict = DECGuidObject._objs
+ objdict[self._name].remove(self)
+ if len(objdict[self._name]) == 0:
+ del objdict[self._name]
+
+ @staticmethod
+ def GetObjectDict():
+ return DECGuidObject._objs
+
+class DECPpiObject(DECSectionObject):
+ _objs = {}
+ def __init__(self, parent):
+ DECSectionObject.__init__(self, parent)
+ self._name = None
+
+ def Parse(self):
+ line = self.GetLineByOffset(self._start).strip().split('#')[0]
+ self._name = line.split('=')[0].strip()
+ self._guid = line.split('=')[1].strip()
+ objdict = DECPpiObject._objs
+ if self._name not in objdict.keys():
+ objdict[self._name] = [self]
+ else:
+ objdict[self._name].append(self)
+
+ return True
+
+ def GetName(self):
+ return self._name
+
+ def GetGuid(self):
+ return self._guid
+
+ def Destroy(self):
+ objdict = DECPpiObject._objs
+ objdict[self._name].remove(self)
+ if len(objdict[self._name]) == 0:
+ del objdict[self._name]
+
+ @staticmethod
+ def GetObjectDict():
+ return DECPpiObject._objs
+
+class DECProtocolObject(DECSectionObject):
+ _objs = {}
+
+ def __init__(self, parent):
+ DECSectionObject.__init__(self, parent)
+ self._name = None
+
+ def Parse(self):
+ line = self.GetLineByOffset(self._start).strip().split('#')[0]
+ self._name = line.split('=')[0].strip()
+ self._guid = line.split('=')[1].strip()
+ objdict = DECProtocolObject._objs
+ if self._name not in objdict.keys():
+ objdict[self._name] = [self]
+ else:
+ objdict[self._name].append(self)
+
+ return True
+
+ def GetName(self):
+ return self._name
+
+ def GetGuid(self):
+ return self._guid
+
+ def Destroy(self):
+ objdict = DECProtocolObject._objs
+ objdict[self._name].remove(self)
+ if len(objdict[self._name]) == 0:
+ del objdict[self._name]
+
+
+ @staticmethod
+ def GetObjectDict():
+ return DECProtocolObject._objs
+
+class DECLibraryClassObject(DECSectionObject):
+ _objs = {}
+
+ def __init__(self, parent):
+ DECSectionObject.__init__(self, parent)
+ self.mClassName = None
+ self.mHeaderFile = None
+
+ def Parse(self):
+ line = self.GetLineByOffset(self._start).strip().split('#')[0]
+ self.mClassName, self.mHeaderFile = line.split('|')
+ objdict = DECLibraryClassObject._objs
+ if self.mClassName not in objdict.keys():
+ objdict[self.mClassName] = [self]
+ else:
+ objdict[self.mClassName].append(self)
+ return True
+
+ def GetClassName(self):
+ return self.mClassName
+
+ def GetName(self):
+ return self.mClassName
+
+ def GetHeaderFile(self):
+ return self.mHeaderFile
+
+ def Destroy(self):
+ objdict = DECLibraryClassObject._objs
+ objdict[self.mClassName].remove(self)
+ if len(objdict[self.mClassName]) == 0:
+ del objdict[self.mClassName]
+
+ @staticmethod
+ def GetObjectDict():
+ return DECLibraryClassObject._objs
+
+class DECIncludeObject(DECSectionObject):
+ def __init__(self, parent):
+ DECSectionObject.__init__(self, parent)
+
+ def GetPath(self):
+ return self.GetLineByOffset(self._start).split('#')[0].strip()
+
+class DECPcdObject(DECSectionObject):
+ _objs = {}
+
+ def __init__(self, parent):
+ DECSectionObject.__init__(self, parent)
+ self.mPcdName = None
+ self.mPcdDefaultValue = None
+ self.mPcdDataType = None
+ self.mPcdToken = None
+
+ def Parse(self):
+ line = self.GetLineByOffset(self._start).strip().split('#')[0]
+ (self.mPcdName, self.mPcdDefaultValue, self.mPcdDataType, self.mPcdToken) = line.split('|')
+ objdict = DECPcdObject._objs
+ if self.mPcdName not in objdict.keys():
+ objdict[self.mPcdName] = [self]
+ else:
+ objdict[self.mPcdName].append(self)
+
+ return True
+
+ def Destroy(self):
+ objdict = DECPcdObject._objs
+ objdict[self.mPcdName].remove(self)
+ if len(objdict[self.mPcdName]) == 0:
+ del objdict[self.mPcdName]
+
+ def GetPcdType(self):
+ return self.GetParent().GetType()
+
+ def GetPcdName(self):
+ return self.mPcdName
+
+ def GetPcdValue(self):
+ return self.mPcdDefaultValue
+
+ def GetPcdDataType(self):
+ return self.mPcdDataType
+
+ def GetPcdToken(self):
+ return self.mPcdToken
+
+ def GetName(self):
+ return self.GetPcdName().split('.')[1]
+
+ @staticmethod
+ def GetObjectDict():
+ return DECPcdObject._objs
diff --git a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/doxygengen.py b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/doxygengen.py
index 89833043c6..829ac803df 100644
--- a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/doxygengen.py
+++ b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/doxygengen.py
@@ -1,1084 +1,1084 @@
-## @file
-#
-# This file produce action class to generate doxygen document for edk2 codebase.
-# The action classes are shared by GUI and command line tools.
-#
-# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-
-"""This file produce action class to generate doxygen document for edk2 codebase.
- The action classes are shared by GUI and command line tools.
-"""
-from plugins.EdkPlugins.basemodel import doxygen
-import os
-try:
- import wx
- gInGui = True
-except:
- gInGui = False
-import re
-from plugins.EdkPlugins.edk2.model import inf
-from plugins.EdkPlugins.edk2.model import dec
-from plugins.EdkPlugins.basemodel.message import *
-
-_ignore_dir = ['.svn', '_svn', 'cvs']
-_inf_key_description_mapping_table = {
- 'INF_VERSION':'Version of INF file specification',
- #'BASE_NAME':'Module Name',
- 'FILE_GUID':'Module Guid',
- 'MODULE_TYPE': 'Module Type',
- 'VERSION_STRING': 'Module Version',
- 'LIBRARY_CLASS': 'Produced Library Class',
- 'EFI_SPECIFICATION_VERSION': 'UEFI Specification Version',
- 'PI_SPECIFICATION_VERSION': 'PI Specification Version',
- 'ENTRY_POINT': 'Module Entry Point Function',
- 'CONSTRUCTOR': 'Library Constructor Function'
-}
-
-_dec_key_description_mapping_table = {
- 'DEC_SPECIFICATION': 'Version of DEC file specification',
- 'PACKAGE_GUID': 'Package Guid'
-}
-class DoxygenAction:
- """This is base class for all doxygen action.
- """
-
- def __init__(self, doxPath, chmPath, outputPath, projname, mode='html', log=None, verbose=False):
- """Constructor function.
- @param doxPath the obosolution path of doxygen execute file.
- @param outputPath the obosolution output path.
- @param log log function for output message
- """
- self._doxPath = doxPath
- self._chmPath = chmPath
- self._outputPath = outputPath
- self._projname = projname
- self._configFile = None # doxygen config file is used by doxygen exe file
- self._indexPageFile = None # doxygen page file for index page.
- self._log = log
- self._mode = mode
- self._verbose = verbose
- self._doxygenCallback = None
- self._chmCallback = None
-
- def Log(self, message, level='info'):
- if self._log is not None:
- self._log(message, level)
-
- def IsVerbose(self):
- return self._verbose
-
- def Generate(self):
- """Generate interface called by outer directly"""
- self.Log(">>>>>> Start generate doxygen document for %s... Zzz....\n" % self._projname)
-
- # create doxygen config file at first
- self._configFile = doxygen.DoxygenConfigFile()
- self._configFile.SetOutputDir(self._outputPath)
-
- self._configFile.SetWarningFilePath(os.path.join(self._outputPath, 'warning.txt'))
- if self._mode.lower() == 'html':
- self._configFile.SetHtmlMode()
- else:
- self._configFile.SetChmMode()
-
- self.Log(" >>>>>> Initialize doxygen config file...Zzz...\n")
- self.InitializeConfigFile()
-
- self.Log(" >>>>>> Generate doxygen index page file...Zzz...\n")
- indexPagePath = self.GenerateIndexPage()
- if indexPagePath is None:
- self.Log("Fail to generate index page!\n", 'error')
- return False
- else:
- self.Log("Success to create doxygen index page file %s \n" % indexPagePath)
-
- # Add index page doxygen file to file list.
- self._configFile.AddFile(indexPagePath)
-
- # save config file to output path
- configFilePath = os.path.join(self._outputPath, self._projname + '.doxygen_config')
- self._configFile.Generate(configFilePath)
- self.Log(" <<<<<< Success Save doxygen config file to %s...\n" % configFilePath)
-
- # launch doxygen tool to generate document
- if self._doxygenCallback is not None:
- self.Log(" >>>>>> Start doxygen process...Zzz...\n")
- if not self._doxygenCallback(self._doxPath, configFilePath):
- return False
- else:
- self.Log("Fail to create doxygen process!", 'error')
- return False
-
- return True
-
- def InitializeConfigFile(self):
- """Initialize config setting for doxygen project. It will be invoked after config file
- object is created. Inherited class should implement it.
- """
-
- def GenerateIndexPage(self):
- """Generate doxygen index page. Inherited class should implement it."""
- return None
-
- def RegisterCallbackDoxygenProcess(self, callback):
- self._doxygenCallback = callback
-
- def RegisterCallbackCHMProcess(self, callback):
- self._chmCallback = callback
-
-class PlatformDocumentAction(DoxygenAction):
- """Generate platform doxygen document, will be implement at future."""
-
-class PackageDocumentAction(DoxygenAction):
- """Generate package reference document"""
-
- def __init__(self, doxPath, chmPath, outputPath, pObj, mode='html', log=None, arch=None, tooltag=None,
- onlyInclude=False, verbose=False):
- DoxygenAction.__init__(self, doxPath, chmPath, outputPath, pObj.GetName(), mode, log, verbose)
- self._pObj = pObj
- self._arch = arch
- self._tooltag = tooltag
- self._onlyIncludeDocument = onlyInclude
-
- def InitializeConfigFile(self):
- if self._arch == 'IA32':
- self._configFile.AddPreDefined('MDE_CPU_IA32')
- elif self._arch == 'X64':
- self._configFile.AddPreDefined('MDE_CPU_X64')
- elif self._arch == 'IPF':
- self._configFile.AddPreDefined('MDE_CPU_IPF')
- elif self._arch == 'EBC':
- self._configFile.AddPreDefined('MDE_CPU_EBC')
- else:
- self._arch = None
- self._configFile.AddPreDefined('MDE_CPU_IA32')
- self._configFile.AddPreDefined('MDE_CPU_X64')
- self._configFile.AddPreDefined('MDE_CPU_IPF')
- self._configFile.AddPreDefined('MDE_CPU_EBC')
- self._configFile.AddPreDefined('MDE_CPU_ARM')
-
- namestr = self._pObj.GetName()
- if self._arch is not None:
- namestr += '[%s]' % self._arch
- if self._tooltag is not None:
- namestr += '[%s]' % self._tooltag
- self._configFile.SetProjectName(namestr)
- self._configFile.SetStripPath(self._pObj.GetWorkspace())
- self._configFile.SetProjectVersion(self._pObj.GetFileObj().GetVersion())
- self._configFile.AddPattern('*.decdoxygen')
-
- if self._tooltag.lower() == 'msft':
- self._configFile.AddPreDefined('_MSC_EXTENSIONS')
- elif self._tooltag.lower() == 'gnu':
- self._configFile.AddPreDefined('__GNUC__')
- elif self._tooltag.lower() == 'intel':
- self._configFile.AddPreDefined('__INTEL_COMPILER')
- else:
- self._tooltag = None
- self._configFile.AddPreDefined('_MSC_EXTENSIONS')
- self._configFile.AddPreDefined('__GNUC__')
- self._configFile.AddPreDefined('__INTEL_COMPILER')
-
- self._configFile.AddPreDefined('ASM_PFX= ')
- self._configFile.AddPreDefined('OPTIONAL= ')
-
- def GenerateIndexPage(self):
- """Generate doxygen index page. Inherited class should implement it."""
- fObj = self._pObj.GetFileObj()
- pdObj = doxygen.DoxygenFile('%s Package Document' % self._pObj.GetName(),
- '%s.decdoxygen' % self._pObj.GetFilename())
- self._configFile.AddFile(pdObj.GetFilename())
- pdObj.AddDescription(fObj.GetFileHeader())
-
- defSection = fObj.GetSectionByName('defines')[0]
- baseSection = doxygen.Section('PackageBasicInformation', 'Package Basic Information')
- descr = '<TABLE>'
- for obj in defSection.GetObjects():
- if obj.GetKey() in _dec_key_description_mapping_table.keys():
- descr += '<TR>'
- descr += '<TD><B>%s</B></TD>' % _dec_key_description_mapping_table[obj.GetKey()]
- descr += '<TD>%s</TD>' % obj.GetValue()
- descr += '</TR>'
- descr += '</TABLE><br>'
- baseSection.AddDescription(descr)
- pdObj.AddSection(baseSection)
-
- knownIssueSection = doxygen.Section('Known_Issue_section', 'Known Issue')
- knownIssueSection.AddDescription('<ul>')
- knownIssueSection.AddDescription('<li> OPTIONAL macro for function parameter can not be dealed with doxygen, so it disapear in this document! </li>')
- knownIssueSection.AddDescription('</ul>')
- pdObj.AddSection(knownIssueSection)
-
- self.AddAllIncludeFiles(self._pObj, self._configFile)
- pages = self.GenerateIncludesSubPage(self._pObj, self._configFile)
- if len(pages) != 0:
- pdObj.AddPages(pages)
- pages = self.GenerateLibraryClassesSubPage(self._pObj, self._configFile)
- if len(pages) != 0:
- pdObj.AddPages(pages)
- pages = self.GeneratePcdSubPages(self._pObj, self._configFile)
- if len(pages) != 0:
- pdObj.AddPages(pages)
- pages = self.GenerateGuidSubPages(self._pObj, self._configFile)
- if len(pages) != 0:
- pdObj.AddPages(pages)
- pages = self.GeneratePpiSubPages(self._pObj, self._configFile)
- if len(pages) != 0:
- pdObj.AddPages(pages)
- pages = self.GenerateProtocolSubPages(self._pObj, self._configFile)
- if len(pages) != 0:
- pdObj.AddPages(pages)
- if not self._onlyIncludeDocument:
- pdObj.AddPages(self.GenerateModulePages(self._pObj, self._configFile))
-
- pdObj.Save()
- return pdObj.GetFilename()
-
- def GenerateIncludesSubPage(self, pObj, configFile):
- # by default add following path as include path to config file
- pkpath = pObj.GetFileObj().GetPackageRootPath()
- configFile.AddIncludePath(os.path.join(pkpath, 'Include'))
- configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Library'))
- configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Protocol'))
- configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Ppi'))
- configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Guid'))
- configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'IndustryStandard'))
-
- rootArray = []
- pageRoot = doxygen.Page("Public Includes", "%s_public_includes" % pObj.GetName())
- objs = pObj.GetFileObj().GetSectionObjectsByName('includes')
- if len(objs) == 0: return []
-
- for obj in objs:
- # Add path to include path
- path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetPath())
- configFile.AddIncludePath(path)
-
- # only list common folder's include file
- if obj.GetArch().lower() != 'common':
- continue
-
- bNeedAddIncludePage = False
- topPage = doxygen.Page(self._ConvertPathToDoxygen(path, pObj), 'public_include_top')
-
- topPage.AddDescription('<ul>\n')
- for file in os.listdir(path):
- if file.lower() in _ignore_dir: continue
- fullpath = os.path.join(path, file)
- if os.path.isfile(fullpath):
- self.ProcessSourceFileForInclude(fullpath, pObj, configFile)
- topPage.AddDescription('<li> \link %s\endlink </li>\n' % self._ConvertPathToDoxygen(fullpath, pObj))
- else:
- if file.lower() in ['library', 'protocol', 'guid', 'ppi', 'ia32', 'x64', 'ipf', 'ebc', 'arm', 'pi', 'uefi', 'aarch64']:
- continue
- bNeedAddSubPage = False
- subpage = doxygen.Page(self._ConvertPathToDoxygen(fullpath, pObj), 'public_include_%s' % file)
- subpage.AddDescription('<ul>\n')
- for subfile in os.listdir(fullpath):
- if subfile.lower() in _ignore_dir: continue
- bNeedAddSubPage = True
- subfullpath = os.path.join(fullpath, subfile)
- self.ProcessSourceFileForInclude(subfullpath, pObj, configFile)
- subpage.AddDescription('<li> \link %s \endlink </li>\n' % self._ConvertPathToDoxygen(subfullpath, pObj))
- subpage.AddDescription('</ul>\n')
- if bNeedAddSubPage:
- bNeedAddIncludePage = True
- pageRoot.AddPage(subpage)
- topPage.AddDescription('</ul>\n')
- if bNeedAddIncludePage:
- pageRoot.AddPage(topPage)
-
- if pageRoot.GetSubpageCount() != 0:
- return [pageRoot]
- else:
- return []
-
- def GenerateLibraryClassesSubPage(self, pObj, configFile):
- """
- Generate sub page for library class for package.
- One DEC file maybe contains many library class sections
- for different architecture.
-
- @param fObj DEC file object.
- """
- rootArray = []
- pageRoot = doxygen.Page("Library Class", "%s_libraryclass" % pObj.GetName())
- objs = pObj.GetFileObj().GetSectionObjectsByName('libraryclass', self._arch)
- if len(objs) == 0: return []
-
- if self._arch is not None:
- for obj in objs:
- classPage = doxygen.Page(obj.GetClassName(),
- "lc_%s" % obj.GetClassName())
- comments = obj.GetComment()
- if len(comments) != 0:
- classPage.AddDescription('<br>\n'.join(comments) + '<br>\n')
- pageRoot.AddPage(classPage)
- path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())
- path = path[len(pObj.GetWorkspace()) + 1:]
- if len(comments) == 0:
- classPage.AddDescription('\copydoc %s<p>' % obj.GetHeaderFile())
- section = doxygen.Section('ref', 'Refer to Header File')
- section.AddDescription('\link %s\n' % obj.GetHeaderFile())
- section.AddDescription(' \endlink<p>\n')
- classPage.AddSection(section)
- fullPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())
- self.ProcessSourceFileForInclude(fullPath, pObj, configFile)
- else:
- archPageDict = {}
- for obj in objs:
- if obj.GetArch() not in archPageDict.keys():
- archPageDict[obj.GetArch()] = doxygen.Page(obj.GetArch(),
- 'lc_%s' % obj.GetArch())
- pageRoot.AddPage(archPageDict[obj.GetArch()])
- subArchRoot = archPageDict[obj.GetArch()]
- classPage = doxygen.Page(obj.GetClassName(),
- "lc_%s" % obj.GetClassName())
- comments = obj.GetComment()
- if len(comments) != 0:
- classPage.AddDescription('<br>\n'.join(comments) + '<br>\n')
- subArchRoot.AddPage(classPage)
- path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())
- path = path[len(pObj.GetWorkspace()) + 1:]
- if len(comments) == 0:
- classPage.AddDescription('\copydoc %s<p>' % obj.GetHeaderFile())
- section = doxygen.Section('ref', 'Refer to Header File')
- section.AddDescription('\link %s\n' % obj.GetHeaderFile())
- section.AddDescription(' \endlink<p>\n')
- classPage.AddSection(section)
- fullPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())
-
- self.ProcessSourceFileForInclude(fullPath, pObj, configFile)
- rootArray.append(pageRoot)
- return rootArray
-
- def ProcessSourceFileForInclude(self, path, pObj, configFile, infObj=None):
- """
- @param path the analysising file full path
- @param pObj package object
- @param configFile doxygen config file.
- """
- if gInGui:
- wx.Yield()
- if not os.path.exists(path):
- ErrorMsg('Source file path %s does not exist!' % path)
- return
-
- if configFile.FileExists(path):
- return
-
- try:
- with open(path, 'r') as f:
- lines = f.readlines()
- except UnicodeDecodeError:
- return
- except IOError:
- ErrorMsg('Fail to open file %s' % path)
- return
-
- configFile.AddFile(path)
-
- no = 0
- for no in range(len(lines)):
- if len(lines[no].strip()) == 0:
- continue
- if lines[no].strip()[:2] in ['##', '//', '/*', '*/']:
- continue
- index = lines[no].lower().find('include')
- #mo = IncludePattern.finditer(lines[no].lower())
- mo = re.match(r"^#\s*include\s+[<\"]([\\/\w.]+)[>\"]$", lines[no].strip().lower())
- if not mo:
- continue
- mo = re.match(r"^[#\w\s]+[<\"]([\\/\w.]+)[>\"]$", lines[no].strip())
- filePath = mo.groups()[0]
-
- if filePath is None or len(filePath) == 0:
- continue
-
- # find header file in module's path firstly.
- fullPath = None
-
- if os.path.exists(os.path.join(os.path.dirname(path), filePath)):
- # Find the file in current directory
- fullPath = os.path.join(os.path.dirname(path), filePath).replace('\\', '/')
- else:
- # find in depedent package's include path
- incObjs = pObj.GetFileObj().GetSectionObjectsByName('includes')
- for incObj in incObjs:
- incPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), incObj.GetPath()).strip()
- incPath = os.path.realpath(os.path.join(incPath, filePath))
- if os.path.exists(incPath):
- fullPath = incPath
- break
- if infObj is not None:
- pkgInfObjs = infObj.GetSectionObjectsByName('packages')
- for obj in pkgInfObjs:
- decObj = dec.DECFile(os.path.join(pObj.GetWorkspace(), obj.GetPath()))
- if not decObj:
- ErrorMsg ('Fail to create pacakge object for %s' % obj.GetPackageName())
- continue
- if not decObj.Parse():
- ErrorMsg ('Fail to load package object for %s' % obj.GetPackageName())
- continue
- incObjs = decObj.GetSectionObjectsByName('includes')
- for incObj in incObjs:
- incPath = os.path.join(decObj.GetPackageRootPath(), incObj.GetPath()).replace('\\', '/')
- if os.path.exists(os.path.join(incPath, filePath)):
- fullPath = os.path.join(os.path.join(incPath, filePath))
- break
- if fullPath is not None:
- break
-
- if fullPath is None and self.IsVerbose():
- self.Log('Can not resolve header file %s for file %s in package %s\n' % (filePath, path, pObj.GetFileObj().GetFilename()), 'error')
- return
- else:
- fullPath = fullPath.replace('\\', '/')
- if self.IsVerbose():
- self.Log('Preprocessing: Add include file %s for file %s\n' % (fullPath, path))
- #LogMsg ('Preprocessing: Add include file %s for file %s' % (fullPath, path))
- self.ProcessSourceFileForInclude(fullPath, pObj, configFile, infObj)
-
- def AddAllIncludeFiles(self, pObj, configFile):
- objs = pObj.GetFileObj().GetSectionObjectsByName('includes')
- for obj in objs:
- incPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetPath())
- for root, dirs, files in os.walk(incPath):
- for dir in dirs:
- if dir.lower() in _ignore_dir:
- dirs.remove(dir)
- for file in files:
- path = os.path.normpath(os.path.join(root, file))
- configFile.AddFile(path.replace('/', '\\'))
-
- def GeneratePcdSubPages(self, pObj, configFile):
- """
- Generate sub pages for package's PCD definition.
- @param pObj package object
- @param configFile config file object
- """
- rootArray = []
- objs = pObj.GetFileObj().GetSectionObjectsByName('pcd')
- if len(objs) == 0:
- return []
-
- pcdRootPage = doxygen.Page('PCD', 'pcd_root_page')
- typeRootPageDict = {}
- typeArchRootPageDict = {}
- for obj in objs:
- if obj.GetPcdType() not in typeRootPageDict.keys():
- typeRootPageDict[obj.GetPcdType()] = doxygen.Page(obj.GetPcdType(), 'pcd_%s_root_page' % obj.GetPcdType())
- pcdRootPage.AddPage(typeRootPageDict[obj.GetPcdType()])
- typeRoot = typeRootPageDict[obj.GetPcdType()]
- if self._arch is not None:
- pcdPage = doxygen.Page('%s' % obj.GetPcdName(),
- 'pcd_%s_%s_%s' % (obj.GetPcdType(), obj.GetArch(), obj.GetPcdName().split('.')[1]))
- pcdPage.AddDescription('<br>\n'.join(obj.GetComment()) + '<br>\n')
- section = doxygen.Section('PCDinformation', 'PCD Information')
- desc = '<TABLE>'
- desc += '<TR>'
- desc += '<TD><CAPTION>Name</CAPTION></TD>'
- desc += '<TD><CAPTION>Token Space</CAPTION></TD>'
- desc += '<TD><CAPTION>Token number</CAPTION></TD>'
- desc += '<TD><CAPTION>Data Type</CAPTION></TD>'
- desc += '<TD><CAPTION>Default Value</CAPTION></TD>'
- desc += '</TR>'
- desc += '<TR>'
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[1]
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[0]
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdToken()
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdDataType()
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdValue()
- desc += '</TR>'
- desc += '</TABLE>'
- section.AddDescription(desc)
- pcdPage.AddSection(section)
- typeRoot.AddPage(pcdPage)
- else:
- keystr = obj.GetPcdType() + obj.GetArch()
- if keystr not in typeArchRootPageDict.keys():
- typeArchRootPage = doxygen.Page(obj.GetArch(), 'pcd_%s_%s_root_page' % (obj.GetPcdType(), obj.GetArch()))
- typeArchRootPageDict[keystr] = typeArchRootPage
- typeRoot.AddPage(typeArchRootPage)
- typeArchRoot = typeArchRootPageDict[keystr]
- pcdPage = doxygen.Page('%s' % obj.GetPcdName(),
- 'pcd_%s_%s_%s' % (obj.GetPcdType(), obj.GetArch(), obj.GetPcdName().split('.')[1]))
- pcdPage.AddDescription('<br>\n'.join(obj.GetComment()) + '<br>\n')
- section = doxygen.Section('PCDinformation', 'PCD Information')
- desc = '<TABLE>'
- desc += '<TR>'
- desc += '<TD><CAPTION>Name</CAPTION></TD>'
- desc += '<TD><CAPTION>Token Space</CAPTION></TD>'
- desc += '<TD><CAPTION>Token number</CAPTION></TD>'
- desc += '<TD><CAPTION>Data Type</CAPTION></TD>'
- desc += '<TD><CAPTION>Default Value</CAPTION></TD>'
- desc += '</TR>'
- desc += '<TR>'
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[1]
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[0]
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdToken()
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdDataType()
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdValue()
- desc += '</TR>'
- desc += '</TABLE>'
- section.AddDescription(desc)
- pcdPage.AddSection(section)
- typeArchRoot.AddPage(pcdPage)
- return [pcdRootPage]
-
- def _GenerateGuidSubPage(self, pObj, obj, configFile):
- guidPage = doxygen.Page('%s' % obj.GetName(),
- 'guid_%s_%s' % (obj.GetArch(), obj.GetName()))
- comments = obj.GetComment()
- if len(comments) != 0:
- guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')
- section = doxygen.Section('BasicGuidInfo', 'GUID Information')
- desc = '<TABLE>'
- desc += '<TR>'
- desc += '<TD><CAPTION>GUID\'s Guid Name</CAPTION></TD><TD><CAPTION>GUID\'s Guid</CAPTION></TD>'
- desc += '</TR>'
- desc += '<TR>'
- desc += '<TD>%s</TD>' % obj.GetName()
- desc += '<TD>%s</TD>' % obj.GetGuid()
- desc += '</TR>'
- desc += '</TABLE>'
- section.AddDescription(desc)
- guidPage.AddSection(section)
- refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)
- if refFile:
- relPath = refFile[len(pObj.GetWorkspace()) + 1:]
- if len(comments) == 0:
- guidPage.AddDescription(' \\copydoc %s <br>' % relPath)
-
- section = doxygen.Section('ref', 'Refer to Header File')
- section.AddDescription('\link %s\n' % relPath)
- section.AddDescription('\endlink\n')
- self.ProcessSourceFileForInclude(refFile, pObj, configFile)
- guidPage.AddSection(section)
- return guidPage
-
- def GenerateGuidSubPages(self, pObj, configFile):
- """
- Generate sub pages for package's GUID definition.
- @param pObj package object
- @param configFilf doxygen config file object
- """
- pageRoot = doxygen.Page('GUID', 'guid_root_page')
- objs = pObj.GetFileObj().GetSectionObjectsByName('guids', self._arch)
- if len(objs) == 0: return []
- if self._arch is not None:
- for obj in objs:
- pageRoot.AddPage(self._GenerateGuidSubPage(pObj, obj, configFile))
- else:
- guidArchRootPageDict = {}
- for obj in objs:
- if obj.GetArch() not in guidArchRootPageDict.keys():
- guidArchRoot = doxygen.Page(obj.GetArch(), 'guid_arch_root_%s' % obj.GetArch())
- pageRoot.AddPage(guidArchRoot)
- guidArchRootPageDict[obj.GetArch()] = guidArchRoot
- guidArchRoot = guidArchRootPageDict[obj.GetArch()]
- guidArchRoot.AddPage(self._GenerateGuidSubPage(pObj, obj, configFile))
- return [pageRoot]
-
- def _GeneratePpiSubPage(self, pObj, obj, configFile):
- guidPage = doxygen.Page(obj.GetName(), 'ppi_page_%s' % obj.GetName())
- comments = obj.GetComment()
- if len(comments) != 0:
- guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')
- section = doxygen.Section('BasicPpiInfo', 'PPI Information')
- desc = '<TABLE>'
- desc += '<TR>'
- desc += '<TD><CAPTION>PPI\'s Guid Name</CAPTION></TD><TD><CAPTION>PPI\'s Guid</CAPTION></TD>'
- desc += '</TR>'
- desc += '<TR>'
- desc += '<TD>%s</TD>' % obj.GetName()
- desc += '<TD>%s</TD>' % obj.GetGuid()
- desc += '</TR>'
- desc += '</TABLE>'
- section.AddDescription(desc)
- guidPage.AddSection(section)
- refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)
- if refFile:
- relPath = refFile[len(pObj.GetWorkspace()) + 1:]
- if len(comments) == 0:
- guidPage.AddDescription(' \\copydoc %s <br>' % relPath)
- section = doxygen.Section('ref', 'Refer to Header File')
- section.AddDescription('\link %s\n' % relPath)
- section.AddDescription('\endlink\n')
- self.ProcessSourceFileForInclude(refFile, pObj, configFile)
- guidPage.AddSection(section)
-
- return guidPage
-
- def GeneratePpiSubPages(self, pObj, configFile):
- """
- Generate sub pages for package's GUID definition.
- @param pObj package object
- @param configFilf doxygen config file object
- """
- pageRoot = doxygen.Page('PPI', 'ppi_root_page')
- objs = pObj.GetFileObj().GetSectionObjectsByName('ppis', self._arch)
- if len(objs) == 0: return []
- if self._arch is not None:
- for obj in objs:
- pageRoot.AddPage(self._GeneratePpiSubPage(pObj, obj, configFile))
- else:
- guidArchRootPageDict = {}
- for obj in objs:
- if obj.GetArch() not in guidArchRootPageDict.keys():
- guidArchRoot = doxygen.Page(obj.GetArch(), 'ppi_arch_root_%s' % obj.GetArch())
- pageRoot.AddPage(guidArchRoot)
- guidArchRootPageDict[obj.GetArch()] = guidArchRoot
- guidArchRoot = guidArchRootPageDict[obj.GetArch()]
- guidArchRoot.AddPage(self._GeneratePpiSubPage(pObj, obj, configFile))
- return [pageRoot]
-
- def _GenerateProtocolSubPage(self, pObj, obj, configFile):
- guidPage = doxygen.Page(obj.GetName(), 'protocol_page_%s' % obj.GetName())
- comments = obj.GetComment()
- if len(comments) != 0:
- guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')
- section = doxygen.Section('BasicProtocolInfo', 'PROTOCOL Information')
- desc = '<TABLE>'
- desc += '<TR>'
- desc += '<TD><CAPTION>PROTOCOL\'s Guid Name</CAPTION></TD><TD><CAPTION>PROTOCOL\'s Guid</CAPTION></TD>'
- desc += '</TR>'
- desc += '<TR>'
- desc += '<TD>%s</TD>' % obj.GetName()
- desc += '<TD>%s</TD>' % obj.GetGuid()
- desc += '</TR>'
- desc += '</TABLE>'
- section.AddDescription(desc)
- guidPage.AddSection(section)
-
- refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)
- if refFile:
- relPath = refFile[len(pObj.GetWorkspace()) + 1:]
- if len(comments) == 0:
- guidPage.AddDescription(' \\copydoc %s <br>' % relPath)
- section = doxygen.Section('ref', 'Refer to Header File')
- section.AddDescription('\link %s\n' % relPath)
- section.AddDescription('\endlink\n')
- self.ProcessSourceFileForInclude(refFile, pObj, configFile)
- guidPage.AddSection(section)
-
- return guidPage
-
- def GenerateProtocolSubPages(self, pObj, configFile):
- """
- Generate sub pages for package's GUID definition.
- @param pObj package object
- @param configFilf doxygen config file object
- """
- pageRoot = doxygen.Page('PROTOCOL', 'protocol_root_page')
- objs = pObj.GetFileObj().GetSectionObjectsByName('protocols', self._arch)
- if len(objs) == 0: return []
- if self._arch is not None:
- for obj in objs:
- pageRoot.AddPage(self._GenerateProtocolSubPage(pObj, obj, configFile))
- else:
- guidArchRootPageDict = {}
- for obj in objs:
- if obj.GetArch() not in guidArchRootPageDict.keys():
- guidArchRoot = doxygen.Page(obj.GetArch(), 'protocol_arch_root_%s' % obj.GetArch())
- pageRoot.AddPage(guidArchRoot)
- guidArchRootPageDict[obj.GetArch()] = guidArchRoot
- guidArchRoot = guidArchRootPageDict[obj.GetArch()]
- guidArchRoot.AddPage(self._GenerateProtocolSubPage(pObj, obj, configFile))
- return [pageRoot]
-
- def FindHeaderFileForGuid(self, pObj, name, configFile):
- """
- For declaration header file for GUID/PPI/Protocol.
-
- @param pObj package object
- @param name guid/ppi/protocol's name
- @param configFile config file object
-
- @return full path of header file and None if not found.
- """
- startPath = pObj.GetFileObj().GetPackageRootPath()
- incPath = os.path.join(startPath, 'Include').replace('\\', '/')
- # if <PackagePath>/include exist, then search header under it.
- if os.path.exists(incPath):
- startPath = incPath
-
- for root, dirs, files in os.walk(startPath):
- for dir in dirs:
- if dir.lower() in _ignore_dir:
- dirs.remove(dir)
- for file in files:
- fPath = os.path.join(root, file)
- if not IsCHeaderFile(fPath):
- continue
- try:
- f = open(fPath, 'r')
- lines = f.readlines()
- f.close()
- except IOError:
- self.Log('Fail to open file %s\n' % fPath)
- continue
- for line in lines:
- if line.find(name) != -1 and \
- line.find('extern') != -1:
- return fPath.replace('\\', '/')
- return None
-
- def GetPackageModuleList(self, pObj):
- """
- Get all module's INF path under package's root path
- @param pObj package object
- @return arrary of INF full path
- """
- mArray = []
- packPath = pObj.GetFileObj().GetPackageRootPath()
- if not os.path.exists:
- return None
- for root, dirs, files in os.walk(packPath):
- for dir in dirs:
- if dir.lower() in _ignore_dir:
- dirs.remove(dir)
- for file in files:
- if CheckPathPostfix(file, 'inf'):
- fPath = os.path.join(root, file).replace('\\', '/')
- mArray.append(fPath)
- return mArray
-
- def GenerateModulePages(self, pObj, configFile):
- """
- Generate sub pages for package's module which is under the package
- root directory.
-
- @param pObj package object
- @param configFilf doxygen config file object
- """
- infList = self.GetPackageModuleList(pObj)
- rootPages = []
- libObjs = []
- modObjs = []
- for infpath in infList:
- infObj = inf.INFFile(infpath)
- #infObj = INFFileObject.INFFile (pObj.GetWorkspacePath(),
- # inf)
- if not infObj:
- self.Log('Fail create INF object for %s' % inf)
- continue
- if not infObj.Parse():
- self.Log('Fail to load INF file %s' % inf)
- continue
- if infObj.GetProduceLibraryClass() is not None:
- libObjs.append(infObj)
- else:
- modObjs.append(infObj)
-
- if len(libObjs) != 0:
- libRootPage = doxygen.Page('Libraries', 'lib_root_page')
- rootPages.append(libRootPage)
- for libInf in libObjs:
- libRootPage.AddPage(self.GenerateModulePage(pObj, libInf, configFile, True))
-
- if len(modObjs) != 0:
- modRootPage = doxygen.Page('Modules', 'module_root_page')
- rootPages.append(modRootPage)
- for modInf in modObjs:
- modRootPage.AddPage(self.GenerateModulePage(pObj, modInf, configFile, False))
-
- return rootPages
-
- def GenerateModulePage(self, pObj, infObj, configFile, isLib):
- """
- Generate page for a module/library.
- @param infObj INF file object for module/library
- @param configFile doxygen config file object
- @param isLib Whether this module is library
-
- @param module doxygen page object
- """
- workspace = pObj.GetWorkspace()
- refDecObjs = []
- for obj in infObj.GetSectionObjectsByName('packages'):
- decObj = dec.DECFile(os.path.join(workspace, obj.GetPath()))
- if not decObj:
- ErrorMsg ('Fail to create pacakge object for %s' % obj.GetPackageName())
- continue
- if not decObj.Parse():
- ErrorMsg ('Fail to load package object for %s' % obj.GetPackageName())
- continue
- refDecObjs.append(decObj)
-
- modPage = doxygen.Page('%s' % infObj.GetBaseName(),
- 'module_%s' % infObj.GetBaseName())
- modPage.AddDescription(infObj.GetFileHeader())
-
- basicInfSection = doxygen.Section('BasicModuleInformation', 'Basic Module Information')
- desc = "<TABLE>"
- for obj in infObj.GetSectionObjectsByName('defines'):
- key = obj.GetKey()
- value = obj.GetValue()
- if key not in _inf_key_description_mapping_table.keys(): continue
- if key == 'LIBRARY_CLASS' and value.find('|') != -1:
- clsname, types = value.split('|')
- desc += '<TR>'
- desc += '<TD><B>%s</B></TD>' % _inf_key_description_mapping_table[key]
- desc += '<TD>%s</TD>' % clsname
- desc += '</TR>'
-
- desc += '<TR>'
- desc += '<TD><B>Supported Module Types</B></TD>'
- desc += '<TD>%s</TD>' % types
- desc += '</TR>'
- else:
- desc += '<TR>'
- desc += '<TD><B>%s</B></TD>' % _inf_key_description_mapping_table[key]
- if key == 'EFI_SPECIFICATION_VERSION' and value == '0x00020000':
- value = '2.0'
- desc += '<TD>%s</TD>' % value
- desc += '</TR>'
- desc += '</TABLE>'
- basicInfSection.AddDescription(desc)
- modPage.AddSection(basicInfSection)
-
- # Add protocol section
- data = []
- for obj in infObj.GetSectionObjectsByName('pcd', self._arch):
- data.append(obj.GetPcdName().strip())
- if len(data) != 0:
- s = doxygen.Section('Pcds', 'Pcds')
- desc = "<TABLE>"
- desc += '<TR><TD><B>PCD Name</B></TD><TD><B>TokenSpace</B></TD><TD><B>Package</B></TD></TR>'
- for item in data:
- desc += '<TR>'
- desc += '<TD>%s</TD>' % item.split('.')[1]
- desc += '<TD>%s</TD>' % item.split('.')[0]
- pkgbasename = self.SearchPcdPackage(item, workspace, refDecObjs)
- desc += '<TD>%s</TD>' % pkgbasename
- desc += '</TR>'
- desc += "</TABLE>"
- s.AddDescription(desc)
- modPage.AddSection(s)
-
- # Add protocol section
- #sects = infObj.GetSectionByString('protocol')
- data = []
- #for sect in sects:
- for obj in infObj.GetSectionObjectsByName('protocol', self._arch):
- data.append(obj.GetName().strip())
- if len(data) != 0:
- s = doxygen.Section('Protocols', 'Protocols')
- desc = "<TABLE>"
- desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'
- for item in data:
- desc += '<TR>'
- desc += '<TD>%s</TD>' % item
- pkgbasename = self.SearchProtocolPackage(item, workspace, refDecObjs)
- desc += '<TD>%s</TD>' % pkgbasename
- desc += '</TR>'
- desc += "</TABLE>"
- s.AddDescription(desc)
- modPage.AddSection(s)
-
- # Add ppi section
- #sects = infObj.GetSectionByString('ppi')
- data = []
- #for sect in sects:
- for obj in infObj.GetSectionObjectsByName('ppi', self._arch):
- data.append(obj.GetName().strip())
- if len(data) != 0:
- s = doxygen.Section('Ppis', 'Ppis')
- desc = "<TABLE>"
- desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'
- for item in data:
- desc += '<TR>'
- desc += '<TD>%s</TD>' % item
- pkgbasename = self.SearchPpiPackage(item, workspace, refDecObjs)
- desc += '<TD>%s</TD>' % pkgbasename
- desc += '</TR>'
- desc += "</TABLE>"
- s.AddDescription(desc)
- modPage.AddSection(s)
-
- # Add guid section
- #sects = infObj.GetSectionByString('guid')
- data = []
- #for sect in sects:
- for obj in infObj.GetSectionObjectsByName('guid', self._arch):
- data.append(obj.GetName().strip())
- if len(data) != 0:
- s = doxygen.Section('Guids', 'Guids')
- desc = "<TABLE>"
- desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'
- for item in data:
- desc += '<TR>'
- desc += '<TD>%s</TD>' % item
- pkgbasename = self.SearchGuidPackage(item, workspace, refDecObjs)
- desc += '<TD>%s</TD>' % pkgbasename
- desc += '</TR>'
- desc += "</TABLE>"
- s.AddDescription(desc)
- modPage.AddSection(s)
-
- section = doxygen.Section('LibraryClasses', 'Library Classes')
- desc = "<TABLE>"
- desc += '<TR><TD><B>Name</B></TD><TD><B>Type</B></TD><TD><B>Package</B></TD><TD><B>Header File</B></TD></TR>'
- if isLib:
- desc += '<TR>'
- desc += '<TD>%s</TD>' % infObj.GetProduceLibraryClass()
- desc += '<TD>Produce</TD>'
- try:
- pkgname, hPath = self.SearchLibraryClassHeaderFile(infObj.GetProduceLibraryClass(),
- workspace,
- refDecObjs)
- except:
- self.Log ('fail to get package header file for lib class %s' % infObj.GetProduceLibraryClass())
- pkgname = 'NULL'
- hPath = 'NULL'
- desc += '<TD>%s</TD>' % pkgname
- if hPath != "NULL":
- desc += '<TD>\link %s \endlink</TD>' % hPath
- else:
- desc += '<TD>%s</TD>' % hPath
- desc += '</TR>'
- for lcObj in infObj.GetSectionObjectsByName('libraryclasses', self._arch):
- desc += '<TR>'
- desc += '<TD>%s</TD>' % lcObj.GetClass()
- retarr = self.SearchLibraryClassHeaderFile(lcObj.GetClass(),
- workspace,
- refDecObjs)
- if retarr is not None:
- pkgname, hPath = retarr
- else:
- self.Log('Fail find the library class %s definition from module %s dependent package!' % (lcObj.GetClass(), infObj.GetFilename()), 'error')
- pkgname = 'NULL'
- hPath = 'NULL'
- desc += '<TD>Consume</TD>'
- desc += '<TD>%s</TD>' % pkgname
- desc += '<TD>\link %s \endlink</TD>' % hPath
- desc += '</TR>'
- desc += "</TABLE>"
- section.AddDescription(desc)
- modPage.AddSection(section)
-
- section = doxygen.Section('SourceFiles', 'Source Files')
- section.AddDescription('<ul>\n')
- for obj in infObj.GetSourceObjects(self._arch, self._tooltag):
- sPath = infObj.GetModuleRootPath()
- sPath = os.path.join(sPath, obj.GetSourcePath()).replace('\\', '/').strip()
- if sPath.lower().endswith('.uni') or sPath.lower().endswith('.s') or sPath.lower().endswith('.asm') or sPath.lower().endswith('.nasm'):
- newPath = self.TranslateUniFile(sPath)
- configFile.AddFile(newPath)
- newPath = newPath[len(pObj.GetWorkspace()) + 1:]
- section.AddDescription('<li> \link %s \endlink </li>' % newPath)
- else:
- self.ProcessSourceFileForInclude(sPath, pObj, configFile, infObj)
- sPath = sPath[len(pObj.GetWorkspace()) + 1:]
- section.AddDescription('<li>\link %s \endlink </li>' % sPath)
- section.AddDescription('</ul>\n')
- modPage.AddSection(section)
-
- #sects = infObj.GetSectionByString('depex')
- data = []
- #for sect in sects:
- for obj in infObj.GetSectionObjectsByName('depex'):
- data.append(str(obj))
- if len(data) != 0:
- s = doxygen.Section('DependentSection', 'Module Dependencies')
- s.AddDescription('<br>'.join(data))
- modPage.AddSection(s)
-
- return modPage
-
- def TranslateUniFile(self, path):
- newpath = path + '.dox'
- #import core.textfile as textfile
- #file = textfile.TextFile(path)
-
- try:
- file = open(path, 'r')
- except (IOError, OSError) as msg:
- return None
-
- t = file.read()
- file.close()
-
- output = '/** @file \n'
- #output = '<html><body>'
- arr = t.split('\r\n')
- for line in arr:
- if line.find('@file') != -1:
- continue
- if line.find('*/') != -1:
- continue
- line = line.strip()
- if line.strip().startswith('/'):
- arr = line.split(' ')
- if len(arr) > 1:
- line = ' '.join(arr[1:])
- else:
- continue
- output += '%s<br>\n' % line
- output += '**/'
-
- if os.path.exists(newpath):
- os.remove(newpath)
-
- file = open(newpath, "w")
- file.write(output)
- file.close()
- return newpath
-
- def SearchPcdPackage(self, pcdname, workspace, decObjs):
- for decObj in decObjs:
- for pcd in decObj.GetSectionObjectsByName('pcd'):
- if pcdname == pcd.GetPcdName():
- return decObj.GetBaseName()
- return None
-
- def SearchProtocolPackage(self, protname, workspace, decObjs):
- for decObj in decObjs:
- for proto in decObj.GetSectionObjectsByName('protocol'):
- if protname == proto.GetName():
- return decObj.GetBaseName()
- return None
-
- def SearchPpiPackage(self, ppiname, workspace, decObjs):
- for decObj in decObjs:
- for ppi in decObj.GetSectionObjectsByName('ppi'):
- if ppiname == ppi.GetName():
- return decObj.GetBaseName()
- return None
-
- def SearchGuidPackage(self, guidname, workspace, decObjs):
- for decObj in decObjs:
- for guid in decObj.GetSectionObjectsByName('guid'):
- if guidname == guid.GetName():
- return decObj.GetBaseName()
- return None
-
- def SearchLibraryClassHeaderFile(self, className, workspace, decObjs):
- for decObj in decObjs:
- for cls in decObj.GetSectionObjectsByName('libraryclasses'):
- if cls.GetClassName().strip() == className:
- path = cls.GetHeaderFile().strip()
- path = os.path.join(decObj.GetPackageRootPath(), path)
- path = path[len(workspace) + 1:]
- return decObj.GetBaseName(), path.replace('\\', '/')
-
- return None
-
- def _ConvertPathToDoxygen(self, path, pObj):
- pRootPath = pObj.GetWorkspace()
- path = path[len(pRootPath) + 1:]
- return path.replace('\\', '/')
-
-def IsCHeaderFile(path):
- return CheckPathPostfix(path, 'h')
-
-def CheckPathPostfix(path, str):
- index = path.rfind('.')
- if index == -1:
- return False
- if path[index + 1:].lower() == str.lower():
- return True
- return False
+## @file
+#
+# This file produce action class to generate doxygen document for edk2 codebase.
+# The action classes are shared by GUI and command line tools.
+#
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+"""This file produce action class to generate doxygen document for edk2 codebase.
+ The action classes are shared by GUI and command line tools.
+"""
+from plugins.EdkPlugins.basemodel import doxygen
+import os
+try:
+ import wx
+ gInGui = True
+except:
+ gInGui = False
+import re
+from plugins.EdkPlugins.edk2.model import inf
+from plugins.EdkPlugins.edk2.model import dec
+from plugins.EdkPlugins.basemodel.message import *
+
+_ignore_dir = ['.svn', '_svn', 'cvs']
+_inf_key_description_mapping_table = {
+ 'INF_VERSION':'Version of INF file specification',
+ #'BASE_NAME':'Module Name',
+ 'FILE_GUID':'Module Guid',
+ 'MODULE_TYPE': 'Module Type',
+ 'VERSION_STRING': 'Module Version',
+ 'LIBRARY_CLASS': 'Produced Library Class',
+ 'EFI_SPECIFICATION_VERSION': 'UEFI Specification Version',
+ 'PI_SPECIFICATION_VERSION': 'PI Specification Version',
+ 'ENTRY_POINT': 'Module Entry Point Function',
+ 'CONSTRUCTOR': 'Library Constructor Function'
+}
+
+_dec_key_description_mapping_table = {
+ 'DEC_SPECIFICATION': 'Version of DEC file specification',
+ 'PACKAGE_GUID': 'Package Guid'
+}
+class DoxygenAction:
+ """This is base class for all doxygen action.
+ """
+
+ def __init__(self, doxPath, chmPath, outputPath, projname, mode='html', log=None, verbose=False):
+ """Constructor function.
+ @param doxPath the obosolution path of doxygen execute file.
+ @param outputPath the obosolution output path.
+ @param log log function for output message
+ """
+ self._doxPath = doxPath
+ self._chmPath = chmPath
+ self._outputPath = outputPath
+ self._projname = projname
+ self._configFile = None # doxygen config file is used by doxygen exe file
+ self._indexPageFile = None # doxygen page file for index page.
+ self._log = log
+ self._mode = mode
+ self._verbose = verbose
+ self._doxygenCallback = None
+ self._chmCallback = None
+
+ def Log(self, message, level='info'):
+ if self._log is not None:
+ self._log(message, level)
+
+ def IsVerbose(self):
+ return self._verbose
+
+ def Generate(self):
+ """Generate interface called by outer directly"""
+ self.Log(">>>>>> Start generate doxygen document for %s... Zzz....\n" % self._projname)
+
+ # create doxygen config file at first
+ self._configFile = doxygen.DoxygenConfigFile()
+ self._configFile.SetOutputDir(self._outputPath)
+
+ self._configFile.SetWarningFilePath(os.path.join(self._outputPath, 'warning.txt'))
+ if self._mode.lower() == 'html':
+ self._configFile.SetHtmlMode()
+ else:
+ self._configFile.SetChmMode()
+
+ self.Log(" >>>>>> Initialize doxygen config file...Zzz...\n")
+ self.InitializeConfigFile()
+
+ self.Log(" >>>>>> Generate doxygen index page file...Zzz...\n")
+ indexPagePath = self.GenerateIndexPage()
+ if indexPagePath is None:
+ self.Log("Fail to generate index page!\n", 'error')
+ return False
+ else:
+ self.Log("Success to create doxygen index page file %s \n" % indexPagePath)
+
+ # Add index page doxygen file to file list.
+ self._configFile.AddFile(indexPagePath)
+
+ # save config file to output path
+ configFilePath = os.path.join(self._outputPath, self._projname + '.doxygen_config')
+ self._configFile.Generate(configFilePath)
+ self.Log(" <<<<<< Success Save doxygen config file to %s...\n" % configFilePath)
+
+ # launch doxygen tool to generate document
+ if self._doxygenCallback is not None:
+ self.Log(" >>>>>> Start doxygen process...Zzz...\n")
+ if not self._doxygenCallback(self._doxPath, configFilePath):
+ return False
+ else:
+ self.Log("Fail to create doxygen process!", 'error')
+ return False
+
+ return True
+
+ def InitializeConfigFile(self):
+ """Initialize config setting for doxygen project. It will be invoked after config file
+ object is created. Inherited class should implement it.
+ """
+
+ def GenerateIndexPage(self):
+ """Generate doxygen index page. Inherited class should implement it."""
+ return None
+
+ def RegisterCallbackDoxygenProcess(self, callback):
+ self._doxygenCallback = callback
+
+ def RegisterCallbackCHMProcess(self, callback):
+ self._chmCallback = callback
+
+class PlatformDocumentAction(DoxygenAction):
+ """Generate platform doxygen document, will be implement at future."""
+
+class PackageDocumentAction(DoxygenAction):
+ """Generate package reference document"""
+
+ def __init__(self, doxPath, chmPath, outputPath, pObj, mode='html', log=None, arch=None, tooltag=None,
+ onlyInclude=False, verbose=False):
+ DoxygenAction.__init__(self, doxPath, chmPath, outputPath, pObj.GetName(), mode, log, verbose)
+ self._pObj = pObj
+ self._arch = arch
+ self._tooltag = tooltag
+ self._onlyIncludeDocument = onlyInclude
+
+ def InitializeConfigFile(self):
+ if self._arch == 'IA32':
+ self._configFile.AddPreDefined('MDE_CPU_IA32')
+ elif self._arch == 'X64':
+ self._configFile.AddPreDefined('MDE_CPU_X64')
+ elif self._arch == 'IPF':
+ self._configFile.AddPreDefined('MDE_CPU_IPF')
+ elif self._arch == 'EBC':
+ self._configFile.AddPreDefined('MDE_CPU_EBC')
+ else:
+ self._arch = None
+ self._configFile.AddPreDefined('MDE_CPU_IA32')
+ self._configFile.AddPreDefined('MDE_CPU_X64')
+ self._configFile.AddPreDefined('MDE_CPU_IPF')
+ self._configFile.AddPreDefined('MDE_CPU_EBC')
+ self._configFile.AddPreDefined('MDE_CPU_ARM')
+
+ namestr = self._pObj.GetName()
+ if self._arch is not None:
+ namestr += '[%s]' % self._arch
+ if self._tooltag is not None:
+ namestr += '[%s]' % self._tooltag
+ self._configFile.SetProjectName(namestr)
+ self._configFile.SetStripPath(self._pObj.GetWorkspace())
+ self._configFile.SetProjectVersion(self._pObj.GetFileObj().GetVersion())
+ self._configFile.AddPattern('*.decdoxygen')
+
+ if self._tooltag.lower() == 'msft':
+ self._configFile.AddPreDefined('_MSC_EXTENSIONS')
+ elif self._tooltag.lower() == 'gnu':
+ self._configFile.AddPreDefined('__GNUC__')
+ elif self._tooltag.lower() == 'intel':
+ self._configFile.AddPreDefined('__INTEL_COMPILER')
+ else:
+ self._tooltag = None
+ self._configFile.AddPreDefined('_MSC_EXTENSIONS')
+ self._configFile.AddPreDefined('__GNUC__')
+ self._configFile.AddPreDefined('__INTEL_COMPILER')
+
+ self._configFile.AddPreDefined('ASM_PFX= ')
+ self._configFile.AddPreDefined('OPTIONAL= ')
+
+ def GenerateIndexPage(self):
+ """Generate doxygen index page. Inherited class should implement it."""
+ fObj = self._pObj.GetFileObj()
+ pdObj = doxygen.DoxygenFile('%s Package Document' % self._pObj.GetName(),
+ '%s.decdoxygen' % self._pObj.GetFilename())
+ self._configFile.AddFile(pdObj.GetFilename())
+ pdObj.AddDescription(fObj.GetFileHeader())
+
+ defSection = fObj.GetSectionByName('defines')[0]
+ baseSection = doxygen.Section('PackageBasicInformation', 'Package Basic Information')
+ descr = '<TABLE>'
+ for obj in defSection.GetObjects():
+ if obj.GetKey() in _dec_key_description_mapping_table.keys():
+ descr += '<TR>'
+ descr += '<TD><B>%s</B></TD>' % _dec_key_description_mapping_table[obj.GetKey()]
+ descr += '<TD>%s</TD>' % obj.GetValue()
+ descr += '</TR>'
+ descr += '</TABLE><br>'
+ baseSection.AddDescription(descr)
+ pdObj.AddSection(baseSection)
+
+ knownIssueSection = doxygen.Section('Known_Issue_section', 'Known Issue')
+ knownIssueSection.AddDescription('<ul>')
+ knownIssueSection.AddDescription('<li> OPTIONAL macro for function parameter can not be dealed with doxygen, so it disapear in this document! </li>')
+ knownIssueSection.AddDescription('</ul>')
+ pdObj.AddSection(knownIssueSection)
+
+ self.AddAllIncludeFiles(self._pObj, self._configFile)
+ pages = self.GenerateIncludesSubPage(self._pObj, self._configFile)
+ if len(pages) != 0:
+ pdObj.AddPages(pages)
+ pages = self.GenerateLibraryClassesSubPage(self._pObj, self._configFile)
+ if len(pages) != 0:
+ pdObj.AddPages(pages)
+ pages = self.GeneratePcdSubPages(self._pObj, self._configFile)
+ if len(pages) != 0:
+ pdObj.AddPages(pages)
+ pages = self.GenerateGuidSubPages(self._pObj, self._configFile)
+ if len(pages) != 0:
+ pdObj.AddPages(pages)
+ pages = self.GeneratePpiSubPages(self._pObj, self._configFile)
+ if len(pages) != 0:
+ pdObj.AddPages(pages)
+ pages = self.GenerateProtocolSubPages(self._pObj, self._configFile)
+ if len(pages) != 0:
+ pdObj.AddPages(pages)
+ if not self._onlyIncludeDocument:
+ pdObj.AddPages(self.GenerateModulePages(self._pObj, self._configFile))
+
+ pdObj.Save()
+ return pdObj.GetFilename()
+
+ def GenerateIncludesSubPage(self, pObj, configFile):
+ # by default add following path as include path to config file
+ pkpath = pObj.GetFileObj().GetPackageRootPath()
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include'))
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Library'))
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Protocol'))
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Ppi'))
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Guid'))
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'IndustryStandard'))
+
+ rootArray = []
+ pageRoot = doxygen.Page("Public Includes", "%s_public_includes" % pObj.GetName())
+ objs = pObj.GetFileObj().GetSectionObjectsByName('includes')
+ if len(objs) == 0: return []
+
+ for obj in objs:
+ # Add path to include path
+ path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetPath())
+ configFile.AddIncludePath(path)
+
+ # only list common folder's include file
+ if obj.GetArch().lower() != 'common':
+ continue
+
+ bNeedAddIncludePage = False
+ topPage = doxygen.Page(self._ConvertPathToDoxygen(path, pObj), 'public_include_top')
+
+ topPage.AddDescription('<ul>\n')
+ for file in os.listdir(path):
+ if file.lower() in _ignore_dir: continue
+ fullpath = os.path.join(path, file)
+ if os.path.isfile(fullpath):
+ self.ProcessSourceFileForInclude(fullpath, pObj, configFile)
+ topPage.AddDescription('<li> \link %s\endlink </li>\n' % self._ConvertPathToDoxygen(fullpath, pObj))
+ else:
+ if file.lower() in ['library', 'protocol', 'guid', 'ppi', 'ia32', 'x64', 'ipf', 'ebc', 'arm', 'pi', 'uefi', 'aarch64']:
+ continue
+ bNeedAddSubPage = False
+ subpage = doxygen.Page(self._ConvertPathToDoxygen(fullpath, pObj), 'public_include_%s' % file)
+ subpage.AddDescription('<ul>\n')
+ for subfile in os.listdir(fullpath):
+ if subfile.lower() in _ignore_dir: continue
+ bNeedAddSubPage = True
+ subfullpath = os.path.join(fullpath, subfile)
+ self.ProcessSourceFileForInclude(subfullpath, pObj, configFile)
+ subpage.AddDescription('<li> \link %s \endlink </li>\n' % self._ConvertPathToDoxygen(subfullpath, pObj))
+ subpage.AddDescription('</ul>\n')
+ if bNeedAddSubPage:
+ bNeedAddIncludePage = True
+ pageRoot.AddPage(subpage)
+ topPage.AddDescription('</ul>\n')
+ if bNeedAddIncludePage:
+ pageRoot.AddPage(topPage)
+
+ if pageRoot.GetSubpageCount() != 0:
+ return [pageRoot]
+ else:
+ return []
+
+ def GenerateLibraryClassesSubPage(self, pObj, configFile):
+ """
+ Generate sub page for library class for package.
+ One DEC file maybe contains many library class sections
+ for different architecture.
+
+ @param fObj DEC file object.
+ """
+ rootArray = []
+ pageRoot = doxygen.Page("Library Class", "%s_libraryclass" % pObj.GetName())
+ objs = pObj.GetFileObj().GetSectionObjectsByName('libraryclass', self._arch)
+ if len(objs) == 0: return []
+
+ if self._arch is not None:
+ for obj in objs:
+ classPage = doxygen.Page(obj.GetClassName(),
+ "lc_%s" % obj.GetClassName())
+ comments = obj.GetComment()
+ if len(comments) != 0:
+ classPage.AddDescription('<br>\n'.join(comments) + '<br>\n')
+ pageRoot.AddPage(classPage)
+ path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())
+ path = path[len(pObj.GetWorkspace()) + 1:]
+ if len(comments) == 0:
+ classPage.AddDescription('\copydoc %s<p>' % obj.GetHeaderFile())
+ section = doxygen.Section('ref', 'Refer to Header File')
+ section.AddDescription('\link %s\n' % obj.GetHeaderFile())
+ section.AddDescription(' \endlink<p>\n')
+ classPage.AddSection(section)
+ fullPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())
+ self.ProcessSourceFileForInclude(fullPath, pObj, configFile)
+ else:
+ archPageDict = {}
+ for obj in objs:
+ if obj.GetArch() not in archPageDict.keys():
+ archPageDict[obj.GetArch()] = doxygen.Page(obj.GetArch(),
+ 'lc_%s' % obj.GetArch())
+ pageRoot.AddPage(archPageDict[obj.GetArch()])
+ subArchRoot = archPageDict[obj.GetArch()]
+ classPage = doxygen.Page(obj.GetClassName(),
+ "lc_%s" % obj.GetClassName())
+ comments = obj.GetComment()
+ if len(comments) != 0:
+ classPage.AddDescription('<br>\n'.join(comments) + '<br>\n')
+ subArchRoot.AddPage(classPage)
+ path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())
+ path = path[len(pObj.GetWorkspace()) + 1:]
+ if len(comments) == 0:
+ classPage.AddDescription('\copydoc %s<p>' % obj.GetHeaderFile())
+ section = doxygen.Section('ref', 'Refer to Header File')
+ section.AddDescription('\link %s\n' % obj.GetHeaderFile())
+ section.AddDescription(' \endlink<p>\n')
+ classPage.AddSection(section)
+ fullPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())
+
+ self.ProcessSourceFileForInclude(fullPath, pObj, configFile)
+ rootArray.append(pageRoot)
+ return rootArray
+
+ def ProcessSourceFileForInclude(self, path, pObj, configFile, infObj=None):
+ """
+ @param path the analysising file full path
+ @param pObj package object
+ @param configFile doxygen config file.
+ """
+ if gInGui:
+ wx.Yield()
+ if not os.path.exists(path):
+ ErrorMsg('Source file path %s does not exist!' % path)
+ return
+
+ if configFile.FileExists(path):
+ return
+
+ try:
+ with open(path, 'r') as f:
+ lines = f.readlines()
+ except UnicodeDecodeError:
+ return
+ except IOError:
+ ErrorMsg('Fail to open file %s' % path)
+ return
+
+ configFile.AddFile(path)
+
+ no = 0
+ for no in range(len(lines)):
+ if len(lines[no].strip()) == 0:
+ continue
+ if lines[no].strip()[:2] in ['##', '//', '/*', '*/']:
+ continue
+ index = lines[no].lower().find('include')
+ #mo = IncludePattern.finditer(lines[no].lower())
+ mo = re.match(r"^#\s*include\s+[<\"]([\\/\w.]+)[>\"]$", lines[no].strip().lower())
+ if not mo:
+ continue
+ mo = re.match(r"^[#\w\s]+[<\"]([\\/\w.]+)[>\"]$", lines[no].strip())
+ filePath = mo.groups()[0]
+
+ if filePath is None or len(filePath) == 0:
+ continue
+
+ # find header file in module's path firstly.
+ fullPath = None
+
+ if os.path.exists(os.path.join(os.path.dirname(path), filePath)):
+ # Find the file in current directory
+ fullPath = os.path.join(os.path.dirname(path), filePath).replace('\\', '/')
+ else:
+ # find in depedent package's include path
+ incObjs = pObj.GetFileObj().GetSectionObjectsByName('includes')
+ for incObj in incObjs:
+ incPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), incObj.GetPath()).strip()
+ incPath = os.path.realpath(os.path.join(incPath, filePath))
+ if os.path.exists(incPath):
+ fullPath = incPath
+ break
+ if infObj is not None:
+ pkgInfObjs = infObj.GetSectionObjectsByName('packages')
+ for obj in pkgInfObjs:
+ decObj = dec.DECFile(os.path.join(pObj.GetWorkspace(), obj.GetPath()))
+ if not decObj:
+ ErrorMsg ('Fail to create pacakge object for %s' % obj.GetPackageName())
+ continue
+ if not decObj.Parse():
+ ErrorMsg ('Fail to load package object for %s' % obj.GetPackageName())
+ continue
+ incObjs = decObj.GetSectionObjectsByName('includes')
+ for incObj in incObjs:
+ incPath = os.path.join(decObj.GetPackageRootPath(), incObj.GetPath()).replace('\\', '/')
+ if os.path.exists(os.path.join(incPath, filePath)):
+ fullPath = os.path.join(os.path.join(incPath, filePath))
+ break
+ if fullPath is not None:
+ break
+
+ if fullPath is None and self.IsVerbose():
+ self.Log('Can not resolve header file %s for file %s in package %s\n' % (filePath, path, pObj.GetFileObj().GetFilename()), 'error')
+ return
+ else:
+ fullPath = fullPath.replace('\\', '/')
+ if self.IsVerbose():
+ self.Log('Preprocessing: Add include file %s for file %s\n' % (fullPath, path))
+ #LogMsg ('Preprocessing: Add include file %s for file %s' % (fullPath, path))
+ self.ProcessSourceFileForInclude(fullPath, pObj, configFile, infObj)
+
+ def AddAllIncludeFiles(self, pObj, configFile):
+ objs = pObj.GetFileObj().GetSectionObjectsByName('includes')
+ for obj in objs:
+ incPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetPath())
+ for root, dirs, files in os.walk(incPath):
+ for dir in dirs:
+ if dir.lower() in _ignore_dir:
+ dirs.remove(dir)
+ for file in files:
+ path = os.path.normpath(os.path.join(root, file))
+ configFile.AddFile(path.replace('/', '\\'))
+
+ def GeneratePcdSubPages(self, pObj, configFile):
+ """
+ Generate sub pages for package's PCD definition.
+ @param pObj package object
+ @param configFile config file object
+ """
+ rootArray = []
+ objs = pObj.GetFileObj().GetSectionObjectsByName('pcd')
+ if len(objs) == 0:
+ return []
+
+ pcdRootPage = doxygen.Page('PCD', 'pcd_root_page')
+ typeRootPageDict = {}
+ typeArchRootPageDict = {}
+ for obj in objs:
+ if obj.GetPcdType() not in typeRootPageDict.keys():
+ typeRootPageDict[obj.GetPcdType()] = doxygen.Page(obj.GetPcdType(), 'pcd_%s_root_page' % obj.GetPcdType())
+ pcdRootPage.AddPage(typeRootPageDict[obj.GetPcdType()])
+ typeRoot = typeRootPageDict[obj.GetPcdType()]
+ if self._arch is not None:
+ pcdPage = doxygen.Page('%s' % obj.GetPcdName(),
+ 'pcd_%s_%s_%s' % (obj.GetPcdType(), obj.GetArch(), obj.GetPcdName().split('.')[1]))
+ pcdPage.AddDescription('<br>\n'.join(obj.GetComment()) + '<br>\n')
+ section = doxygen.Section('PCDinformation', 'PCD Information')
+ desc = '<TABLE>'
+ desc += '<TR>'
+ desc += '<TD><CAPTION>Name</CAPTION></TD>'
+ desc += '<TD><CAPTION>Token Space</CAPTION></TD>'
+ desc += '<TD><CAPTION>Token number</CAPTION></TD>'
+ desc += '<TD><CAPTION>Data Type</CAPTION></TD>'
+ desc += '<TD><CAPTION>Default Value</CAPTION></TD>'
+ desc += '</TR>'
+ desc += '<TR>'
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[1]
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[0]
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdToken()
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdDataType()
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdValue()
+ desc += '</TR>'
+ desc += '</TABLE>'
+ section.AddDescription(desc)
+ pcdPage.AddSection(section)
+ typeRoot.AddPage(pcdPage)
+ else:
+ keystr = obj.GetPcdType() + obj.GetArch()
+ if keystr not in typeArchRootPageDict.keys():
+ typeArchRootPage = doxygen.Page(obj.GetArch(), 'pcd_%s_%s_root_page' % (obj.GetPcdType(), obj.GetArch()))
+ typeArchRootPageDict[keystr] = typeArchRootPage
+ typeRoot.AddPage(typeArchRootPage)
+ typeArchRoot = typeArchRootPageDict[keystr]
+ pcdPage = doxygen.Page('%s' % obj.GetPcdName(),
+ 'pcd_%s_%s_%s' % (obj.GetPcdType(), obj.GetArch(), obj.GetPcdName().split('.')[1]))
+ pcdPage.AddDescription('<br>\n'.join(obj.GetComment()) + '<br>\n')
+ section = doxygen.Section('PCDinformation', 'PCD Information')
+ desc = '<TABLE>'
+ desc += '<TR>'
+ desc += '<TD><CAPTION>Name</CAPTION></TD>'
+ desc += '<TD><CAPTION>Token Space</CAPTION></TD>'
+ desc += '<TD><CAPTION>Token number</CAPTION></TD>'
+ desc += '<TD><CAPTION>Data Type</CAPTION></TD>'
+ desc += '<TD><CAPTION>Default Value</CAPTION></TD>'
+ desc += '</TR>'
+ desc += '<TR>'
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[1]
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[0]
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdToken()
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdDataType()
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdValue()
+ desc += '</TR>'
+ desc += '</TABLE>'
+ section.AddDescription(desc)
+ pcdPage.AddSection(section)
+ typeArchRoot.AddPage(pcdPage)
+ return [pcdRootPage]
+
+ def _GenerateGuidSubPage(self, pObj, obj, configFile):
+ guidPage = doxygen.Page('%s' % obj.GetName(),
+ 'guid_%s_%s' % (obj.GetArch(), obj.GetName()))
+ comments = obj.GetComment()
+ if len(comments) != 0:
+ guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')
+ section = doxygen.Section('BasicGuidInfo', 'GUID Information')
+ desc = '<TABLE>'
+ desc += '<TR>'
+ desc += '<TD><CAPTION>GUID\'s Guid Name</CAPTION></TD><TD><CAPTION>GUID\'s Guid</CAPTION></TD>'
+ desc += '</TR>'
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % obj.GetName()
+ desc += '<TD>%s</TD>' % obj.GetGuid()
+ desc += '</TR>'
+ desc += '</TABLE>'
+ section.AddDescription(desc)
+ guidPage.AddSection(section)
+ refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)
+ if refFile:
+ relPath = refFile[len(pObj.GetWorkspace()) + 1:]
+ if len(comments) == 0:
+ guidPage.AddDescription(' \\copydoc %s <br>' % relPath)
+
+ section = doxygen.Section('ref', 'Refer to Header File')
+ section.AddDescription('\link %s\n' % relPath)
+ section.AddDescription('\endlink\n')
+ self.ProcessSourceFileForInclude(refFile, pObj, configFile)
+ guidPage.AddSection(section)
+ return guidPage
+
+ def GenerateGuidSubPages(self, pObj, configFile):
+ """
+ Generate sub pages for package's GUID definition.
+ @param pObj package object
+ @param configFilf doxygen config file object
+ """
+ pageRoot = doxygen.Page('GUID', 'guid_root_page')
+ objs = pObj.GetFileObj().GetSectionObjectsByName('guids', self._arch)
+ if len(objs) == 0: return []
+ if self._arch is not None:
+ for obj in objs:
+ pageRoot.AddPage(self._GenerateGuidSubPage(pObj, obj, configFile))
+ else:
+ guidArchRootPageDict = {}
+ for obj in objs:
+ if obj.GetArch() not in guidArchRootPageDict.keys():
+ guidArchRoot = doxygen.Page(obj.GetArch(), 'guid_arch_root_%s' % obj.GetArch())
+ pageRoot.AddPage(guidArchRoot)
+ guidArchRootPageDict[obj.GetArch()] = guidArchRoot
+ guidArchRoot = guidArchRootPageDict[obj.GetArch()]
+ guidArchRoot.AddPage(self._GenerateGuidSubPage(pObj, obj, configFile))
+ return [pageRoot]
+
+ def _GeneratePpiSubPage(self, pObj, obj, configFile):
+ guidPage = doxygen.Page(obj.GetName(), 'ppi_page_%s' % obj.GetName())
+ comments = obj.GetComment()
+ if len(comments) != 0:
+ guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')
+ section = doxygen.Section('BasicPpiInfo', 'PPI Information')
+ desc = '<TABLE>'
+ desc += '<TR>'
+ desc += '<TD><CAPTION>PPI\'s Guid Name</CAPTION></TD><TD><CAPTION>PPI\'s Guid</CAPTION></TD>'
+ desc += '</TR>'
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % obj.GetName()
+ desc += '<TD>%s</TD>' % obj.GetGuid()
+ desc += '</TR>'
+ desc += '</TABLE>'
+ section.AddDescription(desc)
+ guidPage.AddSection(section)
+ refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)
+ if refFile:
+ relPath = refFile[len(pObj.GetWorkspace()) + 1:]
+ if len(comments) == 0:
+ guidPage.AddDescription(' \\copydoc %s <br>' % relPath)
+ section = doxygen.Section('ref', 'Refer to Header File')
+ section.AddDescription('\link %s\n' % relPath)
+ section.AddDescription('\endlink\n')
+ self.ProcessSourceFileForInclude(refFile, pObj, configFile)
+ guidPage.AddSection(section)
+
+ return guidPage
+
+ def GeneratePpiSubPages(self, pObj, configFile):
+ """
+ Generate sub pages for package's GUID definition.
+ @param pObj package object
+ @param configFilf doxygen config file object
+ """
+ pageRoot = doxygen.Page('PPI', 'ppi_root_page')
+ objs = pObj.GetFileObj().GetSectionObjectsByName('ppis', self._arch)
+ if len(objs) == 0: return []
+ if self._arch is not None:
+ for obj in objs:
+ pageRoot.AddPage(self._GeneratePpiSubPage(pObj, obj, configFile))
+ else:
+ guidArchRootPageDict = {}
+ for obj in objs:
+ if obj.GetArch() not in guidArchRootPageDict.keys():
+ guidArchRoot = doxygen.Page(obj.GetArch(), 'ppi_arch_root_%s' % obj.GetArch())
+ pageRoot.AddPage(guidArchRoot)
+ guidArchRootPageDict[obj.GetArch()] = guidArchRoot
+ guidArchRoot = guidArchRootPageDict[obj.GetArch()]
+ guidArchRoot.AddPage(self._GeneratePpiSubPage(pObj, obj, configFile))
+ return [pageRoot]
+
+ def _GenerateProtocolSubPage(self, pObj, obj, configFile):
+ guidPage = doxygen.Page(obj.GetName(), 'protocol_page_%s' % obj.GetName())
+ comments = obj.GetComment()
+ if len(comments) != 0:
+ guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')
+ section = doxygen.Section('BasicProtocolInfo', 'PROTOCOL Information')
+ desc = '<TABLE>'
+ desc += '<TR>'
+ desc += '<TD><CAPTION>PROTOCOL\'s Guid Name</CAPTION></TD><TD><CAPTION>PROTOCOL\'s Guid</CAPTION></TD>'
+ desc += '</TR>'
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % obj.GetName()
+ desc += '<TD>%s</TD>' % obj.GetGuid()
+ desc += '</TR>'
+ desc += '</TABLE>'
+ section.AddDescription(desc)
+ guidPage.AddSection(section)
+
+ refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)
+ if refFile:
+ relPath = refFile[len(pObj.GetWorkspace()) + 1:]
+ if len(comments) == 0:
+ guidPage.AddDescription(' \\copydoc %s <br>' % relPath)
+ section = doxygen.Section('ref', 'Refer to Header File')
+ section.AddDescription('\link %s\n' % relPath)
+ section.AddDescription('\endlink\n')
+ self.ProcessSourceFileForInclude(refFile, pObj, configFile)
+ guidPage.AddSection(section)
+
+ return guidPage
+
+ def GenerateProtocolSubPages(self, pObj, configFile):
+ """
+ Generate sub pages for package's GUID definition.
+ @param pObj package object
+ @param configFilf doxygen config file object
+ """
+ pageRoot = doxygen.Page('PROTOCOL', 'protocol_root_page')
+ objs = pObj.GetFileObj().GetSectionObjectsByName('protocols', self._arch)
+ if len(objs) == 0: return []
+ if self._arch is not None:
+ for obj in objs:
+ pageRoot.AddPage(self._GenerateProtocolSubPage(pObj, obj, configFile))
+ else:
+ guidArchRootPageDict = {}
+ for obj in objs:
+ if obj.GetArch() not in guidArchRootPageDict.keys():
+ guidArchRoot = doxygen.Page(obj.GetArch(), 'protocol_arch_root_%s' % obj.GetArch())
+ pageRoot.AddPage(guidArchRoot)
+ guidArchRootPageDict[obj.GetArch()] = guidArchRoot
+ guidArchRoot = guidArchRootPageDict[obj.GetArch()]
+ guidArchRoot.AddPage(self._GenerateProtocolSubPage(pObj, obj, configFile))
+ return [pageRoot]
+
+ def FindHeaderFileForGuid(self, pObj, name, configFile):
+ """
+ For declaration header file for GUID/PPI/Protocol.
+
+ @param pObj package object
+ @param name guid/ppi/protocol's name
+ @param configFile config file object
+
+ @return full path of header file and None if not found.
+ """
+ startPath = pObj.GetFileObj().GetPackageRootPath()
+ incPath = os.path.join(startPath, 'Include').replace('\\', '/')
+ # if <PackagePath>/include exist, then search header under it.
+ if os.path.exists(incPath):
+ startPath = incPath
+
+ for root, dirs, files in os.walk(startPath):
+ for dir in dirs:
+ if dir.lower() in _ignore_dir:
+ dirs.remove(dir)
+ for file in files:
+ fPath = os.path.join(root, file)
+ if not IsCHeaderFile(fPath):
+ continue
+ try:
+ f = open(fPath, 'r')
+ lines = f.readlines()
+ f.close()
+ except IOError:
+ self.Log('Fail to open file %s\n' % fPath)
+ continue
+ for line in lines:
+ if line.find(name) != -1 and \
+ line.find('extern') != -1:
+ return fPath.replace('\\', '/')
+ return None
+
+ def GetPackageModuleList(self, pObj):
+ """
+ Get all module's INF path under package's root path
+ @param pObj package object
+ @return arrary of INF full path
+ """
+ mArray = []
+ packPath = pObj.GetFileObj().GetPackageRootPath()
+ if not os.path.exists:
+ return None
+ for root, dirs, files in os.walk(packPath):
+ for dir in dirs:
+ if dir.lower() in _ignore_dir:
+ dirs.remove(dir)
+ for file in files:
+ if CheckPathPostfix(file, 'inf'):
+ fPath = os.path.join(root, file).replace('\\', '/')
+ mArray.append(fPath)
+ return mArray
+
+ def GenerateModulePages(self, pObj, configFile):
+ """
+ Generate sub pages for package's module which is under the package
+ root directory.
+
+ @param pObj package object
+ @param configFilf doxygen config file object
+ """
+ infList = self.GetPackageModuleList(pObj)
+ rootPages = []
+ libObjs = []
+ modObjs = []
+ for infpath in infList:
+ infObj = inf.INFFile(infpath)
+ #infObj = INFFileObject.INFFile (pObj.GetWorkspacePath(),
+ # inf)
+ if not infObj:
+ self.Log('Fail create INF object for %s' % inf)
+ continue
+ if not infObj.Parse():
+ self.Log('Fail to load INF file %s' % inf)
+ continue
+ if infObj.GetProduceLibraryClass() is not None:
+ libObjs.append(infObj)
+ else:
+ modObjs.append(infObj)
+
+ if len(libObjs) != 0:
+ libRootPage = doxygen.Page('Libraries', 'lib_root_page')
+ rootPages.append(libRootPage)
+ for libInf in libObjs:
+ libRootPage.AddPage(self.GenerateModulePage(pObj, libInf, configFile, True))
+
+ if len(modObjs) != 0:
+ modRootPage = doxygen.Page('Modules', 'module_root_page')
+ rootPages.append(modRootPage)
+ for modInf in modObjs:
+ modRootPage.AddPage(self.GenerateModulePage(pObj, modInf, configFile, False))
+
+ return rootPages
+
+ def GenerateModulePage(self, pObj, infObj, configFile, isLib):
+ """
+ Generate page for a module/library.
+ @param infObj INF file object for module/library
+ @param configFile doxygen config file object
+ @param isLib Whether this module is library
+
+ @param module doxygen page object
+ """
+ workspace = pObj.GetWorkspace()
+ refDecObjs = []
+ for obj in infObj.GetSectionObjectsByName('packages'):
+ decObj = dec.DECFile(os.path.join(workspace, obj.GetPath()))
+ if not decObj:
+ ErrorMsg ('Fail to create pacakge object for %s' % obj.GetPackageName())
+ continue
+ if not decObj.Parse():
+ ErrorMsg ('Fail to load package object for %s' % obj.GetPackageName())
+ continue
+ refDecObjs.append(decObj)
+
+ modPage = doxygen.Page('%s' % infObj.GetBaseName(),
+ 'module_%s' % infObj.GetBaseName())
+ modPage.AddDescription(infObj.GetFileHeader())
+
+ basicInfSection = doxygen.Section('BasicModuleInformation', 'Basic Module Information')
+ desc = "<TABLE>"
+ for obj in infObj.GetSectionObjectsByName('defines'):
+ key = obj.GetKey()
+ value = obj.GetValue()
+ if key not in _inf_key_description_mapping_table.keys(): continue
+ if key == 'LIBRARY_CLASS' and value.find('|') != -1:
+ clsname, types = value.split('|')
+ desc += '<TR>'
+ desc += '<TD><B>%s</B></TD>' % _inf_key_description_mapping_table[key]
+ desc += '<TD>%s</TD>' % clsname
+ desc += '</TR>'
+
+ desc += '<TR>'
+ desc += '<TD><B>Supported Module Types</B></TD>'
+ desc += '<TD>%s</TD>' % types
+ desc += '</TR>'
+ else:
+ desc += '<TR>'
+ desc += '<TD><B>%s</B></TD>' % _inf_key_description_mapping_table[key]
+ if key == 'EFI_SPECIFICATION_VERSION' and value == '0x00020000':
+ value = '2.0'
+ desc += '<TD>%s</TD>' % value
+ desc += '</TR>'
+ desc += '</TABLE>'
+ basicInfSection.AddDescription(desc)
+ modPage.AddSection(basicInfSection)
+
+ # Add protocol section
+ data = []
+ for obj in infObj.GetSectionObjectsByName('pcd', self._arch):
+ data.append(obj.GetPcdName().strip())
+ if len(data) != 0:
+ s = doxygen.Section('Pcds', 'Pcds')
+ desc = "<TABLE>"
+ desc += '<TR><TD><B>PCD Name</B></TD><TD><B>TokenSpace</B></TD><TD><B>Package</B></TD></TR>'
+ for item in data:
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % item.split('.')[1]
+ desc += '<TD>%s</TD>' % item.split('.')[0]
+ pkgbasename = self.SearchPcdPackage(item, workspace, refDecObjs)
+ desc += '<TD>%s</TD>' % pkgbasename
+ desc += '</TR>'
+ desc += "</TABLE>"
+ s.AddDescription(desc)
+ modPage.AddSection(s)
+
+ # Add protocol section
+ #sects = infObj.GetSectionByString('protocol')
+ data = []
+ #for sect in sects:
+ for obj in infObj.GetSectionObjectsByName('protocol', self._arch):
+ data.append(obj.GetName().strip())
+ if len(data) != 0:
+ s = doxygen.Section('Protocols', 'Protocols')
+ desc = "<TABLE>"
+ desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'
+ for item in data:
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % item
+ pkgbasename = self.SearchProtocolPackage(item, workspace, refDecObjs)
+ desc += '<TD>%s</TD>' % pkgbasename
+ desc += '</TR>'
+ desc += "</TABLE>"
+ s.AddDescription(desc)
+ modPage.AddSection(s)
+
+ # Add ppi section
+ #sects = infObj.GetSectionByString('ppi')
+ data = []
+ #for sect in sects:
+ for obj in infObj.GetSectionObjectsByName('ppi', self._arch):
+ data.append(obj.GetName().strip())
+ if len(data) != 0:
+ s = doxygen.Section('Ppis', 'Ppis')
+ desc = "<TABLE>"
+ desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'
+ for item in data:
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % item
+ pkgbasename = self.SearchPpiPackage(item, workspace, refDecObjs)
+ desc += '<TD>%s</TD>' % pkgbasename
+ desc += '</TR>'
+ desc += "</TABLE>"
+ s.AddDescription(desc)
+ modPage.AddSection(s)
+
+ # Add guid section
+ #sects = infObj.GetSectionByString('guid')
+ data = []
+ #for sect in sects:
+ for obj in infObj.GetSectionObjectsByName('guid', self._arch):
+ data.append(obj.GetName().strip())
+ if len(data) != 0:
+ s = doxygen.Section('Guids', 'Guids')
+ desc = "<TABLE>"
+ desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'
+ for item in data:
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % item
+ pkgbasename = self.SearchGuidPackage(item, workspace, refDecObjs)
+ desc += '<TD>%s</TD>' % pkgbasename
+ desc += '</TR>'
+ desc += "</TABLE>"
+ s.AddDescription(desc)
+ modPage.AddSection(s)
+
+ section = doxygen.Section('LibraryClasses', 'Library Classes')
+ desc = "<TABLE>"
+ desc += '<TR><TD><B>Name</B></TD><TD><B>Type</B></TD><TD><B>Package</B></TD><TD><B>Header File</B></TD></TR>'
+ if isLib:
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % infObj.GetProduceLibraryClass()
+ desc += '<TD>Produce</TD>'
+ try:
+ pkgname, hPath = self.SearchLibraryClassHeaderFile(infObj.GetProduceLibraryClass(),
+ workspace,
+ refDecObjs)
+ except:
+ self.Log ('fail to get package header file for lib class %s' % infObj.GetProduceLibraryClass())
+ pkgname = 'NULL'
+ hPath = 'NULL'
+ desc += '<TD>%s</TD>' % pkgname
+ if hPath != "NULL":
+ desc += '<TD>\link %s \endlink</TD>' % hPath
+ else:
+ desc += '<TD>%s</TD>' % hPath
+ desc += '</TR>'
+ for lcObj in infObj.GetSectionObjectsByName('libraryclasses', self._arch):
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % lcObj.GetClass()
+ retarr = self.SearchLibraryClassHeaderFile(lcObj.GetClass(),
+ workspace,
+ refDecObjs)
+ if retarr is not None:
+ pkgname, hPath = retarr
+ else:
+ self.Log('Fail find the library class %s definition from module %s dependent package!' % (lcObj.GetClass(), infObj.GetFilename()), 'error')
+ pkgname = 'NULL'
+ hPath = 'NULL'
+ desc += '<TD>Consume</TD>'
+ desc += '<TD>%s</TD>' % pkgname
+ desc += '<TD>\link %s \endlink</TD>' % hPath
+ desc += '</TR>'
+ desc += "</TABLE>"
+ section.AddDescription(desc)
+ modPage.AddSection(section)
+
+ section = doxygen.Section('SourceFiles', 'Source Files')
+ section.AddDescription('<ul>\n')
+ for obj in infObj.GetSourceObjects(self._arch, self._tooltag):
+ sPath = infObj.GetModuleRootPath()
+ sPath = os.path.join(sPath, obj.GetSourcePath()).replace('\\', '/').strip()
+ if sPath.lower().endswith('.uni') or sPath.lower().endswith('.s') or sPath.lower().endswith('.asm') or sPath.lower().endswith('.nasm'):
+ newPath = self.TranslateUniFile(sPath)
+ configFile.AddFile(newPath)
+ newPath = newPath[len(pObj.GetWorkspace()) + 1:]
+ section.AddDescription('<li> \link %s \endlink </li>' % newPath)
+ else:
+ self.ProcessSourceFileForInclude(sPath, pObj, configFile, infObj)
+ sPath = sPath[len(pObj.GetWorkspace()) + 1:]
+ section.AddDescription('<li>\link %s \endlink </li>' % sPath)
+ section.AddDescription('</ul>\n')
+ modPage.AddSection(section)
+
+ #sects = infObj.GetSectionByString('depex')
+ data = []
+ #for sect in sects:
+ for obj in infObj.GetSectionObjectsByName('depex'):
+ data.append(str(obj))
+ if len(data) != 0:
+ s = doxygen.Section('DependentSection', 'Module Dependencies')
+ s.AddDescription('<br>'.join(data))
+ modPage.AddSection(s)
+
+ return modPage
+
+ def TranslateUniFile(self, path):
+ newpath = path + '.dox'
+ #import core.textfile as textfile
+ #file = textfile.TextFile(path)
+
+ try:
+ file = open(path, 'r')
+ except (IOError, OSError) as msg:
+ return None
+
+ t = file.read()
+ file.close()
+
+ output = '/** @file \n'
+ #output = '<html><body>'
+ arr = t.split('\r\n')
+ for line in arr:
+ if line.find('@file') != -1:
+ continue
+ if line.find('*/') != -1:
+ continue
+ line = line.strip()
+ if line.strip().startswith('/'):
+ arr = line.split(' ')
+ if len(arr) > 1:
+ line = ' '.join(arr[1:])
+ else:
+ continue
+ output += '%s<br>\n' % line
+ output += '**/'
+
+ if os.path.exists(newpath):
+ os.remove(newpath)
+
+ file = open(newpath, "w")
+ file.write(output)
+ file.close()
+ return newpath
+
+ def SearchPcdPackage(self, pcdname, workspace, decObjs):
+ for decObj in decObjs:
+ for pcd in decObj.GetSectionObjectsByName('pcd'):
+ if pcdname == pcd.GetPcdName():
+ return decObj.GetBaseName()
+ return None
+
+ def SearchProtocolPackage(self, protname, workspace, decObjs):
+ for decObj in decObjs:
+ for proto in decObj.GetSectionObjectsByName('protocol'):
+ if protname == proto.GetName():
+ return decObj.GetBaseName()
+ return None
+
+ def SearchPpiPackage(self, ppiname, workspace, decObjs):
+ for decObj in decObjs:
+ for ppi in decObj.GetSectionObjectsByName('ppi'):
+ if ppiname == ppi.GetName():
+ return decObj.GetBaseName()
+ return None
+
+ def SearchGuidPackage(self, guidname, workspace, decObjs):
+ for decObj in decObjs:
+ for guid in decObj.GetSectionObjectsByName('guid'):
+ if guidname == guid.GetName():
+ return decObj.GetBaseName()
+ return None
+
+ def SearchLibraryClassHeaderFile(self, className, workspace, decObjs):
+ for decObj in decObjs:
+ for cls in decObj.GetSectionObjectsByName('libraryclasses'):
+ if cls.GetClassName().strip() == className:
+ path = cls.GetHeaderFile().strip()
+ path = os.path.join(decObj.GetPackageRootPath(), path)
+ path = path[len(workspace) + 1:]
+ return decObj.GetBaseName(), path.replace('\\', '/')
+
+ return None
+
+ def _ConvertPathToDoxygen(self, path, pObj):
+ pRootPath = pObj.GetWorkspace()
+ path = path[len(pRootPath) + 1:]
+ return path.replace('\\', '/')
+
+def IsCHeaderFile(path):
+ return CheckPathPostfix(path, 'h')
+
+def CheckPathPostfix(path, str):
+ index = path.rfind('.')
+ if index == -1:
+ return False
+ if path[index + 1:].lower() == str.lower():
+ return True
+ return False
diff --git a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/doxygengen_spec.py b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/doxygengen_spec.py
index e37938c466..448e3682c1 100644
--- a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/doxygengen_spec.py
+++ b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/doxygengen_spec.py
@@ -1,1086 +1,1086 @@
-## @file
-#
-# This file produce action class to generate doxygen document for edk2 codebase.
-# The action classes are shared by GUI and command line tools.
-#
-# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-
-from plugins.EdkPlugins.basemodel import doxygen
-import os
-try:
- import wx
- gInGui = True
-except:
- gInGui = False
-import re
-from plugins.EdkPlugins.edk2.model import inf
-from plugins.EdkPlugins.edk2.model import dec
-from plugins.EdkPlugins.basemodel.message import *
-
-_ignore_dir = ['.svn', '_svn', 'cvs']
-_inf_key_description_mapping_table = {
- 'INF_VERSION':'Version of INF file specification',
- #'BASE_NAME':'Module Name',
- 'FILE_GUID':'Module Guid',
- 'MODULE_TYPE': 'Module Type',
- 'VERSION_STRING': 'Module Version',
- 'LIBRARY_CLASS': 'Produced Library Class',
- 'EFI_SPECIFICATION_VERSION': 'UEFI Specification Version',
- 'PI_SPECIFICATION_VERSION': 'PI Specification Version',
- 'ENTRY_POINT': 'Module Entry Point Function',
- 'CONSTRUCTOR': 'Library Constructor Function'
-}
-
-_dec_key_description_mapping_table = {
- 'DEC_SPECIFICATION': 'Version of DEC file specification',
- 'PACKAGE_GUID': 'Package Guid'
-}
-class DoxygenAction:
- """This is base class for all doxygen action.
- """
-
- def __init__(self, doxPath, chmPath, outputPath, projname, mode='html', log=None, verbose=False):
- """Constructor function.
- @param doxPath the obosolution path of doxygen execute file.
- @param outputPath the obosolution output path.
- @param log log function for output message
- """
- self._doxPath = doxPath
- self._chmPath = chmPath
- self._outputPath = outputPath
- self._projname = projname
- self._configFile = None # doxygen config file is used by doxygen exe file
- self._indexPageFile = None # doxygen page file for index page.
- self._log = log
- self._mode = mode
- self._verbose = verbose
- self._doxygenCallback = None
- self._chmCallback = None
-
- def Log(self, message, level='info'):
- if self._log is not None:
- self._log(message, level)
-
- def IsVerbose(self):
- return self._verbose
-
- def Generate(self):
- """Generate interface called by outer directly"""
- self.Log(">>>>>> Start generate doxygen document for %s... Zzz....\n" % self._projname)
-
- # create doxygen config file at first
- self._configFile = doxygen.DoxygenConfigFile()
- self._configFile.SetOutputDir(self._outputPath)
-
- self._configFile.SetWarningFilePath(os.path.join(self._outputPath, 'warning.txt'))
- if self._mode.lower() == 'html':
- self._configFile.SetHtmlMode()
- else:
- self._configFile.SetChmMode()
-
- self.Log(" >>>>>> Initialize doxygen config file...Zzz...\n")
- self.InitializeConfigFile()
-
- self.Log(" >>>>>> Generate doxygen index page file...Zzz...\n")
- indexPagePath = self.GenerateIndexPage()
- if indexPagePath is None:
- self.Log("Fail to generate index page!\n", 'error')
- return False
- else:
- self.Log("Success to create doxygen index page file %s \n" % indexPagePath)
-
- # Add index page doxygen file to file list.
- self._configFile.AddFile(indexPagePath)
-
- # save config file to output path
- configFilePath = os.path.join(self._outputPath, self._projname + '.doxygen_config')
- self._configFile.Generate(configFilePath)
- self.Log(" <<<<<< Success Save doxygen config file to %s...\n" % configFilePath)
-
- # launch doxygen tool to generate document
- if self._doxygenCallback is not None:
- self.Log(" >>>>>> Start doxygen process...Zzz...\n")
- if not self._doxygenCallback(self._doxPath, configFilePath):
- return False
- else:
- self.Log("Fail to create doxygen process!", 'error')
- return False
-
- return True
-
- def InitializeConfigFile(self):
- """Initialize config setting for doxygen project. It will be invoked after config file
- object is created. Inherited class should implement it.
- """
-
- def GenerateIndexPage(self):
- """Generate doxygen index page. Inherited class should implement it."""
- return None
-
- def RegisterCallbackDoxygenProcess(self, callback):
- self._doxygenCallback = callback
-
- def RegisterCallbackCHMProcess(self, callback):
- self._chmCallback = callback
-
-class PlatformDocumentAction(DoxygenAction):
- """Generate platform doxygen document, will be implement at future."""
-
-class PackageDocumentAction(DoxygenAction):
- """Generate package reference document"""
-
- def __init__(self, doxPath, chmPath, outputPath, pObj, mode='html', log=None, arch=None, tooltag=None,
- macros=[], onlyInclude=False, verbose=False):
- DoxygenAction.__init__(self, doxPath, chmPath, outputPath, pObj.GetName(), mode, log, verbose)
- self._pObj = pObj
- self._arch = arch
- self._tooltag = tooltag
- self._macros = macros
- self._onlyIncludeDocument = onlyInclude
-
- def InitializeConfigFile(self):
- if self._arch == 'IA32':
- self._configFile.AddPreDefined('MDE_CPU_IA32')
- elif self._arch == 'X64':
- self._configFile.AddPreDefined('MDE_CPU_X64')
- elif self._arch == 'IPF':
- self._configFile.AddPreDefined('MDE_CPU_IPF')
- elif self._arch == 'EBC':
- self._configFile.AddPreDefined('MDE_CPU_EBC')
- else:
- self._arch = None
- self._configFile.AddPreDefined('MDE_CPU_IA32')
- self._configFile.AddPreDefined('MDE_CPU_X64')
- self._configFile.AddPreDefined('MDE_CPU_IPF')
- self._configFile.AddPreDefined('MDE_CPU_EBC')
- self._configFile.AddPreDefined('MDE_CPU_ARM')
-
- for macro in self._macros:
- self._configFile.AddPreDefined(macro)
-
- namestr = self._pObj.GetName()
- if self._arch is not None:
- namestr += '[%s]' % self._arch
- if self._tooltag is not None:
- namestr += '[%s]' % self._tooltag
- self._configFile.SetProjectName(namestr)
- self._configFile.SetStripPath(self._pObj.GetWorkspace())
- self._configFile.SetProjectVersion(self._pObj.GetFileObj().GetVersion())
- self._configFile.AddPattern('*.decdoxygen')
-
- if self._tooltag.lower() == 'msft':
- self._configFile.AddPreDefined('_MSC_EXTENSIONS')
- elif self._tooltag.lower() == 'gnu':
- self._configFile.AddPreDefined('__GNUC__')
- elif self._tooltag.lower() == 'intel':
- self._configFile.AddPreDefined('__INTEL_COMPILER')
- else:
- self._tooltag = None
- self._configFile.AddPreDefined('_MSC_EXTENSIONS')
- self._configFile.AddPreDefined('__GNUC__')
- self._configFile.AddPreDefined('__INTEL_COMPILER')
-
- self._configFile.AddPreDefined('ASM_PFX= ')
- self._configFile.AddPreDefined('OPTIONAL= ')
-
- def GenerateIndexPage(self):
- """Generate doxygen index page. Inherited class should implement it."""
- fObj = self._pObj.GetFileObj()
- pdObj = doxygen.DoxygenFile('%s Package Document' % self._pObj.GetName(),
- '%s.decdoxygen' % self._pObj.GetFilename())
- self._configFile.AddFile(pdObj.GetFilename())
- pdObj.AddDescription(fObj.GetFileHeader())
-
- defSection = fObj.GetSectionByName('defines')[0]
- baseSection = doxygen.Section('PackageBasicInformation', 'Package Basic Information')
- descr = '<TABLE>'
- for obj in defSection.GetObjects():
- if obj.GetKey() in _dec_key_description_mapping_table.keys():
- descr += '<TR>'
- descr += '<TD><B>%s</B></TD>' % _dec_key_description_mapping_table[obj.GetKey()]
- descr += '<TD>%s</TD>' % obj.GetValue()
- descr += '</TR>'
- descr += '</TABLE><br>'
- baseSection.AddDescription(descr)
- pdObj.AddSection(baseSection)
-
- knownIssueSection = doxygen.Section('Known_Issue_section', 'Known Issue')
- knownIssueSection.AddDescription('<ul>')
- knownIssueSection.AddDescription('<li> OPTIONAL macro for function parameter can not be dealed with doxygen, so it disapear in this document! </li>')
- knownIssueSection.AddDescription('</ul>')
- pdObj.AddSection(knownIssueSection)
-
- self.AddAllIncludeFiles(self._pObj, self._configFile)
- pages = self.GenerateIncludesSubPage(self._pObj, self._configFile)
- if len(pages) != 0:
- pdObj.AddPages(pages)
- pages = self.GenerateLibraryClassesSubPage(self._pObj, self._configFile)
- if len(pages) != 0:
- pdObj.AddPages(pages)
- pages = self.GeneratePcdSubPages(self._pObj, self._configFile)
- if len(pages) != 0:
- pdObj.AddPages(pages)
- pages = self.GenerateGuidSubPages(self._pObj, self._configFile)
- if len(pages) != 0:
- pdObj.AddPages(pages)
- pages = self.GeneratePpiSubPages(self._pObj, self._configFile)
- if len(pages) != 0:
- pdObj.AddPages(pages)
- pages = self.GenerateProtocolSubPages(self._pObj, self._configFile)
- if len(pages) != 0:
- pdObj.AddPages(pages)
- if not self._onlyIncludeDocument:
- pdObj.AddPages(self.GenerateModulePages(self._pObj, self._configFile))
-
- pdObj.Save()
- return pdObj.GetFilename()
-
- def GenerateIncludesSubPage(self, pObj, configFile):
- # by default add following path as include path to config file
- pkpath = pObj.GetFileObj().GetPackageRootPath()
- configFile.AddIncludePath(os.path.join(pkpath, 'Include'))
- configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Library'))
- configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Protocol'))
- configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Ppi'))
- configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Guid'))
- configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'IndustryStandard'))
-
- rootArray = []
- pageRoot = doxygen.Page("Public Includes", "%s_public_includes" % pObj.GetName())
- objs = pObj.GetFileObj().GetSectionObjectsByName('includes')
- if len(objs) == 0: return []
-
- for obj in objs:
- # Add path to include path
- path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetPath())
- configFile.AddIncludePath(path)
-
- # only list common folder's include file
- if obj.GetArch().lower() != 'common':
- continue
-
- bNeedAddIncludePage = False
- topPage = doxygen.Page(self._ConvertPathToDoxygen(path, pObj), 'public_include_top')
-
- topPage.AddDescription('<ul>\n')
- for file in os.listdir(path):
- if file.lower() in _ignore_dir: continue
- fullpath = os.path.join(path, file)
- if os.path.isfile(fullpath):
- self.ProcessSourceFileForInclude(fullpath, pObj, configFile)
- topPage.AddDescription('<li> \link %s\endlink </li>\n' % self._ConvertPathToDoxygen(fullpath, pObj))
- else:
- if file.lower() in ['library', 'protocol', 'guid', 'ppi', 'ia32', 'x64', 'ipf', 'ebc', 'arm', 'pi', 'uefi', 'aarch64']:
- continue
- bNeedAddSubPage = False
- subpage = doxygen.Page(self._ConvertPathToDoxygen(fullpath, pObj), 'public_include_%s' % file)
- subpage.AddDescription('<ul>\n')
- for subfile in os.listdir(fullpath):
- if subfile.lower() in _ignore_dir: continue
- bNeedAddSubPage = True
- subfullpath = os.path.join(fullpath, subfile)
- self.ProcessSourceFileForInclude(subfullpath, pObj, configFile)
- subpage.AddDescription('<li> \link %s \endlink </li>\n' % self._ConvertPathToDoxygen(subfullpath, pObj))
- subpage.AddDescription('</ul>\n')
- if bNeedAddSubPage:
- bNeedAddIncludePage = True
- pageRoot.AddPage(subpage)
- topPage.AddDescription('</ul>\n')
- if bNeedAddIncludePage:
- pageRoot.AddPage(topPage)
-
- if pageRoot.GetSubpageCount() != 0:
- return [pageRoot]
- else:
- return []
-
- def GenerateLibraryClassesSubPage(self, pObj, configFile):
- """
- Generate sub page for library class for package.
- One DEC file maybe contains many library class sections
- for different architecture.
-
- @param fObj DEC file object.
- """
- rootArray = []
- pageRoot = doxygen.Page("Library Class", "%s_libraryclass" % pObj.GetName())
- objs = pObj.GetFileObj().GetSectionObjectsByName('libraryclass', self._arch)
- if len(objs) == 0: return []
-
- if self._arch is not None:
- for obj in objs:
- classPage = doxygen.Page(obj.GetClassName(),
- "lc_%s" % obj.GetClassName())
- comments = obj.GetComment()
- if len(comments) != 0:
- classPage.AddDescription('<br>\n'.join(comments) + '<br>\n')
- pageRoot.AddPage(classPage)
- path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())
- path = path[len(pObj.GetWorkspace()) + 1:]
- if len(comments) == 0:
- classPage.AddDescription('\copydoc %s<p>' % obj.GetHeaderFile())
- section = doxygen.Section('ref', 'Refer to Header File')
- section.AddDescription('\link %s\n' % obj.GetHeaderFile())
- section.AddDescription(' \endlink<p>\n')
- classPage.AddSection(section)
- fullPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())
- self.ProcessSourceFileForInclude(fullPath, pObj, configFile)
- else:
- archPageDict = {}
- for obj in objs:
- if obj.GetArch() not in archPageDict.keys():
- archPageDict[obj.GetArch()] = doxygen.Page(obj.GetArch(),
- 'lc_%s' % obj.GetArch())
- pageRoot.AddPage(archPageDict[obj.GetArch()])
- subArchRoot = archPageDict[obj.GetArch()]
- classPage = doxygen.Page(obj.GetClassName(),
- "lc_%s" % obj.GetClassName())
- comments = obj.GetComment()
- if len(comments) != 0:
- classPage.AddDescription('<br>\n'.join(comments) + '<br>\n')
- subArchRoot.AddPage(classPage)
- path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())
- path = path[len(pObj.GetWorkspace()) + 1:]
- if len(comments) == 0:
- classPage.AddDescription('\copydoc %s<p>' % obj.GetHeaderFile())
- section = doxygen.Section('ref', 'Refer to Header File')
- section.AddDescription('\link %s\n' % obj.GetHeaderFile())
- section.AddDescription(' \endlink<p>\n')
- classPage.AddSection(section)
- fullPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())
-
- self.ProcessSourceFileForInclude(fullPath, pObj, configFile)
- rootArray.append(pageRoot)
- return rootArray
-
- def ProcessSourceFileForInclude(self, path, pObj, configFile, infObj=None):
- """
- @param path the analysising file full path
- @param pObj package object
- @param configFile doxygen config file.
- """
-
- if gInGui:
- wx.Yield()
- if not os.path.exists(path):
- ErrorMsg('Source file path %s does not exist!' % path)
- return
-
- if configFile.FileExists(path):
- return
-
- try:
- f = open(path, 'r')
- lines = f.readlines()
- f.close()
- except IOError:
- ErrorMsg('Fail to open file %s' % path)
- return
-
- configFile.AddFile(path)
- return
- no = 0
- for no in range(len(lines)):
- if len(lines[no].strip()) == 0:
- continue
- if lines[no].strip()[:2] in ['##', '//', '/*', '*/']:
- continue
- index = lines[no].lower().find('include')
- #mo = IncludePattern.finditer(lines[no].lower())
- mo = re.match(r"^#\s*include\s+[<\"]([\\/\w.]+)[>\"]$", lines[no].strip().lower())
- if not mo:
- continue
- mo = re.match(r"^[#\w\s]+[<\"]([\\/\w.]+)[>\"]$", lines[no].strip())
- filePath = mo.groups()[0]
-
- if filePath is None or len(filePath) == 0:
- continue
-
- # find header file in module's path firstly.
- fullPath = None
-
- if os.path.exists(os.path.join(os.path.dirname(path), filePath)):
- # Find the file in current directory
- fullPath = os.path.join(os.path.dirname(path), filePath).replace('\\', '/')
- else:
- # find in depedent package's include path
- incObjs = pObj.GetFileObj().GetSectionObjectsByName('includes')
- for incObj in incObjs:
- incPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), incObj.GetPath()).strip()
- incPath = os.path.realpath(os.path.join(incPath, filePath))
- if os.path.exists(incPath):
- fullPath = incPath
- break
- if infObj is not None:
- pkgInfObjs = infObj.GetSectionObjectsByName('packages')
- for obj in pkgInfObjs:
- decObj = dec.DECFile(os.path.join(pObj.GetWorkspace(), obj.GetPath()))
- if not decObj:
- ErrorMsg ('Fail to create pacakge object for %s' % obj.GetPackageName())
- continue
- if not decObj.Parse():
- ErrorMsg ('Fail to load package object for %s' % obj.GetPackageName())
- continue
- incObjs = decObj.GetSectionObjectsByName('includes')
- for incObj in incObjs:
- incPath = os.path.join(decObj.GetPackageRootPath(), incObj.GetPath()).replace('\\', '/')
- if os.path.exists(os.path.join(incPath, filePath)):
- fullPath = os.path.join(os.path.join(incPath, filePath))
- break
- if fullPath is not None:
- break
-
- if fullPath is None and self.IsVerbose():
- self.Log('Can not resolve header file %s for file %s in package %s\n' % (filePath, path, pObj.GetFileObj().GetFilename()), 'error')
- return
- else:
- fullPath = fullPath.replace('\\', '/')
- if self.IsVerbose():
- self.Log('Preprocessing: Add include file %s for file %s\n' % (fullPath, path))
- #LogMsg ('Preprocessing: Add include file %s for file %s' % (fullPath, path))
- self.ProcessSourceFileForInclude(fullPath, pObj, configFile, infObj)
-
- def AddAllIncludeFiles(self, pObj, configFile):
- objs = pObj.GetFileObj().GetSectionObjectsByName('includes')
- for obj in objs:
- incPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetPath())
- for root, dirs, files in os.walk(incPath):
- for dir in dirs:
- if dir.lower() in _ignore_dir:
- dirs.remove(dir)
- for file in files:
- path = os.path.normpath(os.path.join(root, file))
- configFile.AddFile(path.replace('/', '\\'))
-
- def GeneratePcdSubPages(self, pObj, configFile):
- """
- Generate sub pages for package's PCD definition.
- @param pObj package object
- @param configFile config file object
- """
- rootArray = []
- objs = pObj.GetFileObj().GetSectionObjectsByName('pcd')
- if len(objs) == 0:
- return []
-
- pcdRootPage = doxygen.Page('PCD', 'pcd_root_page')
- typeRootPageDict = {}
- typeArchRootPageDict = {}
- for obj in objs:
- if obj.GetPcdType() not in typeRootPageDict.keys():
- typeRootPageDict[obj.GetPcdType()] = doxygen.Page(obj.GetPcdType(), 'pcd_%s_root_page' % obj.GetPcdType())
- pcdRootPage.AddPage(typeRootPageDict[obj.GetPcdType()])
- typeRoot = typeRootPageDict[obj.GetPcdType()]
- if self._arch is not None:
- pcdPage = doxygen.Page('%s' % obj.GetPcdName(),
- 'pcd_%s_%s_%s' % (obj.GetPcdType(), obj.GetArch(), obj.GetPcdName().split('.')[1]))
- pcdPage.AddDescription('<br>\n'.join(obj.GetComment()) + '<br>\n')
- section = doxygen.Section('PCDinformation', 'PCD Information')
- desc = '<TABLE>'
- desc += '<TR>'
- desc += '<TD><CAPTION>Name</CAPTION></TD>'
- desc += '<TD><CAPTION>Token Space</CAPTION></TD>'
- desc += '<TD><CAPTION>Token number</CAPTION></TD>'
- desc += '<TD><CAPTION>Data Type</CAPTION></TD>'
- desc += '<TD><CAPTION>Default Value</CAPTION></TD>'
- desc += '</TR>'
- desc += '<TR>'
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[1]
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[0]
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdToken()
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdDataType()
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdValue()
- desc += '</TR>'
- desc += '</TABLE>'
- section.AddDescription(desc)
- pcdPage.AddSection(section)
- typeRoot.AddPage(pcdPage)
- else:
- keystr = obj.GetPcdType() + obj.GetArch()
- if keystr not in typeArchRootPageDict.keys():
- typeArchRootPage = doxygen.Page(obj.GetArch(), 'pcd_%s_%s_root_page' % (obj.GetPcdType(), obj.GetArch()))
- typeArchRootPageDict[keystr] = typeArchRootPage
- typeRoot.AddPage(typeArchRootPage)
- typeArchRoot = typeArchRootPageDict[keystr]
- pcdPage = doxygen.Page('%s' % obj.GetPcdName(),
- 'pcd_%s_%s_%s' % (obj.GetPcdType(), obj.GetArch(), obj.GetPcdName().split('.')[1]))
- pcdPage.AddDescription('<br>\n'.join(obj.GetComment()) + '<br>\n')
- section = doxygen.Section('PCDinformation', 'PCD Information')
- desc = '<TABLE>'
- desc += '<TR>'
- desc += '<TD><CAPTION>Name</CAPTION></TD>'
- desc += '<TD><CAPTION>Token Space</CAPTION></TD>'
- desc += '<TD><CAPTION>Token number</CAPTION></TD>'
- desc += '<TD><CAPTION>Data Type</CAPTION></TD>'
- desc += '<TD><CAPTION>Default Value</CAPTION></TD>'
- desc += '</TR>'
- desc += '<TR>'
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[1]
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[0]
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdToken()
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdDataType()
- desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdValue()
- desc += '</TR>'
- desc += '</TABLE>'
- section.AddDescription(desc)
- pcdPage.AddSection(section)
- typeArchRoot.AddPage(pcdPage)
- return [pcdRootPage]
-
- def _GenerateGuidSubPage(self, pObj, obj, configFile):
- guidPage = doxygen.Page('%s' % obj.GetName(),
- 'guid_%s_%s' % (obj.GetArch(), obj.GetName()))
- comments = obj.GetComment()
- if len(comments) != 0:
- guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')
- section = doxygen.Section('BasicGuidInfo', 'GUID Information')
- desc = '<TABLE>'
- desc += '<TR>'
- desc += '<TD><CAPTION>GUID\'s Guid Name</CAPTION></TD><TD><CAPTION>GUID\'s Guid</CAPTION></TD>'
- desc += '</TR>'
- desc += '<TR>'
- desc += '<TD>%s</TD>' % obj.GetName()
- desc += '<TD>%s</TD>' % obj.GetGuid()
- desc += '</TR>'
- desc += '</TABLE>'
- section.AddDescription(desc)
- guidPage.AddSection(section)
- refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)
- if refFile:
- relPath = refFile[len(pObj.GetWorkspace()) + 1:]
- if len(comments) == 0:
- guidPage.AddDescription(' \\copydoc %s <br>' % relPath)
-
- section = doxygen.Section('ref', 'Refer to Header File')
- section.AddDescription('\link %s\n' % relPath)
- section.AddDescription('\endlink\n')
- self.ProcessSourceFileForInclude(refFile, pObj, configFile)
- guidPage.AddSection(section)
- return guidPage
-
- def GenerateGuidSubPages(self, pObj, configFile):
- """
- Generate sub pages for package's GUID definition.
- @param pObj package object
- @param configFilf doxygen config file object
- """
- pageRoot = doxygen.Page('GUID', 'guid_root_page')
- objs = pObj.GetFileObj().GetSectionObjectsByName('guids', self._arch)
- if len(objs) == 0: return []
- if self._arch is not None:
- for obj in objs:
- pageRoot.AddPage(self._GenerateGuidSubPage(pObj, obj, configFile))
- else:
- guidArchRootPageDict = {}
- for obj in objs:
- if obj.GetArch() not in guidArchRootPageDict.keys():
- guidArchRoot = doxygen.Page(obj.GetArch(), 'guid_arch_root_%s' % obj.GetArch())
- pageRoot.AddPage(guidArchRoot)
- guidArchRootPageDict[obj.GetArch()] = guidArchRoot
- guidArchRoot = guidArchRootPageDict[obj.GetArch()]
- guidArchRoot.AddPage(self._GenerateGuidSubPage(pObj, obj, configFile))
- return [pageRoot]
-
- def _GeneratePpiSubPage(self, pObj, obj, configFile):
- guidPage = doxygen.Page(obj.GetName(), 'ppi_page_%s' % obj.GetName())
- comments = obj.GetComment()
- if len(comments) != 0:
- guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')
- section = doxygen.Section('BasicPpiInfo', 'PPI Information')
- desc = '<TABLE>'
- desc += '<TR>'
- desc += '<TD><CAPTION>PPI\'s Guid Name</CAPTION></TD><TD><CAPTION>PPI\'s Guid</CAPTION></TD>'
- desc += '</TR>'
- desc += '<TR>'
- desc += '<TD>%s</TD>' % obj.GetName()
- desc += '<TD>%s</TD>' % obj.GetGuid()
- desc += '</TR>'
- desc += '</TABLE>'
- section.AddDescription(desc)
- guidPage.AddSection(section)
- refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)
- if refFile:
- relPath = refFile[len(pObj.GetWorkspace()) + 1:]
- if len(comments) == 0:
- guidPage.AddDescription(' \\copydoc %s <br>' % relPath)
- section = doxygen.Section('ref', 'Refer to Header File')
- section.AddDescription('\link %s\n' % relPath)
- section.AddDescription('\endlink\n')
- self.ProcessSourceFileForInclude(refFile, pObj, configFile)
- guidPage.AddSection(section)
-
- return guidPage
-
- def GeneratePpiSubPages(self, pObj, configFile):
- """
- Generate sub pages for package's GUID definition.
- @param pObj package object
- @param configFilf doxygen config file object
- """
- pageRoot = doxygen.Page('PPI', 'ppi_root_page')
- objs = pObj.GetFileObj().GetSectionObjectsByName('ppis', self._arch)
- if len(objs) == 0: return []
- if self._arch is not None:
- for obj in objs:
- pageRoot.AddPage(self._GeneratePpiSubPage(pObj, obj, configFile))
- else:
- guidArchRootPageDict = {}
- for obj in objs:
- if obj.GetArch() not in guidArchRootPageDict.keys():
- guidArchRoot = doxygen.Page(obj.GetArch(), 'ppi_arch_root_%s' % obj.GetArch())
- pageRoot.AddPage(guidArchRoot)
- guidArchRootPageDict[obj.GetArch()] = guidArchRoot
- guidArchRoot = guidArchRootPageDict[obj.GetArch()]
- guidArchRoot.AddPage(self._GeneratePpiSubPage(pObj, obj, configFile))
- return [pageRoot]
-
- def _GenerateProtocolSubPage(self, pObj, obj, configFile):
- guidPage = doxygen.Page(obj.GetName(), 'protocol_page_%s' % obj.GetName())
- comments = obj.GetComment()
- if len(comments) != 0:
- guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')
- section = doxygen.Section('BasicProtocolInfo', 'PROTOCOL Information')
- desc = '<TABLE>'
- desc += '<TR>'
- desc += '<TD><CAPTION>PROTOCOL\'s Guid Name</CAPTION></TD><TD><CAPTION>PROTOCOL\'s Guid</CAPTION></TD>'
- desc += '</TR>'
- desc += '<TR>'
- desc += '<TD>%s</TD>' % obj.GetName()
- desc += '<TD>%s</TD>' % obj.GetGuid()
- desc += '</TR>'
- desc += '</TABLE>'
- section.AddDescription(desc)
- guidPage.AddSection(section)
-
- refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)
- if refFile:
- relPath = refFile[len(pObj.GetWorkspace()) + 1:]
- if len(comments) == 0:
- guidPage.AddDescription(' \\copydoc %s <br>' % relPath)
- section = doxygen.Section('ref', 'Refer to Header File')
- section.AddDescription('\link %s\n' % relPath)
- section.AddDescription('\endlink\n')
- self.ProcessSourceFileForInclude(refFile, pObj, configFile)
- guidPage.AddSection(section)
-
- return guidPage
-
- def GenerateProtocolSubPages(self, pObj, configFile):
- """
- Generate sub pages for package's GUID definition.
- @param pObj package object
- @param configFilf doxygen config file object
- """
- pageRoot = doxygen.Page('PROTOCOL', 'protocol_root_page')
- objs = pObj.GetFileObj().GetSectionObjectsByName('protocols', self._arch)
- if len(objs) == 0: return []
- if self._arch is not None:
- for obj in objs:
- pageRoot.AddPage(self._GenerateProtocolSubPage(pObj, obj, configFile))
- else:
- guidArchRootPageDict = {}
- for obj in objs:
- if obj.GetArch() not in guidArchRootPageDict.keys():
- guidArchRoot = doxygen.Page(obj.GetArch(), 'protocol_arch_root_%s' % obj.GetArch())
- pageRoot.AddPage(guidArchRoot)
- guidArchRootPageDict[obj.GetArch()] = guidArchRoot
- guidArchRoot = guidArchRootPageDict[obj.GetArch()]
- guidArchRoot.AddPage(self._GenerateProtocolSubPage(pObj, obj, configFile))
- return [pageRoot]
-
- def FindHeaderFileForGuid(self, pObj, name, configFile):
- """
- For declaration header file for GUID/PPI/Protocol.
-
- @param pObj package object
- @param name guid/ppi/protocol's name
- @param configFile config file object
-
- @return full path of header file and None if not found.
- """
- startPath = pObj.GetFileObj().GetPackageRootPath()
- incPath = os.path.join(startPath, 'Include').replace('\\', '/')
- # if <PackagePath>/include exist, then search header under it.
- if os.path.exists(incPath):
- startPath = incPath
-
- for root, dirs, files in os.walk(startPath):
- for dir in dirs:
- if dir.lower() in _ignore_dir:
- dirs.remove(dir)
- for file in files:
- fPath = os.path.join(root, file)
- if not IsCHeaderFile(fPath):
- continue
- try:
- f = open(fPath, 'r')
- lines = f.readlines()
- f.close()
- except IOError:
- self.Log('Fail to open file %s\n' % fPath)
- continue
- for line in lines:
- if line.find(name) != -1 and \
- line.find('extern') != -1:
- return fPath.replace('\\', '/')
- return None
-
- def GetPackageModuleList(self, pObj):
- """
- Get all module's INF path under package's root path
- @param pObj package object
- @return arrary of INF full path
- """
- mArray = []
- packPath = pObj.GetFileObj().GetPackageRootPath()
- if not os.path.exists:
- return None
- for root, dirs, files in os.walk(packPath):
- for dir in dirs:
- if dir.lower() in _ignore_dir:
- dirs.remove(dir)
- for file in files:
- if CheckPathPostfix(file, 'inf'):
- fPath = os.path.join(root, file).replace('\\', '/')
- mArray.append(fPath)
- return mArray
-
- def GenerateModulePages(self, pObj, configFile):
- """
- Generate sub pages for package's module which is under the package
- root directory.
-
- @param pObj package object
- @param configFilf doxygen config file object
- """
- infList = self.GetPackageModuleList(pObj)
- rootPages = []
- libObjs = []
- modObjs = []
- for infpath in infList:
- infObj = inf.INFFile(infpath)
- #infObj = INFFileObject.INFFile (pObj.GetWorkspacePath(),
- # inf)
- if not infObj:
- self.Log('Fail create INF object for %s' % inf)
- continue
- if not infObj.Parse():
- self.Log('Fail to load INF file %s' % inf)
- continue
- if infObj.GetProduceLibraryClass() is not None:
- libObjs.append(infObj)
- else:
- modObjs.append(infObj)
-
- if len(libObjs) != 0:
- libRootPage = doxygen.Page('Libraries', 'lib_root_page')
- rootPages.append(libRootPage)
- for libInf in libObjs:
- libRootPage.AddPage(self.GenerateModulePage(pObj, libInf, configFile, True))
-
- if len(modObjs) != 0:
- modRootPage = doxygen.Page('Modules', 'module_root_page')
- rootPages.append(modRootPage)
- for modInf in modObjs:
- modRootPage.AddPage(self.GenerateModulePage(pObj, modInf, configFile, False))
-
- return rootPages
-
- def GenerateModulePage(self, pObj, infObj, configFile, isLib):
- """
- Generate page for a module/library.
- @param infObj INF file object for module/library
- @param configFile doxygen config file object
- @param isLib Whether this module is library
-
- @param module doxygen page object
- """
- workspace = pObj.GetWorkspace()
- refDecObjs = []
- for obj in infObj.GetSectionObjectsByName('packages'):
- decObj = dec.DECFile(os.path.join(workspace, obj.GetPath()))
- if not decObj:
- ErrorMsg ('Fail to create pacakge object for %s' % obj.GetPackageName())
- continue
- if not decObj.Parse():
- ErrorMsg ('Fail to load package object for %s' % obj.GetPackageName())
- continue
- refDecObjs.append(decObj)
-
- modPage = doxygen.Page('%s' % infObj.GetBaseName(),
- 'module_%s' % infObj.GetBaseName())
- modPage.AddDescription(infObj.GetFileHeader())
-
- basicInfSection = doxygen.Section('BasicModuleInformation', 'Basic Module Information')
- desc = "<TABLE>"
- for obj in infObj.GetSectionObjectsByName('defines'):
- key = obj.GetKey()
- value = obj.GetValue()
- if key not in _inf_key_description_mapping_table.keys(): continue
- if key == 'LIBRARY_CLASS' and value.find('|') != -1:
- clsname, types = value.split('|')
- desc += '<TR>'
- desc += '<TD><B>%s</B></TD>' % _inf_key_description_mapping_table[key]
- desc += '<TD>%s</TD>' % clsname
- desc += '</TR>'
-
- desc += '<TR>'
- desc += '<TD><B>Supported Module Types</B></TD>'
- desc += '<TD>%s</TD>' % types
- desc += '</TR>'
- else:
- desc += '<TR>'
- desc += '<TD><B>%s</B></TD>' % _inf_key_description_mapping_table[key]
- if key == 'EFI_SPECIFICATION_VERSION' and value == '0x00020000':
- value = '2.0'
- desc += '<TD>%s</TD>' % value
- desc += '</TR>'
- desc += '</TABLE>'
- basicInfSection.AddDescription(desc)
- modPage.AddSection(basicInfSection)
-
- # Add protocol section
- data = []
- for obj in infObj.GetSectionObjectsByName('pcd', self._arch):
- data.append(obj.GetPcdName().strip())
- if len(data) != 0:
- s = doxygen.Section('Pcds', 'Pcds')
- desc = "<TABLE>"
- desc += '<TR><TD><B>PCD Name</B></TD><TD><B>TokenSpace</B></TD><TD><B>Package</B></TD></TR>'
- for item in data:
- desc += '<TR>'
- desc += '<TD>%s</TD>' % item.split('.')[1]
- desc += '<TD>%s</TD>' % item.split('.')[0]
- pkgbasename = self.SearchPcdPackage(item, workspace, refDecObjs)
- desc += '<TD>%s</TD>' % pkgbasename
- desc += '</TR>'
- desc += "</TABLE>"
- s.AddDescription(desc)
- modPage.AddSection(s)
-
- # Add protocol section
- #sects = infObj.GetSectionByString('protocol')
- data = []
- #for sect in sects:
- for obj in infObj.GetSectionObjectsByName('protocol', self._arch):
- data.append(obj.GetName().strip())
- if len(data) != 0:
- s = doxygen.Section('Protocols', 'Protocols')
- desc = "<TABLE>"
- desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'
- for item in data:
- desc += '<TR>'
- desc += '<TD>%s</TD>' % item
- pkgbasename = self.SearchProtocolPackage(item, workspace, refDecObjs)
- desc += '<TD>%s</TD>' % pkgbasename
- desc += '</TR>'
- desc += "</TABLE>"
- s.AddDescription(desc)
- modPage.AddSection(s)
-
- # Add ppi section
- #sects = infObj.GetSectionByString('ppi')
- data = []
- #for sect in sects:
- for obj in infObj.GetSectionObjectsByName('ppi', self._arch):
- data.append(obj.GetName().strip())
- if len(data) != 0:
- s = doxygen.Section('Ppis', 'Ppis')
- desc = "<TABLE>"
- desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'
- for item in data:
- desc += '<TR>'
- desc += '<TD>%s</TD>' % item
- pkgbasename = self.SearchPpiPackage(item, workspace, refDecObjs)
- desc += '<TD>%s</TD>' % pkgbasename
- desc += '</TR>'
- desc += "</TABLE>"
- s.AddDescription(desc)
- modPage.AddSection(s)
-
- # Add guid section
- #sects = infObj.GetSectionByString('guid')
- data = []
- #for sect in sects:
- for obj in infObj.GetSectionObjectsByName('guid', self._arch):
- data.append(obj.GetName().strip())
- if len(data) != 0:
- s = doxygen.Section('Guids', 'Guids')
- desc = "<TABLE>"
- desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'
- for item in data:
- desc += '<TR>'
- desc += '<TD>%s</TD>' % item
- pkgbasename = self.SearchGuidPackage(item, workspace, refDecObjs)
- desc += '<TD>%s</TD>' % pkgbasename
- desc += '</TR>'
- desc += "</TABLE>"
- s.AddDescription(desc)
- modPage.AddSection(s)
-
- section = doxygen.Section('LibraryClasses', 'Library Classes')
- desc = "<TABLE>"
- desc += '<TR><TD><B>Name</B></TD><TD><B>Type</B></TD><TD><B>Package</B></TD><TD><B>Header File</B></TD></TR>'
- if isLib:
- desc += '<TR>'
- desc += '<TD>%s</TD>' % infObj.GetProduceLibraryClass()
- desc += '<TD>Produce</TD>'
- try:
- pkgname, hPath = self.SearchLibraryClassHeaderFile(infObj.GetProduceLibraryClass(),
- workspace,
- refDecObjs)
- except:
- self.Log ('fail to get package header file for lib class %s' % infObj.GetProduceLibraryClass())
- pkgname = 'NULL'
- hPath = 'NULL'
- desc += '<TD>%s</TD>' % pkgname
- if hPath != "NULL":
- #desc += '<TD>\link %s \endlink</TD>' % hPath
- desc += '<TD>%s</TD>' % hPath
- else:
- desc += '<TD>%s</TD>' % hPath
- desc += '</TR>'
- for lcObj in infObj.GetSectionObjectsByName('libraryclasses', self._arch):
- desc += '<TR>'
- desc += '<TD>%s</TD>' % lcObj.GetClass()
- retarr = self.SearchLibraryClassHeaderFile(lcObj.GetClass(),
- workspace,
- refDecObjs)
- if retarr is not None:
- pkgname, hPath = retarr
- else:
- self.Log('Fail find the library class %s definition from module %s dependent package!' % (lcObj.GetClass(), infObj.GetFilename()), 'error')
- pkgname = 'NULL'
- hPath = 'NULL'
- desc += '<TD>Consume</TD>'
- desc += '<TD>%s</TD>' % pkgname
- desc += '<TD>%s</TD>' % hPath
- desc += '</TR>'
- desc += "</TABLE>"
- section.AddDescription(desc)
- modPage.AddSection(section)
-
- section = doxygen.Section('SourceFiles', 'Source Files')
- section.AddDescription('<ul>\n')
- for obj in infObj.GetSourceObjects(self._arch, self._tooltag):
- sPath = infObj.GetModuleRootPath()
- sPath = os.path.join(sPath, obj.GetSourcePath()).replace('\\', '/').strip()
- if sPath.lower().endswith('.uni') or sPath.lower().endswith('.s') or sPath.lower().endswith('.asm') or sPath.lower().endswith('.nasm'):
- newPath = self.TranslateUniFile(sPath)
- configFile.AddFile(newPath)
- newPath = newPath[len(pObj.GetWorkspace()) + 1:]
- section.AddDescription('<li> \link %s \endlink </li>' % newPath)
- else:
- self.ProcessSourceFileForInclude(sPath, pObj, configFile, infObj)
- sPath = sPath[len(pObj.GetWorkspace()) + 1:]
- section.AddDescription('<li>\link %s \endlink </li>' % sPath)
- section.AddDescription('</ul>\n')
- modPage.AddSection(section)
-
- #sects = infObj.GetSectionByString('depex')
- data = []
- #for sect in sects:
- for obj in infObj.GetSectionObjectsByName('depex'):
- data.append(str(obj))
- if len(data) != 0:
- s = doxygen.Section('DependentSection', 'Module Dependencies')
- s.AddDescription('<br>'.join(data))
- modPage.AddSection(s)
-
- return modPage
-
- def TranslateUniFile(self, path):
- newpath = path + '.dox'
- #import core.textfile as textfile
- #file = textfile.TextFile(path)
-
- try:
- file = open(path, 'r')
- except (IOError, OSError) as msg:
- return None
-
- t = file.read()
- file.close()
-
- output = '/** @file \n'
- #output = '<html><body>'
- arr = t.split('\r\n')
- for line in arr:
- if line.find('@file') != -1:
- continue
- if line.find('*/') != -1:
- continue
- line = line.strip()
- if line.strip().startswith('/'):
- arr = line.split(' ')
- if len(arr) > 1:
- line = ' '.join(arr[1:])
- else:
- continue
- output += '%s<br>\n' % line
- output += '**/'
-
- if os.path.exists(newpath):
- os.remove(newpath)
-
- file = open(newpath, "w")
- file.write(output)
- file.close()
- return newpath
-
- def SearchPcdPackage(self, pcdname, workspace, decObjs):
- for decObj in decObjs:
- for pcd in decObj.GetSectionObjectsByName('pcd'):
- if pcdname == pcd.GetPcdName():
- return decObj.GetBaseName()
- return None
-
- def SearchProtocolPackage(self, protname, workspace, decObjs):
- for decObj in decObjs:
- for proto in decObj.GetSectionObjectsByName('protocol'):
- if protname == proto.GetName():
- return decObj.GetBaseName()
- return None
-
- def SearchPpiPackage(self, ppiname, workspace, decObjs):
- for decObj in decObjs:
- for ppi in decObj.GetSectionObjectsByName('ppi'):
- if ppiname == ppi.GetName():
- return decObj.GetBaseName()
- return None
-
- def SearchGuidPackage(self, guidname, workspace, decObjs):
- for decObj in decObjs:
- for guid in decObj.GetSectionObjectsByName('guid'):
- if guidname == guid.GetName():
- return decObj.GetBaseName()
- return None
-
- def SearchLibraryClassHeaderFile(self, className, workspace, decObjs):
- for decObj in decObjs:
- for cls in decObj.GetSectionObjectsByName('libraryclasses'):
- if cls.GetClassName().strip() == className:
- path = cls.GetHeaderFile().strip()
- path = os.path.join(decObj.GetPackageRootPath(), path)
- path = path[len(workspace) + 1:]
- return decObj.GetBaseName(), path.replace('\\', '/')
-
- return None
-
- def _ConvertPathToDoxygen(self, path, pObj):
- pRootPath = pObj.GetWorkspace()
- path = path[len(pRootPath) + 1:]
- return path.replace('\\', '/')
-
-def IsCHeaderFile(path):
- return CheckPathPostfix(path, 'h')
-
-def CheckPathPostfix(path, str):
- index = path.rfind('.')
- if index == -1:
- return False
- if path[index + 1:].lower() == str.lower():
- return True
- return False
+## @file
+#
+# This file produce action class to generate doxygen document for edk2 codebase.
+# The action classes are shared by GUI and command line tools.
+#
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+from plugins.EdkPlugins.basemodel import doxygen
+import os
+try:
+ import wx
+ gInGui = True
+except:
+ gInGui = False
+import re
+from plugins.EdkPlugins.edk2.model import inf
+from plugins.EdkPlugins.edk2.model import dec
+from plugins.EdkPlugins.basemodel.message import *
+
+_ignore_dir = ['.svn', '_svn', 'cvs']
+_inf_key_description_mapping_table = {
+ 'INF_VERSION':'Version of INF file specification',
+ #'BASE_NAME':'Module Name',
+ 'FILE_GUID':'Module Guid',
+ 'MODULE_TYPE': 'Module Type',
+ 'VERSION_STRING': 'Module Version',
+ 'LIBRARY_CLASS': 'Produced Library Class',
+ 'EFI_SPECIFICATION_VERSION': 'UEFI Specification Version',
+ 'PI_SPECIFICATION_VERSION': 'PI Specification Version',
+ 'ENTRY_POINT': 'Module Entry Point Function',
+ 'CONSTRUCTOR': 'Library Constructor Function'
+}
+
+_dec_key_description_mapping_table = {
+ 'DEC_SPECIFICATION': 'Version of DEC file specification',
+ 'PACKAGE_GUID': 'Package Guid'
+}
+class DoxygenAction:
+ """This is base class for all doxygen action.
+ """
+
+ def __init__(self, doxPath, chmPath, outputPath, projname, mode='html', log=None, verbose=False):
+ """Constructor function.
+ @param doxPath the obosolution path of doxygen execute file.
+ @param outputPath the obosolution output path.
+ @param log log function for output message
+ """
+ self._doxPath = doxPath
+ self._chmPath = chmPath
+ self._outputPath = outputPath
+ self._projname = projname
+ self._configFile = None # doxygen config file is used by doxygen exe file
+ self._indexPageFile = None # doxygen page file for index page.
+ self._log = log
+ self._mode = mode
+ self._verbose = verbose
+ self._doxygenCallback = None
+ self._chmCallback = None
+
+ def Log(self, message, level='info'):
+ if self._log is not None:
+ self._log(message, level)
+
+ def IsVerbose(self):
+ return self._verbose
+
+ def Generate(self):
+ """Generate interface called by outer directly"""
+ self.Log(">>>>>> Start generate doxygen document for %s... Zzz....\n" % self._projname)
+
+ # create doxygen config file at first
+ self._configFile = doxygen.DoxygenConfigFile()
+ self._configFile.SetOutputDir(self._outputPath)
+
+ self._configFile.SetWarningFilePath(os.path.join(self._outputPath, 'warning.txt'))
+ if self._mode.lower() == 'html':
+ self._configFile.SetHtmlMode()
+ else:
+ self._configFile.SetChmMode()
+
+ self.Log(" >>>>>> Initialize doxygen config file...Zzz...\n")
+ self.InitializeConfigFile()
+
+ self.Log(" >>>>>> Generate doxygen index page file...Zzz...\n")
+ indexPagePath = self.GenerateIndexPage()
+ if indexPagePath is None:
+ self.Log("Fail to generate index page!\n", 'error')
+ return False
+ else:
+ self.Log("Success to create doxygen index page file %s \n" % indexPagePath)
+
+ # Add index page doxygen file to file list.
+ self._configFile.AddFile(indexPagePath)
+
+ # save config file to output path
+ configFilePath = os.path.join(self._outputPath, self._projname + '.doxygen_config')
+ self._configFile.Generate(configFilePath)
+ self.Log(" <<<<<< Success Save doxygen config file to %s...\n" % configFilePath)
+
+ # launch doxygen tool to generate document
+ if self._doxygenCallback is not None:
+ self.Log(" >>>>>> Start doxygen process...Zzz...\n")
+ if not self._doxygenCallback(self._doxPath, configFilePath):
+ return False
+ else:
+ self.Log("Fail to create doxygen process!", 'error')
+ return False
+
+ return True
+
+ def InitializeConfigFile(self):
+ """Initialize config setting for doxygen project. It will be invoked after config file
+ object is created. Inherited class should implement it.
+ """
+
+ def GenerateIndexPage(self):
+ """Generate doxygen index page. Inherited class should implement it."""
+ return None
+
+ def RegisterCallbackDoxygenProcess(self, callback):
+ self._doxygenCallback = callback
+
+ def RegisterCallbackCHMProcess(self, callback):
+ self._chmCallback = callback
+
+class PlatformDocumentAction(DoxygenAction):
+ """Generate platform doxygen document, will be implement at future."""
+
+class PackageDocumentAction(DoxygenAction):
+ """Generate package reference document"""
+
+ def __init__(self, doxPath, chmPath, outputPath, pObj, mode='html', log=None, arch=None, tooltag=None,
+ macros=[], onlyInclude=False, verbose=False):
+ DoxygenAction.__init__(self, doxPath, chmPath, outputPath, pObj.GetName(), mode, log, verbose)
+ self._pObj = pObj
+ self._arch = arch
+ self._tooltag = tooltag
+ self._macros = macros
+ self._onlyIncludeDocument = onlyInclude
+
+ def InitializeConfigFile(self):
+ if self._arch == 'IA32':
+ self._configFile.AddPreDefined('MDE_CPU_IA32')
+ elif self._arch == 'X64':
+ self._configFile.AddPreDefined('MDE_CPU_X64')
+ elif self._arch == 'IPF':
+ self._configFile.AddPreDefined('MDE_CPU_IPF')
+ elif self._arch == 'EBC':
+ self._configFile.AddPreDefined('MDE_CPU_EBC')
+ else:
+ self._arch = None
+ self._configFile.AddPreDefined('MDE_CPU_IA32')
+ self._configFile.AddPreDefined('MDE_CPU_X64')
+ self._configFile.AddPreDefined('MDE_CPU_IPF')
+ self._configFile.AddPreDefined('MDE_CPU_EBC')
+ self._configFile.AddPreDefined('MDE_CPU_ARM')
+
+ for macro in self._macros:
+ self._configFile.AddPreDefined(macro)
+
+ namestr = self._pObj.GetName()
+ if self._arch is not None:
+ namestr += '[%s]' % self._arch
+ if self._tooltag is not None:
+ namestr += '[%s]' % self._tooltag
+ self._configFile.SetProjectName(namestr)
+ self._configFile.SetStripPath(self._pObj.GetWorkspace())
+ self._configFile.SetProjectVersion(self._pObj.GetFileObj().GetVersion())
+ self._configFile.AddPattern('*.decdoxygen')
+
+ if self._tooltag.lower() == 'msft':
+ self._configFile.AddPreDefined('_MSC_EXTENSIONS')
+ elif self._tooltag.lower() == 'gnu':
+ self._configFile.AddPreDefined('__GNUC__')
+ elif self._tooltag.lower() == 'intel':
+ self._configFile.AddPreDefined('__INTEL_COMPILER')
+ else:
+ self._tooltag = None
+ self._configFile.AddPreDefined('_MSC_EXTENSIONS')
+ self._configFile.AddPreDefined('__GNUC__')
+ self._configFile.AddPreDefined('__INTEL_COMPILER')
+
+ self._configFile.AddPreDefined('ASM_PFX= ')
+ self._configFile.AddPreDefined('OPTIONAL= ')
+
+ def GenerateIndexPage(self):
+ """Generate doxygen index page. Inherited class should implement it."""
+ fObj = self._pObj.GetFileObj()
+ pdObj = doxygen.DoxygenFile('%s Package Document' % self._pObj.GetName(),
+ '%s.decdoxygen' % self._pObj.GetFilename())
+ self._configFile.AddFile(pdObj.GetFilename())
+ pdObj.AddDescription(fObj.GetFileHeader())
+
+ defSection = fObj.GetSectionByName('defines')[0]
+ baseSection = doxygen.Section('PackageBasicInformation', 'Package Basic Information')
+ descr = '<TABLE>'
+ for obj in defSection.GetObjects():
+ if obj.GetKey() in _dec_key_description_mapping_table.keys():
+ descr += '<TR>'
+ descr += '<TD><B>%s</B></TD>' % _dec_key_description_mapping_table[obj.GetKey()]
+ descr += '<TD>%s</TD>' % obj.GetValue()
+ descr += '</TR>'
+ descr += '</TABLE><br>'
+ baseSection.AddDescription(descr)
+ pdObj.AddSection(baseSection)
+
+ knownIssueSection = doxygen.Section('Known_Issue_section', 'Known Issue')
+ knownIssueSection.AddDescription('<ul>')
+ knownIssueSection.AddDescription('<li> OPTIONAL macro for function parameter can not be dealed with doxygen, so it disapear in this document! </li>')
+ knownIssueSection.AddDescription('</ul>')
+ pdObj.AddSection(knownIssueSection)
+
+ self.AddAllIncludeFiles(self._pObj, self._configFile)
+ pages = self.GenerateIncludesSubPage(self._pObj, self._configFile)
+ if len(pages) != 0:
+ pdObj.AddPages(pages)
+ pages = self.GenerateLibraryClassesSubPage(self._pObj, self._configFile)
+ if len(pages) != 0:
+ pdObj.AddPages(pages)
+ pages = self.GeneratePcdSubPages(self._pObj, self._configFile)
+ if len(pages) != 0:
+ pdObj.AddPages(pages)
+ pages = self.GenerateGuidSubPages(self._pObj, self._configFile)
+ if len(pages) != 0:
+ pdObj.AddPages(pages)
+ pages = self.GeneratePpiSubPages(self._pObj, self._configFile)
+ if len(pages) != 0:
+ pdObj.AddPages(pages)
+ pages = self.GenerateProtocolSubPages(self._pObj, self._configFile)
+ if len(pages) != 0:
+ pdObj.AddPages(pages)
+ if not self._onlyIncludeDocument:
+ pdObj.AddPages(self.GenerateModulePages(self._pObj, self._configFile))
+
+ pdObj.Save()
+ return pdObj.GetFilename()
+
+ def GenerateIncludesSubPage(self, pObj, configFile):
+ # by default add following path as include path to config file
+ pkpath = pObj.GetFileObj().GetPackageRootPath()
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include'))
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Library'))
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Protocol'))
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Ppi'))
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Guid'))
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'IndustryStandard'))
+
+ rootArray = []
+ pageRoot = doxygen.Page("Public Includes", "%s_public_includes" % pObj.GetName())
+ objs = pObj.GetFileObj().GetSectionObjectsByName('includes')
+ if len(objs) == 0: return []
+
+ for obj in objs:
+ # Add path to include path
+ path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetPath())
+ configFile.AddIncludePath(path)
+
+ # only list common folder's include file
+ if obj.GetArch().lower() != 'common':
+ continue
+
+ bNeedAddIncludePage = False
+ topPage = doxygen.Page(self._ConvertPathToDoxygen(path, pObj), 'public_include_top')
+
+ topPage.AddDescription('<ul>\n')
+ for file in os.listdir(path):
+ if file.lower() in _ignore_dir: continue
+ fullpath = os.path.join(path, file)
+ if os.path.isfile(fullpath):
+ self.ProcessSourceFileForInclude(fullpath, pObj, configFile)
+ topPage.AddDescription('<li> \link %s\endlink </li>\n' % self._ConvertPathToDoxygen(fullpath, pObj))
+ else:
+ if file.lower() in ['library', 'protocol', 'guid', 'ppi', 'ia32', 'x64', 'ipf', 'ebc', 'arm', 'pi', 'uefi', 'aarch64']:
+ continue
+ bNeedAddSubPage = False
+ subpage = doxygen.Page(self._ConvertPathToDoxygen(fullpath, pObj), 'public_include_%s' % file)
+ subpage.AddDescription('<ul>\n')
+ for subfile in os.listdir(fullpath):
+ if subfile.lower() in _ignore_dir: continue
+ bNeedAddSubPage = True
+ subfullpath = os.path.join(fullpath, subfile)
+ self.ProcessSourceFileForInclude(subfullpath, pObj, configFile)
+ subpage.AddDescription('<li> \link %s \endlink </li>\n' % self._ConvertPathToDoxygen(subfullpath, pObj))
+ subpage.AddDescription('</ul>\n')
+ if bNeedAddSubPage:
+ bNeedAddIncludePage = True
+ pageRoot.AddPage(subpage)
+ topPage.AddDescription('</ul>\n')
+ if bNeedAddIncludePage:
+ pageRoot.AddPage(topPage)
+
+ if pageRoot.GetSubpageCount() != 0:
+ return [pageRoot]
+ else:
+ return []
+
+ def GenerateLibraryClassesSubPage(self, pObj, configFile):
+ """
+ Generate sub page for library class for package.
+ One DEC file maybe contains many library class sections
+ for different architecture.
+
+ @param fObj DEC file object.
+ """
+ rootArray = []
+ pageRoot = doxygen.Page("Library Class", "%s_libraryclass" % pObj.GetName())
+ objs = pObj.GetFileObj().GetSectionObjectsByName('libraryclass', self._arch)
+ if len(objs) == 0: return []
+
+ if self._arch is not None:
+ for obj in objs:
+ classPage = doxygen.Page(obj.GetClassName(),
+ "lc_%s" % obj.GetClassName())
+ comments = obj.GetComment()
+ if len(comments) != 0:
+ classPage.AddDescription('<br>\n'.join(comments) + '<br>\n')
+ pageRoot.AddPage(classPage)
+ path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())
+ path = path[len(pObj.GetWorkspace()) + 1:]
+ if len(comments) == 0:
+ classPage.AddDescription('\copydoc %s<p>' % obj.GetHeaderFile())
+ section = doxygen.Section('ref', 'Refer to Header File')
+ section.AddDescription('\link %s\n' % obj.GetHeaderFile())
+ section.AddDescription(' \endlink<p>\n')
+ classPage.AddSection(section)
+ fullPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())
+ self.ProcessSourceFileForInclude(fullPath, pObj, configFile)
+ else:
+ archPageDict = {}
+ for obj in objs:
+ if obj.GetArch() not in archPageDict.keys():
+ archPageDict[obj.GetArch()] = doxygen.Page(obj.GetArch(),
+ 'lc_%s' % obj.GetArch())
+ pageRoot.AddPage(archPageDict[obj.GetArch()])
+ subArchRoot = archPageDict[obj.GetArch()]
+ classPage = doxygen.Page(obj.GetClassName(),
+ "lc_%s" % obj.GetClassName())
+ comments = obj.GetComment()
+ if len(comments) != 0:
+ classPage.AddDescription('<br>\n'.join(comments) + '<br>\n')
+ subArchRoot.AddPage(classPage)
+ path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())
+ path = path[len(pObj.GetWorkspace()) + 1:]
+ if len(comments) == 0:
+ classPage.AddDescription('\copydoc %s<p>' % obj.GetHeaderFile())
+ section = doxygen.Section('ref', 'Refer to Header File')
+ section.AddDescription('\link %s\n' % obj.GetHeaderFile())
+ section.AddDescription(' \endlink<p>\n')
+ classPage.AddSection(section)
+ fullPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())
+
+ self.ProcessSourceFileForInclude(fullPath, pObj, configFile)
+ rootArray.append(pageRoot)
+ return rootArray
+
+ def ProcessSourceFileForInclude(self, path, pObj, configFile, infObj=None):
+ """
+ @param path the analysising file full path
+ @param pObj package object
+ @param configFile doxygen config file.
+ """
+
+ if gInGui:
+ wx.Yield()
+ if not os.path.exists(path):
+ ErrorMsg('Source file path %s does not exist!' % path)
+ return
+
+ if configFile.FileExists(path):
+ return
+
+ try:
+ f = open(path, 'r')
+ lines = f.readlines()
+ f.close()
+ except IOError:
+ ErrorMsg('Fail to open file %s' % path)
+ return
+
+ configFile.AddFile(path)
+ return
+ no = 0
+ for no in range(len(lines)):
+ if len(lines[no].strip()) == 0:
+ continue
+ if lines[no].strip()[:2] in ['##', '//', '/*', '*/']:
+ continue
+ index = lines[no].lower().find('include')
+ #mo = IncludePattern.finditer(lines[no].lower())
+ mo = re.match(r"^#\s*include\s+[<\"]([\\/\w.]+)[>\"]$", lines[no].strip().lower())
+ if not mo:
+ continue
+ mo = re.match(r"^[#\w\s]+[<\"]([\\/\w.]+)[>\"]$", lines[no].strip())
+ filePath = mo.groups()[0]
+
+ if filePath is None or len(filePath) == 0:
+ continue
+
+ # find header file in module's path firstly.
+ fullPath = None
+
+ if os.path.exists(os.path.join(os.path.dirname(path), filePath)):
+ # Find the file in current directory
+ fullPath = os.path.join(os.path.dirname(path), filePath).replace('\\', '/')
+ else:
+ # find in depedent package's include path
+ incObjs = pObj.GetFileObj().GetSectionObjectsByName('includes')
+ for incObj in incObjs:
+ incPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), incObj.GetPath()).strip()
+ incPath = os.path.realpath(os.path.join(incPath, filePath))
+ if os.path.exists(incPath):
+ fullPath = incPath
+ break
+ if infObj is not None:
+ pkgInfObjs = infObj.GetSectionObjectsByName('packages')
+ for obj in pkgInfObjs:
+ decObj = dec.DECFile(os.path.join(pObj.GetWorkspace(), obj.GetPath()))
+ if not decObj:
+ ErrorMsg ('Fail to create pacakge object for %s' % obj.GetPackageName())
+ continue
+ if not decObj.Parse():
+ ErrorMsg ('Fail to load package object for %s' % obj.GetPackageName())
+ continue
+ incObjs = decObj.GetSectionObjectsByName('includes')
+ for incObj in incObjs:
+ incPath = os.path.join(decObj.GetPackageRootPath(), incObj.GetPath()).replace('\\', '/')
+ if os.path.exists(os.path.join(incPath, filePath)):
+ fullPath = os.path.join(os.path.join(incPath, filePath))
+ break
+ if fullPath is not None:
+ break
+
+ if fullPath is None and self.IsVerbose():
+ self.Log('Can not resolve header file %s for file %s in package %s\n' % (filePath, path, pObj.GetFileObj().GetFilename()), 'error')
+ return
+ else:
+ fullPath = fullPath.replace('\\', '/')
+ if self.IsVerbose():
+ self.Log('Preprocessing: Add include file %s for file %s\n' % (fullPath, path))
+ #LogMsg ('Preprocessing: Add include file %s for file %s' % (fullPath, path))
+ self.ProcessSourceFileForInclude(fullPath, pObj, configFile, infObj)
+
+ def AddAllIncludeFiles(self, pObj, configFile):
+ objs = pObj.GetFileObj().GetSectionObjectsByName('includes')
+ for obj in objs:
+ incPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetPath())
+ for root, dirs, files in os.walk(incPath):
+ for dir in dirs:
+ if dir.lower() in _ignore_dir:
+ dirs.remove(dir)
+ for file in files:
+ path = os.path.normpath(os.path.join(root, file))
+ configFile.AddFile(path.replace('/', '\\'))
+
+ def GeneratePcdSubPages(self, pObj, configFile):
+ """
+ Generate sub pages for package's PCD definition.
+ @param pObj package object
+ @param configFile config file object
+ """
+ rootArray = []
+ objs = pObj.GetFileObj().GetSectionObjectsByName('pcd')
+ if len(objs) == 0:
+ return []
+
+ pcdRootPage = doxygen.Page('PCD', 'pcd_root_page')
+ typeRootPageDict = {}
+ typeArchRootPageDict = {}
+ for obj in objs:
+ if obj.GetPcdType() not in typeRootPageDict.keys():
+ typeRootPageDict[obj.GetPcdType()] = doxygen.Page(obj.GetPcdType(), 'pcd_%s_root_page' % obj.GetPcdType())
+ pcdRootPage.AddPage(typeRootPageDict[obj.GetPcdType()])
+ typeRoot = typeRootPageDict[obj.GetPcdType()]
+ if self._arch is not None:
+ pcdPage = doxygen.Page('%s' % obj.GetPcdName(),
+ 'pcd_%s_%s_%s' % (obj.GetPcdType(), obj.GetArch(), obj.GetPcdName().split('.')[1]))
+ pcdPage.AddDescription('<br>\n'.join(obj.GetComment()) + '<br>\n')
+ section = doxygen.Section('PCDinformation', 'PCD Information')
+ desc = '<TABLE>'
+ desc += '<TR>'
+ desc += '<TD><CAPTION>Name</CAPTION></TD>'
+ desc += '<TD><CAPTION>Token Space</CAPTION></TD>'
+ desc += '<TD><CAPTION>Token number</CAPTION></TD>'
+ desc += '<TD><CAPTION>Data Type</CAPTION></TD>'
+ desc += '<TD><CAPTION>Default Value</CAPTION></TD>'
+ desc += '</TR>'
+ desc += '<TR>'
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[1]
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[0]
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdToken()
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdDataType()
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdValue()
+ desc += '</TR>'
+ desc += '</TABLE>'
+ section.AddDescription(desc)
+ pcdPage.AddSection(section)
+ typeRoot.AddPage(pcdPage)
+ else:
+ keystr = obj.GetPcdType() + obj.GetArch()
+ if keystr not in typeArchRootPageDict.keys():
+ typeArchRootPage = doxygen.Page(obj.GetArch(), 'pcd_%s_%s_root_page' % (obj.GetPcdType(), obj.GetArch()))
+ typeArchRootPageDict[keystr] = typeArchRootPage
+ typeRoot.AddPage(typeArchRootPage)
+ typeArchRoot = typeArchRootPageDict[keystr]
+ pcdPage = doxygen.Page('%s' % obj.GetPcdName(),
+ 'pcd_%s_%s_%s' % (obj.GetPcdType(), obj.GetArch(), obj.GetPcdName().split('.')[1]))
+ pcdPage.AddDescription('<br>\n'.join(obj.GetComment()) + '<br>\n')
+ section = doxygen.Section('PCDinformation', 'PCD Information')
+ desc = '<TABLE>'
+ desc += '<TR>'
+ desc += '<TD><CAPTION>Name</CAPTION></TD>'
+ desc += '<TD><CAPTION>Token Space</CAPTION></TD>'
+ desc += '<TD><CAPTION>Token number</CAPTION></TD>'
+ desc += '<TD><CAPTION>Data Type</CAPTION></TD>'
+ desc += '<TD><CAPTION>Default Value</CAPTION></TD>'
+ desc += '</TR>'
+ desc += '<TR>'
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[1]
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[0]
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdToken()
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdDataType()
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdValue()
+ desc += '</TR>'
+ desc += '</TABLE>'
+ section.AddDescription(desc)
+ pcdPage.AddSection(section)
+ typeArchRoot.AddPage(pcdPage)
+ return [pcdRootPage]
+
+ def _GenerateGuidSubPage(self, pObj, obj, configFile):
+ guidPage = doxygen.Page('%s' % obj.GetName(),
+ 'guid_%s_%s' % (obj.GetArch(), obj.GetName()))
+ comments = obj.GetComment()
+ if len(comments) != 0:
+ guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')
+ section = doxygen.Section('BasicGuidInfo', 'GUID Information')
+ desc = '<TABLE>'
+ desc += '<TR>'
+ desc += '<TD><CAPTION>GUID\'s Guid Name</CAPTION></TD><TD><CAPTION>GUID\'s Guid</CAPTION></TD>'
+ desc += '</TR>'
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % obj.GetName()
+ desc += '<TD>%s</TD>' % obj.GetGuid()
+ desc += '</TR>'
+ desc += '</TABLE>'
+ section.AddDescription(desc)
+ guidPage.AddSection(section)
+ refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)
+ if refFile:
+ relPath = refFile[len(pObj.GetWorkspace()) + 1:]
+ if len(comments) == 0:
+ guidPage.AddDescription(' \\copydoc %s <br>' % relPath)
+
+ section = doxygen.Section('ref', 'Refer to Header File')
+ section.AddDescription('\link %s\n' % relPath)
+ section.AddDescription('\endlink\n')
+ self.ProcessSourceFileForInclude(refFile, pObj, configFile)
+ guidPage.AddSection(section)
+ return guidPage
+
+ def GenerateGuidSubPages(self, pObj, configFile):
+ """
+ Generate sub pages for package's GUID definition.
+ @param pObj package object
+ @param configFilf doxygen config file object
+ """
+ pageRoot = doxygen.Page('GUID', 'guid_root_page')
+ objs = pObj.GetFileObj().GetSectionObjectsByName('guids', self._arch)
+ if len(objs) == 0: return []
+ if self._arch is not None:
+ for obj in objs:
+ pageRoot.AddPage(self._GenerateGuidSubPage(pObj, obj, configFile))
+ else:
+ guidArchRootPageDict = {}
+ for obj in objs:
+ if obj.GetArch() not in guidArchRootPageDict.keys():
+ guidArchRoot = doxygen.Page(obj.GetArch(), 'guid_arch_root_%s' % obj.GetArch())
+ pageRoot.AddPage(guidArchRoot)
+ guidArchRootPageDict[obj.GetArch()] = guidArchRoot
+ guidArchRoot = guidArchRootPageDict[obj.GetArch()]
+ guidArchRoot.AddPage(self._GenerateGuidSubPage(pObj, obj, configFile))
+ return [pageRoot]
+
+ def _GeneratePpiSubPage(self, pObj, obj, configFile):
+ guidPage = doxygen.Page(obj.GetName(), 'ppi_page_%s' % obj.GetName())
+ comments = obj.GetComment()
+ if len(comments) != 0:
+ guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')
+ section = doxygen.Section('BasicPpiInfo', 'PPI Information')
+ desc = '<TABLE>'
+ desc += '<TR>'
+ desc += '<TD><CAPTION>PPI\'s Guid Name</CAPTION></TD><TD><CAPTION>PPI\'s Guid</CAPTION></TD>'
+ desc += '</TR>'
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % obj.GetName()
+ desc += '<TD>%s</TD>' % obj.GetGuid()
+ desc += '</TR>'
+ desc += '</TABLE>'
+ section.AddDescription(desc)
+ guidPage.AddSection(section)
+ refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)
+ if refFile:
+ relPath = refFile[len(pObj.GetWorkspace()) + 1:]
+ if len(comments) == 0:
+ guidPage.AddDescription(' \\copydoc %s <br>' % relPath)
+ section = doxygen.Section('ref', 'Refer to Header File')
+ section.AddDescription('\link %s\n' % relPath)
+ section.AddDescription('\endlink\n')
+ self.ProcessSourceFileForInclude(refFile, pObj, configFile)
+ guidPage.AddSection(section)
+
+ return guidPage
+
+ def GeneratePpiSubPages(self, pObj, configFile):
+ """
+ Generate sub pages for package's GUID definition.
+ @param pObj package object
+ @param configFilf doxygen config file object
+ """
+ pageRoot = doxygen.Page('PPI', 'ppi_root_page')
+ objs = pObj.GetFileObj().GetSectionObjectsByName('ppis', self._arch)
+ if len(objs) == 0: return []
+ if self._arch is not None:
+ for obj in objs:
+ pageRoot.AddPage(self._GeneratePpiSubPage(pObj, obj, configFile))
+ else:
+ guidArchRootPageDict = {}
+ for obj in objs:
+ if obj.GetArch() not in guidArchRootPageDict.keys():
+ guidArchRoot = doxygen.Page(obj.GetArch(), 'ppi_arch_root_%s' % obj.GetArch())
+ pageRoot.AddPage(guidArchRoot)
+ guidArchRootPageDict[obj.GetArch()] = guidArchRoot
+ guidArchRoot = guidArchRootPageDict[obj.GetArch()]
+ guidArchRoot.AddPage(self._GeneratePpiSubPage(pObj, obj, configFile))
+ return [pageRoot]
+
+ def _GenerateProtocolSubPage(self, pObj, obj, configFile):
+ guidPage = doxygen.Page(obj.GetName(), 'protocol_page_%s' % obj.GetName())
+ comments = obj.GetComment()
+ if len(comments) != 0:
+ guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')
+ section = doxygen.Section('BasicProtocolInfo', 'PROTOCOL Information')
+ desc = '<TABLE>'
+ desc += '<TR>'
+ desc += '<TD><CAPTION>PROTOCOL\'s Guid Name</CAPTION></TD><TD><CAPTION>PROTOCOL\'s Guid</CAPTION></TD>'
+ desc += '</TR>'
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % obj.GetName()
+ desc += '<TD>%s</TD>' % obj.GetGuid()
+ desc += '</TR>'
+ desc += '</TABLE>'
+ section.AddDescription(desc)
+ guidPage.AddSection(section)
+
+ refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)
+ if refFile:
+ relPath = refFile[len(pObj.GetWorkspace()) + 1:]
+ if len(comments) == 0:
+ guidPage.AddDescription(' \\copydoc %s <br>' % relPath)
+ section = doxygen.Section('ref', 'Refer to Header File')
+ section.AddDescription('\link %s\n' % relPath)
+ section.AddDescription('\endlink\n')
+ self.ProcessSourceFileForInclude(refFile, pObj, configFile)
+ guidPage.AddSection(section)
+
+ return guidPage
+
+ def GenerateProtocolSubPages(self, pObj, configFile):
+ """
+ Generate sub pages for package's GUID definition.
+ @param pObj package object
+ @param configFilf doxygen config file object
+ """
+ pageRoot = doxygen.Page('PROTOCOL', 'protocol_root_page')
+ objs = pObj.GetFileObj().GetSectionObjectsByName('protocols', self._arch)
+ if len(objs) == 0: return []
+ if self._arch is not None:
+ for obj in objs:
+ pageRoot.AddPage(self._GenerateProtocolSubPage(pObj, obj, configFile))
+ else:
+ guidArchRootPageDict = {}
+ for obj in objs:
+ if obj.GetArch() not in guidArchRootPageDict.keys():
+ guidArchRoot = doxygen.Page(obj.GetArch(), 'protocol_arch_root_%s' % obj.GetArch())
+ pageRoot.AddPage(guidArchRoot)
+ guidArchRootPageDict[obj.GetArch()] = guidArchRoot
+ guidArchRoot = guidArchRootPageDict[obj.GetArch()]
+ guidArchRoot.AddPage(self._GenerateProtocolSubPage(pObj, obj, configFile))
+ return [pageRoot]
+
+ def FindHeaderFileForGuid(self, pObj, name, configFile):
+ """
+ For declaration header file for GUID/PPI/Protocol.
+
+ @param pObj package object
+ @param name guid/ppi/protocol's name
+ @param configFile config file object
+
+ @return full path of header file and None if not found.
+ """
+ startPath = pObj.GetFileObj().GetPackageRootPath()
+ incPath = os.path.join(startPath, 'Include').replace('\\', '/')
+ # if <PackagePath>/include exist, then search header under it.
+ if os.path.exists(incPath):
+ startPath = incPath
+
+ for root, dirs, files in os.walk(startPath):
+ for dir in dirs:
+ if dir.lower() in _ignore_dir:
+ dirs.remove(dir)
+ for file in files:
+ fPath = os.path.join(root, file)
+ if not IsCHeaderFile(fPath):
+ continue
+ try:
+ f = open(fPath, 'r')
+ lines = f.readlines()
+ f.close()
+ except IOError:
+ self.Log('Fail to open file %s\n' % fPath)
+ continue
+ for line in lines:
+ if line.find(name) != -1 and \
+ line.find('extern') != -1:
+ return fPath.replace('\\', '/')
+ return None
+
+ def GetPackageModuleList(self, pObj):
+ """
+ Get all module's INF path under package's root path
+ @param pObj package object
+ @return arrary of INF full path
+ """
+ mArray = []
+ packPath = pObj.GetFileObj().GetPackageRootPath()
+ if not os.path.exists:
+ return None
+ for root, dirs, files in os.walk(packPath):
+ for dir in dirs:
+ if dir.lower() in _ignore_dir:
+ dirs.remove(dir)
+ for file in files:
+ if CheckPathPostfix(file, 'inf'):
+ fPath = os.path.join(root, file).replace('\\', '/')
+ mArray.append(fPath)
+ return mArray
+
+ def GenerateModulePages(self, pObj, configFile):
+ """
+ Generate sub pages for package's module which is under the package
+ root directory.
+
+ @param pObj package object
+ @param configFilf doxygen config file object
+ """
+ infList = self.GetPackageModuleList(pObj)
+ rootPages = []
+ libObjs = []
+ modObjs = []
+ for infpath in infList:
+ infObj = inf.INFFile(infpath)
+ #infObj = INFFileObject.INFFile (pObj.GetWorkspacePath(),
+ # inf)
+ if not infObj:
+ self.Log('Fail create INF object for %s' % inf)
+ continue
+ if not infObj.Parse():
+ self.Log('Fail to load INF file %s' % inf)
+ continue
+ if infObj.GetProduceLibraryClass() is not None:
+ libObjs.append(infObj)
+ else:
+ modObjs.append(infObj)
+
+ if len(libObjs) != 0:
+ libRootPage = doxygen.Page('Libraries', 'lib_root_page')
+ rootPages.append(libRootPage)
+ for libInf in libObjs:
+ libRootPage.AddPage(self.GenerateModulePage(pObj, libInf, configFile, True))
+
+ if len(modObjs) != 0:
+ modRootPage = doxygen.Page('Modules', 'module_root_page')
+ rootPages.append(modRootPage)
+ for modInf in modObjs:
+ modRootPage.AddPage(self.GenerateModulePage(pObj, modInf, configFile, False))
+
+ return rootPages
+
+ def GenerateModulePage(self, pObj, infObj, configFile, isLib):
+ """
+ Generate page for a module/library.
+ @param infObj INF file object for module/library
+ @param configFile doxygen config file object
+ @param isLib Whether this module is library
+
+ @param module doxygen page object
+ """
+ workspace = pObj.GetWorkspace()
+ refDecObjs = []
+ for obj in infObj.GetSectionObjectsByName('packages'):
+ decObj = dec.DECFile(os.path.join(workspace, obj.GetPath()))
+ if not decObj:
+ ErrorMsg ('Fail to create pacakge object for %s' % obj.GetPackageName())
+ continue
+ if not decObj.Parse():
+ ErrorMsg ('Fail to load package object for %s' % obj.GetPackageName())
+ continue
+ refDecObjs.append(decObj)
+
+ modPage = doxygen.Page('%s' % infObj.GetBaseName(),
+ 'module_%s' % infObj.GetBaseName())
+ modPage.AddDescription(infObj.GetFileHeader())
+
+ basicInfSection = doxygen.Section('BasicModuleInformation', 'Basic Module Information')
+ desc = "<TABLE>"
+ for obj in infObj.GetSectionObjectsByName('defines'):
+ key = obj.GetKey()
+ value = obj.GetValue()
+ if key not in _inf_key_description_mapping_table.keys(): continue
+ if key == 'LIBRARY_CLASS' and value.find('|') != -1:
+ clsname, types = value.split('|')
+ desc += '<TR>'
+ desc += '<TD><B>%s</B></TD>' % _inf_key_description_mapping_table[key]
+ desc += '<TD>%s</TD>' % clsname
+ desc += '</TR>'
+
+ desc += '<TR>'
+ desc += '<TD><B>Supported Module Types</B></TD>'
+ desc += '<TD>%s</TD>' % types
+ desc += '</TR>'
+ else:
+ desc += '<TR>'
+ desc += '<TD><B>%s</B></TD>' % _inf_key_description_mapping_table[key]
+ if key == 'EFI_SPECIFICATION_VERSION' and value == '0x00020000':
+ value = '2.0'
+ desc += '<TD>%s</TD>' % value
+ desc += '</TR>'
+ desc += '</TABLE>'
+ basicInfSection.AddDescription(desc)
+ modPage.AddSection(basicInfSection)
+
+ # Add protocol section
+ data = []
+ for obj in infObj.GetSectionObjectsByName('pcd', self._arch):
+ data.append(obj.GetPcdName().strip())
+ if len(data) != 0:
+ s = doxygen.Section('Pcds', 'Pcds')
+ desc = "<TABLE>"
+ desc += '<TR><TD><B>PCD Name</B></TD><TD><B>TokenSpace</B></TD><TD><B>Package</B></TD></TR>'
+ for item in data:
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % item.split('.')[1]
+ desc += '<TD>%s</TD>' % item.split('.')[0]
+ pkgbasename = self.SearchPcdPackage(item, workspace, refDecObjs)
+ desc += '<TD>%s</TD>' % pkgbasename
+ desc += '</TR>'
+ desc += "</TABLE>"
+ s.AddDescription(desc)
+ modPage.AddSection(s)
+
+ # Add protocol section
+ #sects = infObj.GetSectionByString('protocol')
+ data = []
+ #for sect in sects:
+ for obj in infObj.GetSectionObjectsByName('protocol', self._arch):
+ data.append(obj.GetName().strip())
+ if len(data) != 0:
+ s = doxygen.Section('Protocols', 'Protocols')
+ desc = "<TABLE>"
+ desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'
+ for item in data:
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % item
+ pkgbasename = self.SearchProtocolPackage(item, workspace, refDecObjs)
+ desc += '<TD>%s</TD>' % pkgbasename
+ desc += '</TR>'
+ desc += "</TABLE>"
+ s.AddDescription(desc)
+ modPage.AddSection(s)
+
+ # Add ppi section
+ #sects = infObj.GetSectionByString('ppi')
+ data = []
+ #for sect in sects:
+ for obj in infObj.GetSectionObjectsByName('ppi', self._arch):
+ data.append(obj.GetName().strip())
+ if len(data) != 0:
+ s = doxygen.Section('Ppis', 'Ppis')
+ desc = "<TABLE>"
+ desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'
+ for item in data:
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % item
+ pkgbasename = self.SearchPpiPackage(item, workspace, refDecObjs)
+ desc += '<TD>%s</TD>' % pkgbasename
+ desc += '</TR>'
+ desc += "</TABLE>"
+ s.AddDescription(desc)
+ modPage.AddSection(s)
+
+ # Add guid section
+ #sects = infObj.GetSectionByString('guid')
+ data = []
+ #for sect in sects:
+ for obj in infObj.GetSectionObjectsByName('guid', self._arch):
+ data.append(obj.GetName().strip())
+ if len(data) != 0:
+ s = doxygen.Section('Guids', 'Guids')
+ desc = "<TABLE>"
+ desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'
+ for item in data:
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % item
+ pkgbasename = self.SearchGuidPackage(item, workspace, refDecObjs)
+ desc += '<TD>%s</TD>' % pkgbasename
+ desc += '</TR>'
+ desc += "</TABLE>"
+ s.AddDescription(desc)
+ modPage.AddSection(s)
+
+ section = doxygen.Section('LibraryClasses', 'Library Classes')
+ desc = "<TABLE>"
+ desc += '<TR><TD><B>Name</B></TD><TD><B>Type</B></TD><TD><B>Package</B></TD><TD><B>Header File</B></TD></TR>'
+ if isLib:
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % infObj.GetProduceLibraryClass()
+ desc += '<TD>Produce</TD>'
+ try:
+ pkgname, hPath = self.SearchLibraryClassHeaderFile(infObj.GetProduceLibraryClass(),
+ workspace,
+ refDecObjs)
+ except:
+ self.Log ('fail to get package header file for lib class %s' % infObj.GetProduceLibraryClass())
+ pkgname = 'NULL'
+ hPath = 'NULL'
+ desc += '<TD>%s</TD>' % pkgname
+ if hPath != "NULL":
+ #desc += '<TD>\link %s \endlink</TD>' % hPath
+ desc += '<TD>%s</TD>' % hPath
+ else:
+ desc += '<TD>%s</TD>' % hPath
+ desc += '</TR>'
+ for lcObj in infObj.GetSectionObjectsByName('libraryclasses', self._arch):
+ desc += '<TR>'
+ desc += '<TD>%s</TD>' % lcObj.GetClass()
+ retarr = self.SearchLibraryClassHeaderFile(lcObj.GetClass(),
+ workspace,
+ refDecObjs)
+ if retarr is not None:
+ pkgname, hPath = retarr
+ else:
+ self.Log('Fail find the library class %s definition from module %s dependent package!' % (lcObj.GetClass(), infObj.GetFilename()), 'error')
+ pkgname = 'NULL'
+ hPath = 'NULL'
+ desc += '<TD>Consume</TD>'
+ desc += '<TD>%s</TD>' % pkgname
+ desc += '<TD>%s</TD>' % hPath
+ desc += '</TR>'
+ desc += "</TABLE>"
+ section.AddDescription(desc)
+ modPage.AddSection(section)
+
+ section = doxygen.Section('SourceFiles', 'Source Files')
+ section.AddDescription('<ul>\n')
+ for obj in infObj.GetSourceObjects(self._arch, self._tooltag):
+ sPath = infObj.GetModuleRootPath()
+ sPath = os.path.join(sPath, obj.GetSourcePath()).replace('\\', '/').strip()
+ if sPath.lower().endswith('.uni') or sPath.lower().endswith('.s') or sPath.lower().endswith('.asm') or sPath.lower().endswith('.nasm'):
+ newPath = self.TranslateUniFile(sPath)
+ configFile.AddFile(newPath)
+ newPath = newPath[len(pObj.GetWorkspace()) + 1:]
+ section.AddDescription('<li> \link %s \endlink </li>' % newPath)
+ else:
+ self.ProcessSourceFileForInclude(sPath, pObj, configFile, infObj)
+ sPath = sPath[len(pObj.GetWorkspace()) + 1:]
+ section.AddDescription('<li>\link %s \endlink </li>' % sPath)
+ section.AddDescription('</ul>\n')
+ modPage.AddSection(section)
+
+ #sects = infObj.GetSectionByString('depex')
+ data = []
+ #for sect in sects:
+ for obj in infObj.GetSectionObjectsByName('depex'):
+ data.append(str(obj))
+ if len(data) != 0:
+ s = doxygen.Section('DependentSection', 'Module Dependencies')
+ s.AddDescription('<br>'.join(data))
+ modPage.AddSection(s)
+
+ return modPage
+
+ def TranslateUniFile(self, path):
+ newpath = path + '.dox'
+ #import core.textfile as textfile
+ #file = textfile.TextFile(path)
+
+ try:
+ file = open(path, 'r')
+ except (IOError, OSError) as msg:
+ return None
+
+ t = file.read()
+ file.close()
+
+ output = '/** @file \n'
+ #output = '<html><body>'
+ arr = t.split('\r\n')
+ for line in arr:
+ if line.find('@file') != -1:
+ continue
+ if line.find('*/') != -1:
+ continue
+ line = line.strip()
+ if line.strip().startswith('/'):
+ arr = line.split(' ')
+ if len(arr) > 1:
+ line = ' '.join(arr[1:])
+ else:
+ continue
+ output += '%s<br>\n' % line
+ output += '**/'
+
+ if os.path.exists(newpath):
+ os.remove(newpath)
+
+ file = open(newpath, "w")
+ file.write(output)
+ file.close()
+ return newpath
+
+ def SearchPcdPackage(self, pcdname, workspace, decObjs):
+ for decObj in decObjs:
+ for pcd in decObj.GetSectionObjectsByName('pcd'):
+ if pcdname == pcd.GetPcdName():
+ return decObj.GetBaseName()
+ return None
+
+ def SearchProtocolPackage(self, protname, workspace, decObjs):
+ for decObj in decObjs:
+ for proto in decObj.GetSectionObjectsByName('protocol'):
+ if protname == proto.GetName():
+ return decObj.GetBaseName()
+ return None
+
+ def SearchPpiPackage(self, ppiname, workspace, decObjs):
+ for decObj in decObjs:
+ for ppi in decObj.GetSectionObjectsByName('ppi'):
+ if ppiname == ppi.GetName():
+ return decObj.GetBaseName()
+ return None
+
+ def SearchGuidPackage(self, guidname, workspace, decObjs):
+ for decObj in decObjs:
+ for guid in decObj.GetSectionObjectsByName('guid'):
+ if guidname == guid.GetName():
+ return decObj.GetBaseName()
+ return None
+
+ def SearchLibraryClassHeaderFile(self, className, workspace, decObjs):
+ for decObj in decObjs:
+ for cls in decObj.GetSectionObjectsByName('libraryclasses'):
+ if cls.GetClassName().strip() == className:
+ path = cls.GetHeaderFile().strip()
+ path = os.path.join(decObj.GetPackageRootPath(), path)
+ path = path[len(workspace) + 1:]
+ return decObj.GetBaseName(), path.replace('\\', '/')
+
+ return None
+
+ def _ConvertPathToDoxygen(self, path, pObj):
+ pRootPath = pObj.GetWorkspace()
+ path = path[len(pRootPath) + 1:]
+ return path.replace('\\', '/')
+
+def IsCHeaderFile(path):
+ return CheckPathPostfix(path, 'h')
+
+def CheckPathPostfix(path, str):
+ index = path.rfind('.')
+ if index == -1:
+ return False
+ if path[index + 1:].lower() == str.lower():
+ return True
+ return False
diff --git a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/dsc.py b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/dsc.py
index a2d23a7732..40535cea27 100644
--- a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/dsc.py
+++ b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/dsc.py
@@ -1,195 +1,195 @@
-## @file
-#
-# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-from plugins.EdkPlugins.basemodel import ini
-import re, os
-from plugins.EdkPlugins.basemodel.message import *
-
-class DSCFile(ini.BaseINIFile):
- def GetSectionInstance(self, parent, name, isCombined=False):
- return DSCSection(parent, name, isCombined)
-
- def GetComponents(self):
- return self.GetSectionObjectsByName('Components')
-
-class DSCSection(ini.BaseINISection):
- def GetSectionINIObject(self, parent):
- type = self.GetType()
-
- if type.lower() == 'components':
- return DSCComponentObject(self)
- if type.lower() == 'libraryclasses':
- return DSCLibraryClassObject(self)
- if type.lower() == 'defines':
- return ini.BaseINISectionObject(self)
- if type.lower() == 'pcdsfeatureflag' or \
- type.lower() == 'pcdsfixedatbuild' or \
- type.lower() == 'pcdspatchableinmodule' or\
- type.lower() == 'pcdsdynamicdefault' or \
- type.lower() == 'pcdsdynamicex' or \
- type.lower() == 'pcdsdynamichii' or \
- type.lower() == 'pcdsdynamicvpd':
- return DSCPcdObject(self)
-
- return DSCSectionObject(self)
-
- def GetType(self):
- arr = self._name.split('.')
- return arr[0].strip()
-
- def GetArch(self):
- arr = self._name.split('.')
- if len(arr) == 1:
- return 'common'
- return arr[1]
-
- def GetModuleType(self):
- arr = self._name.split('.')
- if len(arr) < 3:
- return 'common'
- return arr[2]
-
-class DSCSectionObject(ini.BaseINISectionObject):
- def GetArch(self):
- return self.GetParent().GetArch()
-
-class DSCPcdObject(DSCSectionObject):
-
- def __init__(self, parent):
- ini.BaseINISectionObject.__init__(self, parent)
- self._name = None
-
- def Parse(self):
- line = self.GetLineByOffset(self._start).strip().split('#')[0]
- self._name = line.split('|')[0]
- self._value = line.split('|')[1]
- return True
-
- def GetPcdName(self):
- return self._name
-
- def GetPcdType(self):
- return self.GetParent().GetType()
-
- def GetPcdValue(self):
- return self._value
-
-class DSCLibraryClassObject(DSCSectionObject):
- def __init__(self, parent):
- ini.BaseINISectionObject.__init__(self, parent)
-
- def GetClass(self):
- line = self.GetLineByOffset(self._start)
- return line.split('#')[0].split('|')[0].strip()
-
- def GetInstance(self):
- line = self.GetLineByOffset(self._start)
- return line.split('#')[0].split('|')[1].strip()
-
- def GetArch(self):
- return self.GetParent().GetArch()
-
- def GetModuleType(self):
- return self.GetParent().GetModuleType()
-
-class DSCComponentObject(DSCSectionObject):
-
- def __init__(self, parent):
- ini.BaseINISectionObject.__init__(self, parent)
- self._OveridePcds = {}
- self._OverideLibraries = {}
- self._Filename = ''
-
- def __del__(self):
- self._OverideLibraries.clear()
- self._OverideLibraries.clear()
- ini.BaseINISectionObject.__del__(self)
-
- def AddOverideLib(self, libclass, libinstPath):
- if libclass not in self._OverideLibraries.keys():
- self._OverideLibraries[libclass] = libinstPath
-
- def AddOveridePcd(self, name, type, value=None):
- if type not in self._OveridePcds.keys():
- self._OveridePcds[type] = []
- self._OveridePcds[type].append((name, value))
-
- def GetOverideLibs(self):
- return self._OverideLibraries
-
- def GetArch(self):
- return self.GetParent().GetArch()
-
- def GetOveridePcds(self):
- return self._OveridePcds
-
- def GetFilename(self):
- return self.GetLineByOffset(self._start).split('#')[0].split('{')[0].strip()
-
- def SetFilename(self, fName):
- self._Filename = fName
-
- def Parse(self):
- if (self._start < self._end):
- #
- # The first line is inf path and could be ignored
- # The end line is '}' and could be ignored
- #
- curr = self._start + 1
- end = self._end - 1
- OverideName = ''
- while (curr <= end):
- line = self.GetLineByOffset(curr).strip()
- if len(line) > 0 and line[0] != '#':
- line = line.split('#')[0].strip()
- if line[0] == '<':
- OverideName = line[1:len(line)-1]
- elif OverideName.lower() == 'libraryclasses':
- arr = line.split('|')
- self._OverideLibraries[arr[0].strip()] = arr[1].strip()
- elif OverideName.lower() == 'pcds':
- ErrorMsg('EDES does not support PCD overide',
- self.GetFileName(),
- self.GetParent().GetLinenumberByOffset(curr))
- curr = curr + 1
- return True
-
- def GenerateLines(self):
- lines = []
- hasLib = False
- hasPcd = False
- if len(self._OverideLibraries) != 0:
- hasLib = True
- if len(self._OveridePcds) != 0:
- hasPcd = True
-
- if hasLib or hasPcd:
- lines.append((' %s {\n' % self._Filename))
- else:
- lines.append((' %s \n' % self._Filename))
- return lines
-
- if hasLib:
- lines.append(' <LibraryClasses>\n')
- for libKey in self._OverideLibraries.keys():
- lines.append(' %s|%s\n' % (libKey, self._OverideLibraries[libKey]))
-
- if hasPcd:
- for key in self._OveridePcds.keys():
- lines.append(' <%s>\n' % key)
-
- for name, value in self._OveridePcds[key]:
- if value is not None:
- lines.append(' %s|%s\n' % (name, value))
- else:
- lines.append(' %s\n' % name)
-
- if hasLib or hasPcd:
- lines.append(' }\n')
-
- return lines
-
+## @file
+#
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+from plugins.EdkPlugins.basemodel import ini
+import re, os
+from plugins.EdkPlugins.basemodel.message import *
+
+class DSCFile(ini.BaseINIFile):
+ def GetSectionInstance(self, parent, name, isCombined=False):
+ return DSCSection(parent, name, isCombined)
+
+ def GetComponents(self):
+ return self.GetSectionObjectsByName('Components')
+
+class DSCSection(ini.BaseINISection):
+ def GetSectionINIObject(self, parent):
+ type = self.GetType()
+
+ if type.lower() == 'components':
+ return DSCComponentObject(self)
+ if type.lower() == 'libraryclasses':
+ return DSCLibraryClassObject(self)
+ if type.lower() == 'defines':
+ return ini.BaseINISectionObject(self)
+ if type.lower() == 'pcdsfeatureflag' or \
+ type.lower() == 'pcdsfixedatbuild' or \
+ type.lower() == 'pcdspatchableinmodule' or\
+ type.lower() == 'pcdsdynamicdefault' or \
+ type.lower() == 'pcdsdynamicex' or \
+ type.lower() == 'pcdsdynamichii' or \
+ type.lower() == 'pcdsdynamicvpd':
+ return DSCPcdObject(self)
+
+ return DSCSectionObject(self)
+
+ def GetType(self):
+ arr = self._name.split('.')
+ return arr[0].strip()
+
+ def GetArch(self):
+ arr = self._name.split('.')
+ if len(arr) == 1:
+ return 'common'
+ return arr[1]
+
+ def GetModuleType(self):
+ arr = self._name.split('.')
+ if len(arr) < 3:
+ return 'common'
+ return arr[2]
+
+class DSCSectionObject(ini.BaseINISectionObject):
+ def GetArch(self):
+ return self.GetParent().GetArch()
+
+class DSCPcdObject(DSCSectionObject):
+
+ def __init__(self, parent):
+ ini.BaseINISectionObject.__init__(self, parent)
+ self._name = None
+
+ def Parse(self):
+ line = self.GetLineByOffset(self._start).strip().split('#')[0]
+ self._name = line.split('|')[0]
+ self._value = line.split('|')[1]
+ return True
+
+ def GetPcdName(self):
+ return self._name
+
+ def GetPcdType(self):
+ return self.GetParent().GetType()
+
+ def GetPcdValue(self):
+ return self._value
+
+class DSCLibraryClassObject(DSCSectionObject):
+ def __init__(self, parent):
+ ini.BaseINISectionObject.__init__(self, parent)
+
+ def GetClass(self):
+ line = self.GetLineByOffset(self._start)
+ return line.split('#')[0].split('|')[0].strip()
+
+ def GetInstance(self):
+ line = self.GetLineByOffset(self._start)
+ return line.split('#')[0].split('|')[1].strip()
+
+ def GetArch(self):
+ return self.GetParent().GetArch()
+
+ def GetModuleType(self):
+ return self.GetParent().GetModuleType()
+
+class DSCComponentObject(DSCSectionObject):
+
+ def __init__(self, parent):
+ ini.BaseINISectionObject.__init__(self, parent)
+ self._OveridePcds = {}
+ self._OverideLibraries = {}
+ self._Filename = ''
+
+ def __del__(self):
+ self._OverideLibraries.clear()
+ self._OverideLibraries.clear()
+ ini.BaseINISectionObject.__del__(self)
+
+ def AddOverideLib(self, libclass, libinstPath):
+ if libclass not in self._OverideLibraries.keys():
+ self._OverideLibraries[libclass] = libinstPath
+
+ def AddOveridePcd(self, name, type, value=None):
+ if type not in self._OveridePcds.keys():
+ self._OveridePcds[type] = []
+ self._OveridePcds[type].append((name, value))
+
+ def GetOverideLibs(self):
+ return self._OverideLibraries
+
+ def GetArch(self):
+ return self.GetParent().GetArch()
+
+ def GetOveridePcds(self):
+ return self._OveridePcds
+
+ def GetFilename(self):
+ return self.GetLineByOffset(self._start).split('#')[0].split('{')[0].strip()
+
+ def SetFilename(self, fName):
+ self._Filename = fName
+
+ def Parse(self):
+ if (self._start < self._end):
+ #
+ # The first line is inf path and could be ignored
+ # The end line is '}' and could be ignored
+ #
+ curr = self._start + 1
+ end = self._end - 1
+ OverideName = ''
+ while (curr <= end):
+ line = self.GetLineByOffset(curr).strip()
+ if len(line) > 0 and line[0] != '#':
+ line = line.split('#')[0].strip()
+ if line[0] == '<':
+ OverideName = line[1:len(line)-1]
+ elif OverideName.lower() == 'libraryclasses':
+ arr = line.split('|')
+ self._OverideLibraries[arr[0].strip()] = arr[1].strip()
+ elif OverideName.lower() == 'pcds':
+ ErrorMsg('EDES does not support PCD overide',
+ self.GetFileName(),
+ self.GetParent().GetLinenumberByOffset(curr))
+ curr = curr + 1
+ return True
+
+ def GenerateLines(self):
+ lines = []
+ hasLib = False
+ hasPcd = False
+ if len(self._OverideLibraries) != 0:
+ hasLib = True
+ if len(self._OveridePcds) != 0:
+ hasPcd = True
+
+ if hasLib or hasPcd:
+ lines.append((' %s {\n' % self._Filename))
+ else:
+ lines.append((' %s \n' % self._Filename))
+ return lines
+
+ if hasLib:
+ lines.append(' <LibraryClasses>\n')
+ for libKey in self._OverideLibraries.keys():
+ lines.append(' %s|%s\n' % (libKey, self._OverideLibraries[libKey]))
+
+ if hasPcd:
+ for key in self._OveridePcds.keys():
+ lines.append(' <%s>\n' % key)
+
+ for name, value in self._OveridePcds[key]:
+ if value is not None:
+ lines.append(' %s|%s\n' % (name, value))
+ else:
+ lines.append(' %s\n' % name)
+
+ if hasLib or hasPcd:
+ lines.append(' }\n')
+
+ return lines
+
diff --git a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/inf.py b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/inf.py
index 430e71af2d..fc8056b1ab 100644
--- a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/inf.py
+++ b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/inf.py
@@ -1,335 +1,335 @@
-## @file
-#
-# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-from plugins.EdkPlugins.basemodel import ini
-import re, os
-from plugins.EdkPlugins.basemodel.message import *
-
-class INFFile(ini.BaseINIFile):
- _libobjs = {}
-
- def GetSectionInstance(self, parent, name, isCombined=False):
- return INFSection(parent, name, isCombined)
-
- def GetProduceLibraryClass(self):
- obj = self.GetDefine("LIBRARY_CLASS")
- if obj is None: return None
-
- return obj.split('|')[0].strip()
-
- def GetSectionObjectsByName(self, name, arch=None):
- arr = []
- sects = self.GetSectionByName(name)
- for sect in sects:
- # skip unmatched archtecture content
- if not sect.IsArchMatch(arch):
- continue
-
- for obj in sect.GetObjects():
- arr.append(obj)
-
- return arr
-
- def GetSourceObjects(self, arch=None, tool=None):
- arr = []
- sects = self.GetSectionByName('sources')
- for sect in sects:
- # skip unmatched archtecture content
- if not sect.IsArchMatch(arch):
- continue
-
- for obj in sect.GetObjects():
- if not obj.IsMatchFamily(tool):
- continue
- arr.append(obj)
-
- return arr
-
- def Parse(self):
- if not ini.BaseINIFile.Parse(self):
- return False
- classname = self.GetProduceLibraryClass()
- if classname is not None:
- libobjdict = INFFile._libobjs
- if classname in libobjdict:
- if self not in libobjdict[classname]:
- libobjdict[classname].append(self)
- else:
- libobjdict[classname] = [self]
-
- return True
-
- def GetBaseName(self):
- return self.GetDefine("BASE_NAME").strip()
-
- def GetModuleRootPath(self):
- return os.path.dirname(self.GetFilename())
-
- def Clear(self):
- classname = self.GetProduceLibraryClass()
- if classname is not None:
- libobjdict = INFFile._libobjs
- libobjdict[classname].remove(self)
- if len(libobjdict[classname]) == 0:
- del libobjdict[classname]
- ini.BaseINIFile.Clear(self)
-
-
-class INFSection(ini.BaseINISection):
- def GetSectionINIObject(self, parent):
- type = self.GetType()
-
- if type.lower() == 'libraryclasses':
- return INFLibraryClassObject(self)
- if type.lower() == 'sources':
- return INFSourceObject(self)
- if type.lower().find('pcd') != -1:
- return INFPcdObject(self)
- if type.lower() == 'packages':
- return INFDependentPackageObject(self)
- if type.lower() in ['guids', 'protocols', 'ppis']:
- return INFGuidObject(self)
- if type.lower() == 'defines':
- return INFDefineSectionObject(self)
- return INFSectionObject(self)
-
- def GetType(self):
- arr = self._name.split('.')
- return arr[0].strip()
-
- def GetArch(self):
- arr = self._name.split('.')
- if len(arr) == 1:
- return 'common'
- return arr[1]
-
- def IsArchMatch(self, arch):
- if arch is None or self.GetArch() == 'common':
- return True
-
- if self.GetArch().lower() != arch.lower():
- return False
-
- return True
-
-class INFSectionObject(ini.BaseINISectionObject):
- def GetArch(self):
- return self.GetParent().GetArch()
-
-class INFDefineSectionObject(INFSectionObject):
- def __init__(self, parent):
- INFSectionObject.__init__(self, parent)
- self._key = None
- self._value = None
-
- def Parse(self):
- assert (self._start == self._end), 'The object in define section must be in single line'
-
- line = self.GetLineByOffset(self._start).strip()
-
- line = line.split('#')[0]
- arr = line.split('=')
- if len(arr) != 2:
- ErrorMsg('Invalid define section object',
- self.GetFilename(),
- self._start
- )
- return False
-
- self._key = arr[0].strip()
- self._value = arr[1].strip()
-
- return True
-
- def GetKey(self):
- return self._key
-
- def GetValue(self):
- return self._value
-
-class INFLibraryClassObject(INFSectionObject):
- _objs = {}
- def __init__(self, parent):
- INFSectionObject.__init__(self, parent)
- self._classname = None
-
- def GetClass(self):
- return self._classname
-
- def Parse(self):
- self._classname = self.GetLineByOffset(self._start).split('#')[0].strip()
- objdict = INFLibraryClassObject._objs
- if self._classname in objdict:
- objdict[self._classname].append(self)
- else:
- objdict[self._classname] = [self]
- return True
-
- def Destroy(self):
- objdict = INFLibraryClassObject._objs
- objdict[self._classname].remove(self)
- if len(objdict[self._classname]) == 0:
- del objdict[self._classname]
-
- def GetName(self):
- return self._classname
-
- @staticmethod
- def GetObjectDict():
- return INFLibraryClassObject._objs
-
-class INFDependentPackageObject(INFSectionObject):
- def GetPath(self):
- return self.GetLineByOffset(self._start).split('#')[0].strip()
-
-class INFSourceObject(INFSectionObject):
- _objs = {}
- def __init__(self, parent):
- INFSectionObject.__init__(self, parent)
-
- self.mSourcename = None
- self.mToolCode = None
- self.mFamily = None
- self.mTagName = None
- self.mFeaturePcd = None
- self.mFilename = None
-
- def GetSourcePath(self):
- return self.mSourcename
-
- def GetSourceFullPath(self):
- path = os.path.dirname(self.GetFilename())
- path = os.path.join(path, self.GetSourcePath())
- return os.path.normpath(path)
-
- def GetToolCode(self):
- return self.mToolCode
-
- def GetFamily(self):
- return self.mFamily
-
- def GetTagName(self):
- return self.mTagName
-
- def GetFeaturePcd(self):
- return self.mFeaturePcd
-
- def Parse(self):
- line = self.GetLineByOffset(self._start).strip().split('#')[0]
-
- arr = line.split('|')
-
- self.mSourcename = arr[0].strip()
- if len(arr) >= 2:
- self.mFamily = arr[1].strip()
- if len(arr) >= 3:
- self.mTagName = arr[2].strip()
- if len(arr) >= 4:
- self.mToolCode = arr[3].strip()
- if len(arr) >= 5:
- self.mFeaturePcd = arr[4].strip()
-
- self.mFilename = os.path.basename(self.GetSourceFullPath())
- objdict = INFSourceObject._objs
- if self.mFilename not in objdict:
- objdict[self.mFilename] = [self]
- else:
- objdict[self.mFilename].append(self)
-
- return True
-
- def GetName(self):
- return self.mFilename
-
- def Destroy(self):
- objdict = INFSourceObject._objs
- objdict[self.mFilename].remove(self)
- if len(objdict[self.mFilename]) == 0:
- del objdict[self.mFilename]
-
- def IsMatchFamily(self, family):
- if family is None:
- return True
- if self.mFamily is not None:
- if family.strip().lower() == self.mFamily.lower():
- return True
- else:
- return False
- else:
- fname = self.GetSourcePath()
- if fname.endswith('.S') and family.lower() != 'gcc':
- return False
- if fname.endswith('.s') and (self.GetArch().lower() != 'ipf' and self.GetArch().lower() != 'common'):
- return False
- if fname.lower().endswith('.asm') and (family.lower() != 'msft' and family.lower() != 'intel'):
- return False
- return True
-
- @staticmethod
- def GetObjectDict():
- return INFSourceObject._objs
-
-class INFPcdObject(INFSectionObject):
- _objs = {}
-
- def __init__(self, parent):
- INFSectionObject.__init__(self, parent)
-
- self.mPcdType = None
- self.mDefaultValue = None
- self.mPcdName = None
-
- @staticmethod
- def GetObjectDict():
- return INFPcdObject._objs
-
- def Parse(self):
- line = self.GetLineByOffset(self._start).strip().split('#')[0]
-
- arr = line.split('|')
- self.mPcdName = arr[0].strip()
-
- if len(arr) >= 2:
- self.mDefaultValue = arr[1].strip()
-
- objdict = INFPcdObject._objs
- if self.GetName() in objdict:
- if self not in objdict[self.GetName()]:
- objdict[self.GetName()].append(self)
- else:
- objdict[self.GetName()] = [self]
- return True
-
- def GetPcdName(self):
- return self.mPcdName
-
- def GetPcdType(self):
- return self.GetParent().GetType()
-
- def GetName(self):
- return self.mPcdName.split('.')[1]
-
- def Destroy(self):
- objdict = INFPcdObject._objs
- objdict[self.GetName()].remove(self)
- if len(objdict[self.GetName()]) == 0:
- del objdict[self.GetName()]
-
-class INFGuidObject(INFSectionObject):
- def __init__(self, parent):
- INFSectionObject.__init__(self, parent)
- self._name = None
-
- def Parse(self):
- line = self.GetLineByOffset(self._start).strip().split('#')[0].split("|")[0]
- self._name = line.strip()
- return True
-
- def GetName(self):
- return self._name
-
-
+## @file
+#
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+from plugins.EdkPlugins.basemodel import ini
+import re, os
+from plugins.EdkPlugins.basemodel.message import *
+
+class INFFile(ini.BaseINIFile):
+ _libobjs = {}
+
+ def GetSectionInstance(self, parent, name, isCombined=False):
+ return INFSection(parent, name, isCombined)
+
+ def GetProduceLibraryClass(self):
+ obj = self.GetDefine("LIBRARY_CLASS")
+ if obj is None: return None
+
+ return obj.split('|')[0].strip()
+
+ def GetSectionObjectsByName(self, name, arch=None):
+ arr = []
+ sects = self.GetSectionByName(name)
+ for sect in sects:
+ # skip unmatched archtecture content
+ if not sect.IsArchMatch(arch):
+ continue
+
+ for obj in sect.GetObjects():
+ arr.append(obj)
+
+ return arr
+
+ def GetSourceObjects(self, arch=None, tool=None):
+ arr = []
+ sects = self.GetSectionByName('sources')
+ for sect in sects:
+ # skip unmatched archtecture content
+ if not sect.IsArchMatch(arch):
+ continue
+
+ for obj in sect.GetObjects():
+ if not obj.IsMatchFamily(tool):
+ continue
+ arr.append(obj)
+
+ return arr
+
+ def Parse(self):
+ if not ini.BaseINIFile.Parse(self):
+ return False
+ classname = self.GetProduceLibraryClass()
+ if classname is not None:
+ libobjdict = INFFile._libobjs
+ if classname in libobjdict:
+ if self not in libobjdict[classname]:
+ libobjdict[classname].append(self)
+ else:
+ libobjdict[classname] = [self]
+
+ return True
+
+ def GetBaseName(self):
+ return self.GetDefine("BASE_NAME").strip()
+
+ def GetModuleRootPath(self):
+ return os.path.dirname(self.GetFilename())
+
+ def Clear(self):
+ classname = self.GetProduceLibraryClass()
+ if classname is not None:
+ libobjdict = INFFile._libobjs
+ libobjdict[classname].remove(self)
+ if len(libobjdict[classname]) == 0:
+ del libobjdict[classname]
+ ini.BaseINIFile.Clear(self)
+
+
+class INFSection(ini.BaseINISection):
+ def GetSectionINIObject(self, parent):
+ type = self.GetType()
+
+ if type.lower() == 'libraryclasses':
+ return INFLibraryClassObject(self)
+ if type.lower() == 'sources':
+ return INFSourceObject(self)
+ if type.lower().find('pcd') != -1:
+ return INFPcdObject(self)
+ if type.lower() == 'packages':
+ return INFDependentPackageObject(self)
+ if type.lower() in ['guids', 'protocols', 'ppis']:
+ return INFGuidObject(self)
+ if type.lower() == 'defines':
+ return INFDefineSectionObject(self)
+ return INFSectionObject(self)
+
+ def GetType(self):
+ arr = self._name.split('.')
+ return arr[0].strip()
+
+ def GetArch(self):
+ arr = self._name.split('.')
+ if len(arr) == 1:
+ return 'common'
+ return arr[1]
+
+ def IsArchMatch(self, arch):
+ if arch is None or self.GetArch() == 'common':
+ return True
+
+ if self.GetArch().lower() != arch.lower():
+ return False
+
+ return True
+
+class INFSectionObject(ini.BaseINISectionObject):
+ def GetArch(self):
+ return self.GetParent().GetArch()
+
+class INFDefineSectionObject(INFSectionObject):
+ def __init__(self, parent):
+ INFSectionObject.__init__(self, parent)
+ self._key = None
+ self._value = None
+
+ def Parse(self):
+ assert (self._start == self._end), 'The object in define section must be in single line'
+
+ line = self.GetLineByOffset(self._start).strip()
+
+ line = line.split('#')[0]
+ arr = line.split('=')
+ if len(arr) != 2:
+ ErrorMsg('Invalid define section object',
+ self.GetFilename(),
+ self._start
+ )
+ return False
+
+ self._key = arr[0].strip()
+ self._value = arr[1].strip()
+
+ return True
+
+ def GetKey(self):
+ return self._key
+
+ def GetValue(self):
+ return self._value
+
+class INFLibraryClassObject(INFSectionObject):
+ _objs = {}
+ def __init__(self, parent):
+ INFSectionObject.__init__(self, parent)
+ self._classname = None
+
+ def GetClass(self):
+ return self._classname
+
+ def Parse(self):
+ self._classname = self.GetLineByOffset(self._start).split('#')[0].strip()
+ objdict = INFLibraryClassObject._objs
+ if self._classname in objdict:
+ objdict[self._classname].append(self)
+ else:
+ objdict[self._classname] = [self]
+ return True
+
+ def Destroy(self):
+ objdict = INFLibraryClassObject._objs
+ objdict[self._classname].remove(self)
+ if len(objdict[self._classname]) == 0:
+ del objdict[self._classname]
+
+ def GetName(self):
+ return self._classname
+
+ @staticmethod
+ def GetObjectDict():
+ return INFLibraryClassObject._objs
+
+class INFDependentPackageObject(INFSectionObject):
+ def GetPath(self):
+ return self.GetLineByOffset(self._start).split('#')[0].strip()
+
+class INFSourceObject(INFSectionObject):
+ _objs = {}
+ def __init__(self, parent):
+ INFSectionObject.__init__(self, parent)
+
+ self.mSourcename = None
+ self.mToolCode = None
+ self.mFamily = None
+ self.mTagName = None
+ self.mFeaturePcd = None
+ self.mFilename = None
+
+ def GetSourcePath(self):
+ return self.mSourcename
+
+ def GetSourceFullPath(self):
+ path = os.path.dirname(self.GetFilename())
+ path = os.path.join(path, self.GetSourcePath())
+ return os.path.normpath(path)
+
+ def GetToolCode(self):
+ return self.mToolCode
+
+ def GetFamily(self):
+ return self.mFamily
+
+ def GetTagName(self):
+ return self.mTagName
+
+ def GetFeaturePcd(self):
+ return self.mFeaturePcd
+
+ def Parse(self):
+ line = self.GetLineByOffset(self._start).strip().split('#')[0]
+
+ arr = line.split('|')
+
+ self.mSourcename = arr[0].strip()
+ if len(arr) >= 2:
+ self.mFamily = arr[1].strip()
+ if len(arr) >= 3:
+ self.mTagName = arr[2].strip()
+ if len(arr) >= 4:
+ self.mToolCode = arr[3].strip()
+ if len(arr) >= 5:
+ self.mFeaturePcd = arr[4].strip()
+
+ self.mFilename = os.path.basename(self.GetSourceFullPath())
+ objdict = INFSourceObject._objs
+ if self.mFilename not in objdict:
+ objdict[self.mFilename] = [self]
+ else:
+ objdict[self.mFilename].append(self)
+
+ return True
+
+ def GetName(self):
+ return self.mFilename
+
+ def Destroy(self):
+ objdict = INFSourceObject._objs
+ objdict[self.mFilename].remove(self)
+ if len(objdict[self.mFilename]) == 0:
+ del objdict[self.mFilename]
+
+ def IsMatchFamily(self, family):
+ if family is None:
+ return True
+ if self.mFamily is not None:
+ if family.strip().lower() == self.mFamily.lower():
+ return True
+ else:
+ return False
+ else:
+ fname = self.GetSourcePath()
+ if fname.endswith('.S') and family.lower() != 'gcc':
+ return False
+ if fname.endswith('.s') and (self.GetArch().lower() != 'ipf' and self.GetArch().lower() != 'common'):
+ return False
+ if fname.lower().endswith('.asm') and (family.lower() != 'msft' and family.lower() != 'intel'):
+ return False
+ return True
+
+ @staticmethod
+ def GetObjectDict():
+ return INFSourceObject._objs
+
+class INFPcdObject(INFSectionObject):
+ _objs = {}
+
+ def __init__(self, parent):
+ INFSectionObject.__init__(self, parent)
+
+ self.mPcdType = None
+ self.mDefaultValue = None
+ self.mPcdName = None
+
+ @staticmethod
+ def GetObjectDict():
+ return INFPcdObject._objs
+
+ def Parse(self):
+ line = self.GetLineByOffset(self._start).strip().split('#')[0]
+
+ arr = line.split('|')
+ self.mPcdName = arr[0].strip()
+
+ if len(arr) >= 2:
+ self.mDefaultValue = arr[1].strip()
+
+ objdict = INFPcdObject._objs
+ if self.GetName() in objdict:
+ if self not in objdict[self.GetName()]:
+ objdict[self.GetName()].append(self)
+ else:
+ objdict[self.GetName()] = [self]
+ return True
+
+ def GetPcdName(self):
+ return self.mPcdName
+
+ def GetPcdType(self):
+ return self.GetParent().GetType()
+
+ def GetName(self):
+ return self.mPcdName.split('.')[1]
+
+ def Destroy(self):
+ objdict = INFPcdObject._objs
+ objdict[self.GetName()].remove(self)
+ if len(objdict[self.GetName()]) == 0:
+ del objdict[self.GetName()]
+
+class INFGuidObject(INFSectionObject):
+ def __init__(self, parent):
+ INFSectionObject.__init__(self, parent)
+ self._name = None
+
+ def Parse(self):
+ line = self.GetLineByOffset(self._start).strip().split('#')[0].split("|")[0]
+ self._name = line.strip()
+ return True
+
+ def GetName(self):
+ return self._name
+
+