--- /dev/null
+## @file\r
+#\r
+# This file produce action class to generate doxygen document for edk2 codebase.\r
+# The action classes are shared by GUI and command line tools.\r
+#\r
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# This program and the accompanying materials are licensed and made available\r
+# under the terms and conditions of the BSD License which accompanies this\r
+# distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+import plugins.EdkPlugins.basemodel.doxygen as doxygen\r
+import os\r
+try:\r
+ import wx\r
+ gInGui = True\r
+except:\r
+ gInGui = False\r
+import re\r
+import plugins.EdkPlugins.edk2.model.inf as inf\r
+import plugins.EdkPlugins.edk2.model.dec as dec\r
+from plugins.EdkPlugins.basemodel.message import *\r
+\r
+_ignore_dir = ['.svn', '_svn', 'cvs']\r
+_inf_key_description_mapping_table = {\r
+ 'INF_VERSION':'Version of INF file specification',\r
+ #'BASE_NAME':'Module Name',\r
+ 'FILE_GUID':'Module Guid',\r
+ 'MODULE_TYPE': 'Module Type',\r
+ 'VERSION_STRING': 'Module Version',\r
+ 'LIBRARY_CLASS': 'Produced Library Class',\r
+ 'EFI_SPECIFICATION_VERSION': 'UEFI Specification Version',\r
+ 'PI_SPECIFICATION_VERSION': 'PI Specification Version',\r
+ 'ENTRY_POINT': 'Module Entry Point Function',\r
+ 'CONSTRUCTOR': 'Library Constructor Function'\r
+}\r
+\r
+_dec_key_description_mapping_table = {\r
+ 'DEC_SPECIFICATION': 'Version of DEC file specification',\r
+ 'PACKAGE_GUID': 'Package Guid'\r
+}\r
+class DoxygenAction:\r
+ """This is base class for all doxygen action.\r
+ """\r
+\r
+ def __init__(self, doxPath, chmPath, outputPath, projname, mode='html', log=None, verbose=False):\r
+ """Constructor function.\r
+ @param doxPath the obosolution path of doxygen execute file.\r
+ @param outputPath the obosolution output path.\r
+ @param log log function for output message\r
+ """\r
+ self._doxPath = doxPath\r
+ self._chmPath = chmPath\r
+ self._outputPath = outputPath\r
+ self._projname = projname\r
+ self._configFile = None # doxygen config file is used by doxygen exe file\r
+ self._indexPageFile = None # doxygen page file for index page.\r
+ self._log = log\r
+ self._mode = mode\r
+ self._verbose = verbose\r
+ self._doxygenCallback = None\r
+ self._chmCallback = None\r
+\r
+ def Log(self, message, level='info'):\r
+ if self._log != None:\r
+ self._log(message, level)\r
+\r
+ def IsVerbose(self):\r
+ return self._verbose\r
+\r
+ def Generate(self):\r
+ """Generate interface called by outer directly"""\r
+ self.Log(">>>>>> Start generate doxygen document for %s... Zzz....\n" % self._projname)\r
+\r
+ # create doxygen config file at first\r
+ self._configFile = doxygen.DoxygenConfigFile()\r
+ self._configFile.SetOutputDir(self._outputPath)\r
+\r
+ self._configFile.SetWarningFilePath(os.path.join(self._outputPath, 'warning.txt'))\r
+ if self._mode.lower() == 'html':\r
+ self._configFile.SetHtmlMode()\r
+ else:\r
+ self._configFile.SetChmMode()\r
+\r
+ self.Log(" >>>>>> Initialize doxygen config file...Zzz...\n")\r
+ self.InitializeConfigFile()\r
+\r
+ self.Log(" >>>>>> Generate doxygen index page file...Zzz...\n")\r
+ indexPagePath = self.GenerateIndexPage()\r
+ if indexPagePath == None:\r
+ self.Log("Fail to generate index page!\n", 'error')\r
+ return False\r
+ else:\r
+ self.Log("Success to create doxygen index page file %s \n" % indexPagePath)\r
+\r
+ # Add index page doxygen file to file list.\r
+ self._configFile.AddFile(indexPagePath)\r
+\r
+ # save config file to output path\r
+ configFilePath = os.path.join(self._outputPath, self._projname + '.doxygen_config')\r
+ self._configFile.Generate(configFilePath)\r
+ self.Log(" <<<<<< Success Save doxygen config file to %s...\n" % configFilePath)\r
+\r
+ # launch doxygen tool to generate document\r
+ if self._doxygenCallback != None:\r
+ self.Log(" >>>>>> Start doxygen process...Zzz...\n")\r
+ if not self._doxygenCallback(self._doxPath, configFilePath):\r
+ return False\r
+ else:\r
+ self.Log("Fail to create doxygen process!", 'error')\r
+ return False\r
+\r
+ return True\r
+\r
+ def InitializeConfigFile(self):\r
+ """Initialize config setting for doxygen project. It will be invoked after config file\r
+ object is created. Inherited class should implement it.\r
+ """\r
+\r
+ def GenerateIndexPage(self):\r
+ """Generate doxygen index page. Inherited class should implement it."""\r
+ return None\r
+\r
+ def RegisterCallbackDoxygenProcess(self, callback):\r
+ self._doxygenCallback = callback\r
+\r
+ def RegisterCallbackCHMProcess(self, callback):\r
+ self._chmCallback = callback\r
+\r
+class PlatformDocumentAction(DoxygenAction):\r
+ """Generate platform doxygen document, will be implement at future."""\r
+\r
+class PackageDocumentAction(DoxygenAction):\r
+ """Generate package reference document"""\r
+\r
+ def __init__(self, doxPath, chmPath, outputPath, pObj, mode='html', log=None, arch=None, tooltag=None,\r
+ macros=[], onlyInclude=False, verbose=False):\r
+ DoxygenAction.__init__(self, doxPath, chmPath, outputPath, pObj.GetName(), mode, log, verbose)\r
+ self._pObj = pObj\r
+ self._arch = arch\r
+ self._tooltag = tooltag\r
+ self._macros = macros\r
+ self._onlyIncludeDocument = onlyInclude\r
+\r
+ def InitializeConfigFile(self):\r
+ if self._arch == 'IA32':\r
+ self._configFile.AddPreDefined('MDE_CPU_IA32')\r
+ elif self._arch == 'X64':\r
+ self._configFile.AddPreDefined('MDE_CPU_X64')\r
+ elif self._arch == 'IPF':\r
+ self._configFile.AddPreDefined('MDE_CPU_IPF')\r
+ elif self._arch == 'EBC':\r
+ self._configFile.AddPreDefined('MDE_CPU_EBC')\r
+ else:\r
+ self._arch = None\r
+ self._configFile.AddPreDefined('MDE_CPU_IA32')\r
+ self._configFile.AddPreDefined('MDE_CPU_X64')\r
+ self._configFile.AddPreDefined('MDE_CPU_IPF')\r
+ self._configFile.AddPreDefined('MDE_CPU_EBC')\r
+ self._configFile.AddPreDefined('MDE_CPU_ARM')\r
+\r
+ for macro in self._macros:\r
+ self._configFile.AddPreDefined(macro)\r
+\r
+ namestr = self._pObj.GetName()\r
+ if self._arch != None:\r
+ namestr += '[%s]' % self._arch\r
+ if self._tooltag != None:\r
+ namestr += '[%s]' % self._tooltag\r
+ self._configFile.SetProjectName(namestr)\r
+ self._configFile.SetStripPath(self._pObj.GetWorkspace())\r
+ self._configFile.SetProjectVersion(self._pObj.GetFileObj().GetVersion())\r
+ self._configFile.AddPattern('*.decdoxygen')\r
+\r
+ if self._tooltag.lower() == 'msft':\r
+ self._configFile.AddPreDefined('_MSC_EXTENSIONS')\r
+ elif self._tooltag.lower() == 'gnu':\r
+ self._configFile.AddPreDefined('__GNUC__')\r
+ elif self._tooltag.lower() == 'intel':\r
+ self._configFile.AddPreDefined('__INTEL_COMPILER')\r
+ else:\r
+ self._tooltag = None\r
+ self._configFile.AddPreDefined('_MSC_EXTENSIONS')\r
+ self._configFile.AddPreDefined('__GNUC__')\r
+ self._configFile.AddPreDefined('__INTEL_COMPILER')\r
+\r
+ self._configFile.AddPreDefined('ASM_PFX= ')\r
+ self._configFile.AddPreDefined('OPTIONAL= ')\r
+\r
+ def GenerateIndexPage(self):\r
+ """Generate doxygen index page. Inherited class should implement it."""\r
+ fObj = self._pObj.GetFileObj()\r
+ pdObj = doxygen.DoxygenFile('%s Package Document' % self._pObj.GetName(),\r
+ '%s.decdoxygen' % self._pObj.GetFilename())\r
+ self._configFile.AddFile(pdObj.GetFilename())\r
+ pdObj.AddDescription(fObj.GetFileHeader())\r
+\r
+ defSection = fObj.GetSectionByName('defines')[0]\r
+ baseSection = doxygen.Section('PackageBasicInformation', 'Package Basic Information')\r
+ descr = '<TABLE>'\r
+ for obj in defSection.GetObjects():\r
+ if obj.GetKey() in _dec_key_description_mapping_table.keys():\r
+ descr += '<TR>'\r
+ descr += '<TD><B>%s</B></TD>' % _dec_key_description_mapping_table[obj.GetKey()]\r
+ descr += '<TD>%s</TD>' % obj.GetValue()\r
+ descr += '</TR>'\r
+ descr += '</TABLE><br>'\r
+ baseSection.AddDescription(descr)\r
+ pdObj.AddSection(baseSection)\r
+\r
+ knownIssueSection = doxygen.Section('Known_Issue_section', 'Known Issue')\r
+ knownIssueSection.AddDescription('<ul>')\r
+ knownIssueSection.AddDescription('<li> OPTIONAL macro for function parameter can not be dealed with doxygen, so it disapear in this document! </li>')\r
+ knownIssueSection.AddDescription('</ul>')\r
+ pdObj.AddSection(knownIssueSection)\r
+\r
+ self.AddAllIncludeFiles(self._pObj, self._configFile)\r
+ pages = self.GenerateIncludesSubPage(self._pObj, self._configFile)\r
+ if len(pages) != 0:\r
+ pdObj.AddPages(pages)\r
+ pages = self.GenerateLibraryClassesSubPage(self._pObj, self._configFile)\r
+ if len(pages) != 0:\r
+ pdObj.AddPages(pages)\r
+ pages = self.GeneratePcdSubPages(self._pObj, self._configFile)\r
+ if len(pages) != 0:\r
+ pdObj.AddPages(pages)\r
+ pages = self.GenerateGuidSubPages(self._pObj, self._configFile)\r
+ if len(pages) != 0:\r
+ pdObj.AddPages(pages)\r
+ pages = self.GeneratePpiSubPages(self._pObj, self._configFile)\r
+ if len(pages) != 0:\r
+ pdObj.AddPages(pages)\r
+ pages = self.GenerateProtocolSubPages(self._pObj, self._configFile)\r
+ if len(pages) != 0:\r
+ pdObj.AddPages(pages)\r
+ if not self._onlyIncludeDocument:\r
+ pdObj.AddPages(self.GenerateModulePages(self._pObj, self._configFile))\r
+\r
+ pdObj.Save()\r
+ return pdObj.GetFilename()\r
+\r
+ def GenerateIncludesSubPage(self, pObj, configFile):\r
+ # by default add following path as include path to config file\r
+ pkpath = pObj.GetFileObj().GetPackageRootPath()\r
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include'))\r
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Library'))\r
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Protocol'))\r
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Ppi'))\r
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Guid'))\r
+ configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'IndustryStandard'))\r
+\r
+ rootArray = []\r
+ pageRoot = doxygen.Page("Public Includes", "%s_public_includes" % pObj.GetName())\r
+ objs = pObj.GetFileObj().GetSectionObjectsByName('includes')\r
+ if len(objs) == 0: return []\r
+\r
+ for obj in objs:\r
+ # Add path to include path\r
+ path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetPath())\r
+ configFile.AddIncludePath(path)\r
+\r
+ # only list common folder's include file\r
+ if obj.GetArch().lower() != 'common':\r
+ continue\r
+\r
+ bNeedAddIncludePage = False\r
+ topPage = doxygen.Page(self._ConvertPathToDoxygen(path, pObj), 'public_include_top')\r
+\r
+ topPage.AddDescription('<ul>\n')\r
+ for file in os.listdir(path):\r
+ if file.lower() in _ignore_dir: continue\r
+ fullpath = os.path.join(path, file)\r
+ if os.path.isfile(fullpath):\r
+ self.ProcessSourceFileForInclude(fullpath, pObj, configFile)\r
+ topPage.AddDescription('<li> \link %s\endlink </li>\n' % self._ConvertPathToDoxygen(fullpath, pObj))\r
+ else:\r
+ if file.lower() in ['library', 'protocol', 'guid', 'ppi', 'ia32', 'x64', 'ipf', 'ebc', 'arm', 'pi', 'uefi', 'aarch64']:\r
+ continue\r
+ bNeedAddSubPage = False\r
+ subpage = doxygen.Page(self._ConvertPathToDoxygen(fullpath, pObj), 'public_include_%s' % file)\r
+ subpage.AddDescription('<ul>\n')\r
+ for subfile in os.listdir(fullpath):\r
+ if subfile.lower() in _ignore_dir: continue\r
+ bNeedAddSubPage = True\r
+ subfullpath = os.path.join(fullpath, subfile)\r
+ self.ProcessSourceFileForInclude(subfullpath, pObj, configFile)\r
+ subpage.AddDescription('<li> \link %s \endlink </li>\n' % self._ConvertPathToDoxygen(subfullpath, pObj))\r
+ subpage.AddDescription('</ul>\n')\r
+ if bNeedAddSubPage:\r
+ bNeedAddIncludePage = True\r
+ pageRoot.AddPage(subpage)\r
+ topPage.AddDescription('</ul>\n')\r
+ if bNeedAddIncludePage:\r
+ pageRoot.AddPage(topPage)\r
+\r
+ if pageRoot.GetSubpageCount() != 0:\r
+ return [pageRoot]\r
+ else:\r
+ return []\r
+\r
+ def GenerateLibraryClassesSubPage(self, pObj, configFile):\r
+ """\r
+ Generate sub page for library class for package.\r
+ One DEC file maybe contains many library class sections\r
+ for different architecture.\r
+\r
+ @param fObj DEC file object.\r
+ """\r
+ rootArray = []\r
+ pageRoot = doxygen.Page("Library Class", "%s_libraryclass" % pObj.GetName())\r
+ objs = pObj.GetFileObj().GetSectionObjectsByName('libraryclass', self._arch)\r
+ if len(objs) == 0: return []\r
+\r
+ if self._arch != None:\r
+ for obj in objs:\r
+ classPage = doxygen.Page(obj.GetClassName(),\r
+ "lc_%s" % obj.GetClassName())\r
+ comments = obj.GetComment()\r
+ if len(comments) != 0:\r
+ classPage.AddDescription('<br>\n'.join(comments) + '<br>\n')\r
+ pageRoot.AddPage(classPage)\r
+ path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())\r
+ path = path[len(pObj.GetWorkspace()) + 1:]\r
+ if len(comments) == 0:\r
+ classPage.AddDescription('\copydoc %s<p>' % obj.GetHeaderFile())\r
+ section = doxygen.Section('ref', 'Refer to Header File')\r
+ section.AddDescription('\link %s\n' % obj.GetHeaderFile())\r
+ section.AddDescription(' \endlink<p>\n')\r
+ classPage.AddSection(section)\r
+ fullPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())\r
+ self.ProcessSourceFileForInclude(fullPath, pObj, configFile)\r
+ else:\r
+ archPageDict = {}\r
+ for obj in objs:\r
+ if obj.GetArch() not in archPageDict.keys():\r
+ archPageDict[obj.GetArch()] = doxygen.Page(obj.GetArch(),\r
+ 'lc_%s' % obj.GetArch())\r
+ pageRoot.AddPage(archPageDict[obj.GetArch()])\r
+ subArchRoot = archPageDict[obj.GetArch()]\r
+ classPage = doxygen.Page(obj.GetClassName(),\r
+ "lc_%s" % obj.GetClassName())\r
+ comments = obj.GetComment()\r
+ if len(comments) != 0:\r
+ classPage.AddDescription('<br>\n'.join(comments) + '<br>\n')\r
+ subArchRoot.AddPage(classPage)\r
+ path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())\r
+ path = path[len(pObj.GetWorkspace()) + 1:]\r
+ if len(comments) == 0:\r
+ classPage.AddDescription('\copydoc %s<p>' % obj.GetHeaderFile())\r
+ section = doxygen.Section('ref', 'Refer to Header File')\r
+ section.AddDescription('\link %s\n' % obj.GetHeaderFile())\r
+ section.AddDescription(' \endlink<p>\n')\r
+ classPage.AddSection(section)\r
+ fullPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())\r
+\r
+ self.ProcessSourceFileForInclude(fullPath, pObj, configFile)\r
+ rootArray.append(pageRoot)\r
+ return rootArray\r
+\r
+ def ProcessSourceFileForInclude(self, path, pObj, configFile, infObj=None):\r
+ """\r
+ @param path the analysising file full path\r
+ @param pObj package object\r
+ @param configFile doxygen config file.\r
+ """\r
+\r
+ if gInGui:\r
+ wx.Yield()\r
+ if not os.path.exists(path):\r
+ ErrorMsg('Source file path %s does not exist!' % path)\r
+ return\r
+\r
+ if configFile.FileExists(path):\r
+ return\r
+\r
+ try:\r
+ f = open(path, 'r')\r
+ lines = f.readlines()\r
+ f.close()\r
+ except IOError:\r
+ ErrorMsg('Fail to open file %s' % path)\r
+ return\r
+\r
+ configFile.AddFile(path)\r
+ return\r
+ no = 0\r
+ for no in xrange(len(lines)):\r
+ if len(lines[no].strip()) == 0:\r
+ continue\r
+ if lines[no].strip()[:2] in ['##', '//', '/*', '*/']:\r
+ continue\r
+ index = lines[no].lower().find('include')\r
+ #mo = IncludePattern.finditer(lines[no].lower())\r
+ mo = re.match(r"^#\s*include\s+[<\"]([\\/\w.]+)[>\"]$", lines[no].strip().lower())\r
+ if not mo:\r
+ continue\r
+ mo = re.match(r"^[#\w\s]+[<\"]([\\/\w.]+)[>\"]$", lines[no].strip())\r
+ filePath = mo.groups()[0]\r
+\r
+ if filePath == None or len(filePath) == 0:\r
+ continue\r
+\r
+ # find header file in module's path firstly.\r
+ fullPath = None\r
+\r
+ if os.path.exists(os.path.join(os.path.dirname(path), filePath)):\r
+ # Find the file in current directory\r
+ fullPath = os.path.join(os.path.dirname(path), filePath).replace('\\', '/')\r
+ else:\r
+ # find in depedent package's include path\r
+ incObjs = pObj.GetFileObj().GetSectionObjectsByName('includes')\r
+ for incObj in incObjs:\r
+ incPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), incObj.GetPath()).strip()\r
+ incPath = os.path.realpath(os.path.join(incPath, filePath))\r
+ if os.path.exists(incPath):\r
+ fullPath = incPath\r
+ break\r
+ if infObj != None:\r
+ pkgInfObjs = infObj.GetSectionObjectsByName('packages')\r
+ for obj in pkgInfObjs:\r
+ decObj = dec.DECFile(os.path.join(pObj.GetWorkspace(), obj.GetPath()))\r
+ if not decObj:\r
+ ErrorMsg ('Fail to create pacakge object for %s' % obj.GetPackageName())\r
+ continue\r
+ if not decObj.Parse():\r
+ ErrorMsg ('Fail to load package object for %s' % obj.GetPackageName())\r
+ continue\r
+ incObjs = decObj.GetSectionObjectsByName('includes')\r
+ for incObj in incObjs:\r
+ incPath = os.path.join(decObj.GetPackageRootPath(), incObj.GetPath()).replace('\\', '/')\r
+ if os.path.exists(os.path.join(incPath, filePath)):\r
+ fullPath = os.path.join(os.path.join(incPath, filePath))\r
+ break\r
+ if fullPath != None:\r
+ break\r
+\r
+ if fullPath == None and self.IsVerbose():\r
+ self.Log('Can not resolve header file %s for file %s in package %s\n' % (filePath, path, pObj.GetFileObj().GetFilename()), 'error')\r
+ return\r
+ else:\r
+ fullPath = fullPath.replace('\\', '/')\r
+ if self.IsVerbose():\r
+ self.Log('Preprocessing: Add include file %s for file %s\n' % (fullPath, path))\r
+ #LogMsg ('Preprocessing: Add include file %s for file %s' % (fullPath, path))\r
+ self.ProcessSourceFileForInclude(fullPath, pObj, configFile, infObj)\r
+\r
+ def AddAllIncludeFiles(self, pObj, configFile):\r
+ objs = pObj.GetFileObj().GetSectionObjectsByName('includes')\r
+ for obj in objs:\r
+ incPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetPath())\r
+ for root, dirs, files in os.walk(incPath):\r
+ for dir in dirs:\r
+ if dir.lower() in _ignore_dir:\r
+ dirs.remove(dir)\r
+ for file in files:\r
+ path = os.path.normpath(os.path.join(root, file))\r
+ configFile.AddFile(path.replace('/', '\\'))\r
+\r
+ def GeneratePcdSubPages(self, pObj, configFile):\r
+ """\r
+ Generate sub pages for package's PCD definition.\r
+ @param pObj package object\r
+ @param configFile config file object\r
+ """\r
+ rootArray = []\r
+ objs = pObj.GetFileObj().GetSectionObjectsByName('pcd')\r
+ if len(objs) == 0:\r
+ return []\r
+\r
+ pcdRootPage = doxygen.Page('PCD', 'pcd_root_page')\r
+ typeRootPageDict = {}\r
+ typeArchRootPageDict = {}\r
+ for obj in objs:\r
+ if obj.GetPcdType() not in typeRootPageDict.keys():\r
+ typeRootPageDict[obj.GetPcdType()] = doxygen.Page(obj.GetPcdType(), 'pcd_%s_root_page' % obj.GetPcdType())\r
+ pcdRootPage.AddPage(typeRootPageDict[obj.GetPcdType()])\r
+ typeRoot = typeRootPageDict[obj.GetPcdType()]\r
+ if self._arch != None:\r
+ pcdPage = doxygen.Page('%s' % obj.GetPcdName(),\r
+ 'pcd_%s_%s_%s' % (obj.GetPcdType(), obj.GetArch(), obj.GetPcdName().split('.')[1]))\r
+ pcdPage.AddDescription('<br>\n'.join(obj.GetComment()) + '<br>\n')\r
+ section = doxygen.Section('PCDinformation', 'PCD Information')\r
+ desc = '<TABLE>'\r
+ desc += '<TR>'\r
+ desc += '<TD><CAPTION>Name</CAPTION></TD>'\r
+ desc += '<TD><CAPTION>Token Space</CAPTION></TD>'\r
+ desc += '<TD><CAPTION>Token number</CAPTION></TD>'\r
+ desc += '<TD><CAPTION>Data Type</CAPTION></TD>'\r
+ desc += '<TD><CAPTION>Default Value</CAPTION></TD>'\r
+ desc += '</TR>'\r
+ desc += '<TR>'\r
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[1]\r
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[0]\r
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdToken()\r
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdDataType()\r
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdValue()\r
+ desc += '</TR>'\r
+ desc += '</TABLE>'\r
+ section.AddDescription(desc)\r
+ pcdPage.AddSection(section)\r
+ typeRoot.AddPage(pcdPage)\r
+ else:\r
+ keystr = obj.GetPcdType() + obj.GetArch()\r
+ if keystr not in typeArchRootPageDict.keys():\r
+ typeArchRootPage = doxygen.Page(obj.GetArch(), 'pcd_%s_%s_root_page' % (obj.GetPcdType(), obj.GetArch()))\r
+ typeArchRootPageDict[keystr] = typeArchRootPage\r
+ typeRoot.AddPage(typeArchRootPage)\r
+ typeArchRoot = typeArchRootPageDict[keystr]\r
+ pcdPage = doxygen.Page('%s' % obj.GetPcdName(),\r
+ 'pcd_%s_%s_%s' % (obj.GetPcdType(), obj.GetArch(), obj.GetPcdName().split('.')[1]))\r
+ pcdPage.AddDescription('<br>\n'.join(obj.GetComment()) + '<br>\n')\r
+ section = doxygen.Section('PCDinformation', 'PCD Information')\r
+ desc = '<TABLE>'\r
+ desc += '<TR>'\r
+ desc += '<TD><CAPTION>Name</CAPTION></TD>'\r
+ desc += '<TD><CAPTION>Token Space</CAPTION></TD>'\r
+ desc += '<TD><CAPTION>Token number</CAPTION></TD>'\r
+ desc += '<TD><CAPTION>Data Type</CAPTION></TD>'\r
+ desc += '<TD><CAPTION>Default Value</CAPTION></TD>'\r
+ desc += '</TR>'\r
+ desc += '<TR>'\r
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[1]\r
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[0]\r
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdToken()\r
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdDataType()\r
+ desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdValue()\r
+ desc += '</TR>'\r
+ desc += '</TABLE>'\r
+ section.AddDescription(desc)\r
+ pcdPage.AddSection(section)\r
+ typeArchRoot.AddPage(pcdPage)\r
+ return [pcdRootPage]\r
+\r
+ def _GenerateGuidSubPage(self, pObj, obj, configFile):\r
+ guidPage = doxygen.Page('%s' % obj.GetName(),\r
+ 'guid_%s_%s' % (obj.GetArch(), obj.GetName()))\r
+ comments = obj.GetComment()\r
+ if len(comments) != 0:\r
+ guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')\r
+ section = doxygen.Section('BasicGuidInfo', 'GUID Information')\r
+ desc = '<TABLE>'\r
+ desc += '<TR>'\r
+ desc += '<TD><CAPTION>GUID\'s Guid Name</CAPTION></TD><TD><CAPTION>GUID\'s Guid</CAPTION></TD>'\r
+ desc += '</TR>'\r
+ desc += '<TR>'\r
+ desc += '<TD>%s</TD>' % obj.GetName()\r
+ desc += '<TD>%s</TD>' % obj.GetGuid()\r
+ desc += '</TR>'\r
+ desc += '</TABLE>'\r
+ section.AddDescription(desc)\r
+ guidPage.AddSection(section)\r
+ refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)\r
+ if refFile:\r
+ relPath = refFile[len(pObj.GetWorkspace()) + 1:]\r
+ if len(comments) == 0:\r
+ guidPage.AddDescription(' \\copydoc %s <br>' % relPath)\r
+\r
+ section = doxygen.Section('ref', 'Refer to Header File')\r
+ section.AddDescription('\link %s\n' % relPath)\r
+ section.AddDescription('\endlink\n')\r
+ self.ProcessSourceFileForInclude(refFile, pObj, configFile)\r
+ guidPage.AddSection(section)\r
+ return guidPage\r
+\r
+ def GenerateGuidSubPages(self, pObj, configFile):\r
+ """\r
+ Generate sub pages for package's GUID definition.\r
+ @param pObj package object\r
+ @param configFilf doxygen config file object\r
+ """\r
+ pageRoot = doxygen.Page('GUID', 'guid_root_page')\r
+ objs = pObj.GetFileObj().GetSectionObjectsByName('guids', self._arch)\r
+ if len(objs) == 0: return []\r
+ if self._arch != None:\r
+ for obj in objs:\r
+ pageRoot.AddPage(self._GenerateGuidSubPage(pObj, obj, configFile))\r
+ else:\r
+ guidArchRootPageDict = {}\r
+ for obj in objs:\r
+ if obj.GetArch() not in guidArchRootPageDict.keys():\r
+ guidArchRoot = doxygen.Page(obj.GetArch(), 'guid_arch_root_%s' % obj.GetArch())\r
+ pageRoot.AddPage(guidArchRoot)\r
+ guidArchRootPageDict[obj.GetArch()] = guidArchRoot\r
+ guidArchRoot = guidArchRootPageDict[obj.GetArch()]\r
+ guidArchRoot.AddPage(self._GenerateGuidSubPage(pObj, obj, configFile))\r
+ return [pageRoot]\r
+\r
+ def _GeneratePpiSubPage(self, pObj, obj, configFile):\r
+ guidPage = doxygen.Page(obj.GetName(), 'ppi_page_%s' % obj.GetName())\r
+ comments = obj.GetComment()\r
+ if len(comments) != 0:\r
+ guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')\r
+ section = doxygen.Section('BasicPpiInfo', 'PPI Information')\r
+ desc = '<TABLE>'\r
+ desc += '<TR>'\r
+ desc += '<TD><CAPTION>PPI\'s Guid Name</CAPTION></TD><TD><CAPTION>PPI\'s Guid</CAPTION></TD>'\r
+ desc += '</TR>'\r
+ desc += '<TR>'\r
+ desc += '<TD>%s</TD>' % obj.GetName()\r
+ desc += '<TD>%s</TD>' % obj.GetGuid()\r
+ desc += '</TR>'\r
+ desc += '</TABLE>'\r
+ section.AddDescription(desc)\r
+ guidPage.AddSection(section)\r
+ refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)\r
+ if refFile:\r
+ relPath = refFile[len(pObj.GetWorkspace()) + 1:]\r
+ if len(comments) == 0:\r
+ guidPage.AddDescription(' \\copydoc %s <br>' % relPath)\r
+ section = doxygen.Section('ref', 'Refer to Header File')\r
+ section.AddDescription('\link %s\n' % relPath)\r
+ section.AddDescription('\endlink\n')\r
+ self.ProcessSourceFileForInclude(refFile, pObj, configFile)\r
+ guidPage.AddSection(section)\r
+\r
+ return guidPage\r
+\r
+ def GeneratePpiSubPages(self, pObj, configFile):\r
+ """\r
+ Generate sub pages for package's GUID definition.\r
+ @param pObj package object\r
+ @param configFilf doxygen config file object\r
+ """\r
+ pageRoot = doxygen.Page('PPI', 'ppi_root_page')\r
+ objs = pObj.GetFileObj().GetSectionObjectsByName('ppis', self._arch)\r
+ if len(objs) == 0: return []\r
+ if self._arch != None:\r
+ for obj in objs:\r
+ pageRoot.AddPage(self._GeneratePpiSubPage(pObj, obj, configFile))\r
+ else:\r
+ guidArchRootPageDict = {}\r
+ for obj in objs:\r
+ if obj.GetArch() not in guidArchRootPageDict.keys():\r
+ guidArchRoot = doxygen.Page(obj.GetArch(), 'ppi_arch_root_%s' % obj.GetArch())\r
+ pageRoot.AddPage(guidArchRoot)\r
+ guidArchRootPageDict[obj.GetArch()] = guidArchRoot\r
+ guidArchRoot = guidArchRootPageDict[obj.GetArch()]\r
+ guidArchRoot.AddPage(self._GeneratePpiSubPage(pObj, obj, configFile))\r
+ return [pageRoot]\r
+\r
+ def _GenerateProtocolSubPage(self, pObj, obj, configFile):\r
+ guidPage = doxygen.Page(obj.GetName(), 'protocol_page_%s' % obj.GetName())\r
+ comments = obj.GetComment()\r
+ if len(comments) != 0:\r
+ guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')\r
+ section = doxygen.Section('BasicProtocolInfo', 'PROTOCOL Information')\r
+ desc = '<TABLE>'\r
+ desc += '<TR>'\r
+ desc += '<TD><CAPTION>PROTOCOL\'s Guid Name</CAPTION></TD><TD><CAPTION>PROTOCOL\'s Guid</CAPTION></TD>'\r
+ desc += '</TR>'\r
+ desc += '<TR>'\r
+ desc += '<TD>%s</TD>' % obj.GetName()\r
+ desc += '<TD>%s</TD>' % obj.GetGuid()\r
+ desc += '</TR>'\r
+ desc += '</TABLE>'\r
+ section.AddDescription(desc)\r
+ guidPage.AddSection(section)\r
+\r
+ refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)\r
+ if refFile:\r
+ relPath = refFile[len(pObj.GetWorkspace()) + 1:]\r
+ if len(comments) == 0:\r
+ guidPage.AddDescription(' \\copydoc %s <br>' % relPath)\r
+ section = doxygen.Section('ref', 'Refer to Header File')\r
+ section.AddDescription('\link %s\n' % relPath)\r
+ section.AddDescription('\endlink\n')\r
+ self.ProcessSourceFileForInclude(refFile, pObj, configFile)\r
+ guidPage.AddSection(section)\r
+\r
+ return guidPage\r
+\r
+ def GenerateProtocolSubPages(self, pObj, configFile):\r
+ """\r
+ Generate sub pages for package's GUID definition.\r
+ @param pObj package object\r
+ @param configFilf doxygen config file object\r
+ """\r
+ pageRoot = doxygen.Page('PROTOCOL', 'protocol_root_page')\r
+ objs = pObj.GetFileObj().GetSectionObjectsByName('protocols', self._arch)\r
+ if len(objs) == 0: return []\r
+ if self._arch != None:\r
+ for obj in objs:\r
+ pageRoot.AddPage(self._GenerateProtocolSubPage(pObj, obj, configFile))\r
+ else:\r
+ guidArchRootPageDict = {}\r
+ for obj in objs:\r
+ if obj.GetArch() not in guidArchRootPageDict.keys():\r
+ guidArchRoot = doxygen.Page(obj.GetArch(), 'protocol_arch_root_%s' % obj.GetArch())\r
+ pageRoot.AddPage(guidArchRoot)\r
+ guidArchRootPageDict[obj.GetArch()] = guidArchRoot\r
+ guidArchRoot = guidArchRootPageDict[obj.GetArch()]\r
+ guidArchRoot.AddPage(self._GenerateProtocolSubPage(pObj, obj, configFile))\r
+ return [pageRoot]\r
+\r
+ def FindHeaderFileForGuid(self, pObj, name, configFile):\r
+ """\r
+ For declaration header file for GUID/PPI/Protocol.\r
+\r
+ @param pObj package object\r
+ @param name guid/ppi/protocol's name\r
+ @param configFile config file object\r
+\r
+ @return full path of header file and None if not found.\r
+ """\r
+ startPath = pObj.GetFileObj().GetPackageRootPath()\r
+ incPath = os.path.join(startPath, 'Include').replace('\\', '/')\r
+ # if <PackagePath>/include exist, then search header under it.\r
+ if os.path.exists(incPath):\r
+ startPath = incPath\r
+\r
+ for root, dirs, files in os.walk(startPath):\r
+ for dir in dirs:\r
+ if dir.lower() in _ignore_dir:\r
+ dirs.remove(dir)\r
+ for file in files:\r
+ fPath = os.path.join(root, file)\r
+ if not IsCHeaderFile(fPath):\r
+ continue\r
+ try:\r
+ f = open(fPath, 'r')\r
+ lines = f.readlines()\r
+ f.close()\r
+ except IOError:\r
+ self.Log('Fail to open file %s\n' % fPath)\r
+ continue\r
+ for line in lines:\r
+ if line.find(name) != -1 and \\r
+ line.find('extern') != -1:\r
+ return fPath.replace('\\', '/')\r
+ return None\r
+\r
+ def GetPackageModuleList(self, pObj):\r
+ """\r
+ Get all module's INF path under package's root path\r
+ @param pObj package object\r
+ @return arrary of INF full path\r
+ """\r
+ mArray = []\r
+ packPath = pObj.GetFileObj().GetPackageRootPath()\r
+ if not os.path.exists:\r
+ return None\r
+ for root, dirs, files in os.walk(packPath):\r
+ for dir in dirs:\r
+ if dir.lower() in _ignore_dir:\r
+ dirs.remove(dir)\r
+ for file in files:\r
+ if CheckPathPostfix(file, 'inf'):\r
+ fPath = os.path.join(root, file).replace('\\', '/')\r
+ mArray.append(fPath)\r
+ return mArray\r
+\r
+ def GenerateModulePages(self, pObj, configFile):\r
+ """\r
+ Generate sub pages for package's module which is under the package\r
+ root directory.\r
+\r
+ @param pObj package object\r
+ @param configFilf doxygen config file object\r
+ """\r
+ infList = self.GetPackageModuleList(pObj)\r
+ rootPages = []\r
+ libObjs = []\r
+ modObjs = []\r
+ for infpath in infList:\r
+ infObj = inf.INFFile(infpath)\r
+ #infObj = INFFileObject.INFFile (pObj.GetWorkspacePath(),\r
+ # inf)\r
+ if not infObj:\r
+ self.Log('Fail create INF object for %s' % inf)\r
+ continue\r
+ if not infObj.Parse():\r
+ self.Log('Fail to load INF file %s' % inf)\r
+ continue\r
+ if infObj.GetProduceLibraryClass() != None:\r
+ libObjs.append(infObj)\r
+ else:\r
+ modObjs.append(infObj)\r
+\r
+ if len(libObjs) != 0:\r
+ libRootPage = doxygen.Page('Libraries', 'lib_root_page')\r
+ rootPages.append(libRootPage)\r
+ for libInf in libObjs:\r
+ libRootPage.AddPage(self.GenerateModulePage(pObj, libInf, configFile, True))\r
+\r
+ if len(modObjs) != 0:\r
+ modRootPage = doxygen.Page('Modules', 'module_root_page')\r
+ rootPages.append(modRootPage)\r
+ for modInf in modObjs:\r
+ modRootPage.AddPage(self.GenerateModulePage(pObj, modInf, configFile, False))\r
+\r
+ return rootPages\r
+\r
+ def GenerateModulePage(self, pObj, infObj, configFile, isLib):\r
+ """\r
+ Generate page for a module/library.\r
+ @param infObj INF file object for module/library\r
+ @param configFile doxygen config file object\r
+ @param isLib Whether this module is libary\r
+\r
+ @param module doxygen page object\r
+ """\r
+ workspace = pObj.GetWorkspace()\r
+ refDecObjs = []\r
+ for obj in infObj.GetSectionObjectsByName('packages'):\r
+ decObj = dec.DECFile(os.path.join(workspace, obj.GetPath()))\r
+ if not decObj:\r
+ ErrorMsg ('Fail to create pacakge object for %s' % obj.GetPackageName())\r
+ continue\r
+ if not decObj.Parse():\r
+ ErrorMsg ('Fail to load package object for %s' % obj.GetPackageName())\r
+ continue\r
+ refDecObjs.append(decObj)\r
+\r
+ modPage = doxygen.Page('%s' % infObj.GetBaseName(),\r
+ 'module_%s' % infObj.GetBaseName())\r
+ modPage.AddDescription(infObj.GetFileHeader())\r
+\r
+ basicInfSection = doxygen.Section('BasicModuleInformation', 'Basic Module Information')\r
+ desc = "<TABLE>"\r
+ for obj in infObj.GetSectionObjectsByName('defines'):\r
+ key = obj.GetKey()\r
+ value = obj.GetValue()\r
+ if key not in _inf_key_description_mapping_table.keys(): continue\r
+ if key == 'LIBRARY_CLASS' and value.find('|') != -1:\r
+ clsname, types = value.split('|')\r
+ desc += '<TR>'\r
+ desc += '<TD><B>%s</B></TD>' % _inf_key_description_mapping_table[key]\r
+ desc += '<TD>%s</TD>' % clsname\r
+ desc += '</TR>'\r
+\r
+ desc += '<TR>'\r
+ desc += '<TD><B>Supported Module Types</B></TD>'\r
+ desc += '<TD>%s</TD>' % types\r
+ desc += '</TR>'\r
+ else:\r
+ desc += '<TR>'\r
+ desc += '<TD><B>%s</B></TD>' % _inf_key_description_mapping_table[key]\r
+ if key == 'EFI_SPECIFICATION_VERSION' and value == '0x00020000':\r
+ value = '2.0'\r
+ desc += '<TD>%s</TD>' % value\r
+ desc += '</TR>'\r
+ desc += '</TABLE>'\r
+ basicInfSection.AddDescription(desc)\r
+ modPage.AddSection(basicInfSection)\r
+\r
+ # Add protocol section\r
+ data = []\r
+ for obj in infObj.GetSectionObjectsByName('pcd', self._arch):\r
+ data.append(obj.GetPcdName().strip())\r
+ if len(data) != 0:\r
+ s = doxygen.Section('Pcds', 'Pcds')\r
+ desc = "<TABLE>"\r
+ desc += '<TR><TD><B>PCD Name</B></TD><TD><B>TokenSpace</B></TD><TD><B>Package</B></TD></TR>'\r
+ for item in data:\r
+ desc += '<TR>'\r
+ desc += '<TD>%s</TD>' % item.split('.')[1]\r
+ desc += '<TD>%s</TD>' % item.split('.')[0]\r
+ pkgbasename = self.SearchPcdPackage(item, workspace, refDecObjs)\r
+ desc += '<TD>%s</TD>' % pkgbasename\r
+ desc += '</TR>'\r
+ desc += "</TABLE>"\r
+ s.AddDescription(desc)\r
+ modPage.AddSection(s)\r
+\r
+ # Add protocol section\r
+ #sects = infObj.GetSectionByString('protocol')\r
+ data = []\r
+ #for sect in sects:\r
+ for obj in infObj.GetSectionObjectsByName('protocol', self._arch):\r
+ data.append(obj.GetName().strip())\r
+ if len(data) != 0:\r
+ s = doxygen.Section('Protocols', 'Protocols')\r
+ desc = "<TABLE>"\r
+ desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'\r
+ for item in data:\r
+ desc += '<TR>'\r
+ desc += '<TD>%s</TD>' % item\r
+ pkgbasename = self.SearchProtocolPackage(item, workspace, refDecObjs)\r
+ desc += '<TD>%s</TD>' % pkgbasename\r
+ desc += '</TR>'\r
+ desc += "</TABLE>"\r
+ s.AddDescription(desc)\r
+ modPage.AddSection(s)\r
+\r
+ # Add ppi section\r
+ #sects = infObj.GetSectionByString('ppi')\r
+ data = []\r
+ #for sect in sects:\r
+ for obj in infObj.GetSectionObjectsByName('ppi', self._arch):\r
+ data.append(obj.GetName().strip())\r
+ if len(data) != 0:\r
+ s = doxygen.Section('Ppis', 'Ppis')\r
+ desc = "<TABLE>"\r
+ desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'\r
+ for item in data:\r
+ desc += '<TR>'\r
+ desc += '<TD>%s</TD>' % item\r
+ pkgbasename = self.SearchPpiPackage(item, workspace, refDecObjs)\r
+ desc += '<TD>%s</TD>' % pkgbasename\r
+ desc += '</TR>'\r
+ desc += "</TABLE>"\r
+ s.AddDescription(desc)\r
+ modPage.AddSection(s)\r
+\r
+ # Add guid section\r
+ #sects = infObj.GetSectionByString('guid')\r
+ data = []\r
+ #for sect in sects:\r
+ for obj in infObj.GetSectionObjectsByName('guid', self._arch):\r
+ data.append(obj.GetName().strip())\r
+ if len(data) != 0:\r
+ s = doxygen.Section('Guids', 'Guids')\r
+ desc = "<TABLE>"\r
+ desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'\r
+ for item in data:\r
+ desc += '<TR>'\r
+ desc += '<TD>%s</TD>' % item\r
+ pkgbasename = self.SearchGuidPackage(item, workspace, refDecObjs)\r
+ desc += '<TD>%s</TD>' % pkgbasename\r
+ desc += '</TR>'\r
+ desc += "</TABLE>"\r
+ s.AddDescription(desc)\r
+ modPage.AddSection(s)\r
+\r
+ section = doxygen.Section('LibraryClasses', 'Library Classes')\r
+ desc = "<TABLE>"\r
+ desc += '<TR><TD><B>Name</B></TD><TD><B>Type</B></TD><TD><B>Package</B></TD><TD><B>Header File</B></TD></TR>'\r
+ if isLib:\r
+ desc += '<TR>'\r
+ desc += '<TD>%s</TD>' % infObj.GetProduceLibraryClass()\r
+ desc += '<TD>Produce</TD>'\r
+ try:\r
+ pkgname, hPath = self.SearchLibraryClassHeaderFile(infObj.GetProduceLibraryClass(),\r
+ workspace,\r
+ refDecObjs)\r
+ except:\r
+ self.Log ('fail to get package header file for lib class %s' % infObj.GetProduceLibraryClass())\r
+ pkgname = 'NULL'\r
+ hPath = 'NULL'\r
+ desc += '<TD>%s</TD>' % pkgname\r
+ if hPath != "NULL":\r
+ #desc += '<TD>\link %s \endlink</TD>' % hPath\r
+ desc += '<TD>%s</TD>' % hPath\r
+ else:\r
+ desc += '<TD>%s</TD>' % hPath\r
+ desc += '</TR>'\r
+ for lcObj in infObj.GetSectionObjectsByName('libraryclasses', self._arch):\r
+ desc += '<TR>'\r
+ desc += '<TD>%s</TD>' % lcObj.GetClass()\r
+ retarr = self.SearchLibraryClassHeaderFile(lcObj.GetClass(),\r
+ workspace,\r
+ refDecObjs)\r
+ if retarr != None:\r
+ pkgname, hPath = retarr\r
+ else:\r
+ self.Log('Fail find the library class %s definition from module %s dependent package!' % (lcObj.GetClass(), infObj.GetFilename()), 'error')\r
+ pkgname = 'NULL'\r
+ hPath = 'NULL'\r
+ desc += '<TD>Consume</TD>'\r
+ desc += '<TD>%s</TD>' % pkgname\r
+ desc += '<TD>%s</TD>' % hPath\r
+ desc += '</TR>'\r
+ desc += "</TABLE>"\r
+ section.AddDescription(desc)\r
+ modPage.AddSection(section)\r
+\r
+ section = doxygen.Section('SourceFiles', 'Source Files')\r
+ section.AddDescription('<ul>\n')\r
+ for obj in infObj.GetSourceObjects(self._arch, self._tooltag):\r
+ sPath = infObj.GetModuleRootPath()\r
+ sPath = os.path.join(sPath, obj.GetSourcePath()).replace('\\', '/').strip()\r
+ if sPath.lower().endswith('.uni') or sPath.lower().endswith('.s') or sPath.lower().endswith('.asm') or sPath.lower().endswith('.nasm'):\r
+ newPath = self.TranslateUniFile(sPath)\r
+ configFile.AddFile(newPath)\r
+ newPath = newPath[len(pObj.GetWorkspace()) + 1:]\r
+ section.AddDescription('<li> \link %s \endlink </li>' % newPath)\r
+ else:\r
+ self.ProcessSourceFileForInclude(sPath, pObj, configFile, infObj)\r
+ sPath = sPath[len(pObj.GetWorkspace()) + 1:]\r
+ section.AddDescription('<li>\link %s \endlink </li>' % sPath)\r
+ section.AddDescription('</ul>\n')\r
+ modPage.AddSection(section)\r
+\r
+ #sects = infObj.GetSectionByString('depex')\r
+ data = []\r
+ #for sect in sects:\r
+ for obj in infObj.GetSectionObjectsByName('depex'):\r
+ data.append(str(obj))\r
+ if len(data) != 0:\r
+ s = doxygen.Section('DependentSection', 'Module Dependencies')\r
+ s.AddDescription('<br>'.join(data))\r
+ modPage.AddSection(s)\r
+\r
+ return modPage\r
+\r
+ def TranslateUniFile(self, path):\r
+ newpath = path + '.dox'\r
+ #import core.textfile as textfile\r
+ #file = textfile.TextFile(path)\r
+\r
+ try:\r
+ file = open(path, 'rb')\r
+ except (IOError, OSError), msg:\r
+ return None\r
+\r
+ t = file.read()\r
+ file.close()\r
+\r
+ output = '/** @file \n'\r
+ #output = '<html><body>'\r
+ arr = t.split('\r\n')\r
+ for line in arr:\r
+ if line.find('@file') != -1:\r
+ continue\r
+ if line.find('*/') != -1:\r
+ continue\r
+ line = line.strip()\r
+ if line.strip().startswith('/'):\r
+ arr = line.split(' ')\r
+ if len(arr) > 1:\r
+ line = ' '.join(arr[1:])\r
+ else:\r
+ continue\r
+ output += '%s<br>\n' % line\r
+ output += '**/'\r
+\r
+ if os.path.exists(newpath):\r
+ os.remove(newpath)\r
+\r
+ file = open(newpath, "w")\r
+ file.write(output)\r
+ file.close()\r
+ return newpath\r
+\r
+ def SearchPcdPackage(self, pcdname, workspace, decObjs):\r
+ for decObj in decObjs:\r
+ for pcd in decObj.GetSectionObjectsByName('pcd'):\r
+ if pcdname == pcd.GetPcdName():\r
+ return decObj.GetBaseName()\r
+ return None\r
+\r
+ def SearchProtocolPackage(self, protname, workspace, decObjs):\r
+ for decObj in decObjs:\r
+ for proto in decObj.GetSectionObjectsByName('protocol'):\r
+ if protname == proto.GetName():\r
+ return decObj.GetBaseName()\r
+ return None\r
+\r
+ def SearchPpiPackage(self, ppiname, workspace, decObjs):\r
+ for decObj in decObjs:\r
+ for ppi in decObj.GetSectionObjectsByName('ppi'):\r
+ if ppiname == ppi.GetName():\r
+ return decObj.GetBaseName()\r
+ return None\r
+\r
+ def SearchGuidPackage(self, guidname, workspace, decObjs):\r
+ for decObj in decObjs:\r
+ for guid in decObj.GetSectionObjectsByName('guid'):\r
+ if guidname == guid.GetName():\r
+ return decObj.GetBaseName()\r
+ return None\r
+\r
+ def SearchLibraryClassHeaderFile(self, className, workspace, decObjs):\r
+ for decObj in decObjs:\r
+ for cls in decObj.GetSectionObjectsByName('libraryclasses'):\r
+ if cls.GetClassName().strip() == className:\r
+ path = cls.GetHeaderFile().strip()\r
+ path = os.path.join(decObj.GetPackageRootPath(), path)\r
+ path = path[len(workspace) + 1:]\r
+ return decObj.GetBaseName(), path.replace('\\', '/')\r
+\r
+ return None\r
+\r
+ def _ConvertPathToDoxygen(self, path, pObj):\r
+ pRootPath = pObj.GetWorkspace()\r
+ path = path[len(pRootPath) + 1:]\r
+ return path.replace('\\', '/')\r
+\r
+def IsCHeaderFile(path):\r
+ return CheckPathPostfix(path, 'h')\r
+\r
+def CheckPathPostfix(path, str):\r
+ index = path.rfind('.')\r
+ if index == -1:\r
+ return False\r
+ if path[index + 1:].lower() == str.lower():\r
+ return True\r
+ return False\r