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