]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/doxygengen.py
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Scripts / PackageDocumentTools / plugins / EdkPlugins / edk2 / model / doxygengen.py
CommitLineData
7ccc9c95
YZ
1## @file\r
2#\r
3# This file produce action class to generate doxygen document for edk2 codebase.\r
4# The action classes are shared by GUI and command line tools.\r
5#\r
6# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
7#\r
2e351cbe 8# SPDX-License-Identifier: BSD-2-Clause-Patent\r
7ccc9c95
YZ
9\r
10"""This file produce action class to generate doxygen document for edk2 codebase.\r
11 The action classes are shared by GUI and command line tools.\r
12"""\r
9ab4ec51 13from plugins.EdkPlugins.basemodel import doxygen\r
7ccc9c95
YZ
14import os\r
15try:\r
16 import wx\r
17 gInGui = True\r
18except:\r
19 gInGui = False\r
20import re\r
9ab4ec51
FZ
21from plugins.EdkPlugins.edk2.model import inf\r
22from plugins.EdkPlugins.edk2.model import dec\r
23from plugins.EdkPlugins.basemodel.message import *\r
7ccc9c95
YZ
24\r
25_ignore_dir = ['.svn', '_svn', 'cvs']\r
26_inf_key_description_mapping_table = {\r
27 'INF_VERSION':'Version of INF file specification',\r
28 #'BASE_NAME':'Module Name',\r
29 'FILE_GUID':'Module Guid',\r
30 'MODULE_TYPE': 'Module Type',\r
31 'VERSION_STRING': 'Module Version',\r
32 'LIBRARY_CLASS': 'Produced Library Class',\r
33 'EFI_SPECIFICATION_VERSION': 'UEFI Specification Version',\r
34 'PI_SPECIFICATION_VERSION': 'PI Specification Version',\r
35 'ENTRY_POINT': 'Module Entry Point Function',\r
36 'CONSTRUCTOR': 'Library Constructor Function'\r
37}\r
38\r
39_dec_key_description_mapping_table = {\r
40 'DEC_SPECIFICATION': 'Version of DEC file specification',\r
41 'PACKAGE_GUID': 'Package Guid'\r
42}\r
43class DoxygenAction:\r
44 """This is base class for all doxygen action.\r
45 """\r
46\r
47 def __init__(self, doxPath, chmPath, outputPath, projname, mode='html', log=None, verbose=False):\r
48 """Constructor function.\r
49 @param doxPath the obosolution path of doxygen execute file.\r
50 @param outputPath the obosolution output path.\r
51 @param log log function for output message\r
52 """\r
53 self._doxPath = doxPath\r
54 self._chmPath = chmPath\r
55 self._outputPath = outputPath\r
56 self._projname = projname\r
57 self._configFile = None # doxygen config file is used by doxygen exe file\r
58 self._indexPageFile = None # doxygen page file for index page.\r
59 self._log = log\r
60 self._mode = mode\r
61 self._verbose = verbose\r
62 self._doxygenCallback = None\r
63 self._chmCallback = None\r
64\r
65 def Log(self, message, level='info'):\r
4231a819 66 if self._log is not None:\r
7ccc9c95
YZ
67 self._log(message, level)\r
68\r
69 def IsVerbose(self):\r
70 return self._verbose\r
71\r
72 def Generate(self):\r
73 """Generate interface called by outer directly"""\r
74 self.Log(">>>>>> Start generate doxygen document for %s... Zzz....\n" % self._projname)\r
75\r
76 # create doxygen config file at first\r
77 self._configFile = doxygen.DoxygenConfigFile()\r
78 self._configFile.SetOutputDir(self._outputPath)\r
79\r
80 self._configFile.SetWarningFilePath(os.path.join(self._outputPath, 'warning.txt'))\r
81 if self._mode.lower() == 'html':\r
82 self._configFile.SetHtmlMode()\r
83 else:\r
84 self._configFile.SetChmMode()\r
85\r
86 self.Log(" >>>>>> Initialize doxygen config file...Zzz...\n")\r
87 self.InitializeConfigFile()\r
88\r
89 self.Log(" >>>>>> Generate doxygen index page file...Zzz...\n")\r
90 indexPagePath = self.GenerateIndexPage()\r
4231a819 91 if indexPagePath is None:\r
7ccc9c95
YZ
92 self.Log("Fail to generate index page!\n", 'error')\r
93 return False\r
94 else:\r
95 self.Log("Success to create doxygen index page file %s \n" % indexPagePath)\r
96\r
97 # Add index page doxygen file to file list.\r
98 self._configFile.AddFile(indexPagePath)\r
99\r
100 # save config file to output path\r
101 configFilePath = os.path.join(self._outputPath, self._projname + '.doxygen_config')\r
102 self._configFile.Generate(configFilePath)\r
103 self.Log(" <<<<<< Success Save doxygen config file to %s...\n" % configFilePath)\r
104\r
105 # launch doxygen tool to generate document\r
4231a819 106 if self._doxygenCallback is not None:\r
7ccc9c95
YZ
107 self.Log(" >>>>>> Start doxygen process...Zzz...\n")\r
108 if not self._doxygenCallback(self._doxPath, configFilePath):\r
109 return False\r
110 else:\r
111 self.Log("Fail to create doxygen process!", 'error')\r
112 return False\r
113\r
114 return True\r
115\r
116 def InitializeConfigFile(self):\r
117 """Initialize config setting for doxygen project. It will be invoked after config file\r
118 object is created. Inherited class should implement it.\r
119 """\r
120\r
121 def GenerateIndexPage(self):\r
122 """Generate doxygen index page. Inherited class should implement it."""\r
123 return None\r
124\r
125 def RegisterCallbackDoxygenProcess(self, callback):\r
126 self._doxygenCallback = callback\r
127\r
128 def RegisterCallbackCHMProcess(self, callback):\r
129 self._chmCallback = callback\r
130\r
131class PlatformDocumentAction(DoxygenAction):\r
132 """Generate platform doxygen document, will be implement at future."""\r
133\r
134class PackageDocumentAction(DoxygenAction):\r
135 """Generate package reference document"""\r
136\r
137 def __init__(self, doxPath, chmPath, outputPath, pObj, mode='html', log=None, arch=None, tooltag=None,\r
138 onlyInclude=False, verbose=False):\r
139 DoxygenAction.__init__(self, doxPath, chmPath, outputPath, pObj.GetName(), mode, log, verbose)\r
140 self._pObj = pObj\r
141 self._arch = arch\r
142 self._tooltag = tooltag\r
143 self._onlyIncludeDocument = onlyInclude\r
144\r
145 def InitializeConfigFile(self):\r
146 if self._arch == 'IA32':\r
147 self._configFile.AddPreDefined('MDE_CPU_IA32')\r
148 elif self._arch == 'X64':\r
149 self._configFile.AddPreDefined('MDE_CPU_X64')\r
150 elif self._arch == 'IPF':\r
151 self._configFile.AddPreDefined('MDE_CPU_IPF')\r
152 elif self._arch == 'EBC':\r
153 self._configFile.AddPreDefined('MDE_CPU_EBC')\r
154 else:\r
155 self._arch = None\r
156 self._configFile.AddPreDefined('MDE_CPU_IA32')\r
157 self._configFile.AddPreDefined('MDE_CPU_X64')\r
158 self._configFile.AddPreDefined('MDE_CPU_IPF')\r
159 self._configFile.AddPreDefined('MDE_CPU_EBC')\r
160 self._configFile.AddPreDefined('MDE_CPU_ARM')\r
161\r
162 namestr = self._pObj.GetName()\r
4231a819 163 if self._arch is not None:\r
7ccc9c95 164 namestr += '[%s]' % self._arch\r
4231a819 165 if self._tooltag is not None:\r
7ccc9c95
YZ
166 namestr += '[%s]' % self._tooltag\r
167 self._configFile.SetProjectName(namestr)\r
168 self._configFile.SetStripPath(self._pObj.GetWorkspace())\r
169 self._configFile.SetProjectVersion(self._pObj.GetFileObj().GetVersion())\r
170 self._configFile.AddPattern('*.decdoxygen')\r
171\r
172 if self._tooltag.lower() == 'msft':\r
173 self._configFile.AddPreDefined('_MSC_EXTENSIONS')\r
174 elif self._tooltag.lower() == 'gnu':\r
175 self._configFile.AddPreDefined('__GNUC__')\r
176 elif self._tooltag.lower() == 'intel':\r
177 self._configFile.AddPreDefined('__INTEL_COMPILER')\r
178 else:\r
179 self._tooltag = None\r
180 self._configFile.AddPreDefined('_MSC_EXTENSIONS')\r
181 self._configFile.AddPreDefined('__GNUC__')\r
182 self._configFile.AddPreDefined('__INTEL_COMPILER')\r
183\r
184 self._configFile.AddPreDefined('ASM_PFX= ')\r
185 self._configFile.AddPreDefined('OPTIONAL= ')\r
186\r
187 def GenerateIndexPage(self):\r
188 """Generate doxygen index page. Inherited class should implement it."""\r
189 fObj = self._pObj.GetFileObj()\r
190 pdObj = doxygen.DoxygenFile('%s Package Document' % self._pObj.GetName(),\r
191 '%s.decdoxygen' % self._pObj.GetFilename())\r
192 self._configFile.AddFile(pdObj.GetFilename())\r
193 pdObj.AddDescription(fObj.GetFileHeader())\r
194\r
195 defSection = fObj.GetSectionByName('defines')[0]\r
196 baseSection = doxygen.Section('PackageBasicInformation', 'Package Basic Information')\r
197 descr = '<TABLE>'\r
198 for obj in defSection.GetObjects():\r
199 if obj.GetKey() in _dec_key_description_mapping_table.keys():\r
200 descr += '<TR>'\r
201 descr += '<TD><B>%s</B></TD>' % _dec_key_description_mapping_table[obj.GetKey()]\r
202 descr += '<TD>%s</TD>' % obj.GetValue()\r
203 descr += '</TR>'\r
204 descr += '</TABLE><br>'\r
205 baseSection.AddDescription(descr)\r
206 pdObj.AddSection(baseSection)\r
207\r
208 knownIssueSection = doxygen.Section('Known_Issue_section', 'Known Issue')\r
209 knownIssueSection.AddDescription('<ul>')\r
210 knownIssueSection.AddDescription('<li> OPTIONAL macro for function parameter can not be dealed with doxygen, so it disapear in this document! </li>')\r
211 knownIssueSection.AddDescription('</ul>')\r
212 pdObj.AddSection(knownIssueSection)\r
213\r
214 self.AddAllIncludeFiles(self._pObj, self._configFile)\r
215 pages = self.GenerateIncludesSubPage(self._pObj, self._configFile)\r
216 if len(pages) != 0:\r
217 pdObj.AddPages(pages)\r
218 pages = self.GenerateLibraryClassesSubPage(self._pObj, self._configFile)\r
219 if len(pages) != 0:\r
220 pdObj.AddPages(pages)\r
221 pages = self.GeneratePcdSubPages(self._pObj, self._configFile)\r
222 if len(pages) != 0:\r
223 pdObj.AddPages(pages)\r
224 pages = self.GenerateGuidSubPages(self._pObj, self._configFile)\r
225 if len(pages) != 0:\r
226 pdObj.AddPages(pages)\r
227 pages = self.GeneratePpiSubPages(self._pObj, self._configFile)\r
228 if len(pages) != 0:\r
229 pdObj.AddPages(pages)\r
230 pages = self.GenerateProtocolSubPages(self._pObj, self._configFile)\r
231 if len(pages) != 0:\r
232 pdObj.AddPages(pages)\r
233 if not self._onlyIncludeDocument:\r
234 pdObj.AddPages(self.GenerateModulePages(self._pObj, self._configFile))\r
235\r
236 pdObj.Save()\r
237 return pdObj.GetFilename()\r
238\r
239 def GenerateIncludesSubPage(self, pObj, configFile):\r
240 # by default add following path as include path to config file\r
241 pkpath = pObj.GetFileObj().GetPackageRootPath()\r
242 configFile.AddIncludePath(os.path.join(pkpath, 'Include'))\r
243 configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Library'))\r
244 configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Protocol'))\r
245 configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Ppi'))\r
246 configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'Guid'))\r
247 configFile.AddIncludePath(os.path.join(pkpath, 'Include', 'IndustryStandard'))\r
248\r
249 rootArray = []\r
250 pageRoot = doxygen.Page("Public Includes", "%s_public_includes" % pObj.GetName())\r
251 objs = pObj.GetFileObj().GetSectionObjectsByName('includes')\r
252 if len(objs) == 0: return []\r
253\r
254 for obj in objs:\r
255 # Add path to include path\r
256 path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetPath())\r
257 configFile.AddIncludePath(path)\r
258\r
259 # only list common folder's include file\r
260 if obj.GetArch().lower() != 'common':\r
261 continue\r
262\r
263 bNeedAddIncludePage = False\r
264 topPage = doxygen.Page(self._ConvertPathToDoxygen(path, pObj), 'public_include_top')\r
265\r
266 topPage.AddDescription('<ul>\n')\r
267 for file in os.listdir(path):\r
268 if file.lower() in _ignore_dir: continue\r
269 fullpath = os.path.join(path, file)\r
270 if os.path.isfile(fullpath):\r
271 self.ProcessSourceFileForInclude(fullpath, pObj, configFile)\r
272 topPage.AddDescription('<li> \link %s\endlink </li>\n' % self._ConvertPathToDoxygen(fullpath, pObj))\r
273 else:\r
274 if file.lower() in ['library', 'protocol', 'guid', 'ppi', 'ia32', 'x64', 'ipf', 'ebc', 'arm', 'pi', 'uefi', 'aarch64']:\r
275 continue\r
276 bNeedAddSubPage = False\r
277 subpage = doxygen.Page(self._ConvertPathToDoxygen(fullpath, pObj), 'public_include_%s' % file)\r
278 subpage.AddDescription('<ul>\n')\r
279 for subfile in os.listdir(fullpath):\r
280 if subfile.lower() in _ignore_dir: continue\r
281 bNeedAddSubPage = True\r
282 subfullpath = os.path.join(fullpath, subfile)\r
283 self.ProcessSourceFileForInclude(subfullpath, pObj, configFile)\r
284 subpage.AddDescription('<li> \link %s \endlink </li>\n' % self._ConvertPathToDoxygen(subfullpath, pObj))\r
285 subpage.AddDescription('</ul>\n')\r
286 if bNeedAddSubPage:\r
287 bNeedAddIncludePage = True\r
288 pageRoot.AddPage(subpage)\r
289 topPage.AddDescription('</ul>\n')\r
290 if bNeedAddIncludePage:\r
291 pageRoot.AddPage(topPage)\r
292\r
293 if pageRoot.GetSubpageCount() != 0:\r
294 return [pageRoot]\r
295 else:\r
296 return []\r
297\r
298 def GenerateLibraryClassesSubPage(self, pObj, configFile):\r
299 """\r
300 Generate sub page for library class for package.\r
301 One DEC file maybe contains many library class sections\r
302 for different architecture.\r
303\r
304 @param fObj DEC file object.\r
305 """\r
306 rootArray = []\r
307 pageRoot = doxygen.Page("Library Class", "%s_libraryclass" % pObj.GetName())\r
308 objs = pObj.GetFileObj().GetSectionObjectsByName('libraryclass', self._arch)\r
309 if len(objs) == 0: return []\r
310\r
4231a819 311 if self._arch is not None:\r
7ccc9c95
YZ
312 for obj in objs:\r
313 classPage = doxygen.Page(obj.GetClassName(),\r
314 "lc_%s" % obj.GetClassName())\r
315 comments = obj.GetComment()\r
316 if len(comments) != 0:\r
317 classPage.AddDescription('<br>\n'.join(comments) + '<br>\n')\r
318 pageRoot.AddPage(classPage)\r
319 path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())\r
320 path = path[len(pObj.GetWorkspace()) + 1:]\r
321 if len(comments) == 0:\r
322 classPage.AddDescription('\copydoc %s<p>' % obj.GetHeaderFile())\r
323 section = doxygen.Section('ref', 'Refer to Header File')\r
324 section.AddDescription('\link %s\n' % obj.GetHeaderFile())\r
325 section.AddDescription(' \endlink<p>\n')\r
326 classPage.AddSection(section)\r
327 fullPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())\r
328 self.ProcessSourceFileForInclude(fullPath, pObj, configFile)\r
329 else:\r
330 archPageDict = {}\r
331 for obj in objs:\r
332 if obj.GetArch() not in archPageDict.keys():\r
333 archPageDict[obj.GetArch()] = doxygen.Page(obj.GetArch(),\r
334 'lc_%s' % obj.GetArch())\r
335 pageRoot.AddPage(archPageDict[obj.GetArch()])\r
336 subArchRoot = archPageDict[obj.GetArch()]\r
337 classPage = doxygen.Page(obj.GetClassName(),\r
338 "lc_%s" % obj.GetClassName())\r
339 comments = obj.GetComment()\r
340 if len(comments) != 0:\r
341 classPage.AddDescription('<br>\n'.join(comments) + '<br>\n')\r
342 subArchRoot.AddPage(classPage)\r
343 path = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())\r
344 path = path[len(pObj.GetWorkspace()) + 1:]\r
345 if len(comments) == 0:\r
346 classPage.AddDescription('\copydoc %s<p>' % obj.GetHeaderFile())\r
347 section = doxygen.Section('ref', 'Refer to Header File')\r
348 section.AddDescription('\link %s\n' % obj.GetHeaderFile())\r
349 section.AddDescription(' \endlink<p>\n')\r
350 classPage.AddSection(section)\r
351 fullPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetHeaderFile())\r
352\r
353 self.ProcessSourceFileForInclude(fullPath, pObj, configFile)\r
354 rootArray.append(pageRoot)\r
355 return rootArray\r
356\r
357 def ProcessSourceFileForInclude(self, path, pObj, configFile, infObj=None):\r
358 """\r
359 @param path the analysising file full path\r
360 @param pObj package object\r
361 @param configFile doxygen config file.\r
362 """\r
363 if gInGui:\r
364 wx.Yield()\r
365 if not os.path.exists(path):\r
366 ErrorMsg('Source file path %s does not exist!' % path)\r
367 return\r
368\r
369 if configFile.FileExists(path):\r
370 return\r
371\r
372 try:\r
8ef3a6ec
FZ
373 with open(path, 'r') as f:\r
374 lines = f.readlines()\r
375 except UnicodeDecodeError:\r
376 return\r
7ccc9c95
YZ
377 except IOError:\r
378 ErrorMsg('Fail to open file %s' % path)\r
379 return\r
380\r
381 configFile.AddFile(path)\r
382\r
383 no = 0\r
7cc7e054 384 for no in range(len(lines)):\r
7ccc9c95
YZ
385 if len(lines[no].strip()) == 0:\r
386 continue\r
387 if lines[no].strip()[:2] in ['##', '//', '/*', '*/']:\r
388 continue\r
389 index = lines[no].lower().find('include')\r
390 #mo = IncludePattern.finditer(lines[no].lower())\r
391 mo = re.match(r"^#\s*include\s+[<\"]([\\/\w.]+)[>\"]$", lines[no].strip().lower())\r
392 if not mo:\r
393 continue\r
394 mo = re.match(r"^[#\w\s]+[<\"]([\\/\w.]+)[>\"]$", lines[no].strip())\r
395 filePath = mo.groups()[0]\r
396\r
4231a819 397 if filePath is None or len(filePath) == 0:\r
7ccc9c95
YZ
398 continue\r
399\r
400 # find header file in module's path firstly.\r
401 fullPath = None\r
402\r
403 if os.path.exists(os.path.join(os.path.dirname(path), filePath)):\r
404 # Find the file in current directory\r
405 fullPath = os.path.join(os.path.dirname(path), filePath).replace('\\', '/')\r
406 else:\r
407 # find in depedent package's include path\r
408 incObjs = pObj.GetFileObj().GetSectionObjectsByName('includes')\r
409 for incObj in incObjs:\r
410 incPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), incObj.GetPath()).strip()\r
411 incPath = os.path.realpath(os.path.join(incPath, filePath))\r
412 if os.path.exists(incPath):\r
413 fullPath = incPath\r
414 break\r
4231a819 415 if infObj is not None:\r
7ccc9c95
YZ
416 pkgInfObjs = infObj.GetSectionObjectsByName('packages')\r
417 for obj in pkgInfObjs:\r
418 decObj = dec.DECFile(os.path.join(pObj.GetWorkspace(), obj.GetPath()))\r
419 if not decObj:\r
420 ErrorMsg ('Fail to create pacakge object for %s' % obj.GetPackageName())\r
421 continue\r
422 if not decObj.Parse():\r
423 ErrorMsg ('Fail to load package object for %s' % obj.GetPackageName())\r
424 continue\r
425 incObjs = decObj.GetSectionObjectsByName('includes')\r
426 for incObj in incObjs:\r
427 incPath = os.path.join(decObj.GetPackageRootPath(), incObj.GetPath()).replace('\\', '/')\r
428 if os.path.exists(os.path.join(incPath, filePath)):\r
429 fullPath = os.path.join(os.path.join(incPath, filePath))\r
430 break\r
4231a819 431 if fullPath is not None:\r
7ccc9c95
YZ
432 break\r
433\r
4231a819 434 if fullPath is None and self.IsVerbose():\r
7ccc9c95
YZ
435 self.Log('Can not resolve header file %s for file %s in package %s\n' % (filePath, path, pObj.GetFileObj().GetFilename()), 'error')\r
436 return\r
437 else:\r
438 fullPath = fullPath.replace('\\', '/')\r
439 if self.IsVerbose():\r
440 self.Log('Preprocessing: Add include file %s for file %s\n' % (fullPath, path))\r
441 #LogMsg ('Preprocessing: Add include file %s for file %s' % (fullPath, path))\r
442 self.ProcessSourceFileForInclude(fullPath, pObj, configFile, infObj)\r
443\r
444 def AddAllIncludeFiles(self, pObj, configFile):\r
445 objs = pObj.GetFileObj().GetSectionObjectsByName('includes')\r
446 for obj in objs:\r
447 incPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetPath())\r
448 for root, dirs, files in os.walk(incPath):\r
449 for dir in dirs:\r
450 if dir.lower() in _ignore_dir:\r
451 dirs.remove(dir)\r
452 for file in files:\r
453 path = os.path.normpath(os.path.join(root, file))\r
454 configFile.AddFile(path.replace('/', '\\'))\r
455\r
456 def GeneratePcdSubPages(self, pObj, configFile):\r
457 """\r
458 Generate sub pages for package's PCD definition.\r
459 @param pObj package object\r
460 @param configFile config file object\r
461 """\r
462 rootArray = []\r
463 objs = pObj.GetFileObj().GetSectionObjectsByName('pcd')\r
464 if len(objs) == 0:\r
465 return []\r
466\r
467 pcdRootPage = doxygen.Page('PCD', 'pcd_root_page')\r
468 typeRootPageDict = {}\r
469 typeArchRootPageDict = {}\r
470 for obj in objs:\r
471 if obj.GetPcdType() not in typeRootPageDict.keys():\r
472 typeRootPageDict[obj.GetPcdType()] = doxygen.Page(obj.GetPcdType(), 'pcd_%s_root_page' % obj.GetPcdType())\r
473 pcdRootPage.AddPage(typeRootPageDict[obj.GetPcdType()])\r
474 typeRoot = typeRootPageDict[obj.GetPcdType()]\r
4231a819 475 if self._arch is not None:\r
7ccc9c95
YZ
476 pcdPage = doxygen.Page('%s' % obj.GetPcdName(),\r
477 'pcd_%s_%s_%s' % (obj.GetPcdType(), obj.GetArch(), obj.GetPcdName().split('.')[1]))\r
478 pcdPage.AddDescription('<br>\n'.join(obj.GetComment()) + '<br>\n')\r
479 section = doxygen.Section('PCDinformation', 'PCD Information')\r
480 desc = '<TABLE>'\r
481 desc += '<TR>'\r
482 desc += '<TD><CAPTION>Name</CAPTION></TD>'\r
483 desc += '<TD><CAPTION>Token Space</CAPTION></TD>'\r
484 desc += '<TD><CAPTION>Token number</CAPTION></TD>'\r
485 desc += '<TD><CAPTION>Data Type</CAPTION></TD>'\r
486 desc += '<TD><CAPTION>Default Value</CAPTION></TD>'\r
487 desc += '</TR>'\r
488 desc += '<TR>'\r
489 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[1]\r
490 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[0]\r
491 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdToken()\r
492 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdDataType()\r
493 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdValue()\r
494 desc += '</TR>'\r
495 desc += '</TABLE>'\r
496 section.AddDescription(desc)\r
497 pcdPage.AddSection(section)\r
498 typeRoot.AddPage(pcdPage)\r
499 else:\r
500 keystr = obj.GetPcdType() + obj.GetArch()\r
501 if keystr not in typeArchRootPageDict.keys():\r
502 typeArchRootPage = doxygen.Page(obj.GetArch(), 'pcd_%s_%s_root_page' % (obj.GetPcdType(), obj.GetArch()))\r
503 typeArchRootPageDict[keystr] = typeArchRootPage\r
504 typeRoot.AddPage(typeArchRootPage)\r
505 typeArchRoot = typeArchRootPageDict[keystr]\r
506 pcdPage = doxygen.Page('%s' % obj.GetPcdName(),\r
507 'pcd_%s_%s_%s' % (obj.GetPcdType(), obj.GetArch(), obj.GetPcdName().split('.')[1]))\r
508 pcdPage.AddDescription('<br>\n'.join(obj.GetComment()) + '<br>\n')\r
509 section = doxygen.Section('PCDinformation', 'PCD Information')\r
510 desc = '<TABLE>'\r
511 desc += '<TR>'\r
512 desc += '<TD><CAPTION>Name</CAPTION></TD>'\r
513 desc += '<TD><CAPTION>Token Space</CAPTION></TD>'\r
514 desc += '<TD><CAPTION>Token number</CAPTION></TD>'\r
515 desc += '<TD><CAPTION>Data Type</CAPTION></TD>'\r
516 desc += '<TD><CAPTION>Default Value</CAPTION></TD>'\r
517 desc += '</TR>'\r
518 desc += '<TR>'\r
519 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[1]\r
520 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[0]\r
521 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdToken()\r
522 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdDataType()\r
523 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdValue()\r
524 desc += '</TR>'\r
525 desc += '</TABLE>'\r
526 section.AddDescription(desc)\r
527 pcdPage.AddSection(section)\r
528 typeArchRoot.AddPage(pcdPage)\r
529 return [pcdRootPage]\r
530\r
531 def _GenerateGuidSubPage(self, pObj, obj, configFile):\r
532 guidPage = doxygen.Page('%s' % obj.GetName(),\r
533 'guid_%s_%s' % (obj.GetArch(), obj.GetName()))\r
534 comments = obj.GetComment()\r
535 if len(comments) != 0:\r
536 guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')\r
537 section = doxygen.Section('BasicGuidInfo', 'GUID Information')\r
538 desc = '<TABLE>'\r
539 desc += '<TR>'\r
540 desc += '<TD><CAPTION>GUID\'s Guid Name</CAPTION></TD><TD><CAPTION>GUID\'s Guid</CAPTION></TD>'\r
541 desc += '</TR>'\r
542 desc += '<TR>'\r
543 desc += '<TD>%s</TD>' % obj.GetName()\r
544 desc += '<TD>%s</TD>' % obj.GetGuid()\r
545 desc += '</TR>'\r
546 desc += '</TABLE>'\r
547 section.AddDescription(desc)\r
548 guidPage.AddSection(section)\r
549 refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)\r
550 if refFile:\r
551 relPath = refFile[len(pObj.GetWorkspace()) + 1:]\r
552 if len(comments) == 0:\r
553 guidPage.AddDescription(' \\copydoc %s <br>' % relPath)\r
554\r
555 section = doxygen.Section('ref', 'Refer to Header File')\r
556 section.AddDescription('\link %s\n' % relPath)\r
557 section.AddDescription('\endlink\n')\r
558 self.ProcessSourceFileForInclude(refFile, pObj, configFile)\r
559 guidPage.AddSection(section)\r
560 return guidPage\r
561\r
562 def GenerateGuidSubPages(self, pObj, configFile):\r
563 """\r
564 Generate sub pages for package's GUID definition.\r
565 @param pObj package object\r
566 @param configFilf doxygen config file object\r
567 """\r
568 pageRoot = doxygen.Page('GUID', 'guid_root_page')\r
569 objs = pObj.GetFileObj().GetSectionObjectsByName('guids', self._arch)\r
570 if len(objs) == 0: return []\r
4231a819 571 if self._arch is not None:\r
7ccc9c95
YZ
572 for obj in objs:\r
573 pageRoot.AddPage(self._GenerateGuidSubPage(pObj, obj, configFile))\r
574 else:\r
575 guidArchRootPageDict = {}\r
576 for obj in objs:\r
577 if obj.GetArch() not in guidArchRootPageDict.keys():\r
578 guidArchRoot = doxygen.Page(obj.GetArch(), 'guid_arch_root_%s' % obj.GetArch())\r
579 pageRoot.AddPage(guidArchRoot)\r
580 guidArchRootPageDict[obj.GetArch()] = guidArchRoot\r
581 guidArchRoot = guidArchRootPageDict[obj.GetArch()]\r
582 guidArchRoot.AddPage(self._GenerateGuidSubPage(pObj, obj, configFile))\r
583 return [pageRoot]\r
584\r
585 def _GeneratePpiSubPage(self, pObj, obj, configFile):\r
586 guidPage = doxygen.Page(obj.GetName(), 'ppi_page_%s' % obj.GetName())\r
587 comments = obj.GetComment()\r
588 if len(comments) != 0:\r
589 guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')\r
590 section = doxygen.Section('BasicPpiInfo', 'PPI Information')\r
591 desc = '<TABLE>'\r
592 desc += '<TR>'\r
593 desc += '<TD><CAPTION>PPI\'s Guid Name</CAPTION></TD><TD><CAPTION>PPI\'s Guid</CAPTION></TD>'\r
594 desc += '</TR>'\r
595 desc += '<TR>'\r
596 desc += '<TD>%s</TD>' % obj.GetName()\r
597 desc += '<TD>%s</TD>' % obj.GetGuid()\r
598 desc += '</TR>'\r
599 desc += '</TABLE>'\r
600 section.AddDescription(desc)\r
601 guidPage.AddSection(section)\r
602 refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)\r
603 if refFile:\r
604 relPath = refFile[len(pObj.GetWorkspace()) + 1:]\r
605 if len(comments) == 0:\r
606 guidPage.AddDescription(' \\copydoc %s <br>' % relPath)\r
607 section = doxygen.Section('ref', 'Refer to Header File')\r
608 section.AddDescription('\link %s\n' % relPath)\r
609 section.AddDescription('\endlink\n')\r
610 self.ProcessSourceFileForInclude(refFile, pObj, configFile)\r
611 guidPage.AddSection(section)\r
612\r
613 return guidPage\r
614\r
615 def GeneratePpiSubPages(self, pObj, configFile):\r
616 """\r
617 Generate sub pages for package's GUID definition.\r
618 @param pObj package object\r
619 @param configFilf doxygen config file object\r
620 """\r
621 pageRoot = doxygen.Page('PPI', 'ppi_root_page')\r
622 objs = pObj.GetFileObj().GetSectionObjectsByName('ppis', self._arch)\r
623 if len(objs) == 0: return []\r
4231a819 624 if self._arch is not None:\r
7ccc9c95
YZ
625 for obj in objs:\r
626 pageRoot.AddPage(self._GeneratePpiSubPage(pObj, obj, configFile))\r
627 else:\r
628 guidArchRootPageDict = {}\r
629 for obj in objs:\r
630 if obj.GetArch() not in guidArchRootPageDict.keys():\r
631 guidArchRoot = doxygen.Page(obj.GetArch(), 'ppi_arch_root_%s' % obj.GetArch())\r
632 pageRoot.AddPage(guidArchRoot)\r
633 guidArchRootPageDict[obj.GetArch()] = guidArchRoot\r
634 guidArchRoot = guidArchRootPageDict[obj.GetArch()]\r
635 guidArchRoot.AddPage(self._GeneratePpiSubPage(pObj, obj, configFile))\r
636 return [pageRoot]\r
637\r
638 def _GenerateProtocolSubPage(self, pObj, obj, configFile):\r
639 guidPage = doxygen.Page(obj.GetName(), 'protocol_page_%s' % obj.GetName())\r
640 comments = obj.GetComment()\r
641 if len(comments) != 0:\r
642 guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')\r
643 section = doxygen.Section('BasicProtocolInfo', 'PROTOCOL Information')\r
644 desc = '<TABLE>'\r
645 desc += '<TR>'\r
646 desc += '<TD><CAPTION>PROTOCOL\'s Guid Name</CAPTION></TD><TD><CAPTION>PROTOCOL\'s Guid</CAPTION></TD>'\r
647 desc += '</TR>'\r
648 desc += '<TR>'\r
649 desc += '<TD>%s</TD>' % obj.GetName()\r
650 desc += '<TD>%s</TD>' % obj.GetGuid()\r
651 desc += '</TR>'\r
652 desc += '</TABLE>'\r
653 section.AddDescription(desc)\r
654 guidPage.AddSection(section)\r
655\r
656 refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)\r
657 if refFile:\r
658 relPath = refFile[len(pObj.GetWorkspace()) + 1:]\r
659 if len(comments) == 0:\r
660 guidPage.AddDescription(' \\copydoc %s <br>' % relPath)\r
661 section = doxygen.Section('ref', 'Refer to Header File')\r
662 section.AddDescription('\link %s\n' % relPath)\r
663 section.AddDescription('\endlink\n')\r
664 self.ProcessSourceFileForInclude(refFile, pObj, configFile)\r
665 guidPage.AddSection(section)\r
666\r
667 return guidPage\r
668\r
669 def GenerateProtocolSubPages(self, pObj, configFile):\r
670 """\r
671 Generate sub pages for package's GUID definition.\r
672 @param pObj package object\r
673 @param configFilf doxygen config file object\r
674 """\r
675 pageRoot = doxygen.Page('PROTOCOL', 'protocol_root_page')\r
676 objs = pObj.GetFileObj().GetSectionObjectsByName('protocols', self._arch)\r
677 if len(objs) == 0: return []\r
4231a819 678 if self._arch is not None:\r
7ccc9c95
YZ
679 for obj in objs:\r
680 pageRoot.AddPage(self._GenerateProtocolSubPage(pObj, obj, configFile))\r
681 else:\r
682 guidArchRootPageDict = {}\r
683 for obj in objs:\r
684 if obj.GetArch() not in guidArchRootPageDict.keys():\r
685 guidArchRoot = doxygen.Page(obj.GetArch(), 'protocol_arch_root_%s' % obj.GetArch())\r
686 pageRoot.AddPage(guidArchRoot)\r
687 guidArchRootPageDict[obj.GetArch()] = guidArchRoot\r
688 guidArchRoot = guidArchRootPageDict[obj.GetArch()]\r
689 guidArchRoot.AddPage(self._GenerateProtocolSubPage(pObj, obj, configFile))\r
690 return [pageRoot]\r
691\r
692 def FindHeaderFileForGuid(self, pObj, name, configFile):\r
693 """\r
694 For declaration header file for GUID/PPI/Protocol.\r
695\r
696 @param pObj package object\r
697 @param name guid/ppi/protocol's name\r
698 @param configFile config file object\r
699\r
700 @return full path of header file and None if not found.\r
701 """\r
702 startPath = pObj.GetFileObj().GetPackageRootPath()\r
703 incPath = os.path.join(startPath, 'Include').replace('\\', '/')\r
704 # if <PackagePath>/include exist, then search header under it.\r
705 if os.path.exists(incPath):\r
706 startPath = incPath\r
707\r
708 for root, dirs, files in os.walk(startPath):\r
709 for dir in dirs:\r
710 if dir.lower() in _ignore_dir:\r
711 dirs.remove(dir)\r
712 for file in files:\r
713 fPath = os.path.join(root, file)\r
714 if not IsCHeaderFile(fPath):\r
715 continue\r
716 try:\r
717 f = open(fPath, 'r')\r
718 lines = f.readlines()\r
719 f.close()\r
720 except IOError:\r
721 self.Log('Fail to open file %s\n' % fPath)\r
722 continue\r
723 for line in lines:\r
724 if line.find(name) != -1 and \\r
725 line.find('extern') != -1:\r
726 return fPath.replace('\\', '/')\r
727 return None\r
728\r
729 def GetPackageModuleList(self, pObj):\r
730 """\r
731 Get all module's INF path under package's root path\r
732 @param pObj package object\r
733 @return arrary of INF full path\r
734 """\r
735 mArray = []\r
736 packPath = pObj.GetFileObj().GetPackageRootPath()\r
737 if not os.path.exists:\r
738 return None\r
739 for root, dirs, files in os.walk(packPath):\r
740 for dir in dirs:\r
741 if dir.lower() in _ignore_dir:\r
742 dirs.remove(dir)\r
743 for file in files:\r
744 if CheckPathPostfix(file, 'inf'):\r
745 fPath = os.path.join(root, file).replace('\\', '/')\r
746 mArray.append(fPath)\r
747 return mArray\r
748\r
749 def GenerateModulePages(self, pObj, configFile):\r
750 """\r
751 Generate sub pages for package's module which is under the package\r
752 root directory.\r
753\r
754 @param pObj package object\r
755 @param configFilf doxygen config file object\r
756 """\r
757 infList = self.GetPackageModuleList(pObj)\r
758 rootPages = []\r
759 libObjs = []\r
760 modObjs = []\r
761 for infpath in infList:\r
762 infObj = inf.INFFile(infpath)\r
763 #infObj = INFFileObject.INFFile (pObj.GetWorkspacePath(),\r
764 # inf)\r
765 if not infObj:\r
766 self.Log('Fail create INF object for %s' % inf)\r
767 continue\r
768 if not infObj.Parse():\r
769 self.Log('Fail to load INF file %s' % inf)\r
770 continue\r
4231a819 771 if infObj.GetProduceLibraryClass() is not None:\r
7ccc9c95
YZ
772 libObjs.append(infObj)\r
773 else:\r
774 modObjs.append(infObj)\r
775\r
776 if len(libObjs) != 0:\r
777 libRootPage = doxygen.Page('Libraries', 'lib_root_page')\r
778 rootPages.append(libRootPage)\r
779 for libInf in libObjs:\r
780 libRootPage.AddPage(self.GenerateModulePage(pObj, libInf, configFile, True))\r
781\r
782 if len(modObjs) != 0:\r
783 modRootPage = doxygen.Page('Modules', 'module_root_page')\r
784 rootPages.append(modRootPage)\r
785 for modInf in modObjs:\r
786 modRootPage.AddPage(self.GenerateModulePage(pObj, modInf, configFile, False))\r
787\r
788 return rootPages\r
789\r
790 def GenerateModulePage(self, pObj, infObj, configFile, isLib):\r
791 """\r
792 Generate page for a module/library.\r
793 @param infObj INF file object for module/library\r
794 @param configFile doxygen config file object\r
795 @param isLib Whether this module is libary\r
796\r
797 @param module doxygen page object\r
798 """\r
799 workspace = pObj.GetWorkspace()\r
800 refDecObjs = []\r
801 for obj in infObj.GetSectionObjectsByName('packages'):\r
802 decObj = dec.DECFile(os.path.join(workspace, obj.GetPath()))\r
803 if not decObj:\r
804 ErrorMsg ('Fail to create pacakge object for %s' % obj.GetPackageName())\r
805 continue\r
806 if not decObj.Parse():\r
807 ErrorMsg ('Fail to load package object for %s' % obj.GetPackageName())\r
808 continue\r
809 refDecObjs.append(decObj)\r
810\r
811 modPage = doxygen.Page('%s' % infObj.GetBaseName(),\r
812 'module_%s' % infObj.GetBaseName())\r
813 modPage.AddDescription(infObj.GetFileHeader())\r
814\r
815 basicInfSection = doxygen.Section('BasicModuleInformation', 'Basic Module Information')\r
816 desc = "<TABLE>"\r
817 for obj in infObj.GetSectionObjectsByName('defines'):\r
818 key = obj.GetKey()\r
819 value = obj.GetValue()\r
820 if key not in _inf_key_description_mapping_table.keys(): continue\r
821 if key == 'LIBRARY_CLASS' and value.find('|') != -1:\r
822 clsname, types = value.split('|')\r
823 desc += '<TR>'\r
824 desc += '<TD><B>%s</B></TD>' % _inf_key_description_mapping_table[key]\r
825 desc += '<TD>%s</TD>' % clsname\r
826 desc += '</TR>'\r
827\r
828 desc += '<TR>'\r
829 desc += '<TD><B>Supported Module Types</B></TD>'\r
830 desc += '<TD>%s</TD>' % types\r
831 desc += '</TR>'\r
832 else:\r
833 desc += '<TR>'\r
834 desc += '<TD><B>%s</B></TD>' % _inf_key_description_mapping_table[key]\r
835 if key == 'EFI_SPECIFICATION_VERSION' and value == '0x00020000':\r
836 value = '2.0'\r
837 desc += '<TD>%s</TD>' % value\r
838 desc += '</TR>'\r
839 desc += '</TABLE>'\r
840 basicInfSection.AddDescription(desc)\r
841 modPage.AddSection(basicInfSection)\r
842\r
843 # Add protocol section\r
844 data = []\r
845 for obj in infObj.GetSectionObjectsByName('pcd', self._arch):\r
846 data.append(obj.GetPcdName().strip())\r
847 if len(data) != 0:\r
848 s = doxygen.Section('Pcds', 'Pcds')\r
849 desc = "<TABLE>"\r
850 desc += '<TR><TD><B>PCD Name</B></TD><TD><B>TokenSpace</B></TD><TD><B>Package</B></TD></TR>'\r
851 for item in data:\r
852 desc += '<TR>'\r
853 desc += '<TD>%s</TD>' % item.split('.')[1]\r
854 desc += '<TD>%s</TD>' % item.split('.')[0]\r
855 pkgbasename = self.SearchPcdPackage(item, workspace, refDecObjs)\r
856 desc += '<TD>%s</TD>' % pkgbasename\r
857 desc += '</TR>'\r
858 desc += "</TABLE>"\r
859 s.AddDescription(desc)\r
860 modPage.AddSection(s)\r
861\r
862 # Add protocol section\r
863 #sects = infObj.GetSectionByString('protocol')\r
864 data = []\r
865 #for sect in sects:\r
866 for obj in infObj.GetSectionObjectsByName('protocol', self._arch):\r
867 data.append(obj.GetName().strip())\r
868 if len(data) != 0:\r
869 s = doxygen.Section('Protocols', 'Protocols')\r
870 desc = "<TABLE>"\r
871 desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'\r
872 for item in data:\r
873 desc += '<TR>'\r
874 desc += '<TD>%s</TD>' % item\r
875 pkgbasename = self.SearchProtocolPackage(item, workspace, refDecObjs)\r
876 desc += '<TD>%s</TD>' % pkgbasename\r
877 desc += '</TR>'\r
878 desc += "</TABLE>"\r
879 s.AddDescription(desc)\r
880 modPage.AddSection(s)\r
881\r
882 # Add ppi section\r
883 #sects = infObj.GetSectionByString('ppi')\r
884 data = []\r
885 #for sect in sects:\r
886 for obj in infObj.GetSectionObjectsByName('ppi', self._arch):\r
887 data.append(obj.GetName().strip())\r
888 if len(data) != 0:\r
889 s = doxygen.Section('Ppis', 'Ppis')\r
890 desc = "<TABLE>"\r
891 desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'\r
892 for item in data:\r
893 desc += '<TR>'\r
894 desc += '<TD>%s</TD>' % item\r
895 pkgbasename = self.SearchPpiPackage(item, workspace, refDecObjs)\r
896 desc += '<TD>%s</TD>' % pkgbasename\r
897 desc += '</TR>'\r
898 desc += "</TABLE>"\r
899 s.AddDescription(desc)\r
900 modPage.AddSection(s)\r
901\r
902 # Add guid section\r
903 #sects = infObj.GetSectionByString('guid')\r
904 data = []\r
905 #for sect in sects:\r
906 for obj in infObj.GetSectionObjectsByName('guid', self._arch):\r
907 data.append(obj.GetName().strip())\r
908 if len(data) != 0:\r
909 s = doxygen.Section('Guids', 'Guids')\r
910 desc = "<TABLE>"\r
911 desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'\r
912 for item in data:\r
913 desc += '<TR>'\r
914 desc += '<TD>%s</TD>' % item\r
915 pkgbasename = self.SearchGuidPackage(item, workspace, refDecObjs)\r
916 desc += '<TD>%s</TD>' % pkgbasename\r
917 desc += '</TR>'\r
918 desc += "</TABLE>"\r
919 s.AddDescription(desc)\r
920 modPage.AddSection(s)\r
921\r
922 section = doxygen.Section('LibraryClasses', 'Library Classes')\r
923 desc = "<TABLE>"\r
924 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
925 if isLib:\r
926 desc += '<TR>'\r
927 desc += '<TD>%s</TD>' % infObj.GetProduceLibraryClass()\r
928 desc += '<TD>Produce</TD>'\r
929 try:\r
930 pkgname, hPath = self.SearchLibraryClassHeaderFile(infObj.GetProduceLibraryClass(),\r
931 workspace,\r
932 refDecObjs)\r
933 except:\r
934 self.Log ('fail to get package header file for lib class %s' % infObj.GetProduceLibraryClass())\r
935 pkgname = 'NULL'\r
936 hPath = 'NULL'\r
937 desc += '<TD>%s</TD>' % pkgname\r
938 if hPath != "NULL":\r
939 desc += '<TD>\link %s \endlink</TD>' % hPath\r
940 else:\r
941 desc += '<TD>%s</TD>' % hPath\r
942 desc += '</TR>'\r
943 for lcObj in infObj.GetSectionObjectsByName('libraryclasses', self._arch):\r
944 desc += '<TR>'\r
945 desc += '<TD>%s</TD>' % lcObj.GetClass()\r
946 retarr = self.SearchLibraryClassHeaderFile(lcObj.GetClass(),\r
947 workspace,\r
948 refDecObjs)\r
4231a819 949 if retarr is not None:\r
7ccc9c95
YZ
950 pkgname, hPath = retarr\r
951 else:\r
952 self.Log('Fail find the library class %s definition from module %s dependent package!' % (lcObj.GetClass(), infObj.GetFilename()), 'error')\r
953 pkgname = 'NULL'\r
954 hPath = 'NULL'\r
955 desc += '<TD>Consume</TD>'\r
956 desc += '<TD>%s</TD>' % pkgname\r
957 desc += '<TD>\link %s \endlink</TD>' % hPath\r
958 desc += '</TR>'\r
959 desc += "</TABLE>"\r
960 section.AddDescription(desc)\r
961 modPage.AddSection(section)\r
962\r
963 section = doxygen.Section('SourceFiles', 'Source Files')\r
964 section.AddDescription('<ul>\n')\r
965 for obj in infObj.GetSourceObjects(self._arch, self._tooltag):\r
966 sPath = infObj.GetModuleRootPath()\r
967 sPath = os.path.join(sPath, obj.GetSourcePath()).replace('\\', '/').strip()\r
968 if sPath.lower().endswith('.uni') or sPath.lower().endswith('.s') or sPath.lower().endswith('.asm') or sPath.lower().endswith('.nasm'):\r
969 newPath = self.TranslateUniFile(sPath)\r
970 configFile.AddFile(newPath)\r
971 newPath = newPath[len(pObj.GetWorkspace()) + 1:]\r
972 section.AddDescription('<li> \link %s \endlink </li>' % newPath)\r
973 else:\r
974 self.ProcessSourceFileForInclude(sPath, pObj, configFile, infObj)\r
975 sPath = sPath[len(pObj.GetWorkspace()) + 1:]\r
976 section.AddDescription('<li>\link %s \endlink </li>' % sPath)\r
977 section.AddDescription('</ul>\n')\r
978 modPage.AddSection(section)\r
979\r
980 #sects = infObj.GetSectionByString('depex')\r
981 data = []\r
982 #for sect in sects:\r
983 for obj in infObj.GetSectionObjectsByName('depex'):\r
984 data.append(str(obj))\r
985 if len(data) != 0:\r
986 s = doxygen.Section('DependentSection', 'Module Dependencies')\r
987 s.AddDescription('<br>'.join(data))\r
988 modPage.AddSection(s)\r
989\r
990 return modPage\r
991\r
992 def TranslateUniFile(self, path):\r
993 newpath = path + '.dox'\r
994 #import core.textfile as textfile\r
995 #file = textfile.TextFile(path)\r
996\r
997 try:\r
7cc7e054 998 file = open(path, 'r')\r
5b0671c1 999 except (IOError, OSError) as msg:\r
7ccc9c95
YZ
1000 return None\r
1001\r
1002 t = file.read()\r
1003 file.close()\r
1004\r
1005 output = '/** @file \n'\r
1006 #output = '<html><body>'\r
1007 arr = t.split('\r\n')\r
1008 for line in arr:\r
1009 if line.find('@file') != -1:\r
1010 continue\r
1011 if line.find('*/') != -1:\r
1012 continue\r
1013 line = line.strip()\r
1014 if line.strip().startswith('/'):\r
1015 arr = line.split(' ')\r
1016 if len(arr) > 1:\r
1017 line = ' '.join(arr[1:])\r
1018 else:\r
1019 continue\r
1020 output += '%s<br>\n' % line\r
1021 output += '**/'\r
1022\r
1023 if os.path.exists(newpath):\r
1024 os.remove(newpath)\r
1025\r
1026 file = open(newpath, "w")\r
1027 file.write(output)\r
1028 file.close()\r
1029 return newpath\r
1030\r
1031 def SearchPcdPackage(self, pcdname, workspace, decObjs):\r
1032 for decObj in decObjs:\r
1033 for pcd in decObj.GetSectionObjectsByName('pcd'):\r
1034 if pcdname == pcd.GetPcdName():\r
1035 return decObj.GetBaseName()\r
1036 return None\r
1037\r
1038 def SearchProtocolPackage(self, protname, workspace, decObjs):\r
1039 for decObj in decObjs:\r
1040 for proto in decObj.GetSectionObjectsByName('protocol'):\r
1041 if protname == proto.GetName():\r
1042 return decObj.GetBaseName()\r
1043 return None\r
1044\r
1045 def SearchPpiPackage(self, ppiname, workspace, decObjs):\r
1046 for decObj in decObjs:\r
1047 for ppi in decObj.GetSectionObjectsByName('ppi'):\r
1048 if ppiname == ppi.GetName():\r
1049 return decObj.GetBaseName()\r
1050 return None\r
1051\r
1052 def SearchGuidPackage(self, guidname, workspace, decObjs):\r
1053 for decObj in decObjs:\r
1054 for guid in decObj.GetSectionObjectsByName('guid'):\r
1055 if guidname == guid.GetName():\r
1056 return decObj.GetBaseName()\r
1057 return None\r
1058\r
1059 def SearchLibraryClassHeaderFile(self, className, workspace, decObjs):\r
1060 for decObj in decObjs:\r
1061 for cls in decObj.GetSectionObjectsByName('libraryclasses'):\r
1062 if cls.GetClassName().strip() == className:\r
1063 path = cls.GetHeaderFile().strip()\r
1064 path = os.path.join(decObj.GetPackageRootPath(), path)\r
1065 path = path[len(workspace) + 1:]\r
1066 return decObj.GetBaseName(), path.replace('\\', '/')\r
1067\r
1068 return None\r
1069\r
1070 def _ConvertPathToDoxygen(self, path, pObj):\r
1071 pRootPath = pObj.GetWorkspace()\r
1072 path = path[len(pRootPath) + 1:]\r
1073 return path.replace('\\', '/')\r
1074\r
1075def IsCHeaderFile(path):\r
1076 return CheckPathPostfix(path, 'h')\r
1077\r
1078def CheckPathPostfix(path, str):\r
1079 index = path.rfind('.')\r
1080 if index == -1:\r
1081 return False\r
1082 if path[index + 1:].lower() == str.lower():\r
1083 return True\r
1084 return False\r