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