]>
Commit | Line | Data |
---|---|---|
7ccc9c95 YZ |
1 | ## @file\r |
2 | # This module provide command line entry for generating package document!\r | |
3 | #\r | |
4 | # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r | |
5 | #\r | |
6 | # This program and the accompanying materials are licensed and made available\r | |
7 | # under the terms and conditions of the BSD License which accompanies this\r | |
8 | # distribution. The full text of the license may be found at\r | |
9 | # http://opensource.org/licenses/bsd-license.php\r | |
10 | #\r | |
11 | # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
12 | # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
13 | #\r | |
14 | \r | |
72443dd2 | 15 | from __future__ import print_function\r |
7ccc9c95 YZ |
16 | import os, sys, logging, traceback, subprocess\r |
17 | from optparse import OptionParser\r | |
18 | \r | |
19 | import plugins.EdkPlugins.edk2.model.baseobject as baseobject\r | |
20 | import plugins.EdkPlugins.edk2.model.doxygengen as doxygengen\r | |
21 | \r | |
22 | gArchMarcoDict = {'ALL' : 'MDE_CPU_IA32 MDE_CPU_X64 MDE_CPU_EBC MDE_CPU_IPF _MSC_EXTENSIONS __GNUC__ __INTEL_COMPILER',\r | |
23 | 'IA32_MSFT': 'MDE_CPU_IA32 _MSC_EXTENSIONS',\r | |
24 | 'IA32_GNU' : 'MDE_CPU_IA32 __GNUC__',\r | |
25 | 'X64_MSFT' : 'MDE_CPU_X64 _MSC_EXTENSIONS ASM_PFX= OPTIONAL= ',\r | |
26 | 'X64_GNU' : 'MDE_CPU_X64 __GNUC__ ASM_PFX= OPTIONAL= ',\r | |
27 | 'IPF_MSFT' : 'MDE_CPU_IPF _MSC_EXTENSIONS ASM_PFX= OPTIONAL= ',\r | |
28 | 'IPF_GNU' : 'MDE_CPU_IPF __GNUC__ ASM_PFX= OPTIONAL= ',\r | |
29 | 'EBC_INTEL': 'MDE_CPU_EBC __INTEL_COMPILER ASM_PFX= OPTIONAL= '}\r | |
30 | \r | |
31 | def parseCmdArgs():\r | |
32 | parser = OptionParser(version="Package Document Generation Tools - Version 0.1")\r | |
33 | parser.add_option('-w', '--workspace', action='store', type='string', dest='WorkspacePath',\r | |
34 | help='Specify workspace absolute path. For example: c:\\tianocore')\r | |
35 | parser.add_option('-p', '--decfile', action='store', dest='PackagePath',\r | |
36 | help='Specify the absolute path for package DEC file. For example: c:\\tianocore\\MdePkg\\MdePkg.dec')\r | |
37 | parser.add_option('-x', '--doxygen', action='store', dest='DoxygenPath',\r | |
38 | help='Specify the absolute path of doxygen tools installation. For example: C:\\Program Files\\doxygen\bin\doxygen.exe')\r | |
39 | parser.add_option('-o', '--output', action='store', dest='OutputPath',\r | |
40 | help='Specify the document output path. For example: c:\\docoutput')\r | |
41 | parser.add_option('-a', '--arch', action='store', dest='Arch', choices=gArchMarcoDict.keys(),\r | |
42 | help='Specify the architecture used in preprocess package\'s source. For example: -a IA32_MSFT')\r | |
43 | parser.add_option('-m', '--mode', action='store', dest='DocumentMode', choices=['CHM', 'HTML'],\r | |
44 | help='Specify the document mode from : CHM or HTML')\r | |
45 | parser.add_option('-i', '--includeonly', action='store_true', dest='IncludeOnly',\r | |
46 | help='Only generate document for package\'s public interfaces produced by include folder. ')\r | |
47 | parser.add_option('-c', '--htmlworkshop', dest='HtmlWorkshopPath',\r | |
48 | help='Specify the absolute path for Microsoft HTML Workshop\'s hhc.exe file. For example: C:\\Program Files\\HTML Help Workshop\\hhc.exe')\r | |
49 | (options, args) = parser.parse_args()\r | |
50 | \r | |
51 | # validate the options\r | |
52 | errors = []\r | |
4231a819 | 53 | if options.WorkspacePath is None:\r |
7ccc9c95 YZ |
54 | errors.append('- Please specify workspace path via option -w!')\r |
55 | elif not os.path.exists(options.WorkspacePath):\r | |
56 | errors.append("- Invalid workspace path %s! The workspace path should be exist in absolute path!" % options.WorkspacePath)\r | |
57 | \r | |
4231a819 | 58 | if options.PackagePath is None:\r |
7ccc9c95 YZ |
59 | errors.append('- Please specify package DEC file path via option -p!')\r |
60 | elif not os.path.exists(options.PackagePath):\r | |
61 | errors.append("- Invalid package's DEC file path %s! The DEC path should be exist in absolute path!" % options.PackagePath)\r | |
62 | \r | |
63 | default = "C:\\Program Files\\doxygen\\bin\\doxygen.exe"\r | |
4231a819 | 64 | if options.DoxygenPath is None:\r |
7ccc9c95 | 65 | if os.path.exists(default):\r |
72443dd2 | 66 | print("Warning: Assume doxygen tool is installed at %s. If not, please specify via -x" % default)\r |
7ccc9c95 YZ |
67 | options.DoxygenPath = default\r |
68 | else:\r | |
69 | errors.append('- Please specify the path of doxygen tool installation via option -x! or install it in default path %s' % default)\r | |
70 | elif not os.path.exists(options.DoxygenPath):\r | |
71 | errors.append("- Invalid doxygen tool path %s! The doxygen tool path should be exist in absolute path!" % options.DoxygenPath)\r | |
72 | \r | |
4231a819 | 73 | if options.OutputPath is not None:\r |
7ccc9c95 YZ |
74 | if not os.path.exists(options.OutputPath):\r |
75 | # create output\r | |
76 | try:\r | |
77 | os.makedirs(options.OutputPath)\r | |
78 | except:\r | |
79 | errors.append('- Fail to create the output directory %s' % options.OutputPath)\r | |
80 | else:\r | |
4231a819 | 81 | if options.PackagePath is not None and os.path.exists(options.PackagePath):\r |
7ccc9c95 YZ |
82 | dirpath = os.path.dirname(options.PackagePath)\r |
83 | default = os.path.join (dirpath, "Document")\r | |
72443dd2 | 84 | print('Warning: Assume document output at %s. If not, please specify via option -o' % default)\r |
7ccc9c95 YZ |
85 | options.OutputPath = default\r |
86 | if not os.path.exists(default):\r | |
87 | try:\r | |
88 | os.makedirs(default)\r | |
89 | except:\r | |
90 | errors.append('- Fail to create default output directory %s! Please specify document output diretory via option -o' % default)\r | |
91 | else:\r | |
92 | errors.append('- Please specify document output path via option -o!')\r | |
93 | \r | |
4231a819 | 94 | if options.Arch is None:\r |
7ccc9c95 | 95 | options.Arch = 'ALL'\r |
72443dd2 | 96 | print("Warning: Assume arch is \"ALL\". If not, specify via -a")\r |
7ccc9c95 | 97 | \r |
4231a819 | 98 | if options.DocumentMode is None:\r |
7ccc9c95 | 99 | options.DocumentMode = "HTML"\r |
72443dd2 | 100 | print("Warning: Assume document mode is \"HTML\". If not, specify via -m")\r |
7ccc9c95 | 101 | \r |
4231a819 | 102 | if options.IncludeOnly is None:\r |
7ccc9c95 | 103 | options.IncludeOnly = False\r |
72443dd2 | 104 | print("Warning: Assume generate package document for all package\'s source including publich interfaces and implementation libraries and modules.")\r |
7ccc9c95 YZ |
105 | \r |
106 | if options.DocumentMode.lower() == 'chm':\r | |
107 | default = "C:\\Program Files\\HTML Help Workshop\\hhc.exe"\r | |
4231a819 | 108 | if options.HtmlWorkshopPath is None:\r |
7ccc9c95 | 109 | if os.path.exists(default):\r |
72443dd2 | 110 | print('Warning: Assume the installation path of Microsoft HTML Workshop is %s. If not, specify via option -c.' % default)\r |
7ccc9c95 YZ |
111 | options.HtmlWorkshopPath = default\r |
112 | else:\r | |
113 | errors.append('- Please specify the installation path of Microsoft HTML Workshop via option -c!')\r | |
114 | elif not os.path.exists(options.HtmlWorkshopPath):\r | |
115 | errors.append('- The installation path of Microsoft HTML Workshop %s does not exists. ' % options.HtmlWorkshopPath)\r | |
116 | \r | |
117 | if len(errors) != 0:\r | |
72443dd2 | 118 | print('\n')\r |
7ccc9c95 YZ |
119 | parser.error('Fail to start due to following reasons: \n%s' %'\n'.join(errors))\r |
120 | return (options.WorkspacePath, options.PackagePath, options.DoxygenPath, options.OutputPath,\r | |
121 | options.Arch, options.DocumentMode, options.IncludeOnly, options.HtmlWorkshopPath)\r | |
122 | \r | |
123 | def createPackageObject(wsPath, pkgPath):\r | |
124 | try:\r | |
125 | pkgObj = baseobject.Package(None, wsPath)\r | |
126 | pkgObj.Load(pkgPath)\r | |
127 | except:\r | |
128 | logging.getLogger().error ('Fail to create package object!')\r | |
129 | return None\r | |
130 | \r | |
131 | return pkgObj\r | |
132 | \r | |
133 | def callbackLogMessage(msg, level):\r | |
72443dd2 | 134 | print(msg.strip())\r |
7ccc9c95 YZ |
135 | \r |
136 | def callbackCreateDoxygenProcess(doxPath, configPath):\r | |
137 | if sys.platform == 'win32':\r | |
138 | cmd = '"%s" %s' % (doxPath, configPath)\r | |
139 | else:\r | |
140 | cmd = '%s %s' % (doxPath, configPath)\r | |
72443dd2 | 141 | print(cmd)\r |
7ccc9c95 YZ |
142 | subprocess.call(cmd, shell=True)\r |
143 | \r | |
144 | \r | |
145 | def DocumentFixup(outPath, arch):\r | |
146 | # find BASE_LIBRARY_JUMP_BUFFER structure reference page\r | |
147 | \r | |
72443dd2 | 148 | print('\n >>> Start fixup document \n')\r |
7ccc9c95 YZ |
149 | \r |
150 | for root, dirs, files in os.walk(outPath):\r | |
151 | for dir in dirs:\r | |
152 | if dir.lower() in ['.svn', '_svn', 'cvs']:\r | |
153 | dirs.remove(dir)\r | |
154 | for file in files:\r | |
155 | if not file.lower().endswith('.html'): continue\r | |
156 | fullpath = os.path.join(outPath, root, file)\r | |
157 | try:\r | |
158 | f = open(fullpath, 'r')\r | |
159 | text = f.read()\r | |
160 | f.close()\r | |
161 | except:\r | |
162 | logging.getLogger().error('\nFail to open file %s\n' % fullpath)\r | |
163 | continue\r | |
164 | if arch.lower() == 'all':\r | |
165 | if text.find('BASE_LIBRARY_JUMP_BUFFER Struct Reference') != -1:\r | |
166 | FixPageBASE_LIBRARY_JUMP_BUFFER(fullpath, text)\r | |
167 | if text.find('MdePkg/Include/Library/BaseLib.h File Reference') != -1:\r | |
168 | FixPageBaseLib(fullpath, text)\r | |
169 | if text.find('IA32_IDT_GATE_DESCRIPTOR Union Reference') != -1:\r | |
170 | FixPageIA32_IDT_GATE_DESCRIPTOR(fullpath, text)\r | |
171 | if text.find('MdePkg/Include/Library/UefiDriverEntryPoint.h File Reference') != -1:\r | |
172 | FixPageUefiDriverEntryPoint(fullpath, text)\r | |
173 | if text.find('MdePkg/Include/Library/UefiApplicationEntryPoint.h File Reference') != -1:\r | |
174 | FixPageUefiApplicationEntryPoint(fullpath, text)\r | |
175 | \r | |
72443dd2 | 176 | print(' >>> Finish all document fixing up! \n')\r |
7ccc9c95 YZ |
177 | \r |
178 | def FixPageBaseLib(path, text):\r | |
72443dd2 | 179 | print(' >>> Fixup BaseLib file page at file %s \n' % path)\r |
7ccc9c95 YZ |
180 | lines = text.split('\n')\r |
181 | lastBaseJumpIndex = -1\r | |
182 | lastIdtGateDescriptor = -1\r | |
183 | for index in range(len(lines) - 1, -1, -1):\r | |
184 | line = lines[index]\r | |
185 | if line.strip() == '<td class="memname">#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 4 </td>':\r | |
186 | lines[index] = '<td class="memname">#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 4 [IA32] </td>'\r | |
187 | if line.strip() == '<td class="memname">#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 0x10 </td>':\r | |
188 | lines[index] = '<td class="memname">#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 0x10 [IPF] </td>'\r | |
189 | if line.strip() == '<td class="memname">#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 8 </td>':\r | |
190 | lines[index] = '<td class="memname">#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 9 [EBC, x64] </td>'\r | |
191 | if line.find('BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a> 4') != -1:\r | |
192 | lines[index] = lines[index].replace('BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a> 4',\r | |
193 | 'BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a> 4 [IA32]')\r | |
194 | if line.find('BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a> 0x10') != -1:\r | |
195 | lines[index] = lines[index].replace('BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a> 0x10',\r | |
196 | 'BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a> 0x10 [IPF]')\r | |
197 | if line.find('BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a> 8') != -1:\r | |
198 | lines[index] = lines[index].replace('BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a> 8',\r | |
199 | 'BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a> 8 [x64, EBC]')\r | |
200 | if line.find('>BASE_LIBRARY_JUMP_BUFFER</a>') != -1:\r | |
201 | if lastBaseJumpIndex != -1:\r | |
202 | del lines[lastBaseJumpIndex]\r | |
203 | lastBaseJumpIndex = index\r | |
204 | if line.find('>IA32_IDT_GATE_DESCRIPTOR</a></td>') != -1:\r | |
205 | if lastIdtGateDescriptor != -1:\r | |
206 | del lines[lastIdtGateDescriptor]\r | |
207 | lastIdtGateDescriptor = index\r | |
208 | try:\r | |
209 | f = open(path, 'w')\r | |
210 | f.write('\n'.join(lines))\r | |
211 | f.close()\r | |
212 | except:\r | |
213 | logging.getLogger().error(" <<< Fail to fixup file %s\n" % path)\r | |
214 | return\r | |
72443dd2 | 215 | print(" <<< Finish to fixup file %s\n" % path)\r |
7ccc9c95 YZ |
216 | \r |
217 | def FixPageIA32_IDT_GATE_DESCRIPTOR(path, text):\r | |
72443dd2 | 218 | print(' >>> Fixup structure reference IA32_IDT_GATE_DESCRIPTOR at file %s \n' % path)\r |
7ccc9c95 YZ |
219 | lines = text.split('\n')\r |
220 | for index in range(len(lines) - 1, -1, -1):\r | |
221 | line = lines[index].strip()\r | |
222 | if line.find('struct {</td>') != -1 and lines[index - 2].find('>Uint64</a></td>') != -1:\r | |
223 | lines.insert(index, '<tr><td colspan="2"><br><h2>Data Fields For X64</h2></td></tr>')\r | |
224 | if line.find('struct {</td>') != -1 and lines[index - 1].find('Data Fields') != -1:\r | |
225 | lines.insert(index, '<tr><td colspan="2"><br><h2>Data Fields For IA32</h2></td></tr>')\r | |
226 | try:\r | |
227 | f = open(path, 'w')\r | |
228 | f.write('\n'.join(lines))\r | |
229 | f.close()\r | |
230 | except:\r | |
231 | logging.getLogger().error(" <<< Fail to fixup file %s\n" % path)\r | |
232 | return\r | |
72443dd2 | 233 | print(" <<< Finish to fixup file %s\n" % path)\r |
7ccc9c95 YZ |
234 | \r |
235 | def FixPageBASE_LIBRARY_JUMP_BUFFER(path, text):\r | |
72443dd2 | 236 | print(' >>> Fixup structure reference BASE_LIBRARY_JUMP_BUFFER at file %s \n' % path)\r |
7ccc9c95 YZ |
237 | lines = text.split('\n')\r |
238 | bInDetail = True\r | |
239 | bNeedRemove = False\r | |
240 | for index in range(len(lines) - 1, -1, -1):\r | |
241 | line = lines[index]\r | |
242 | if line.find('Detailed Description') != -1:\r | |
243 | bInDetail = False\r | |
244 | if line.startswith('EBC context buffer used by') and lines[index - 1].startswith('x64 context buffer'):\r | |
245 | lines[index] = "IA32/IPF/X64/" + line\r | |
246 | bNeedRemove = True\r | |
247 | if line.startswith("x64 context buffer") or line.startswith('IPF context buffer used by') or \\r | |
248 | line.startswith('IA32 context buffer used by'):\r | |
249 | if bNeedRemove:\r | |
250 | lines.remove(line)\r | |
251 | if line.find('>R0</a>') != -1 and not bInDetail:\r | |
252 | if lines[index - 1] != '<tr><td colspan="2"><br><h2>Data Fields For EBC</h2></td></tr>':\r | |
253 | lines.insert(index, '<tr><td colspan="2"><br><h2>Data Fields For EBC</h2></td></tr>')\r | |
254 | if line.find('>Rbx</a>') != -1 and not bInDetail:\r | |
255 | if lines[index - 1] != '<tr><td colspan="2"><br><h2>Data Fields For X64</h2></td></tr>':\r | |
256 | lines.insert(index, '<tr><td colspan="2"><br><h2>Data Fields For X64</h2></td></tr>')\r | |
257 | if line.find('>F2</a>') != -1 and not bInDetail:\r | |
258 | if lines[index - 1] != '<tr><td colspan="2"><br><h2>Data Fields For IPF</h2></td></tr>':\r | |
259 | lines.insert(index, '<tr><td colspan="2"><br><h2>Data Fields For IPF</h2></td></tr>')\r | |
260 | if line.find('>Ebx</a>') != -1 and not bInDetail:\r | |
261 | if lines[index - 1] != '<tr><td colspan="2"><br><h2>Data Fields For IA32</h2></td></tr>':\r | |
262 | lines.insert(index, '<tr><td colspan="2"><br><h2>Data Fields For IA32</h2></td></tr>')\r | |
263 | try:\r | |
264 | f = open(path, 'w')\r | |
265 | f.write('\n'.join(lines))\r | |
266 | f.close()\r | |
267 | except:\r | |
268 | logging.getLogger().error(" <<< Fail to fixup file %s" % path)\r | |
269 | return\r | |
72443dd2 | 270 | print(" <<< Finish to fixup file %s\n" % path)\r |
7ccc9c95 YZ |
271 | \r |
272 | def FixPageUefiDriverEntryPoint(path, text):\r | |
72443dd2 | 273 | print(' >>> Fixup file reference MdePkg/Include/Library/UefiDriverEntryPoint.h at file %s \n' % path)\r |
7ccc9c95 YZ |
274 | lines = text.split('\n')\r |
275 | bInModuleEntry = False\r | |
276 | bInEfiMain = False\r | |
277 | ModuleEntryDlCount = 0\r | |
278 | ModuleEntryDelStart = 0\r | |
279 | ModuleEntryDelEnd = 0\r | |
280 | EfiMainDlCount = 0\r | |
281 | EfiMainDelStart = 0\r | |
282 | EfiMainDelEnd = 0\r | |
283 | \r | |
284 | for index in range(len(lines)):\r | |
285 | line = lines[index].strip()\r | |
286 | if line.find('EFI_STATUS</a> EFIAPI _ModuleEntryPoint </td>') != -1:\r | |
287 | bInModuleEntry = True\r | |
288 | if line.find('EFI_STATUS</a> EFIAPI EfiMain </td>') != -1:\r | |
289 | bInEfiMain = True\r | |
290 | if line.startswith('<p>References <a'):\r | |
291 | if bInModuleEntry:\r | |
292 | ModuleEntryDelEnd = index - 1\r | |
293 | bInModuleEntry = False\r | |
294 | elif bInEfiMain:\r | |
295 | EfiMainDelEnd = index - 1\r | |
296 | bInEfiMain = False\r | |
297 | if bInModuleEntry:\r | |
298 | if line.startswith('</dl>'):\r | |
299 | ModuleEntryDlCount = ModuleEntryDlCount + 1\r | |
300 | if ModuleEntryDlCount == 1:\r | |
301 | ModuleEntryDelStart = index + 1\r | |
302 | if bInEfiMain:\r | |
303 | if line.startswith('</dl>'):\r | |
304 | EfiMainDlCount = EfiMainDlCount + 1\r | |
305 | if EfiMainDlCount == 1:\r | |
306 | EfiMainDelStart = index + 1\r | |
307 | \r | |
308 | if EfiMainDelEnd > EfiMainDelStart:\r | |
309 | for index in range(EfiMainDelEnd, EfiMainDelStart, -1):\r | |
310 | del lines[index]\r | |
311 | if ModuleEntryDelEnd > ModuleEntryDelStart:\r | |
312 | for index in range(ModuleEntryDelEnd, ModuleEntryDelStart, -1):\r | |
313 | del lines[index]\r | |
314 | \r | |
315 | try:\r | |
316 | f = open(path, 'w')\r | |
317 | f.write('\n'.join(lines))\r | |
318 | f.close()\r | |
319 | except:\r | |
320 | logging.getLogger().error(" <<< Fail to fixup file %s" % path)\r | |
321 | return\r | |
72443dd2 | 322 | print(" <<< Finish to fixup file %s\n" % path)\r |
7ccc9c95 YZ |
323 | \r |
324 | \r | |
325 | def FixPageUefiApplicationEntryPoint(path, text):\r | |
72443dd2 | 326 | print(' >>> Fixup file reference MdePkg/Include/Library/UefiApplicationEntryPoint.h at file %s \n' % path)\r |
7ccc9c95 YZ |
327 | lines = text.split('\n')\r |
328 | bInModuleEntry = False\r | |
329 | bInEfiMain = False\r | |
330 | ModuleEntryDlCount = 0\r | |
331 | ModuleEntryDelStart = 0\r | |
332 | ModuleEntryDelEnd = 0\r | |
333 | EfiMainDlCount = 0\r | |
334 | EfiMainDelStart = 0\r | |
335 | EfiMainDelEnd = 0\r | |
336 | \r | |
337 | for index in range(len(lines)):\r | |
338 | line = lines[index].strip()\r | |
339 | if line.find('EFI_STATUS</a> EFIAPI _ModuleEntryPoint </td>') != -1:\r | |
340 | bInModuleEntry = True\r | |
341 | if line.find('EFI_STATUS</a> EFIAPI EfiMain </td>') != -1:\r | |
342 | bInEfiMain = True\r | |
343 | if line.startswith('<p>References <a'):\r | |
344 | if bInModuleEntry:\r | |
345 | ModuleEntryDelEnd = index - 1\r | |
346 | bInModuleEntry = False\r | |
347 | elif bInEfiMain:\r | |
348 | EfiMainDelEnd = index - 1\r | |
349 | bInEfiMain = False\r | |
350 | if bInModuleEntry:\r | |
351 | if line.startswith('</dl>'):\r | |
352 | ModuleEntryDlCount = ModuleEntryDlCount + 1\r | |
353 | if ModuleEntryDlCount == 1:\r | |
354 | ModuleEntryDelStart = index + 1\r | |
355 | if bInEfiMain:\r | |
356 | if line.startswith('</dl>'):\r | |
357 | EfiMainDlCount = EfiMainDlCount + 1\r | |
358 | if EfiMainDlCount == 1:\r | |
359 | EfiMainDelStart = index + 1\r | |
360 | \r | |
361 | if EfiMainDelEnd > EfiMainDelStart:\r | |
362 | for index in range(EfiMainDelEnd, EfiMainDelStart, -1):\r | |
363 | del lines[index]\r | |
364 | if ModuleEntryDelEnd > ModuleEntryDelStart:\r | |
365 | for index in range(ModuleEntryDelEnd, ModuleEntryDelStart, -1):\r | |
366 | del lines[index]\r | |
367 | \r | |
368 | try:\r | |
369 | f = open(path, 'w')\r | |
370 | f.write('\n'.join(lines))\r | |
371 | f.close()\r | |
372 | except:\r | |
373 | logging.getLogger().error(" <<< Fail to fixup file %s" % path)\r | |
374 | return\r | |
72443dd2 | 375 | print(" <<< Finish to fixup file %s\n" % path)\r |
7ccc9c95 YZ |
376 | \r |
377 | if __name__ == '__main__':\r | |
378 | wspath, pkgpath, doxpath, outpath, archtag, docmode, isinc, hwpath = parseCmdArgs()\r | |
379 | \r | |
380 | # configure logging system\r | |
381 | logfilepath = os.path.join(outpath, 'log.txt')\r | |
382 | logging.basicConfig(format='%(levelname)-8s %(message)s', level=logging.DEBUG)\r | |
383 | \r | |
384 | # create package model object firstly\r | |
385 | pkgObj = createPackageObject(wspath, pkgpath)\r | |
4231a819 | 386 | if pkgObj is None:\r |
7ccc9c95 YZ |
387 | sys.exit(-1)\r |
388 | \r | |
389 | # create doxygen action model\r | |
390 | arch = None\r | |
391 | tooltag = None\r | |
392 | if archtag.lower() != 'all':\r | |
393 | arch = archtag.split('_')[0]\r | |
394 | tooltag = archtag.split('_')[1]\r | |
395 | else:\r | |
396 | arch = 'all'\r | |
397 | tooltag = 'all'\r | |
398 | \r | |
399 | # preprocess package and call doxygen\r | |
400 | try:\r | |
401 | action = doxygengen.PackageDocumentAction(doxpath,\r | |
402 | hwpath,\r | |
403 | outpath,\r | |
404 | pkgObj,\r | |
405 | docmode,\r | |
406 | callbackLogMessage,\r | |
407 | arch,\r | |
408 | tooltag,\r | |
409 | isinc,\r | |
410 | True)\r | |
411 | action.RegisterCallbackDoxygenProcess(callbackCreateDoxygenProcess)\r | |
412 | action.Generate()\r | |
413 | except:\r | |
414 | message = traceback.format_exception(*sys.exc_info())\r | |
415 | logging.getLogger().error('Fail to create doxygen action! \n%s' % ''.join(message))\r | |
416 | sys.exit(-1)\r | |
417 | \r | |
418 | DocumentFixup(outpath, arch)\r | |
419 | \r | |
420 | # generate CHM is necessary\r | |
421 | if docmode.lower() == 'chm':\r | |
422 | indexpath = os.path.join(outpath, 'html', 'index.hhp')\r | |
423 | if sys.platform == 'win32':\r | |
424 | cmd = '"%s" %s' % (hwpath, indexpath)\r | |
425 | else:\r | |
426 | cmd = '%s %s' % (hwpath, indexpath)\r | |
427 | subprocess.call(cmd)\r | |
72443dd2 | 428 | print('\nFinish to generate package document! Please open %s for review' % os.path.join(outpath, 'html', 'index.chm'))\r |
7ccc9c95 | 429 | else:\r |
72443dd2 | 430 | print('\nFinish to generate package document! Please open %s for review' % os.path.join(outpath, 'html', 'index.html'))\r |