]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/doxygengen.py
BaseTools: Add PackageDocumentTools into Scripts folder
[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
19import plugins.EdkPlugins.basemodel.doxygen as doxygen\r
20import os\r
21try:\r
22 import wx\r
23 gInGui = True\r
24except:\r
25 gInGui = False\r
26import re\r
27import plugins.EdkPlugins.edk2.model.inf as inf\r
28import plugins.EdkPlugins.edk2.model.dec as dec\r
29from plugins.EdkPlugins.basemodel.message import *\r
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
72 if self._log != None:\r
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
97 if indexPagePath == None:\r
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
112 if self._doxygenCallback != None:\r
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
169 if self._arch != None:\r
170 namestr += '[%s]' % self._arch\r
171 if self._tooltag != None:\r
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
317 if self._arch != None:\r
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
379 f = open(path, 'r')\r
380 lines = f.readlines()\r
381 f.close()\r
382 except IOError:\r
383 ErrorMsg('Fail to open file %s' % path)\r
384 return\r
385\r
386 configFile.AddFile(path)\r
387\r
388 no = 0\r
389 for no in xrange(len(lines)):\r
390 if len(lines[no].strip()) == 0:\r
391 continue\r
392 if lines[no].strip()[:2] in ['##', '//', '/*', '*/']:\r
393 continue\r
394 index = lines[no].lower().find('include')\r
395 #mo = IncludePattern.finditer(lines[no].lower())\r
396 mo = re.match(r"^#\s*include\s+[<\"]([\\/\w.]+)[>\"]$", lines[no].strip().lower())\r
397 if not mo:\r
398 continue\r
399 mo = re.match(r"^[#\w\s]+[<\"]([\\/\w.]+)[>\"]$", lines[no].strip())\r
400 filePath = mo.groups()[0]\r
401\r
402 if filePath == None or len(filePath) == 0:\r
403 continue\r
404\r
405 # find header file in module's path firstly.\r
406 fullPath = None\r
407\r
408 if os.path.exists(os.path.join(os.path.dirname(path), filePath)):\r
409 # Find the file in current directory\r
410 fullPath = os.path.join(os.path.dirname(path), filePath).replace('\\', '/')\r
411 else:\r
412 # find in depedent package's include path\r
413 incObjs = pObj.GetFileObj().GetSectionObjectsByName('includes')\r
414 for incObj in incObjs:\r
415 incPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), incObj.GetPath()).strip()\r
416 incPath = os.path.realpath(os.path.join(incPath, filePath))\r
417 if os.path.exists(incPath):\r
418 fullPath = incPath\r
419 break\r
420 if infObj != None:\r
421 pkgInfObjs = infObj.GetSectionObjectsByName('packages')\r
422 for obj in pkgInfObjs:\r
423 decObj = dec.DECFile(os.path.join(pObj.GetWorkspace(), obj.GetPath()))\r
424 if not decObj:\r
425 ErrorMsg ('Fail to create pacakge object for %s' % obj.GetPackageName())\r
426 continue\r
427 if not decObj.Parse():\r
428 ErrorMsg ('Fail to load package object for %s' % obj.GetPackageName())\r
429 continue\r
430 incObjs = decObj.GetSectionObjectsByName('includes')\r
431 for incObj in incObjs:\r
432 incPath = os.path.join(decObj.GetPackageRootPath(), incObj.GetPath()).replace('\\', '/')\r
433 if os.path.exists(os.path.join(incPath, filePath)):\r
434 fullPath = os.path.join(os.path.join(incPath, filePath))\r
435 break\r
436 if fullPath != None:\r
437 break\r
438\r
439 if fullPath == None and self.IsVerbose():\r
440 self.Log('Can not resolve header file %s for file %s in package %s\n' % (filePath, path, pObj.GetFileObj().GetFilename()), 'error')\r
441 return\r
442 else:\r
443 fullPath = fullPath.replace('\\', '/')\r
444 if self.IsVerbose():\r
445 self.Log('Preprocessing: Add include file %s for file %s\n' % (fullPath, path))\r
446 #LogMsg ('Preprocessing: Add include file %s for file %s' % (fullPath, path))\r
447 self.ProcessSourceFileForInclude(fullPath, pObj, configFile, infObj)\r
448\r
449 def AddAllIncludeFiles(self, pObj, configFile):\r
450 objs = pObj.GetFileObj().GetSectionObjectsByName('includes')\r
451 for obj in objs:\r
452 incPath = os.path.join(pObj.GetFileObj().GetPackageRootPath(), obj.GetPath())\r
453 for root, dirs, files in os.walk(incPath):\r
454 for dir in dirs:\r
455 if dir.lower() in _ignore_dir:\r
456 dirs.remove(dir)\r
457 for file in files:\r
458 path = os.path.normpath(os.path.join(root, file))\r
459 configFile.AddFile(path.replace('/', '\\'))\r
460\r
461 def GeneratePcdSubPages(self, pObj, configFile):\r
462 """\r
463 Generate sub pages for package's PCD definition.\r
464 @param pObj package object\r
465 @param configFile config file object\r
466 """\r
467 rootArray = []\r
468 objs = pObj.GetFileObj().GetSectionObjectsByName('pcd')\r
469 if len(objs) == 0:\r
470 return []\r
471\r
472 pcdRootPage = doxygen.Page('PCD', 'pcd_root_page')\r
473 typeRootPageDict = {}\r
474 typeArchRootPageDict = {}\r
475 for obj in objs:\r
476 if obj.GetPcdType() not in typeRootPageDict.keys():\r
477 typeRootPageDict[obj.GetPcdType()] = doxygen.Page(obj.GetPcdType(), 'pcd_%s_root_page' % obj.GetPcdType())\r
478 pcdRootPage.AddPage(typeRootPageDict[obj.GetPcdType()])\r
479 typeRoot = typeRootPageDict[obj.GetPcdType()]\r
480 if self._arch != None:\r
481 pcdPage = doxygen.Page('%s' % obj.GetPcdName(),\r
482 'pcd_%s_%s_%s' % (obj.GetPcdType(), obj.GetArch(), obj.GetPcdName().split('.')[1]))\r
483 pcdPage.AddDescription('<br>\n'.join(obj.GetComment()) + '<br>\n')\r
484 section = doxygen.Section('PCDinformation', 'PCD Information')\r
485 desc = '<TABLE>'\r
486 desc += '<TR>'\r
487 desc += '<TD><CAPTION>Name</CAPTION></TD>'\r
488 desc += '<TD><CAPTION>Token Space</CAPTION></TD>'\r
489 desc += '<TD><CAPTION>Token number</CAPTION></TD>'\r
490 desc += '<TD><CAPTION>Data Type</CAPTION></TD>'\r
491 desc += '<TD><CAPTION>Default Value</CAPTION></TD>'\r
492 desc += '</TR>'\r
493 desc += '<TR>'\r
494 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[1]\r
495 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[0]\r
496 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdToken()\r
497 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdDataType()\r
498 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdValue()\r
499 desc += '</TR>'\r
500 desc += '</TABLE>'\r
501 section.AddDescription(desc)\r
502 pcdPage.AddSection(section)\r
503 typeRoot.AddPage(pcdPage)\r
504 else:\r
505 keystr = obj.GetPcdType() + obj.GetArch()\r
506 if keystr not in typeArchRootPageDict.keys():\r
507 typeArchRootPage = doxygen.Page(obj.GetArch(), 'pcd_%s_%s_root_page' % (obj.GetPcdType(), obj.GetArch()))\r
508 typeArchRootPageDict[keystr] = typeArchRootPage\r
509 typeRoot.AddPage(typeArchRootPage)\r
510 typeArchRoot = typeArchRootPageDict[keystr]\r
511 pcdPage = doxygen.Page('%s' % obj.GetPcdName(),\r
512 'pcd_%s_%s_%s' % (obj.GetPcdType(), obj.GetArch(), obj.GetPcdName().split('.')[1]))\r
513 pcdPage.AddDescription('<br>\n'.join(obj.GetComment()) + '<br>\n')\r
514 section = doxygen.Section('PCDinformation', 'PCD Information')\r
515 desc = '<TABLE>'\r
516 desc += '<TR>'\r
517 desc += '<TD><CAPTION>Name</CAPTION></TD>'\r
518 desc += '<TD><CAPTION>Token Space</CAPTION></TD>'\r
519 desc += '<TD><CAPTION>Token number</CAPTION></TD>'\r
520 desc += '<TD><CAPTION>Data Type</CAPTION></TD>'\r
521 desc += '<TD><CAPTION>Default Value</CAPTION></TD>'\r
522 desc += '</TR>'\r
523 desc += '<TR>'\r
524 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[1]\r
525 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdName().split('.')[0]\r
526 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdToken()\r
527 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdDataType()\r
528 desc += '<TD><CAPTION>%s</CAPTION></TD>' % obj.GetPcdValue()\r
529 desc += '</TR>'\r
530 desc += '</TABLE>'\r
531 section.AddDescription(desc)\r
532 pcdPage.AddSection(section)\r
533 typeArchRoot.AddPage(pcdPage)\r
534 return [pcdRootPage]\r
535\r
536 def _GenerateGuidSubPage(self, pObj, obj, configFile):\r
537 guidPage = doxygen.Page('%s' % obj.GetName(),\r
538 'guid_%s_%s' % (obj.GetArch(), obj.GetName()))\r
539 comments = obj.GetComment()\r
540 if len(comments) != 0:\r
541 guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')\r
542 section = doxygen.Section('BasicGuidInfo', 'GUID Information')\r
543 desc = '<TABLE>'\r
544 desc += '<TR>'\r
545 desc += '<TD><CAPTION>GUID\'s Guid Name</CAPTION></TD><TD><CAPTION>GUID\'s Guid</CAPTION></TD>'\r
546 desc += '</TR>'\r
547 desc += '<TR>'\r
548 desc += '<TD>%s</TD>' % obj.GetName()\r
549 desc += '<TD>%s</TD>' % obj.GetGuid()\r
550 desc += '</TR>'\r
551 desc += '</TABLE>'\r
552 section.AddDescription(desc)\r
553 guidPage.AddSection(section)\r
554 refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)\r
555 if refFile:\r
556 relPath = refFile[len(pObj.GetWorkspace()) + 1:]\r
557 if len(comments) == 0:\r
558 guidPage.AddDescription(' \\copydoc %s <br>' % relPath)\r
559\r
560 section = doxygen.Section('ref', 'Refer to Header File')\r
561 section.AddDescription('\link %s\n' % relPath)\r
562 section.AddDescription('\endlink\n')\r
563 self.ProcessSourceFileForInclude(refFile, pObj, configFile)\r
564 guidPage.AddSection(section)\r
565 return guidPage\r
566\r
567 def GenerateGuidSubPages(self, pObj, configFile):\r
568 """\r
569 Generate sub pages for package's GUID definition.\r
570 @param pObj package object\r
571 @param configFilf doxygen config file object\r
572 """\r
573 pageRoot = doxygen.Page('GUID', 'guid_root_page')\r
574 objs = pObj.GetFileObj().GetSectionObjectsByName('guids', self._arch)\r
575 if len(objs) == 0: return []\r
576 if self._arch != None:\r
577 for obj in objs:\r
578 pageRoot.AddPage(self._GenerateGuidSubPage(pObj, obj, configFile))\r
579 else:\r
580 guidArchRootPageDict = {}\r
581 for obj in objs:\r
582 if obj.GetArch() not in guidArchRootPageDict.keys():\r
583 guidArchRoot = doxygen.Page(obj.GetArch(), 'guid_arch_root_%s' % obj.GetArch())\r
584 pageRoot.AddPage(guidArchRoot)\r
585 guidArchRootPageDict[obj.GetArch()] = guidArchRoot\r
586 guidArchRoot = guidArchRootPageDict[obj.GetArch()]\r
587 guidArchRoot.AddPage(self._GenerateGuidSubPage(pObj, obj, configFile))\r
588 return [pageRoot]\r
589\r
590 def _GeneratePpiSubPage(self, pObj, obj, configFile):\r
591 guidPage = doxygen.Page(obj.GetName(), 'ppi_page_%s' % obj.GetName())\r
592 comments = obj.GetComment()\r
593 if len(comments) != 0:\r
594 guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')\r
595 section = doxygen.Section('BasicPpiInfo', 'PPI Information')\r
596 desc = '<TABLE>'\r
597 desc += '<TR>'\r
598 desc += '<TD><CAPTION>PPI\'s Guid Name</CAPTION></TD><TD><CAPTION>PPI\'s Guid</CAPTION></TD>'\r
599 desc += '</TR>'\r
600 desc += '<TR>'\r
601 desc += '<TD>%s</TD>' % obj.GetName()\r
602 desc += '<TD>%s</TD>' % obj.GetGuid()\r
603 desc += '</TR>'\r
604 desc += '</TABLE>'\r
605 section.AddDescription(desc)\r
606 guidPage.AddSection(section)\r
607 refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)\r
608 if refFile:\r
609 relPath = refFile[len(pObj.GetWorkspace()) + 1:]\r
610 if len(comments) == 0:\r
611 guidPage.AddDescription(' \\copydoc %s <br>' % relPath)\r
612 section = doxygen.Section('ref', 'Refer to Header File')\r
613 section.AddDescription('\link %s\n' % relPath)\r
614 section.AddDescription('\endlink\n')\r
615 self.ProcessSourceFileForInclude(refFile, pObj, configFile)\r
616 guidPage.AddSection(section)\r
617\r
618 return guidPage\r
619\r
620 def GeneratePpiSubPages(self, pObj, configFile):\r
621 """\r
622 Generate sub pages for package's GUID definition.\r
623 @param pObj package object\r
624 @param configFilf doxygen config file object\r
625 """\r
626 pageRoot = doxygen.Page('PPI', 'ppi_root_page')\r
627 objs = pObj.GetFileObj().GetSectionObjectsByName('ppis', self._arch)\r
628 if len(objs) == 0: return []\r
629 if self._arch != None:\r
630 for obj in objs:\r
631 pageRoot.AddPage(self._GeneratePpiSubPage(pObj, obj, configFile))\r
632 else:\r
633 guidArchRootPageDict = {}\r
634 for obj in objs:\r
635 if obj.GetArch() not in guidArchRootPageDict.keys():\r
636 guidArchRoot = doxygen.Page(obj.GetArch(), 'ppi_arch_root_%s' % obj.GetArch())\r
637 pageRoot.AddPage(guidArchRoot)\r
638 guidArchRootPageDict[obj.GetArch()] = guidArchRoot\r
639 guidArchRoot = guidArchRootPageDict[obj.GetArch()]\r
640 guidArchRoot.AddPage(self._GeneratePpiSubPage(pObj, obj, configFile))\r
641 return [pageRoot]\r
642\r
643 def _GenerateProtocolSubPage(self, pObj, obj, configFile):\r
644 guidPage = doxygen.Page(obj.GetName(), 'protocol_page_%s' % obj.GetName())\r
645 comments = obj.GetComment()\r
646 if len(comments) != 0:\r
647 guidPage.AddDescription('<br>'.join(obj.GetComment()) + '<br>')\r
648 section = doxygen.Section('BasicProtocolInfo', 'PROTOCOL Information')\r
649 desc = '<TABLE>'\r
650 desc += '<TR>'\r
651 desc += '<TD><CAPTION>PROTOCOL\'s Guid Name</CAPTION></TD><TD><CAPTION>PROTOCOL\'s Guid</CAPTION></TD>'\r
652 desc += '</TR>'\r
653 desc += '<TR>'\r
654 desc += '<TD>%s</TD>' % obj.GetName()\r
655 desc += '<TD>%s</TD>' % obj.GetGuid()\r
656 desc += '</TR>'\r
657 desc += '</TABLE>'\r
658 section.AddDescription(desc)\r
659 guidPage.AddSection(section)\r
660\r
661 refFile = self.FindHeaderFileForGuid(pObj, obj.GetName(), configFile)\r
662 if refFile:\r
663 relPath = refFile[len(pObj.GetWorkspace()) + 1:]\r
664 if len(comments) == 0:\r
665 guidPage.AddDescription(' \\copydoc %s <br>' % relPath)\r
666 section = doxygen.Section('ref', 'Refer to Header File')\r
667 section.AddDescription('\link %s\n' % relPath)\r
668 section.AddDescription('\endlink\n')\r
669 self.ProcessSourceFileForInclude(refFile, pObj, configFile)\r
670 guidPage.AddSection(section)\r
671\r
672 return guidPage\r
673\r
674 def GenerateProtocolSubPages(self, pObj, configFile):\r
675 """\r
676 Generate sub pages for package's GUID definition.\r
677 @param pObj package object\r
678 @param configFilf doxygen config file object\r
679 """\r
680 pageRoot = doxygen.Page('PROTOCOL', 'protocol_root_page')\r
681 objs = pObj.GetFileObj().GetSectionObjectsByName('protocols', self._arch)\r
682 if len(objs) == 0: return []\r
683 if self._arch != None:\r
684 for obj in objs:\r
685 pageRoot.AddPage(self._GenerateProtocolSubPage(pObj, obj, configFile))\r
686 else:\r
687 guidArchRootPageDict = {}\r
688 for obj in objs:\r
689 if obj.GetArch() not in guidArchRootPageDict.keys():\r
690 guidArchRoot = doxygen.Page(obj.GetArch(), 'protocol_arch_root_%s' % obj.GetArch())\r
691 pageRoot.AddPage(guidArchRoot)\r
692 guidArchRootPageDict[obj.GetArch()] = guidArchRoot\r
693 guidArchRoot = guidArchRootPageDict[obj.GetArch()]\r
694 guidArchRoot.AddPage(self._GenerateProtocolSubPage(pObj, obj, configFile))\r
695 return [pageRoot]\r
696\r
697 def FindHeaderFileForGuid(self, pObj, name, configFile):\r
698 """\r
699 For declaration header file for GUID/PPI/Protocol.\r
700\r
701 @param pObj package object\r
702 @param name guid/ppi/protocol's name\r
703 @param configFile config file object\r
704\r
705 @return full path of header file and None if not found.\r
706 """\r
707 startPath = pObj.GetFileObj().GetPackageRootPath()\r
708 incPath = os.path.join(startPath, 'Include').replace('\\', '/')\r
709 # if <PackagePath>/include exist, then search header under it.\r
710 if os.path.exists(incPath):\r
711 startPath = incPath\r
712\r
713 for root, dirs, files in os.walk(startPath):\r
714 for dir in dirs:\r
715 if dir.lower() in _ignore_dir:\r
716 dirs.remove(dir)\r
717 for file in files:\r
718 fPath = os.path.join(root, file)\r
719 if not IsCHeaderFile(fPath):\r
720 continue\r
721 try:\r
722 f = open(fPath, 'r')\r
723 lines = f.readlines()\r
724 f.close()\r
725 except IOError:\r
726 self.Log('Fail to open file %s\n' % fPath)\r
727 continue\r
728 for line in lines:\r
729 if line.find(name) != -1 and \\r
730 line.find('extern') != -1:\r
731 return fPath.replace('\\', '/')\r
732 return None\r
733\r
734 def GetPackageModuleList(self, pObj):\r
735 """\r
736 Get all module's INF path under package's root path\r
737 @param pObj package object\r
738 @return arrary of INF full path\r
739 """\r
740 mArray = []\r
741 packPath = pObj.GetFileObj().GetPackageRootPath()\r
742 if not os.path.exists:\r
743 return None\r
744 for root, dirs, files in os.walk(packPath):\r
745 for dir in dirs:\r
746 if dir.lower() in _ignore_dir:\r
747 dirs.remove(dir)\r
748 for file in files:\r
749 if CheckPathPostfix(file, 'inf'):\r
750 fPath = os.path.join(root, file).replace('\\', '/')\r
751 mArray.append(fPath)\r
752 return mArray\r
753\r
754 def GenerateModulePages(self, pObj, configFile):\r
755 """\r
756 Generate sub pages for package's module which is under the package\r
757 root directory.\r
758\r
759 @param pObj package object\r
760 @param configFilf doxygen config file object\r
761 """\r
762 infList = self.GetPackageModuleList(pObj)\r
763 rootPages = []\r
764 libObjs = []\r
765 modObjs = []\r
766 for infpath in infList:\r
767 infObj = inf.INFFile(infpath)\r
768 #infObj = INFFileObject.INFFile (pObj.GetWorkspacePath(),\r
769 # inf)\r
770 if not infObj:\r
771 self.Log('Fail create INF object for %s' % inf)\r
772 continue\r
773 if not infObj.Parse():\r
774 self.Log('Fail to load INF file %s' % inf)\r
775 continue\r
776 if infObj.GetProduceLibraryClass() != None:\r
777 libObjs.append(infObj)\r
778 else:\r
779 modObjs.append(infObj)\r
780\r
781 if len(libObjs) != 0:\r
782 libRootPage = doxygen.Page('Libraries', 'lib_root_page')\r
783 rootPages.append(libRootPage)\r
784 for libInf in libObjs:\r
785 libRootPage.AddPage(self.GenerateModulePage(pObj, libInf, configFile, True))\r
786\r
787 if len(modObjs) != 0:\r
788 modRootPage = doxygen.Page('Modules', 'module_root_page')\r
789 rootPages.append(modRootPage)\r
790 for modInf in modObjs:\r
791 modRootPage.AddPage(self.GenerateModulePage(pObj, modInf, configFile, False))\r
792\r
793 return rootPages\r
794\r
795 def GenerateModulePage(self, pObj, infObj, configFile, isLib):\r
796 """\r
797 Generate page for a module/library.\r
798 @param infObj INF file object for module/library\r
799 @param configFile doxygen config file object\r
800 @param isLib Whether this module is libary\r
801\r
802 @param module doxygen page object\r
803 """\r
804 workspace = pObj.GetWorkspace()\r
805 refDecObjs = []\r
806 for obj in infObj.GetSectionObjectsByName('packages'):\r
807 decObj = dec.DECFile(os.path.join(workspace, obj.GetPath()))\r
808 if not decObj:\r
809 ErrorMsg ('Fail to create pacakge object for %s' % obj.GetPackageName())\r
810 continue\r
811 if not decObj.Parse():\r
812 ErrorMsg ('Fail to load package object for %s' % obj.GetPackageName())\r
813 continue\r
814 refDecObjs.append(decObj)\r
815\r
816 modPage = doxygen.Page('%s' % infObj.GetBaseName(),\r
817 'module_%s' % infObj.GetBaseName())\r
818 modPage.AddDescription(infObj.GetFileHeader())\r
819\r
820 basicInfSection = doxygen.Section('BasicModuleInformation', 'Basic Module Information')\r
821 desc = "<TABLE>"\r
822 for obj in infObj.GetSectionObjectsByName('defines'):\r
823 key = obj.GetKey()\r
824 value = obj.GetValue()\r
825 if key not in _inf_key_description_mapping_table.keys(): continue\r
826 if key == 'LIBRARY_CLASS' and value.find('|') != -1:\r
827 clsname, types = value.split('|')\r
828 desc += '<TR>'\r
829 desc += '<TD><B>%s</B></TD>' % _inf_key_description_mapping_table[key]\r
830 desc += '<TD>%s</TD>' % clsname\r
831 desc += '</TR>'\r
832\r
833 desc += '<TR>'\r
834 desc += '<TD><B>Supported Module Types</B></TD>'\r
835 desc += '<TD>%s</TD>' % types\r
836 desc += '</TR>'\r
837 else:\r
838 desc += '<TR>'\r
839 desc += '<TD><B>%s</B></TD>' % _inf_key_description_mapping_table[key]\r
840 if key == 'EFI_SPECIFICATION_VERSION' and value == '0x00020000':\r
841 value = '2.0'\r
842 desc += '<TD>%s</TD>' % value\r
843 desc += '</TR>'\r
844 desc += '</TABLE>'\r
845 basicInfSection.AddDescription(desc)\r
846 modPage.AddSection(basicInfSection)\r
847\r
848 # Add protocol section\r
849 data = []\r
850 for obj in infObj.GetSectionObjectsByName('pcd', self._arch):\r
851 data.append(obj.GetPcdName().strip())\r
852 if len(data) != 0:\r
853 s = doxygen.Section('Pcds', 'Pcds')\r
854 desc = "<TABLE>"\r
855 desc += '<TR><TD><B>PCD Name</B></TD><TD><B>TokenSpace</B></TD><TD><B>Package</B></TD></TR>'\r
856 for item in data:\r
857 desc += '<TR>'\r
858 desc += '<TD>%s</TD>' % item.split('.')[1]\r
859 desc += '<TD>%s</TD>' % item.split('.')[0]\r
860 pkgbasename = self.SearchPcdPackage(item, workspace, refDecObjs)\r
861 desc += '<TD>%s</TD>' % pkgbasename\r
862 desc += '</TR>'\r
863 desc += "</TABLE>"\r
864 s.AddDescription(desc)\r
865 modPage.AddSection(s)\r
866\r
867 # Add protocol section\r
868 #sects = infObj.GetSectionByString('protocol')\r
869 data = []\r
870 #for sect in sects:\r
871 for obj in infObj.GetSectionObjectsByName('protocol', self._arch):\r
872 data.append(obj.GetName().strip())\r
873 if len(data) != 0:\r
874 s = doxygen.Section('Protocols', 'Protocols')\r
875 desc = "<TABLE>"\r
876 desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'\r
877 for item in data:\r
878 desc += '<TR>'\r
879 desc += '<TD>%s</TD>' % item\r
880 pkgbasename = self.SearchProtocolPackage(item, workspace, refDecObjs)\r
881 desc += '<TD>%s</TD>' % pkgbasename\r
882 desc += '</TR>'\r
883 desc += "</TABLE>"\r
884 s.AddDescription(desc)\r
885 modPage.AddSection(s)\r
886\r
887 # Add ppi section\r
888 #sects = infObj.GetSectionByString('ppi')\r
889 data = []\r
890 #for sect in sects:\r
891 for obj in infObj.GetSectionObjectsByName('ppi', self._arch):\r
892 data.append(obj.GetName().strip())\r
893 if len(data) != 0:\r
894 s = doxygen.Section('Ppis', 'Ppis')\r
895 desc = "<TABLE>"\r
896 desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'\r
897 for item in data:\r
898 desc += '<TR>'\r
899 desc += '<TD>%s</TD>' % item\r
900 pkgbasename = self.SearchPpiPackage(item, workspace, refDecObjs)\r
901 desc += '<TD>%s</TD>' % pkgbasename\r
902 desc += '</TR>'\r
903 desc += "</TABLE>"\r
904 s.AddDescription(desc)\r
905 modPage.AddSection(s)\r
906\r
907 # Add guid section\r
908 #sects = infObj.GetSectionByString('guid')\r
909 data = []\r
910 #for sect in sects:\r
911 for obj in infObj.GetSectionObjectsByName('guid', self._arch):\r
912 data.append(obj.GetName().strip())\r
913 if len(data) != 0:\r
914 s = doxygen.Section('Guids', 'Guids')\r
915 desc = "<TABLE>"\r
916 desc += '<TR><TD><B>Name</B></TD><TD><B>Package</B></TD></TR>'\r
917 for item in data:\r
918 desc += '<TR>'\r
919 desc += '<TD>%s</TD>' % item\r
920 pkgbasename = self.SearchGuidPackage(item, workspace, refDecObjs)\r
921 desc += '<TD>%s</TD>' % pkgbasename\r
922 desc += '</TR>'\r
923 desc += "</TABLE>"\r
924 s.AddDescription(desc)\r
925 modPage.AddSection(s)\r
926\r
927 section = doxygen.Section('LibraryClasses', 'Library Classes')\r
928 desc = "<TABLE>"\r
929 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
930 if isLib:\r
931 desc += '<TR>'\r
932 desc += '<TD>%s</TD>' % infObj.GetProduceLibraryClass()\r
933 desc += '<TD>Produce</TD>'\r
934 try:\r
935 pkgname, hPath = self.SearchLibraryClassHeaderFile(infObj.GetProduceLibraryClass(),\r
936 workspace,\r
937 refDecObjs)\r
938 except:\r
939 self.Log ('fail to get package header file for lib class %s' % infObj.GetProduceLibraryClass())\r
940 pkgname = 'NULL'\r
941 hPath = 'NULL'\r
942 desc += '<TD>%s</TD>' % pkgname\r
943 if hPath != "NULL":\r
944 desc += '<TD>\link %s \endlink</TD>' % hPath\r
945 else:\r
946 desc += '<TD>%s</TD>' % hPath\r
947 desc += '</TR>'\r
948 for lcObj in infObj.GetSectionObjectsByName('libraryclasses', self._arch):\r
949 desc += '<TR>'\r
950 desc += '<TD>%s</TD>' % lcObj.GetClass()\r
951 retarr = self.SearchLibraryClassHeaderFile(lcObj.GetClass(),\r
952 workspace,\r
953 refDecObjs)\r
954 if retarr != None:\r
955 pkgname, hPath = retarr\r
956 else:\r
957 self.Log('Fail find the library class %s definition from module %s dependent package!' % (lcObj.GetClass(), infObj.GetFilename()), 'error')\r
958 pkgname = 'NULL'\r
959 hPath = 'NULL'\r
960 desc += '<TD>Consume</TD>'\r
961 desc += '<TD>%s</TD>' % pkgname\r
962 desc += '<TD>\link %s \endlink</TD>' % hPath\r
963 desc += '</TR>'\r
964 desc += "</TABLE>"\r
965 section.AddDescription(desc)\r
966 modPage.AddSection(section)\r
967\r
968 section = doxygen.Section('SourceFiles', 'Source Files')\r
969 section.AddDescription('<ul>\n')\r
970 for obj in infObj.GetSourceObjects(self._arch, self._tooltag):\r
971 sPath = infObj.GetModuleRootPath()\r
972 sPath = os.path.join(sPath, obj.GetSourcePath()).replace('\\', '/').strip()\r
973 if sPath.lower().endswith('.uni') or sPath.lower().endswith('.s') or sPath.lower().endswith('.asm') or sPath.lower().endswith('.nasm'):\r
974 newPath = self.TranslateUniFile(sPath)\r
975 configFile.AddFile(newPath)\r
976 newPath = newPath[len(pObj.GetWorkspace()) + 1:]\r
977 section.AddDescription('<li> \link %s \endlink </li>' % newPath)\r
978 else:\r
979 self.ProcessSourceFileForInclude(sPath, pObj, configFile, infObj)\r
980 sPath = sPath[len(pObj.GetWorkspace()) + 1:]\r
981 section.AddDescription('<li>\link %s \endlink </li>' % sPath)\r
982 section.AddDescription('</ul>\n')\r
983 modPage.AddSection(section)\r
984\r
985 #sects = infObj.GetSectionByString('depex')\r
986 data = []\r
987 #for sect in sects:\r
988 for obj in infObj.GetSectionObjectsByName('depex'):\r
989 data.append(str(obj))\r
990 if len(data) != 0:\r
991 s = doxygen.Section('DependentSection', 'Module Dependencies')\r
992 s.AddDescription('<br>'.join(data))\r
993 modPage.AddSection(s)\r
994\r
995 return modPage\r
996\r
997 def TranslateUniFile(self, path):\r
998 newpath = path + '.dox'\r
999 #import core.textfile as textfile\r
1000 #file = textfile.TextFile(path)\r
1001\r
1002 try:\r
1003 file = open(path, 'rb')\r
1004 except (IOError, OSError), msg:\r
1005 return None\r
1006\r
1007 t = file.read()\r
1008 file.close()\r
1009\r
1010 output = '/** @file \n'\r
1011 #output = '<html><body>'\r
1012 arr = t.split('\r\n')\r
1013 for line in arr:\r
1014 if line.find('@file') != -1:\r
1015 continue\r
1016 if line.find('*/') != -1:\r
1017 continue\r
1018 line = line.strip()\r
1019 if line.strip().startswith('/'):\r
1020 arr = line.split(' ')\r
1021 if len(arr) > 1:\r
1022 line = ' '.join(arr[1:])\r
1023 else:\r
1024 continue\r
1025 output += '%s<br>\n' % line\r
1026 output += '**/'\r
1027\r
1028 if os.path.exists(newpath):\r
1029 os.remove(newpath)\r
1030\r
1031 file = open(newpath, "w")\r
1032 file.write(output)\r
1033 file.close()\r
1034 return newpath\r
1035\r
1036 def SearchPcdPackage(self, pcdname, workspace, decObjs):\r
1037 for decObj in decObjs:\r
1038 for pcd in decObj.GetSectionObjectsByName('pcd'):\r
1039 if pcdname == pcd.GetPcdName():\r
1040 return decObj.GetBaseName()\r
1041 return None\r
1042\r
1043 def SearchProtocolPackage(self, protname, workspace, decObjs):\r
1044 for decObj in decObjs:\r
1045 for proto in decObj.GetSectionObjectsByName('protocol'):\r
1046 if protname == proto.GetName():\r
1047 return decObj.GetBaseName()\r
1048 return None\r
1049\r
1050 def SearchPpiPackage(self, ppiname, workspace, decObjs):\r
1051 for decObj in decObjs:\r
1052 for ppi in decObj.GetSectionObjectsByName('ppi'):\r
1053 if ppiname == ppi.GetName():\r
1054 return decObj.GetBaseName()\r
1055 return None\r
1056\r
1057 def SearchGuidPackage(self, guidname, workspace, decObjs):\r
1058 for decObj in decObjs:\r
1059 for guid in decObj.GetSectionObjectsByName('guid'):\r
1060 if guidname == guid.GetName():\r
1061 return decObj.GetBaseName()\r
1062 return None\r
1063\r
1064 def SearchLibraryClassHeaderFile(self, className, workspace, decObjs):\r
1065 for decObj in decObjs:\r
1066 for cls in decObj.GetSectionObjectsByName('libraryclasses'):\r
1067 if cls.GetClassName().strip() == className:\r
1068 path = cls.GetHeaderFile().strip()\r
1069 path = os.path.join(decObj.GetPackageRootPath(), path)\r
1070 path = path[len(workspace) + 1:]\r
1071 return decObj.GetBaseName(), path.replace('\\', '/')\r
1072\r
1073 return None\r
1074\r
1075 def _ConvertPathToDoxygen(self, path, pObj):\r
1076 pRootPath = pObj.GetWorkspace()\r
1077 path = path[len(pRootPath) + 1:]\r
1078 return path.replace('\\', '/')\r
1079\r
1080def IsCHeaderFile(path):\r
1081 return CheckPathPostfix(path, 'h')\r
1082\r
1083def CheckPathPostfix(path, str):\r
1084 index = path.rfind('.')\r
1085 if index == -1:\r
1086 return False\r
1087 if path[index + 1:].lower() == str.lower():\r
1088 return True\r
1089 return False\r