Fix various typos in BaseTools. Signed-off-by: Cœur <coeur@gmx.fr> Reviewed-by: Bob Feng <bob.c.feng@intel.com>
		
			
				
	
	
		
			1085 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			1085 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| ## @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
 |