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