]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Scripts/PackageDocumentTools/packagedocapp.pyw
BaseTools: Use absolute import in Scripts
[mirror_edk2.git] / BaseTools / Scripts / PackageDocumentTools / packagedocapp.pyw
CommitLineData
7ccc9c95
YZ
1## @file\r
2# This file is used to define common string related functions used in parsing\r
3# process\r
4#\r
5# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
6#\r
7# This program and the accompanying materials are licensed and made available\r
8# under the terms and conditions of the BSD License which accompanies this\r
9# distribution. The full text of the license may be found at\r
10# http://opensource.org/licenses/bsd-license.php\r
11#\r
12# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14#\r
15\r
16import os, sys, wx, logging\r
17\r
18import wx.stc\r
19import wx.lib.newevent\r
20import wx.lib.agw.genericmessagedialog as GMD\r
21import plugins.EdkPlugins.edk2.model.baseobject as baseobject\r
22import plugins.EdkPlugins.edk2.model.doxygengen as doxygengen\r
23\r
24if hasattr(sys, "frozen"):\r
25 appPath = os.path.abspath(os.path.dirname(sys.executable))\r
26else:\r
27 appPath = os.path.abspath(os.path.dirname(__file__))\r
28\r
29AppCallBackEvent, EVT_APP_CALLBACK = wx.lib.newevent.NewEvent()\r
30LogEvent, EVT_LOG = wx.lib.newevent.NewEvent()\r
31\r
32class PackageDocApp(wx.App):\r
33\r
34 def OnInit(self):\r
35 logfile = os.path.join(appPath, 'log.txt')\r
36 logging.basicConfig(format='%(name)-8s %(levelname)-8s %(message)s',\r
37 filename=logfile, level=logging.ERROR)\r
38\r
39 self.SetAppName('Package Doxygen Generate Application')\r
40 frame = PackageDocMainFrame(None, "Package Document Generation Application!")\r
41 self.SetTopWindow(frame)\r
42\r
43 frame.Show(True)\r
44\r
45 EVT_APP_CALLBACK( self, self.OnAppCallBack)\r
46 return True\r
47\r
48 def GetLogger(self):\r
49 return logging.getLogger('')\r
50\r
51 def ForegroundProcess(self, function, args):\r
52 wx.PostEvent(self, AppCallBackEvent(callback=function, args=args))\r
53\r
54 def OnAppCallBack(self, event):\r
55 try:\r
56 event.callback(*event.args)\r
57 except:\r
58 self._logger.exception( 'OnAppCallBack<%s.%s>\n' %\r
59 (event.callback.__module__, event.callback.__name__ ))\r
60\r
61class PackageDocMainFrame(wx.Frame):\r
62 def __init__(self, parent, title):\r
63 wx.Frame.__init__(self, parent, -1, title, size=(550, 290), style=wx.MINIMIZE_BOX|wx.SYSTEM_MENU|wx.CAPTION|wx.CLOSE_BOX )\r
64\r
65 panel = wx.Panel(self)\r
66 sizer = wx.BoxSizer(wx.VERTICAL)\r
67\r
68 subsizer = wx.GridBagSizer(5, 10)\r
69 subsizer.AddGrowableCol(1)\r
70 subsizer.Add(wx.StaticText(panel, -1, "Workspace Location : "), (0, 0), flag=wx.ALIGN_CENTER_VERTICAL)\r
71 self._workspacePathCtrl = wx.ComboBox(panel, -1)\r
72 list = self.GetConfigure("WorkspacePath")\r
73 if len(list) != 0:\r
74 for item in list:\r
75 self._workspacePathCtrl.Append(item)\r
76 self._workspacePathCtrl.SetValue(list[len(list) - 1])\r
77\r
78 subsizer.Add(self._workspacePathCtrl, (0, 1), flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)\r
79 self._workspacePathBt = wx.BitmapButton(panel, -1, bitmap=wx.ArtProvider_GetBitmap(wx.ART_FILE_OPEN))\r
80 subsizer.Add(self._workspacePathBt, (0, 2), flag=wx.ALIGN_CENTER_VERTICAL)\r
81 wx.EVT_BUTTON(self._workspacePathBt, self._workspacePathBt.GetId(), self.OnBrowsePath)\r
82\r
83 subsizer.Add(wx.StaticText(panel, -1, "Package DEC Location : "), (1, 0), flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)\r
84 self._packagePathCtrl = wx.ComboBox(panel, -1)\r
85 list = self.GetConfigure("PackagePath")\r
86 if len(list) != 0:\r
87 for item in list:\r
88 self._packagePathCtrl.Append(item)\r
89 self._packagePathCtrl.SetValue(list[len(list) - 1])\r
90 subsizer.Add(self._packagePathCtrl, (1, 1), flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)\r
91 self._packagePathBt = wx.BitmapButton(panel, -1, bitmap=wx.ArtProvider_GetBitmap(wx.ART_FILE_OPEN))\r
92 subsizer.Add(self._packagePathBt, (1, 2), flag=wx.ALIGN_CENTER_VERTICAL)\r
93 wx.EVT_BUTTON(self._packagePathBt, self._packagePathBt.GetId(), self.OnBrowsePath)\r
94\r
95 subsizer.Add(wx.StaticText(panel, -1, "Doxygen Tool Location : "), (2, 0), flag=wx.ALIGN_CENTER_VERTICAL)\r
96 self._doxygenPathCtrl = wx.TextCtrl(panel, -1)\r
97 list = self.GetConfigure('DoxygenPath')\r
98 if len(list) != 0:\r
99 self._doxygenPathCtrl.SetValue(list[0])\r
100 else:\r
101 if wx.Platform == '__WXMSW__':\r
102 self._doxygenPathCtrl.SetValue('C:\\Program Files\\Doxygen\\bin\\doxygen.exe')\r
103 else:\r
104 self._doxygenPathCtrl.SetValue('/usr/bin/doxygen')\r
105\r
106 self._doxygenPathBt = wx.BitmapButton(panel, -1, bitmap=wx.ArtProvider_GetBitmap(wx.ART_FILE_OPEN))\r
107 subsizer.Add(self._doxygenPathCtrl, (2, 1), flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)\r
108 subsizer.Add(self._doxygenPathBt, (2, 2), flag=wx.ALIGN_CENTER_VERTICAL)\r
109 wx.EVT_BUTTON(self._doxygenPathBt, self._doxygenPathBt.GetId(), self.OnBrowsePath)\r
110\r
111 subsizer.Add(wx.StaticText(panel, -1, "CHM Tool Location : "), (3, 0), flag=wx.ALIGN_CENTER_VERTICAL)\r
112 self._chmPathCtrl = wx.TextCtrl(panel, -1)\r
113 list = self.GetConfigure('CHMPath')\r
114 if len(list) != 0:\r
115 self._chmPathCtrl.SetValue(list[0])\r
116 else:\r
117 self._chmPathCtrl.SetValue('C:\\Program Files\\HTML Help Workshop\\hhc.exe')\r
118\r
119 self._chmPathBt = wx.BitmapButton(panel, -1, bitmap=wx.ArtProvider_GetBitmap(wx.ART_FILE_OPEN))\r
120 subsizer.Add(self._chmPathCtrl, (3, 1), flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)\r
121 subsizer.Add(self._chmPathBt, (3, 2), flag=wx.ALIGN_CENTER_VERTICAL)\r
122 wx.EVT_BUTTON(self._chmPathBt, self._chmPathBt.GetId(), self.OnBrowsePath)\r
123\r
124 subsizer.Add(wx.StaticText(panel, -1, "Output Location : "), (4, 0), flag=wx.ALIGN_CENTER_VERTICAL)\r
125 self._outputPathCtrl = wx.ComboBox(panel, -1)\r
126 list = self.GetConfigure("OutputPath")\r
127 if len(list) != 0:\r
128 for item in list:\r
129 self._outputPathCtrl.Append(item)\r
130 self._outputPathCtrl.SetValue(list[len(list) - 1])\r
131\r
132 subsizer.Add(self._outputPathCtrl, (4, 1), flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)\r
133 self._outputPathBt = wx.BitmapButton(panel, -1, bitmap=wx.ArtProvider_GetBitmap(wx.ART_FILE_OPEN))\r
134 subsizer.Add(self._outputPathBt, (4, 2), flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)\r
135 wx.EVT_BUTTON(self._outputPathBt, self._outputPathBt.GetId(), self.OnBrowsePath)\r
136\r
137 subsizer.Add(wx.StaticText(panel, -1, "Architecture Specified : "), (5, 0), flag=wx.ALIGN_CENTER_VERTICAL)\r
138 self._archCtrl = wx.ComboBox(panel, -1, value='ALL', choices=['ALL', 'IA32/MSFT', 'IA32/GNU', 'X64/INTEL', 'X64/GNU', 'IPF/MSFT', 'IPF/GNU', 'EBC/INTEL'],\r
139 style=wx.CB_READONLY)\r
140 self._archCtrl.Bind(wx.EVT_COMBOBOX, self.OnArchtectureSelectChanged)\r
141 subsizer.Add(self._archCtrl, (5, 1), (1, 2), flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)\r
142 sizer.Add(subsizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM|wx.LEFT|wx.RIGHT, 5)\r
143\r
144 sizer6 = wx.BoxSizer(wx.HORIZONTAL)\r
145 self._modesel = wx.RadioBox(panel, -1, 'Generated Document Mode', majorDimension=2, choices=['CHM', 'HTML'], style=wx.RA_SPECIFY_COLS)\r
146 self._modesel.SetStringSelection('HTML')\r
147\r
148 self._includeonlysel = wx.CheckBox(panel, -1, 'Only document public include')\r
149\r
150 sizer6.Add(self._modesel, 0 , wx.EXPAND)\r
151 sizer6.Add(self._includeonlysel, 0, wx.EXPAND|wx.LEFT, 5)\r
152\r
153 sizer.Add(sizer6, 0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 5)\r
154\r
155 self._generateBt = wx.Button(panel, -1, "Generate Package Document!")\r
156 self._generateBt.Bind(wx.EVT_BUTTON, self.OnGenerate)\r
157 sizer.Add(self._generateBt, 0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 5)\r
158\r
159 panel.SetSizer(sizer)\r
160 panel.Layout()\r
161 panel.SetAutoLayout(True)\r
162 self.CenterOnScreen()\r
163\r
164 def SaveConfigure(self, name, value):\r
165 if value ==None or len(value) == 0:\r
166 return\r
167 config = wx.ConfigBase_Get()\r
168 oldvalues = config.Read(name, '').split(';')\r
169 if len(oldvalues) >= 10:\r
170 oldvalues.remove(oldvalues[0])\r
171 if value not in oldvalues:\r
172 oldvalues.append(value)\r
173 else:\r
174 oldvalues.remove(value)\r
175 oldvalues.append(value)\r
176\r
177 config.Write(name, ';'.join(oldvalues))\r
178\r
179 def GetConfigure(self, name):\r
180 config = wx.ConfigBase_Get()\r
181 values = config.Read(name, '').split(';')\r
182 list = []\r
183 for item in values:\r
184 if len(item) != 0:\r
185 list.append(item)\r
186 return list\r
187\r
188 def OnBrowsePath(self, event):\r
189 id = event.GetId()\r
190 editctrl = None\r
191 startdir = ''\r
192 isFile = False\r
193 if id == self._packagePathBt.GetId():\r
194 dlgTitle = "Choose package path:"\r
195 editctrl = self._packagePathCtrl\r
196 isFile = True\r
197 if os.path.exists(self.GetWorkspace()):\r
198 startdir = self.GetWorkspace()\r
199 elif id == self._workspacePathBt.GetId():\r
200 dlgTitle = "Choose workspace path:"\r
201 editctrl = self._workspacePathCtrl\r
202 startdir = editctrl.GetValue()\r
203 elif id == self._doxygenPathBt.GetId():\r
204 isFile = True\r
205 dlgTitle = "Choose doxygen installation path:"\r
206 editctrl = self._doxygenPathCtrl\r
207 startdir = editctrl.GetValue()\r
208 elif id == self._outputPathBt.GetId():\r
209 dlgTitle = "Choose document output path:"\r
210 editctrl = self._outputPathCtrl\r
211 if os.path.exists(self.GetWorkspace()):\r
212 startdir = self.GetWorkspace()\r
213 startdir = editctrl.GetValue()\r
214 elif id == self._chmPathBt.GetId():\r
215 isFile = True\r
216 dlgTitle = "Choose installation path for Microsoft HTML workshop software"\r
217 editctrl = self._chmPathCtrl\r
218 startdir = editctrl.GetValue()\r
219 else:\r
220 return\r
221\r
222 if not isFile:\r
223 dlg = wx.DirDialog(self, dlgTitle, defaultPath=startdir)\r
224 else:\r
225 dlg = wx.FileDialog(self, dlgTitle, defaultDir=startdir)\r
226\r
227 if dlg.ShowModal() == wx.ID_OK:\r
228 editctrl.SetValue(dlg.GetPath())\r
229 dlg.Destroy()\r
230\r
231 def OnArchtectureSelectChanged(self, event):\r
232 str = ''\r
233 selarch = self._archCtrl.GetValue()\r
234 if selarch == 'ALL':\r
235 str += 'MDE_CPU_IA32 MDE_CPU_X64 MDE_CPU_EBC MDE_CPU_IPF _MSC_EXTENSIONS __GNUC__ __INTEL_COMPILER'\r
236 elif selarch == 'IA32/MSFT':\r
237 str += 'MDE_CPU_IA32 _MSC_EXTENSIONS'\r
238 elif selarch == 'IA32/GNU':\r
239 str += 'MDE_CPU_IA32 __GNUC__'\r
240 elif selarch == 'X64/MSFT':\r
241 str += 'MDE_CPU_X64 _MSC_EXTENSIONS'\r
242 elif selarch == 'X64/GNU':\r
243 str += 'MDE_CPU_X64 __GNUC__'\r
244 elif selarch == 'IPF/MSFT':\r
245 str += 'MDE_CPU_IPF _MSC_EXTENSIONS'\r
246 elif selarch == 'IPF/GNU':\r
247 str += 'MDE_CPU_IPF __GNUC__'\r
248 elif selarch == 'EBC/INTEL':\r
249 str += 'MDE_CPU_EBC __INTEL_COMPILER'\r
250\r
251 str += ' ASM_PFX= OPTIONAL= '\r
252\r
253 def OnMacroText(self, event):\r
254 str = ''\r
255 selarch = self._archCtrl.GetValue()\r
256 if selarch == 'ALL':\r
257 str += 'MDE_CPU_IA32 MDE_CPU_X64 MDE_CPU_EBC MDE_CPU_IPF _MSC_EXTENSIONS __GNUC__ __INTEL_COMPILER'\r
258 elif selarch == 'IA32/MSFT':\r
259 str += 'MDE_CPU_IA32 _MSC_EXTENSIONS'\r
260 elif selarch == 'IA32/GNU':\r
261 str += 'MDE_CPU_IA32 __GNUC__'\r
262 elif selarch == 'X64/MSFT':\r
263 str += 'MDE_CPU_X64 _MSC_EXTENSIONS'\r
264 elif selarch == 'X64/GNU':\r
265 str += 'MDE_CPU_X64 __GNUC__'\r
266 elif selarch == 'IPF/MSFT':\r
267 str += 'MDE_CPU_IPF _MSC_EXTENSIONS'\r
268 elif selarch == 'IPF/GNU':\r
269 str += 'MDE_CPU_IPF __GNUC__'\r
270 elif selarch == 'EBC/INTEL':\r
271 str += 'MDE_CPU_EBC __INTEL_COMPILER'\r
272\r
273 str += ' ASM_PFX= OPTIONAL= '\r
274\r
275 def OnGenerate(self, event):\r
276 if not self.CheckInput(): return\r
277\r
278 dlg = ProgressDialog(self)\r
279 dlg.ShowModal()\r
280 dlg.Destroy()\r
281\r
282 def CheckInput(self):\r
283 pPath = self.GetPackagePath()\r
284 wPath = self.GetWorkspace()\r
285 dPath = self.GetDoxygenToolPath()\r
286 cPath = self.GetChmToolPath()\r
287 oPath = self.GetOutputPath()\r
288\r
289 if len(wPath) == 0 or not os.path.exists(wPath):\r
290 self._Error("Please input existing workspace path!")\r
291 return False\r
292 else:\r
293 self.SaveConfigure('WorkspacePath', wPath)\r
294\r
295 if len(pPath) == 0 or not os.path.exists(pPath) or not pPath.lower().endswith('.dec'):\r
296 self._Error("Please input existing package file location!")\r
297 return False\r
298 elif pPath.lower().find(wPath.lower()) == -1:\r
299 self._Error("Package patch should starts with workspace path, such as if workspace path is c:\\edk2, package patch could be c:\\edk2\MdePkg")\r
300 return False\r
301 else:\r
302 self.SaveConfigure('PackagePath', pPath)\r
303\r
304 if len(dPath) == 0 or not os.path.exists(dPath):\r
305 self._Error("Can not find doxygen tool from path %s! Please download it from www.stack.nl/~dimitri/doxygen/download.html" % dPath)\r
306 return False\r
307 else:\r
308 self.SaveConfigure('DoxygenPath', dPath)\r
309\r
310 if self._modesel.GetStringSelection() == 'CHM':\r
311 if (len(cPath) == 0 or not os.path.exists(cPath)):\r
312 self._Error("You select CHM mode to generate document, but can not find software of Microsoft HTML Help Workshop.\nPlease\\r
313 download it from http://www.microsoft.com/downloads/details.aspx?FamilyID=00535334-c8a6-452f-9aa0-d597d16580cc&displaylang=en\n\\r
314and install!")\r
315 return False\r
316 else:\r
317 self.SaveConfigure('CHMPath', cPath)\r
318\r
319 if len(oPath) == 0:\r
320 self._Error("You must specific document output path")\r
321 return False\r
322 else:\r
323 self.SaveConfigure('OutputPath', oPath)\r
324\r
325 if os.path.exists(oPath):\r
326 # add checking whether there is old doxygen config file here\r
327 files = os.listdir(oPath)\r
328 for file in files:\r
329 if os.path.isfile(os.path.join(oPath,file)):\r
330 basename, ext = os.path.splitext(file)\r
331 if ext.lower() == '.doxygen_config':\r
332 dlg = GMD.GenericMessageDialog(self, "Existing doxygen document in output directory will be overwritten\n, Are you sure?",\r
333 "Info", wx.ICON_WARNING|wx.YES_NO)\r
334 if dlg.ShowModal() == wx.ID_YES:\r
335 break\r
336 else:\r
337 return False\r
338 else:\r
339 try:\r
340 os.makedirs(oPath)\r
341 except:\r
342 self._Error("Fail to create output directory, please select another output directory!")\r
343 return False\r
344\r
345 return True\r
346\r
347 def _Error(self, message):\r
348 dlg = GMD.GenericMessageDialog(self, message,\r
349 "Error", wx.ICON_ERROR|wx.OK)\r
350 dlg.ShowModal()\r
351 dlg.Destroy()\r
352\r
353 def GetWorkspace(self):\r
354 return os.path.normpath(self._workspacePathCtrl.GetValue())\r
355\r
356 def GetPackagePath(self):\r
357 return os.path.normpath(self._packagePathCtrl.GetValue())\r
358\r
359 def GetOutputPath(self):\r
360 return os.path.normpath(self._outputPathCtrl.GetValue())\r
361\r
362 def GetDoxygenToolPath(self):\r
363 return os.path.normpath(self._doxygenPathCtrl.GetValue())\r
364\r
365 def GetChmToolPath(self):\r
366 return os.path.normpath(self._chmPathCtrl.GetValue())\r
367\r
368 def GetDocumentMode(self):\r
369 return self._modesel.GetStringSelection()\r
370\r
371 def GetArchitecture(self):\r
372 value = self._archCtrl.GetValue()\r
373 return value.split('/')[0]\r
374\r
375 def GetToolTag(self):\r
376 value = self._archCtrl.GetValue()\r
377 if value == 'ALL':\r
378 return 'ALL'\r
379 return value.split('/')[1]\r
380\r
381 def GetIsOnlyDocumentInclude(self):\r
382 return self._includeonlysel.IsChecked()\r
383\r
384class ProgressDialog(wx.Dialog):\r
385 def __init__(self, parent, id=wx.ID_ANY):\r
386 title = "Generate Document for " + parent.GetPackagePath()\r
387 wx.Dialog.__init__(self, parent, id, title=title, style=wx.CAPTION, size=(600, 300))\r
388 self.Freeze()\r
389 sizer = wx.BoxSizer(wx.VERTICAL)\r
390 self._textCtrl = wx.StaticText(self, -1, "Start launching!")\r
391 self._gaugeCtrl = wx.Gauge(self, -1, 100, size=(-1, 10))\r
392 self._resultCtrl = wx.stc.StyledTextCtrl(self, -1)\r
393 self._closeBt = wx.Button(self, -1, "Close")\r
394 self._gotoOuputBt = wx.Button(self, -1, "Goto Output")\r
395\r
396 # clear all margin\r
397 self._resultCtrl.SetMarginWidth(0, 0)\r
398 self._resultCtrl.SetMarginWidth(1, 0)\r
399 self._resultCtrl.SetMarginWidth(2, 0)\r
400\r
401 sizer.Add(self._textCtrl, 0, wx.EXPAND|wx.LEFT|wx.TOP|wx.RIGHT, 5)\r
402 sizer.Add(self._gaugeCtrl, 0, wx.EXPAND|wx.LEFT|wx.TOP|wx.RIGHT, 5)\r
403 sizer.Add(self._resultCtrl, 1, wx.EXPAND|wx.LEFT|wx.TOP|wx.RIGHT, 5)\r
404 btsizer = wx.BoxSizer(wx.HORIZONTAL)\r
405 btsizer.Add(self._gotoOuputBt, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.LEFT|wx.TOP|wx.LEFT|wx.BOTTOM, 5)\r
406 btsizer.Add(self._closeBt, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.LEFT|wx.TOP|wx.LEFT|wx.BOTTOM, 5)\r
407 sizer.Add(btsizer, 0, wx.ALIGN_CENTER_HORIZONTAL)\r
408\r
409 self.SetSizer(sizer)\r
410 self.CenterOnScreen()\r
411 self.Thaw()\r
412\r
413 self._logger = logging.getLogger('')\r
414 self._loghandle = ResultHandler(self)\r
415 logging.getLogger('edk').addHandler(self._loghandle)\r
416 logging.getLogger('').addHandler(self._loghandle)\r
417 logging.getLogger('app').addHandler(self._loghandle)\r
418\r
419 wx.EVT_BUTTON(self._closeBt, self._closeBt.GetId(), self.OnButtonClose)\r
420 wx.EVT_UPDATE_UI(self, self._closeBt.GetId(), self.OnUpdateCloseButton)\r
421 wx.EVT_BUTTON(self._gotoOuputBt, self._gotoOuputBt.GetId(), self.OnGotoOutput)\r
422 EVT_LOG(self, self.OnPostLog)\r
423\r
424 self._process = None\r
425 self._pid = None\r
426 self._input = None\r
427 self._output = None\r
428 self._error = None\r
429 self._inputThread = None\r
430 self._errorThread = None\r
431 self._isBusy = True\r
432 self._pObj = None\r
433\r
434 wx.CallAfter(self.GenerateAction)\r
435\r
436 def OnUpdateCloseButton(self, event):\r
437 self._closeBt.Enable(not self._isBusy)\r
438 return True\r
439\r
440 def OnButtonClose(self, event):\r
441 if self._isBusy:\r
442 self._InfoDialog("Please don't close in progressing...")\r
443 return\r
444\r
445 if self._process != None:\r
446 self._process.CloseOutput()\r
447\r
448 if self._inputThread:\r
449 self._inputThread.Terminate()\r
450 if self._errorThread:\r
451 self._errorThread.Terminate()\r
452\r
453 if self._pid != None:\r
454 wx.Process.Kill(self._pid, wx.SIGKILL, wx.KILL_CHILDREN)\r
455\r
456 logging.getLogger('edk').removeHandler(self._loghandle)\r
457 logging.getLogger('').removeHandler(self._loghandle)\r
458 logging.getLogger('app').removeHandler(self._loghandle)\r
459\r
460 if self._pObj != None:\r
461 self._pObj.Destroy()\r
462\r
463 self.EndModal(0)\r
464\r
465 def OnGotoOutput(self, event):\r
466 output = self.GetParent().GetOutputPath()\r
467 if os.path.exists(output):\r
468 if wx.Platform == '__WXMSW__':\r
469 os.startfile(self.GetParent().GetOutputPath())\r
470 else:\r
471 import webbrowser\r
472 webbrowser.open(self.GetParent().GetOutputPath())\r
473 else:\r
474 self._ErrorDialog("Output directory does not exist!")\r
475\r
476 def _ErrorDialog(self, message):\r
477 dlg = GMD.GenericMessageDialog(self, message,\r
478 "Error", wx.ICON_ERROR|wx.OK)\r
479 dlg.ShowModal()\r
480 dlg.Destroy()\r
481\r
482 def _InfoDialog(self, message):\r
483 dlg = GMD.GenericMessageDialog(self, message,\r
484 "Info", wx.ICON_INFORMATION|wx.OK)\r
485 dlg.ShowModal()\r
486 dlg.Destroy()\r
487\r
488 def _LogStep(self, index, message):\r
489 stepstr = "Step %d: %s" % (index, message)\r
490 self._textCtrl.SetLabel(stepstr)\r
491 self.LogMessage(os.linesep + stepstr + os.linesep)\r
492 self._gaugeCtrl.SetValue(index * 100 / 6 )\r
493\r
494 def OnPostLog(self, event):\r
495 self.LogMessage(event.message)\r
496\r
497 def GenerateAction(self):\r
498 self._LogStep(1, "Create Package Object Model")\r
499 wsPath = self.GetParent().GetWorkspace()\r
500 pkPath = self.GetParent().GetPackagePath()[len(wsPath) + 1:]\r
501\r
502 try:\r
503 pObj = baseobject.Package(None, self.GetParent().GetWorkspace())\r
504 pObj.Load(pkPath)\r
505 except:\r
506 self._ErrorDialog("Fail to create package object model! Please check log.txt under this application folder!")\r
507 self._isBusy = False\r
508 return\r
509 self._pObj = pObj\r
510\r
511 self.LogMessage(str(pObj.GetPcds()))\r
512\r
513 self._LogStep(2, "Preprocess and Generate Doxygen Config File")\r
514 try:\r
515 action = doxygengen.PackageDocumentAction(self.GetParent().GetDoxygenToolPath(),\r
516 self.GetParent().GetChmToolPath(),\r
517 self.GetParent().GetOutputPath(),\r
518 pObj,\r
519 self.GetParent().GetDocumentMode(),\r
520 self.LogMessage,\r
521 self.GetParent().GetArchitecture(),\r
522 self.GetParent().GetToolTag(),\r
523 self.GetParent().GetIsOnlyDocumentInclude(),\r
524 True)\r
525 except:\r
526 self._ErrorDialog("Fail to preprocess! Please check log.txt under this application folder!")\r
527 self._isBusy = False\r
528 return\r
529\r
530 action.RegisterCallbackDoxygenProcess(self.CreateDoxygeProcess)\r
531\r
532 try:\r
533 if not action.Generate():\r
534 self._isBusy = False\r
535 self.LogMessage("Fail to generate package document! Please check log.txt under this application folder!", 'error')\r
536 except:\r
537 import traceback\r
538 message = traceback.format_exception(*sys.exc_info())\r
539 logging.getLogger('').error(''.join(message))\r
540 self._isBusy = False\r
541 self._ErrorDialog("Fail to generate package document! Please check log.txt under this application folder!")\r
542\r
543 def LogMessage(self, message, level='info'):\r
544 self._resultCtrl.DocumentEnd()\r
545 self._resultCtrl.SetReadOnly(False)\r
546 self._resultCtrl.AppendText(message)\r
547 self._resultCtrl.Home()\r
548 self._resultCtrl.Home()\r
549 self._resultCtrl.SetReadOnly(True)\r
550 if level == 'error':\r
551 wx.GetApp().GetLogger().error(message)\r
552\r
553 def CreateDoxygeProcess(self, doxPath, configFile):\r
554 self._LogStep(3, "Launch Doxygen Tool and Generate Package Document")\r
555\r
556 cmd = '"%s" %s' % (doxPath, configFile)\r
557 try:\r
558 self._process = DoxygenProcess()\r
559 self._process.SetParent(self)\r
560 self._process.Redirect()\r
561 self._pid = wx.Execute(cmd, wx.EXEC_ASYNC, self._process)\r
562 self._input = self._process.GetInputStream()\r
563 self._output = self._process.GetOutputStream()\r
564 self._error = self._process.GetErrorStream()\r
565 except:\r
566 self._ErrorDialog('Fail to launch doxygen cmd %s! Please check log.txt under this application folder!' % cmd)\r
567 self._isBusy = False\r
568 return False\r
569\r
570 self._inputThread = MonitorThread(self._input, self.LogMessage)\r
571 self._errorThread = MonitorThread(self._error, self.LogMessage)\r
572 self._inputThread.start()\r
573 self._errorThread.start()\r
574 return True\r
575\r
576 def OnTerminateDoxygenProcess(self):\r
577 if self._inputThread:\r
578 self._inputThread.Terminate()\r
579 self._inputThread = None\r
580 if self._errorThread:\r
581 self._errorThread.Terminate()\r
582 self._errorThread = None\r
583\r
584 if self._error:\r
585 while self._error.CanRead():\r
586 text = self._error.read()\r
587 self.LogMessage(text)\r
588\r
589 if self._input:\r
590 while self._input.CanRead():\r
591 text = self._input.read()\r
592 self.LogMessage(text)\r
593 self._process.Detach()\r
594\r
595 self._process.CloseOutput()\r
596 self._process = None\r
597 self._pid = None\r
598\r
599 self.DocumentFixup()\r
600\r
601 if self.GetParent().GetDocumentMode().lower() == 'chm':\r
602 hhcfile = os.path.join(self.GetParent().GetOutputPath(), 'html', 'index.hhc')\r
603 hhpfile = os.path.join(self.GetParent().GetOutputPath(), 'html', 'index.hhp')\r
604 self.FixDecDoxygenFileLink(hhcfile, None)\r
605 if not self.CreateCHMProcess(self.GetParent().GetChmToolPath(), hhpfile):\r
606 self._ErrorDialog("Fail to Create %s process for %s" % (self.GetParent().GetChmToolPath(), hhpfile))\r
607 self._isBusy = False\r
608 else:\r
609 self._LogStep(6, "Finished Document Generation!")\r
610 self._isBusy = False\r
611 indexpath = os.path.realpath(os.path.join(self.GetParent().GetOutputPath(), 'html', 'index.html'))\r
612 if wx.Platform == '__WXMSW__':\r
613 os.startfile(indexpath)\r
614 else:\r
615 import webbrowser\r
616 webbrowser.open(indexpath)\r
617\r
618 self._InfoDialog('Success create HTML doxgen document %s' % indexpath)\r
619\r
620 def CreateCHMProcess(self, chmPath, hhpfile):\r
621 self.LogMessage(" >>>>>> Start Microsoft HTML workshop process...Zzz...\n")\r
622 cmd = '"%s" %s' % (chmPath, hhpfile)\r
623 try:\r
624 self._process = CHMProcess()\r
625 self._process.SetParent(self)\r
626 self._process.Redirect()\r
627 self._pid = wx.Execute(cmd, wx.EXEC_ASYNC, self._process)\r
628 self._input = self._process.GetInputStream()\r
629 self._output = self._process.GetOutputStream()\r
630 self._error = self._process.GetErrorStream()\r
631 except:\r
632 self.LogMessage('\nFail to launch hhp cmd %s!\n' % cmd)\r
633 self._isBusy = False\r
634 return False\r
635 self._inputThread = MonitorThread(self._input, self.LogMessage)\r
636 self._errorThread = MonitorThread(self._error, self.LogMessage)\r
637 self._inputThread.start()\r
638 self._errorThread.start()\r
639 return True\r
640\r
641 def OnTerminateCHMProcess(self):\r
642 if self._inputThread:\r
643 self._inputThread.Terminate()\r
644 self._inputThread = None\r
645 if self._errorThread:\r
646 self._errorThread.Terminate()\r
647 self._errorThread = None\r
648\r
649 if self._error:\r
650 while self._error.CanRead():\r
651 text = self._error.read()\r
652 self.LogMessage(text)\r
653 if self._input:\r
654 while self._input.CanRead():\r
655 text = self._input.read()\r
656 self.LogMessage(text)\r
657 self._process.Detach()\r
658\r
659 self._process.CloseOutput()\r
660 self._process = None\r
661 self._pid = None\r
662 self._isBusy = False\r
663 indexpath = os.path.realpath(os.path.join(self.GetParent().GetOutputPath(), 'html', 'index.chm'))\r
664 if os.path.exists(indexpath):\r
665 if wx.Platform == '__WXMSW__':\r
666 os.startfile(indexpath)\r
667 else:\r
668 import webbrowser\r
669 webbrowser.open(indexpath)\r
670\r
671 self._LogStep(6, "Finished Document Generation!")\r
672 self.LogMessage('\nSuccess create CHM doxgen document %s\n' % indexpath)\r
673 self._InfoDialog('Success create CHM doxgen document %s' % indexpath)\r
674\r
675 def DocumentFixup(self):\r
676 # find BASE_LIBRARY_JUMP_BUFFER structure reference page\r
677 self._LogStep(4, "Fixup Package Document!")\r
678 self.LogMessage('\n >>> Start fixup document \n')\r
679\r
680 for root, dirs, files in os.walk(os.path.join(self.GetParent().GetOutputPath(), 'html')):\r
681 for dir in dirs:\r
682 if dir.lower() in ['.svn', '_svn', 'cvs']:\r
683 dirs.remove(dir)\r
684 for file in files:\r
685 wx.YieldIfNeeded()\r
686 if not file.lower().endswith('.html'): continue\r
687 fullpath = os.path.join(self.GetParent().GetOutputPath(), root, file)\r
688 try:\r
689 f = open(fullpath, 'r')\r
690 text = f.read()\r
691 f.close()\r
692 except:\r
693 self.LogMessage('\nFail to open file %s\n' % fullpath)\r
694 continue\r
695 if text.find('BASE_LIBRARY_JUMP_BUFFER Struct Reference') != -1 and self.GetParent().GetArchitecture() == 'ALL':\r
696 self.FixPageBASE_LIBRARY_JUMP_BUFFER(fullpath, text)\r
697 if text.find('MdePkg/Include/Library/BaseLib.h File Reference') != -1 and self.GetParent().GetArchitecture() == 'ALL':\r
698 self.FixPageBaseLib(fullpath, text)\r
699 if text.find('IA32_IDT_GATE_DESCRIPTOR Union Reference') != -1 and self.GetParent().GetArchitecture() == 'ALL':\r
700 self.FixPageIA32_IDT_GATE_DESCRIPTOR(fullpath, text)\r
701 if text.find('MdePkg/Include/Library/UefiDriverEntryPoint.h File Reference') != -1:\r
702 self.FixPageUefiDriverEntryPoint(fullpath, text)\r
703 if text.find('MdePkg/Include/Library/UefiApplicationEntryPoint.h File Reference') != -1:\r
704 self.FixPageUefiApplicationEntryPoint(fullpath, text)\r
705 if text.lower().find('.s.dox') != -1 or \\r
706 text.lower().find('.asm.dox') != -1 or \\r
707 text.lower().find('.uni.dox') != -1:\r
708 self.FixDoxFileLink(fullpath, text)\r
709\r
710 self.RemoveFileList()\r
711 self.LogMessage(' >>> Finish all document fixing up! \n')\r
712\r
713 def RemoveFileList(self):\r
714 path_html = os.path.join(self.GetParent().GetOutputPath(), "html", "tree.html")\r
715 path_chm = os.path.join(self.GetParent().GetOutputPath(), "html", "index.hhc")\r
716 if os.path.exists(path_html):\r
717 self.LogMessage(' >>>Remove FileList item from generated HTML document.\n');\r
718 lines = []\r
719 f = open (path_html, "r")\r
720 lines = f.readlines()\r
721 f.close()\r
722 bfound = False\r
723 for index in xrange(len(lines)):\r
724 if lines[index].find('<a class="el" href="files.html" target="basefrm">File List</a>') != -1:\r
725 lines[index] = "<!-- %s" % lines[index]\r
726 bfound = True\r
727 continue\r
728 if bfound:\r
729 if lines[index].find('</div>') != -1:\r
730 lines[index] = "%s -->" % lines[index]\r
731 break\r
732 if bfound:\r
733 f = open(path_html, "w")\r
734 f.write("".join(lines))\r
735 f.close()\r
736 else:\r
737 self.LogMessage (' !!!Can not found FileList item in HTML document!\n')\r
738\r
739 if os.path.exists(path_chm):\r
740 self.LogMessage(" >>>Warning: Can not remove FileList for CHM files!\n");\r
741 """\r
742 self.LogMessage(' >>>Remove FileList item from generated CHM document!\n');\r
743 lines = []\r
744 f = open (path_chm, "r")\r
745 lines = f.readlines()\r
746 f.close()\r
747 bfound = False\r
748 for index in xrange(len(lines)):\r
749 if not bfound:\r
750 if lines[index].find('<param name="Local" value="files.html">') != -1:\r
751 lines[index] = '<!-- %s' % lines[index]\r
752 bfound = True\r
753 continue\r
754 if bfound:\r
755 if lines[index].find('</UL>') != -1:\r
756 lines[index] = '%s -->\n' % lines[index].rstrip()\r
757 break\r
758 if bfound:\r
759 f = open(path_chm, "w")\r
760 f.write("".join(lines))\r
761 f.close()\r
762 import time\r
763 time.sleep(2)\r
764 else:\r
765 self.LogMessage(' !!!Can not found the FileList item in CHM document!')\r
766 """\r
767 def FixPageBaseLib(self, path, text):\r
768 self.LogMessage(' >>> Fixup BaseLib file page at file %s \n' % path)\r
769 lines = text.split('\n')\r
770 lastBaseJumpIndex = -1\r
771 lastIdtGateDescriptor = -1\r
772 for index in range(len(lines) - 1, -1, -1):\r
773 line = lines[index]\r
774 if line.strip() == '<td class="memname">#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT&nbsp;&nbsp;&nbsp;4 </td>':\r
775 lines[index] = '<td class="memname">#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT&nbsp;&nbsp;&nbsp;4&nbsp;[IA32] </td>'\r
776 if line.strip() == '<td class="memname">#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT&nbsp;&nbsp;&nbsp;0x10 </td>':\r
777 lines[index] = '<td class="memname">#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT&nbsp;&nbsp;&nbsp;0x10&nbsp;[IPF] </td>'\r
778 if line.strip() == '<td class="memname">#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT&nbsp;&nbsp;&nbsp;8 </td>':\r
779 lines[index] = '<td class="memname">#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT&nbsp;&nbsp;&nbsp;9&nbsp;[EBC, x64] </td>'\r
780 if line.find('BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a>&nbsp;&nbsp;&nbsp;4') != -1:\r
781 lines[index] = lines[index].replace('BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a>&nbsp;&nbsp;&nbsp;4',\r
782 'BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a>&nbsp;&nbsp;&nbsp;4&nbsp;[IA32]')\r
783 if line.find('BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a>&nbsp;&nbsp;&nbsp;0x10') != -1:\r
784 lines[index] = lines[index].replace('BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a>&nbsp;&nbsp;&nbsp;0x10',\r
785 'BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a>&nbsp;&nbsp;&nbsp;0x10&nbsp;[IPF]')\r
786 if line.find('BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a>&nbsp;&nbsp;&nbsp;8') != -1:\r
787 lines[index] = lines[index].replace('BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a>&nbsp;&nbsp;&nbsp;8',\r
788 'BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT</a>&nbsp;&nbsp;&nbsp;8&nbsp;[x64, EBC]')\r
789 if line.find('>BASE_LIBRARY_JUMP_BUFFER</a>') != -1:\r
790 if lastBaseJumpIndex != -1:\r
791 del lines[lastBaseJumpIndex]\r
792 lastBaseJumpIndex = index\r
793 if line.find('>IA32_IDT_GATE_DESCRIPTOR</a></td>') != -1:\r
794 if lastIdtGateDescriptor != -1:\r
795 del lines[lastIdtGateDescriptor]\r
796 lastIdtGateDescriptor = index\r
797 try:\r
798 f = open(path, 'w')\r
799 f.write('\n'.join(lines))\r
800 f.close()\r
801 except:\r
802 self._isBusy = False\r
803 self.LogMessage(" <<< Fail to fixup file %s\n" % path)\r
804 self.LogMessage(" <<< Finish to fixup file %s\n" % path)\r
805\r
806 def FixPageIA32_IDT_GATE_DESCRIPTOR(self, path, text):\r
807 self.LogMessage(' >>> Fixup structure reference IA32_IDT_GATE_DESCRIPTOR at file %s \n' % path)\r
808 lines = text.split('\n')\r
809 for index in range(len(lines) - 1, -1, -1):\r
810 line = lines[index].strip()\r
811 if line.find('struct {</td>') != -1 and lines[index - 2].find('>Uint64</a></td>') != -1:\r
812 lines.insert(index, '<tr><td colspan="2"><br><h2>Data Fields For X64</h2></td></tr>')\r
813 if line.find('struct {</td>') != -1 and lines[index - 1].find('Data Fields') != -1:\r
814 lines.insert(index, '<tr><td colspan="2"><br><h2>Data Fields For IA32</h2></td></tr>')\r
815 try:\r
816 f = open(path, 'w')\r
817 f.write('\n'.join(lines))\r
818 f.close()\r
819 except:\r
820 self._isBusy = False\r
821 self.LogMessage(" <<< Fail to fixup file %s\n" % path)\r
822 self.LogMessage(" <<< Finish to fixup file %s\n" % path)\r
823\r
824 def FixPageBASE_LIBRARY_JUMP_BUFFER(self, path, text):\r
825 self.LogMessage(' >>> Fixup structure reference BASE_LIBRARY_JUMP_BUFFER at file %s \n' % path)\r
826 lines = text.split('\n')\r
827 bInDetail = True\r
828 bNeedRemove = False\r
829 for index in range(len(lines) - 1, -1, -1):\r
830 line = lines[index]\r
831 if line.find('Detailed Description') != -1:\r
832 bInDetail = False\r
833 if line.startswith('EBC context buffer used by') and lines[index - 1].startswith('x64 context buffer'):\r
834 lines[index] = "IA32/IPF/X64/" + line\r
835 bNeedRemove = True\r
836 if line.startswith("x64 context buffer") or line.startswith('IPF context buffer used by') or \\r
837 line.startswith('IA32 context buffer used by'):\r
838 if bNeedRemove:\r
839 lines.remove(line)\r
840 if line.find('>R0</a>') != -1 and not bInDetail:\r
841 if lines[index - 1] != '<tr><td colspan="2"><br><h2>Data Fields For EBC</h2></td></tr>':\r
842 lines.insert(index, '<tr><td colspan="2"><br><h2>Data Fields For EBC</h2></td></tr>')\r
843 if line.find('>Rbx</a>') != -1 and not bInDetail:\r
844 if lines[index - 1] != '<tr><td colspan="2"><br><h2>Data Fields For X64</h2></td></tr>':\r
845 lines.insert(index, '<tr><td colspan="2"><br><h2>Data Fields For X64</h2></td></tr>')\r
846 if line.find('>F2</a>') != -1 and not bInDetail:\r
847 if lines[index - 1] != '<tr><td colspan="2"><br><h2>Data Fields For IPF</h2></td></tr>':\r
848 lines.insert(index, '<tr><td colspan="2"><br><h2>Data Fields For IPF</h2></td></tr>')\r
849 if line.find('>Ebx</a>') != -1 and not bInDetail:\r
850 if lines[index - 1] != '<tr><td colspan="2"><br><h2>Data Fields For IA32</h2></td></tr>':\r
851 lines.insert(index, '<tr><td colspan="2"><br><h2>Data Fields For IA32</h2></td></tr>')\r
852 try:\r
853 f = open(path, 'w')\r
854 f.write('\n'.join(lines))\r
855 f.close()\r
856 except:\r
857 self._isBusy = False\r
858 self.LogMessage(" <<< Fail to fixup file %s" % path)\r
859 self.LogMessage(" <<< Finish to fixup file %s\n" % path)\r
860\r
861 def FixPageUefiDriverEntryPoint(self, path, text):\r
862 self.LogMessage(' >>> Fixup file reference MdePkg/Include/Library/UefiDriverEntryPoint.h at file %s \n' % path)\r
863 lines = text.split('\n')\r
864 bInModuleEntry = False\r
865 bInEfiMain = False\r
866 ModuleEntryDlCount = 0\r
867 ModuleEntryDelStart = 0\r
868 ModuleEntryDelEnd = 0\r
869 EfiMainDlCount = 0\r
870 EfiMainDelStart = 0\r
871 EfiMainDelEnd = 0\r
872\r
873 for index in range(len(lines)):\r
874 line = lines[index].strip()\r
875 if line.find('EFI_STATUS</a> EFIAPI _ModuleEntryPoint </td>') != -1:\r
876 bInModuleEntry = True\r
877 if line.find('EFI_STATUS</a> EFIAPI EfiMain </td>') != -1:\r
878 bInEfiMain = True\r
879 if line.startswith('<p>References <a'):\r
880 if bInModuleEntry:\r
881 ModuleEntryDelEnd = index - 1\r
882 bInModuleEntry = False\r
883 elif bInEfiMain:\r
884 EfiMainDelEnd = index - 1\r
885 bInEfiMain = False\r
886 if bInModuleEntry:\r
887 if line.startswith('</dl>'):\r
888 ModuleEntryDlCount = ModuleEntryDlCount + 1\r
889 if ModuleEntryDlCount == 1:\r
890 ModuleEntryDelStart = index + 1\r
891 if bInEfiMain:\r
892 if line.startswith('</dl>'):\r
893 EfiMainDlCount = EfiMainDlCount + 1\r
894 if EfiMainDlCount == 1:\r
895 EfiMainDelStart = index + 1\r
896\r
897 if EfiMainDelEnd > EfiMainDelStart:\r
898 for index in range(EfiMainDelEnd, EfiMainDelStart, -1):\r
899 del lines[index]\r
900 if ModuleEntryDelEnd > ModuleEntryDelStart:\r
901 for index in range(ModuleEntryDelEnd, ModuleEntryDelStart, -1):\r
902 del lines[index]\r
903\r
904 try:\r
905 f = open(path, 'w')\r
906 f.write('\n'.join(lines))\r
907 f.close()\r
908 except:\r
909 self._isBusy = False\r
910 self.LogMessage(" <<< Fail to fixup file %s" % path)\r
911 self.LogMessage(" <<< Finish to fixup file %s\n" % path)\r
912\r
913 def FixPageUefiApplicationEntryPoint(self, path, text):\r
914 self.LogMessage(' >>> Fixup file reference MdePkg/Include/Library/UefiApplicationEntryPoint.h at file %s \n' % path)\r
915 lines = text.split('\n')\r
916 bInModuleEntry = False\r
917 bInEfiMain = False\r
918 ModuleEntryDlCount = 0\r
919 ModuleEntryDelStart = 0\r
920 ModuleEntryDelEnd = 0\r
921 EfiMainDlCount = 0\r
922 EfiMainDelStart = 0\r
923 EfiMainDelEnd = 0\r
924\r
925 for index in range(len(lines)):\r
926 line = lines[index].strip()\r
927 if line.find('EFI_STATUS</a> EFIAPI _ModuleEntryPoint </td>') != -1:\r
928 bInModuleEntry = True\r
929 if line.find('EFI_STATUS</a> EFIAPI EfiMain </td>') != -1:\r
930 bInEfiMain = True\r
931 if line.startswith('<p>References <a'):\r
932 if bInModuleEntry:\r
933 ModuleEntryDelEnd = index - 1\r
934 bInModuleEntry = False\r
935 elif bInEfiMain:\r
936 EfiMainDelEnd = index - 1\r
937 bInEfiMain = False\r
938 if bInModuleEntry:\r
939 if line.startswith('</dl>'):\r
940 ModuleEntryDlCount = ModuleEntryDlCount + 1\r
941 if ModuleEntryDlCount == 1:\r
942 ModuleEntryDelStart = index + 1\r
943 if bInEfiMain:\r
944 if line.startswith('</dl>'):\r
945 EfiMainDlCount = EfiMainDlCount + 1\r
946 if EfiMainDlCount == 1:\r
947 EfiMainDelStart = index + 1\r
948\r
949 if EfiMainDelEnd > EfiMainDelStart:\r
950 for index in range(EfiMainDelEnd, EfiMainDelStart, -1):\r
951 del lines[index]\r
952 if ModuleEntryDelEnd > ModuleEntryDelStart:\r
953 for index in range(ModuleEntryDelEnd, ModuleEntryDelStart, -1):\r
954 del lines[index]\r
955\r
956 try:\r
957 f = open(path, 'w')\r
958 f.write('\n'.join(lines))\r
959 f.close()\r
960 except:\r
961 self._isBusy = False\r
962 self.LogMessage(" <<< Fail to fixup file %s" % path)\r
963 self.LogMessage(" <<< Finish to fixup file %s\n" % path)\r
964\r
965\r
966 def FixDoxFileLink(self, path, text):\r
967 self.LogMessage(' >>> Fixup .dox postfix for file %s \n' % path)\r
968 try:\r
969 fd = open(path, 'r')\r
970 text = fd.read()\r
971 fd.close()\r
972 except Exception, e:\r
973 self.LogMessage (" <<<Fail to open file %s" % path)\r
974 return\r
975 text = text.replace ('.s.dox', '.s')\r
976 text = text.replace ('.S.dox', '.S')\r
977 text = text.replace ('.asm.dox', '.asm')\r
978 text = text.replace ('.Asm.dox', '.Asm')\r
979 text = text.replace ('.uni.dox', '.uni')\r
980 text = text.replace ('.Uni.dox', '.Uni')\r
981 try:\r
982 fd = open(path, 'w')\r
983 fd.write(text)\r
984 fd.close()\r
985 except Exception, e:\r
986 self.LogMessage (" <<<Fail to fixup file %s" % path)\r
987 return\r
988 self.LogMessage(' >>> Finish to fixup .dox postfix for file %s \n' % path)\r
989\r
990 def FixDecDoxygenFileLink(self, path, text):\r
991 self.LogMessage(' >>> Fixup .decdoxygen postfix for file %s \n' % path)\r
992 try:\r
993 fd = open(path, 'r')\r
994 lines = fd.readlines()\r
995 fd.close()\r
996 except Exception, e:\r
997 self.LogMessage (" <<<Fail to open file %s" % path)\r
998 return\r
999 for line in lines:\r
1000 if line.find('.decdoxygen') != -1:\r
1001 lines.remove(line)\r
1002 break\r
1003 try:\r
1004 fd = open(path, 'w')\r
1005 fd.write("".join(lines))\r
1006 fd.close()\r
1007 except Exception, e:\r
1008 self.LogMessage (" <<<Fail to fixup file %s" % path)\r
1009 return\r
1010 self.LogMessage(' >>> Finish to fixup .decdoxygen postfix for file %s \n' % path)\r
1011\r
1012import threading\r
1013class MonitorThread(threading.Thread):\r
1014 def __init__(self, pipe, callback):\r
1015 threading.Thread.__init__(self)\r
1016 self._pipe = pipe\r
1017 self._callback = callback\r
1018 self._isCancel = False\r
1019\r
1020 def run(self):\r
1021 while (not self._isCancel):\r
1022 self._pipe.Peek()\r
1023 if self._pipe.LastRead() == 0:\r
1024 break\r
1025 text = self._pipe.read()\r
1026 if len(text.strip()) != 0:\r
1027 wx.GetApp().ForegroundProcess(self._callback, (text,))\r
1028\r
1029 def Terminate(self):\r
1030 self._pipe.flush()\r
1031 self._isCancel = True\r
1032\r
1033class DoxygenProcess(wx.Process):\r
1034 def OnTerminate(self, id, status):\r
1035 self._parent.OnTerminateDoxygenProcess()\r
1036\r
1037 def SetParent(self, parent):\r
1038 self._parent = parent\r
1039\r
1040class CHMProcess(wx.Process):\r
1041 def OnTerminate(self, id, status):\r
1042 self._parent.OnTerminateCHMProcess()\r
1043\r
1044 def SetParent(self, parent):\r
1045 self._parent = parent\r
1046\r
1047class ResultHandler:\r
1048 def __init__(self, parent):\r
1049 self._parent = parent\r
1050 self.level = 0\r
1051\r
1052 def emit(self, record):\r
1053 self._parent.LogMessage(record)\r
1054\r
1055 def handle(self, record):\r
1056 wx.PostEvent(self._parent, LogEvent(message=record.getMessage()))\r
1057\r
1058 def acquire(self):\r
1059 pass\r
1060\r
1061 def release(self):\r
1062 pass\r
1063\r
1064if __name__ == '__main__':\r
1065 app = PackageDocApp(redirect=False)\r
1066 app.MainLoop()\r