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