From 8d4243f1bd81497181a3cc135239422c43364105 Mon Sep 17 00:00:00 2001 From: mdkinney Date: Thu, 4 Jan 2007 01:07:52 +0000 Subject: [PATCH] 1) Update XmlRoutines.py to strip all whitespace 2) Add function to read section of an XML file 3) Add class to handle workspace relative paths 4) Add utility to manage target.txt 5) Add utility to manage FrameworkDatabase.db git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2164 6f19259b-4bc3-4df7-8a09-765794883524 --- Tools/Python/ContextTool.py | 590 +++++++++++++++++++++++++++++++++ Tools/Python/EdkIIWorkspace.py | 148 +++++++++ Tools/Python/Fd.py | 573 ++++++++++++++++++++++++++++++++ Tools/Python/XmlRoutines.py | 83 ++++- 4 files changed, 1391 insertions(+), 3 deletions(-) create mode 100644 Tools/Python/ContextTool.py create mode 100644 Tools/Python/EdkIIWorkspace.py create mode 100644 Tools/Python/Fd.py diff --git a/Tools/Python/ContextTool.py b/Tools/Python/ContextTool.py new file mode 100644 index 0000000000..3c95adb09d --- /dev/null +++ b/Tools/Python/ContextTool.py @@ -0,0 +1,590 @@ +#!/usr/bin/env python + +# The EDK II Build System Context Tool Utility maintains Target.txt settings in an EDK II Workspace. + +import wx, os, sys, copy +from EdkIIWorkspace import * + +class ContextToolModel(EdkIIWorkspace): + def __init__(self): + self.WorkspaceStatus = EdkIIWorkspace.__init__(self) + self.Database = {} + self.OriginalDatabase = {} + + def LoadTargetTxtFile(self): + self.ConvertTextFileToDictionary('Tools/Conf/Target.txt', self.TargetTxtDictionary, '#', '=', True, None) + if self.TargetTxtDictionary['ACTIVE_PLATFORM'] == []: + self.TargetTxtDictionary['ACTIVE_PLATFORM'] = [''] + else: + self.TargetTxtDictionary['ACTIVE_PLATFORM'] = [self.TargetTxtDictionary['ACTIVE_PLATFORM'][0]] + self.TargetTxtDictionary['TOOL_CHAIN_CONF'] = [self.TargetTxtDictionary['TOOL_CHAIN_CONF'][0]] + self.TargetTxtDictionary['MULTIPLE_THREAD'] = [self.TargetTxtDictionary['MULTIPLE_THREAD'][0]] + self.TargetTxtDictionary['MAX_CONCURRENT_THREAD_NUMBER'] = [self.TargetTxtDictionary['MAX_CONCURRENT_THREAD_NUMBER'][0]] + self.TargetTxtDictionary['TARGET'] = list(set(self.TargetTxtDictionary['TARGET'])) + self.TargetTxtDictionary['TOOL_CHAIN_TAG'] = list(set(self.TargetTxtDictionary['TOOL_CHAIN_TAG'])) + self.TargetTxtDictionary['TARGET_ARCH'] = list(set(self.TargetTxtDictionary['TARGET_ARCH'])) + if self.TargetTxtDictionary['TARGET'] == []: + self.TargetTxtDictionary['TARGET'] = [''] + if self.TargetTxtDictionary['TOOL_CHAIN_TAG'] == []: + self.TargetTxtDictionary['TOOL_CHAIN_TAG'] = [''] + if self.TargetTxtDictionary['TARGET_ARCH'] == []: + self.TargetTxtDictionary['TARGET_ARCH'] = [''] + self.TargetTxtDictionary['TARGET'].sort() + self.TargetTxtDictionary['TOOL_CHAIN_TAG'].sort() + self.TargetTxtDictionary['TARGET_ARCH'].sort() + self.OriginalTargetTxtDictionary = copy.deepcopy(self.TargetTxtDictionary) + + def LoadToolsDefTxtFile(self): + self.ToolsDefTxtDictionary = {} + if self.TargetTxtDictionary['TOOL_CHAIN_CONF'] != ['']: + self.ConvertTextFileToDictionary(self.TargetTxtDictionary['TOOL_CHAIN_CONF'][0], self.ToolsDefTxtDictionary, '#', '=', False, None) + + def LoadFrameworkDatabase(self): + self.PlatformDatabase = {} + Fd = self.XmlParseFile ('Tools/Conf/FrameworkDatabase.db') + PlatformList = XmlList (Fd, '/FrameworkDatabase/PlatformList/Filename') + for File in PlatformList: + FpdFileName = XmlElementData(File) + FpdPlatformHeader = self.XmlParseFileSection (FpdFileName, 'PlatformHeader') + FpdPlatformDefinitions = self.XmlParseFileSection (FpdFileName,'PlatformDefinitions') + PlatformName = XmlElement (FpdPlatformHeader, '/PlatformHeader/PlatformName') + PlatformVersion = XmlElement (FpdPlatformHeader, '/PlatformHeader/Version') + PlatformUiName = PlatformName + '[' + PlatformVersion + ']' + if PlatformUiName not in self.PlatformDatabase: + self.PlatformDatabase[PlatformUiName] = {} + self.PlatformDatabase[PlatformUiName]['XmlFileName'] = FpdFileName + self.PlatformDatabase[PlatformUiName]['SupportedArchitectures'] = set(XmlElement (FpdPlatformDefinitions, '/PlatformSurfaceArea/PlatformDefinitions/SupportedArchitectures').split(' ')) + self.PlatformDatabase[PlatformUiName]['BuildTargets'] = set(XmlElement (FpdPlatformDefinitions, '/PlatformSurfaceArea/PlatformDefinitions/BuildTargets').split(' ')) + + def ComputeToolsDefTxtDatabase(self): + self.ToolsDefTxtDatabase = { + 'TARGET' : [], + 'TOOL_CHAIN_TAG' : [], + 'TARGET_ARCH' : [] + } + for Key in dict(self.ToolsDefTxtDictionary): + List = Key.split('_') + if len(List) != 5: + del self.ToolsDefTxtDictionary[Key] + elif List[4] == '*': + del self.ToolsDefTxtDictionary[Key] + else: + if List[0] != '*': + self.ToolsDefTxtDatabase['TARGET'] += [List[0]] + if List[1] != '*': + self.ToolsDefTxtDatabase['TOOL_CHAIN_TAG'] += [List[1]] + if List[2] != '*': + self.ToolsDefTxtDatabase['TARGET_ARCH'] += [List[2]] + self.ToolsDefTxtDatabase['TARGET'] = list(set(self.ToolsDefTxtDatabase['TARGET'])) + self.ToolsDefTxtDatabase['TOOL_CHAIN_TAG'] = list(set(self.ToolsDefTxtDatabase['TOOL_CHAIN_TAG'])) + self.ToolsDefTxtDatabase['TARGET_ARCH'] = list(set(self.ToolsDefTxtDatabase['TARGET_ARCH'])) + self.ToolsDefTxtDatabase['TARGET'].sort() + self.ToolsDefTxtDatabase['TOOL_CHAIN_TAG'].sort() + self.ToolsDefTxtDatabase['TARGET_ARCH'].sort() + + def NewModel(self): + self.TargetTxtDictionary = { + 'ACTIVE_PLATFORM' : [''], + 'TOOL_CHAIN_CONF' : [''], + 'MULTIPLE_THREAD' : ['Disable'], + 'MAX_CONCURRENT_THREAD_NUMBER' : ['2'], + 'TARGET' : [''], + 'TOOL_CHAIN_TAG' : [''], + 'TARGET_ARCH' : [''] + } + + def RevertModel(self): + self.TargetTxtDictionary = copy.deepcopy(self.OriginalTargetTxtDictionary) + + def RescanModel(self): + self.NewModel() + self.LoadTargetTxtFile() + + def RefreshModel(self): + self.LoadFrameworkDatabase() + self.LoadToolsDefTxtFile() + self.ComputeToolsDefTxtDatabase() + + if self.Verbose: + print self.TargetTxtDictionary + print 'ActivePlatform = ', self.TargetTxtDictionary['ACTIVE_PLATFORM'][0] + print 'ToolChainConf = ', self.TargetTxtDictionary['TOOL_CHAIN_CONF'][0] + print 'MultipleThread = ', self.TargetTxtDictionary['MULTIPLE_THREAD'][0] + print 'MaxThreads = ', self.TargetTxtDictionary['MAX_CONCURRENT_THREAD_NUMBER'][0] + print 'TargetSet = ', self.TargetTxtDictionary['TARGET'] + print 'ToolChainSet = ', self.TargetTxtDictionary['TOOL_CHAIN_TAG'] + print 'TargetArchSet = ', self.TargetTxtDictionary['TARGET_ARCH'] + Platforms = self.PlatformDatabase.keys() + print 'Possible Settings:' + print ' Platforms = ', Platforms + print ' TargetSet = ', self.ToolsDefTxtDatabase['TARGET'] + print ' ToolChainSet = ', self.ToolsDefTxtDatabase['TOOL_CHAIN_TAG'] + print ' TargetArchSet = ', self.ToolsDefTxtDatabase['TARGET_ARCH'] + return True + + def ModelModified(self): + if self.TargetTxtDictionary != self.OriginalTargetTxtDictionary: + return True + return False + + def SaveModel(self, Filename='Tools/Conf/Target.txt'): + if self.Verbose: + for Item in self.TargetTxtDictionary: + print Item,'=',self.TargetTxtDictionary[Item] + self.ConvertDictionaryToTextFile(Filename, self.TargetTxtDictionary, '#', '=', True, None) + self.OriginalTargetTxtDictionary = copy.deepcopy(self.TargetTxtDictionary) + + def CloseModel(self): + pass + +class Frame(wx.Frame): + def __init__(self): + wx.Frame.__init__(self,None,-1,'EDK II Build System Context Tool') + panel = wx.Panel(self, style=wx.SUNKEN_BORDER | wx.TAB_TRAVERSAL) + wx.HelpProvider_Set(wx.SimpleHelpProvider()) + self.Model = ContextToolModel() + if not self.Model.WorkspaceStatus: + self.Close() + return + + # + # Help text + # + ActivePlatformHelpText = ( + "Specifies the Platform Name and Platform Version of the platform that will be " + "used for build. If set to [Build Directory] and the current directory contains " + "an FPD file, then a plaform build on that FPD file will be performed. If set " + "to [Build Directory] and there is no FPD file in the current directory, then no " + "build will be performed." + ) + + ToolChainConfHelpText = ( + "Specifies the name of the file that declares all the tools and flag settings " + "required to complete a build. This is typically set to Tools/Conf/tools_def.txt." + ) + + MultipleThreadHelpText = ( + "Flag to enable or disable multi-thread builds. If your computer is multi-core " + "or contans multiple CPUs, enabling this feature will improve build performance. " + "For multi-thread builds, a log will be written to ${BUILD_DIR}/build.log. This " + "feature is only for platform builds. Clean, cleanall, and stand-alone module " + "builds only use one thread." + ) + + ThreadsHelpText = ( + "The number of concurrent threads. The best performance is achieved if this " + "value is set to one greater than the number or cores or CPUs in the build system." + ) + + TargetHelpText = ( + "Specifies the set of targets to build. If set to All, then all build targets " + "are built. Otherwise, the subset of enabled build targets are built. The " + "standard build targets are RELEASE and DEBUG, but additional user-defined build " + "targets may be declared in the TOOL_CHAIN_CONF file. The DEBUG builds with " + "source level debugging enabled. RELEASE builds with source level debugging " + "disabled and results in smaller firmware images." + ) + + ToolChainTagHelpText = ( + "Specifies the set of tool chains to use during a build. If set to All, then " + "all of the supported tools chains are used. Otherwise, only the subset of " + "enabled tool chains are used. The TOOL_CHAIN_CONF file declares one or more " + "tool chains that may be used." + ) + + TargetArchHelpText = ( + "Specifies the set of CPU architectures to build. If set to All, then all the " + "CPU architectures supported by the platform FPD file are built. Otherwise, " + "only the subset of enabled CPU architectures are built. The standard CPU " + "architectures are IA32, X64, IPF, and EBC, but additional CPU architectures " + "may be declared in the TOOL_CHAIN_CONF file." + ) + + # + # Status Bar + # + self.CreateStatusBar() + + # + # Build Menus + # + MenuBar = wx.MenuBar() + + FileMenu = wx.Menu() + NewMenuItem = FileMenu.Append(-1, "&New\tCtrl+N", "New target.txt") + SaveMenuItem = FileMenu.Append(-1, "&Save\tCtrl+S", "Save target.txt") + SaveAsMenuItem = FileMenu.Append(-1, "Save &As...", "Save target.txt as...") + RevertMenuItem = FileMenu.Append(-1, "&Revert", "Revert to the original target.txt") + ExitMenuItem = FileMenu.Append(-1, "E&xit\tAlt+F4", "Exit ContextTool") + MenuBar.Append(FileMenu, "&File") + self.Bind(wx.EVT_MENU, self.OnSaveClick, SaveMenuItem) + self.Bind(wx.EVT_MENU, self.OnSaveAsClick, SaveAsMenuItem) + self.Bind(wx.EVT_MENU, self.OnRevertClick, RevertMenuItem) + self.Bind(wx.EVT_MENU, self.OnExitClick, ExitMenuItem) + + ViewMenu = wx.Menu() + RefreshMenuItem = ViewMenu.Append (-1, "&Refresh\tF5", "Rescan target.txt") + ShowToolBarMenuItem = ViewMenu.AppendCheckItem (-1, "Show &Toolbar", "Shows or hides the toolbar") + ShowToolBarMenuItem.Check(True) + MenuBar.Append(ViewMenu, "&View") + self.Bind(wx.EVT_MENU, self.OnViewRefreshClick, RefreshMenuItem) + self.Bind(wx.EVT_MENU, self.OnShowToolBarClick, ShowToolBarMenuItem) + + HelpMenu = wx.Menu() + AboutMenuItem = HelpMenu.Append (-1, "&About...", "About") + MenuBar.Append(HelpMenu, "&Help") + self.Bind(wx.EVT_MENU, self.OnAboutClick, AboutMenuItem) + + self.SetMenuBar (MenuBar) + + # + # Build Toolbar + # + self.ShowToolBar = False + self.OnShowToolBarClick(self) + + # + # Active Platform Combo Box + # + ActivePlatformLabel = wx.StaticText(panel, -1, 'ACTIVE_PLATFORM') + ActivePlatformLabel.SetHelpText(ActivePlatformHelpText) + self.ActivePlatformText = wx.ComboBox(panel,-1, style=wx.CB_DROPDOWN | wx.CB_SORT | wx.CB_READONLY) + self.ActivePlatformText.SetHelpText(ActivePlatformHelpText) + self.ActivePlatformText.Bind(wx.EVT_TEXT, self.OnActivePlatformClick) + + # + # Tool Chain Configuration Text Control and Browse Button for a File Dialog Box + # + ToolChainConfFileLabel = wx.StaticText(panel, -1, 'TOOL_CHAIN_CONF') + ToolChainConfFileLabel.SetHelpText(ToolChainConfHelpText) + self.ToolChainConfFileText = wx.TextCtrl(panel, -1, style=wx.TE_PROCESS_ENTER) + self.ToolChainConfFileText.Bind(wx.EVT_TEXT_ENTER, self.OnToolChainConfClick) + self.ToolChainConfFileText.Bind(wx.EVT_KILL_FOCUS, self.OnToolChainConfClick) + self.ToolChainConfFileText.SetHelpText(ToolChainConfHelpText) + self.BrowseButton = wx.Button(panel, -1, 'Browse...') + self.BrowseButton.Bind(wx.EVT_BUTTON, self.OnBrowseButtonClick) + + # + # Multiple Thread enable/disable radio button + # + MultipleThreadLabel = wx.StaticText(panel, -1, 'MULTIPLE_THREAD') + MultipleThreadLabel.SetHelpText(MultipleThreadHelpText) + self.MultipleThreadRadioBox = wx.RadioBox(panel, -1, choices=['Enable','Disable'], style=wx.RA_SPECIFY_COLS) + self.MultipleThreadRadioBox.Bind(wx.EVT_RADIOBOX, self.OnMultipleThreadRadioBox) + self.MultipleThreadRadioBox.SetHelpText(MultipleThreadHelpText) + + # + # Thread count spin control + # + ThreadsLabel = wx.StaticText(panel, -1, 'THREADS') + ThreadsLabel.SetHelpText(ThreadsHelpText) + self.ThreadsSpinCtrl = wx.SpinCtrl(panel, -1, size=(50, -1), min=2) + self.ThreadsSpinCtrl.Bind(wx.EVT_TEXT, self.OnThreadsSpinCtrl) + self.ThreadsSpinCtrl.SetHelpText(ThreadsHelpText) + + # + # Target, ToolChain, and Arch Check List Boxes + # + TargetLabel = wx.StaticText(panel, -1, 'TARGET') + TargetLabel.SetHelpText(TargetHelpText) + + ToolChainTagLabel = wx.StaticText(panel, -1, 'TOOL_CHAIN_TAG') + ToolChainTagLabel.SetHelpText(ToolChainTagHelpText) + + TargetArchLabel = wx.StaticText(panel, -1, 'TARGET_ARCH') + TargetArchLabel.SetHelpText(TargetArchHelpText) + + self.TargetCheckListBox = wx.CheckListBox(panel, -1) + self.TargetCheckListBox.Bind(wx.EVT_CHECKLISTBOX, self.OnTargetCheckListClick) + self.TargetCheckListBox.Bind(wx.EVT_SET_FOCUS, self.OnTargetSetFocus) + self.TargetCheckListBox.Bind(wx.EVT_KILL_FOCUS, self.OnTargetKillFocus) + self.TargetCheckListBox.SetHelpText(TargetHelpText) + + self.ToolChainTagCheckListBox = wx.CheckListBox(panel, -1) + self.ToolChainTagCheckListBox.Bind(wx.EVT_CHECKLISTBOX, self.OnToolChainTagCheckListClick) + self.ToolChainTagCheckListBox.Bind(wx.EVT_SET_FOCUS, self.OnToolChainTagSetFocus) + self.ToolChainTagCheckListBox.Bind(wx.EVT_KILL_FOCUS, self.OnToolChainTagKillFocus) + self.ToolChainTagCheckListBox.SetHelpText(ToolChainTagHelpText) + + self.TargetArchCheckListBox = wx.CheckListBox(panel, -1) + self.TargetArchCheckListBox.Bind(wx.EVT_CHECKLISTBOX, self.OnTargetArchCheckListClick) + self.TargetArchCheckListBox.Bind(wx.EVT_SET_FOCUS, self.OnTargetArchSetFocus) + self.TargetArchCheckListBox.Bind(wx.EVT_KILL_FOCUS, self.OnTargetArchKillFocus) + self.TargetArchCheckListBox.SetHelpText(TargetArchHelpText) + + # + # Define layout using sizers + # + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + + flexSizer = wx.FlexGridSizer(cols=3, hgap=5, vgap=5) + flexSizer.AddGrowableCol(1) + flexSizer.Add(ActivePlatformLabel, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL) + flexSizer.Add(self.ActivePlatformText, 0, wx.EXPAND) + flexSizer.Add((0,0), wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) + + flexSizer.Add(ToolChainConfFileLabel, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL) + flexSizer.Add(self.ToolChainConfFileText, 0, wx.EXPAND) + flexSizer.Add(self.BrowseButton, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) + + self.mainSizer.Add (flexSizer, 0, wx.EXPAND | wx.ALL, 10) + + threadsSizer = wx.FlexGridSizer(cols = 5, hgap=5, vgap=5) + threadsSizer.Add(MultipleThreadLabel, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL) + threadsSizer.Add(self.MultipleThreadRadioBox, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) + threadsSizer.Add(ThreadsLabel, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL) + threadsSizer.Add(self.ThreadsSpinCtrl, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) + + self.mainSizer.Add (threadsSizer, 0, wx.ALL, 10) + + listSizer = wx.FlexGridSizer(rows = 2, cols = 3, hgap=5, vgap=5) + listSizer.AddGrowableRow(1) + listSizer.AddGrowableCol(0) + listSizer.AddGrowableCol(1) + listSizer.AddGrowableCol(2) + listSizer.Add(TargetLabel, 0, wx.ALIGN_CENTER) + listSizer.Add(ToolChainTagLabel, 0, wx.ALIGN_CENTER) + listSizer.Add(TargetArchLabel, 0, wx.ALIGN_CENTER) + listSizer.Add(self.TargetCheckListBox, 0, wx.ALL | wx.EXPAND) + listSizer.Add(self.ToolChainTagCheckListBox, 0, wx.ALL | wx.EXPAND) + listSizer.Add(self.TargetArchCheckListBox, 0, wx.ALL | wx.EXPAND) + + self.mainSizer.Add (listSizer, wx.EXPAND | wx.ALL, wx.EXPAND | wx.ALL, 10) + + panel.SetSizer (self.mainSizer) + + self.Model.RescanModel() + self.OnRefreshClick(self) + + def OnActivePlatformClick(self, event): + Platform = self.ActivePlatformText.GetValue() + if Platform == ' [Build Directory]': + self.Model.TargetTxtDictionary['ACTIVE_PLATFORM'][0] = '' + else: + self.Model.TargetTxtDictionary['ACTIVE_PLATFORM'][0] = self.Model.PlatformDatabase[Platform]['XmlFileName'] + + def OnToolChainConfClick(self, event): + if self.Model.TargetTxtDictionary['TOOL_CHAIN_CONF'][0] != self.ToolChainConfFileText.GetValue(): + self.Model.TargetTxtDictionary['TOOL_CHAIN_CONF'][0] = self.ToolChainConfFileText.GetValue() + self.OnRefreshClick(self) + + def OnBrowseButtonClick(self, event): + wildcard = "Text Documents (*.txt)|*.txt|" \ + "All files (*.*)|*.*" + dialog = wx.FileDialog (None, 'Choose a Tool Chain Configuration File', self.Model.WorkspaceFile('Tools/Conf'), '', wildcard, wx.OPEN) + if dialog.ShowModal() == wx.ID_OK: + print dialog.GetPath() + ToolChainConfFile = self.Model.WorkspaceRelativePath(dialog.GetPath()) + self.ToolChainConfFileText.SetValue(ToolChainConfFile) + self.Model.TargetTxtDictionary['TOOL_CHAIN_CONF'][0] = self.ToolChainConfFileText.GetValue() + self.OnRefreshClick(self) + dialog.Destroy() + + def OnMultipleThreadRadioBox (self, event): + self.Model.TargetTxtDictionary['MULTIPLE_THREAD'] = [self.MultipleThreadRadioBox.GetStringSelection()] + if self.MultipleThreadRadioBox.GetStringSelection() == 'Disable': + self.ThreadsSpinCtrl.Disable() + else: + self.ThreadsSpinCtrl.Enable() + + def OnThreadsSpinCtrl(self, event): + self.Model.TargetTxtDictionary['MAX_CONCURRENT_THREAD_NUMBER'] = [str(self.ThreadsSpinCtrl.GetValue())] + + def CheckListFocus(self, CheckListBox, Set): + Index = 0 + while Index < CheckListBox.GetCount(): + CheckListBox.SetSelection(Index, False) + Index += 1 + if Set: + CheckListBox.SetSelection(0, True) + + def CheckListClick(self, CheckListBox, Name): + if CheckListBox.IsChecked(0): + Index = 1 + while Index < CheckListBox.GetCount(): + CheckListBox.Check(Index, False) + Index += 1 + if CheckListBox.IsChecked(0): + self.Model.TargetTxtDictionary[Name] = [''] + else: + self.Model.TargetTxtDictionary[Name] = [] + Index = 1 + while Index < CheckListBox.GetCount(): + if CheckListBox.IsChecked(Index): + self.Model.TargetTxtDictionary[Name] += [CheckListBox.GetString(Index)] + Index += 1 + if self.Model.TargetTxtDictionary[Name] == []: + self.Model.TargetTxtDictionary[Name] = [''] + + def OnTargetCheckListClick(self, event): + self.CheckListClick(self.TargetCheckListBox, 'TARGET') + + def OnTargetSetFocus(self, event): + self.CheckListFocus(self.TargetCheckListBox, True) + + def OnTargetKillFocus(self, event): + self.CheckListFocus(self.TargetCheckListBox, False) + + def OnToolChainTagCheckListClick(self, event): + self.CheckListClick(self.ToolChainTagCheckListBox, 'TOOL_CHAIN_TAG') + + def OnToolChainTagSetFocus(self, event): + self.CheckListFocus(self.ToolChainTagCheckListBox, True) + + def OnToolChainTagKillFocus(self, event): + self.CheckListFocus(self.ToolChainTagCheckListBox, False) + + def OnTargetArchCheckListClick(self, event): + self.CheckListClick(self.TargetArchCheckListBox, 'TARGET_ARCH') + + def OnTargetArchSetFocus(self, event): + self.CheckListFocus(self.TargetArchCheckListBox, True) + + def OnTargetArchKillFocus(self, event): + self.CheckListFocus(self.TargetArchCheckListBox, False) + + def OnRevertClick(self, event): + self.Model.RevertModel() + self.OnRefreshClick(self) + + def RefreshCheckListBox(self, CheckListBox, Name): + CheckListBox.Set(['All'] + self.Model.ToolsDefTxtDatabase[Name]) + Index = 0 + MaximumString = '' + while Index < CheckListBox.GetCount(): + String = CheckListBox.GetString(Index) + if len(String) > len(MaximumString): + MaximumString = String + if String in self.Model.TargetTxtDictionary[Name]: + CheckListBox.Check(Index, True) + else: + CheckListBox.Check(Index, False) + Index += 1 + if self.Model.TargetTxtDictionary[Name] == ['']: + CheckListBox.Check(0, True) + Extents = CheckListBox.GetFullTextExtent (MaximumString) + CheckListBox.SetMinSize((Extents[0],(CheckListBox.GetCount()+1) * (Extents[1]+Extents[2]))) + + def OnRefreshClick(self, event): + self.Model.RefreshModel() + Platforms = self.Model.PlatformDatabase.keys() + Platforms.sort() + self.ActivePlatformText.SetItems([' [Build Directory]'] + Platforms) + self.ActivePlatformText.SetValue(' [Build Directory]') + for Platform in self.Model.PlatformDatabase: + if self.Model.PlatformDatabase[Platform]['XmlFileName'] == self.Model.TargetTxtDictionary['ACTIVE_PLATFORM'][0]: + self.ActivePlatformText.SetValue(Platform) + if self.ActivePlatformText.GetValue() == ' [Build Directory]': + self.Model.TargetTxtDictionary['ACTIVE_PLATFORM'][0] = '' + MaximumString = ' [Build Directory]' + for String in Platforms: + if len(String) > len(MaximumString): + MaximumString = String + Extents = self.ActivePlatformText.GetFullTextExtent (MaximumString) + self.ActivePlatformText.SetMinSize((Extents[0] + 24,-1)) + + self.ToolChainConfFileText.SetValue(self.Model.TargetTxtDictionary['TOOL_CHAIN_CONF'][0]) + Extents = self.ToolChainConfFileText.GetFullTextExtent (self.Model.TargetTxtDictionary['TOOL_CHAIN_CONF'][0]) + self.ToolChainConfFileText.SetMinSize((Extents[0] + 24,-1)) + + self.MultipleThreadRadioBox.SetStringSelection(self.Model.TargetTxtDictionary['MULTIPLE_THREAD'][0]) + if self.MultipleThreadRadioBox.GetStringSelection() == 'Disable': + self.ThreadsSpinCtrl.Disable() + self.ThreadsSpinCtrl.SetValue(int(self.Model.TargetTxtDictionary['MAX_CONCURRENT_THREAD_NUMBER'][0])) + + self.RefreshCheckListBox (self.TargetCheckListBox, 'TARGET') + self.RefreshCheckListBox (self.ToolChainTagCheckListBox, 'TOOL_CHAIN_TAG') + self.RefreshCheckListBox (self.TargetArchCheckListBox, 'TARGET_ARCH') + + self.mainSizer.SetSizeHints(self) + self.mainSizer.Fit(self) + + def OnViewRefreshClick(self, event): + self.Model.RescanModel() + self.OnRefreshClick(self) + + def AddTool (self, Handler, ArtId, Label, HelpText): + Tool = self.ToolBar.AddSimpleTool( + -1, + wx.ArtProvider.GetBitmap(ArtId, wx.ART_TOOLBAR, self.ToolSize), + Label, + HelpText + ) + self.Bind(wx.EVT_MENU, Handler, Tool) + + def OnShowToolBarClick(self, event): + if self.ShowToolBar: + self.ShowToolBar = False + self.ToolBar.Destroy() + else: + self.ShowToolBar = True + self.ToolBar = self.CreateToolBar() + self.ToolSize = (24,24) + self.ToolBar.SetToolBitmapSize(self.ToolSize) + self.AddTool (self.OnNewClick, wx.ART_NEW, "New", "New target.txt") + self.AddTool (self.OnSaveClick, wx.ART_FILE_SAVE, "Save", "Save target.txt") + self.AddTool (self.OnSaveAsClick, wx.ART_FILE_SAVE_AS, "Save As...", "Save target.txt as...") + self.AddTool (self.OnRevertClick, wx.ART_UNDO, "Revert", "Revert to original target.txt") + self.AddTool (self.OnHelpClick, wx.ART_HELP, "Help", "Context Sensitive Help") + self.AddTool (self.OnExitClick, wx.ART_QUIT, "Exit", "Exit Context Tool application") + self.ToolBar.Realize() + + def OnNewClick(self, event): + self.Model.NewModel() + self.OnRefreshClick(self) + + def OnSaveClick(self, event): + self.Model.SaveModel() + + def OnSaveAsClick(self, event): + wildcard = "Text Documents (*.txt)|*.txt|" \ + "All files (*.*)|*.*" + dialog = wx.FileDialog (None, 'Save As', self.Model.WorkspaceFile('Tools/Conf'), '', wildcard, wx.SAVE | wx.OVERWRITE_PROMPT) + if dialog.ShowModal() == wx.ID_OK: + TargetTxtFile = self.Model.WorkspaceRelativePath(dialog.GetPath()) + if TargetTxtFile != '': + self.Model.SaveModel(TargetTxtFile) + dialog.Destroy() + + def OnExitClick(self, event): + if self.Model.ModelModified(): + dialog = wx.MessageDialog(None, 'The contents have changed.\nDo you want to save changes?', 'EDK II Build System Context Tool', style = wx.YES_NO | wx.YES_DEFAULT | wx.CANCEL | wx.ICON_EXCLAMATION) + Status = dialog.ShowModal() + dialog.Destroy() + if Status == wx.ID_YES: + self.OnSaveClick (self) + elif Status == wx.ID_CANCEL: + return + self.Model.CloseModel() + self.Close() + + def OnHelpClick(self, event): + wx.ContextHelp().BeginContextHelp() + + def OnAboutClick(self, event): + AboutInfo = wx.AboutDialogInfo() + AboutInfo.Name = 'EDK II Build System Context Tool' + AboutInfo.Version = '0.3' + AboutInfo.Copyright = 'Copyright (c) 2006, Intel Corporation' + AboutInfo.Description = """ + The EDK II Build System Context Tool maintains the target.txt + settings in an EDK II Workspace.""" + AboutInfo.WebSite = ("http://tianocore.org", "Tiano Core home page") + AboutInfo.License = """ + All rights reserved. This program and the accompanying materials are + licensed and made available under the terms and conditions of the BSD + License which accompanies this distribution. The full text of the + license may be found at http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" + BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, + EITHER EXPRESS OR IMPLIED.""" + if self.Model.Icon != None: + AboutInfo.Icon = self.Model.Icon + wx.AboutBox(AboutInfo) + +if __name__ == '__main__': + app = wx.PySimpleApp() + frame = Frame() + frame.Show() + app.MainLoop() diff --git a/Tools/Python/EdkIIWorkspace.py b/Tools/Python/EdkIIWorkspace.py new file mode 100644 index 0000000000..935ffadc09 --- /dev/null +++ b/Tools/Python/EdkIIWorkspace.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python + +# This is the base class for applications that operate on an EDK II Workspace + +import os, sys +from XmlRoutines import * + +class EdkIIWorkspace: + def __init__(self): + """Collect WorkspaceDir from the environment, the Verbose command line flag, and detect an icon bitmap file.""" + if os.environ.get('WORKSPACE') == None: + print 'ERROR: WORKSPACE not defined. Please run EdkSetup from the EDK II install directory.' + return False + + self.WorkspaceDir = os.path.realpath(os.environ.get('WORKSPACE')) + (Drive, Path) = os.path.splitdrive(self.WorkspaceDir) + if Drive == '': + (Drive, CwdPath) = os.path.splitdrive(os.getcwd()) + if Drive != '': + self.WorkspaceDir = Drive + Path + else: + self.WorkspaceDir = Drive.upper() + Path + + try: + self.Icon = wx.Icon(self.WorkspaceFile('tools/Python/TianoCoreOrgLogo.gif'),wx.BITMAP_TYPE_GIF) + except: + self.Icon = None + + self.Verbose = False + for arg in sys.argv: + if arg.lower() == '-v': + self.Verbose = True + + return True + + def WorkspaceRelativePath(self, FileName): + """Convert a full path filename to a workspace relative filename.""" + FileName = os.path.realpath(FileName) + if FileName.find(self.WorkspaceDir) != 0: + return '' + return FileName.replace (self.WorkspaceDir, '').strip('\\').strip('/') + + def WorkspaceFile(self, FileName): + """Convert a workspace relative filename to a full path filename.""" + return os.path.realpath(os.path.join(self.WorkspaceDir,FileName)) + + def XmlParseFile (self, FileName): + """Parse an XML file into a DOM and return the DOM.""" + if self.Verbose: + print FileName + return XmlParseFile (self.WorkspaceFile(FileName)) + + def XmlParseFileSection (self, FileName, SectionTag): + """Parse a section of an XML file into a DOM(Document Object Model) and return the DOM.""" + if self.Verbose: + print FileName + return XmlParseFileSection (self.WorkspaceFile(FileName), SectionTag) + + def XmlSaveFile (self, Dom, FileName): + """Save a DOM(Document Object Model) into an XML file.""" + if self.Verbose: + print FileName + return XmlSaveFile (Dom, self.WorkspaceFile(FileName)) + + def ConvertTextFileToDictionary(self, FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): + """Convert a workspace relative text file to a dictionary of (name:value) pairs.""" + if self.Verbose: + print FileName + return ConvertTextFileToDictionary(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter) + + def ConvertDictionaryToTextFile(self, FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): + """Convert a dictionary of (name:value) pairs to a workspace relative text file.""" + if self.Verbose: + print FileName + return ConvertDictionaryToTextFile(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter) + +# +# Convert a text file to a dictionary +# +def ConvertTextFileToDictionary(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): + """Convert a text file to a dictionary of (name:value) pairs.""" + try: + f = open(FileName,'r') + except: + return False + Keys = [] + for Line in f: + LineList = Line.split(KeySplitCharacter,1) + if len(LineList) >= 2: + Key = LineList[0].split() + if len(Key) == 1 and Key[0][0] != CommentCharacter and Key[0] not in Keys: + if ValueSplitFlag: + Dictionary[Key[0]] = LineList[1].replace('\\','/').split(ValueSplitCharacter) + else: + Dictionary[Key[0]] = LineList[1].strip().replace('\\','/') + Keys += [Key[0]] + f.close() + return True + +def ConvertDictionaryToTextFile(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): + """Convert a dictionary of (name:value) pairs to a text file.""" + try: + f = open(FileName,'r') + Lines = [] + Lines = f.readlines() + f.close() + except: + Lines = [] + Keys = Dictionary.keys() + MaxLength = 0 + for Key in Keys: + if len(Key) > MaxLength: + MaxLength = len(Key) + Index = 0 + for Line in Lines: + LineList = Line.split(KeySplitCharacter,1) + if len(LineList) >= 2: + Key = LineList[0].split() + if len(Key) == 1 and Key[0][0] != CommentCharacter and Key[0] in Dictionary: + if ValueSplitFlag: + Line = '%-*s %c %s\n' % (MaxLength, Key[0], KeySplitCharacter, ' '.join(Dictionary[Key[0]])) + else: + Line = '%-*s %c %s\n' % (MaxLength, Key[0], KeySplitCharacter, Dictionary[Key[0]]) + Lines.pop(Index) + if Key[0] in Keys: + Lines.insert(Index,Line) + Keys.remove(Key[0]) + Index += 1 + for RemainingKey in Keys: + if ValueSplitFlag: + Line = '%-*s %c %s\n' % (MaxLength, RemainingKey, KeySplitCharacter,' '.join(Dictionary[RemainingKey])) + else: + Line = '%-*s %c %s\n' % (MaxLength, RemainingKey, KeySplitCharacter, Dictionary[RemainingKey]) + Lines.append(Line) + try: + f = open(FileName,'w') + except: + return False + f.writelines(Lines) + f.close() + return True + +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +if __name__ == '__main__': + + # Nothing to do here. Could do some unit tests. + pass diff --git a/Tools/Python/Fd.py b/Tools/Python/Fd.py new file mode 100644 index 0000000000..f71cc07171 --- /dev/null +++ b/Tools/Python/Fd.py @@ -0,0 +1,573 @@ +#!/usr/bin/env python + +# An EDK II Build System Framework Database Utility maintains FrameworkDatabase.db +# settings in an EDK II Workspace. + +import wx, os, sys, copy +from EdkIIWorkspace import * + +class FrameworkDatabaseModel(EdkIIWorkspace): + def __init__(self): + self.WorkspaceStatus = EdkIIWorkspace.__init__(self) + self.Database = {} + self.OriginalDatabase = {} + + def AddFile (self, DirName, FileName, FileType, Enabled): + if DirName != '': + FileName = os.path.join(DirName,FileName) + if FileType == 'Package': + Header = self.XmlParseFileSection (FileName, 'SpdHeader') + Name = XmlElement (Header, '/SpdHeader/PackageName') + Version = XmlElement (Header, '/SpdHeader/Version') + elif FileType == 'Platform': + Header = self.XmlParseFileSection (FileName, 'PlatformHeader') + Name = XmlElement (Header, '/PlatformHeader/PlatformName') + Version = XmlElement (Header, '/PlatformHeader/Version') + else: + return + FileName = FileName.replace('\\','/') + if Name == '' and Version == '': + ValidType = 'Invalid' + OtherType = 'Valid' + UiName = FileName + else: + ValidType = 'Valid' + OtherType = 'Invalid' + UiName = Name + ' [' + Version + ']' + self.Database[FileType][OtherType]['PossibleSettings'].pop(FileName, None) + self.Database[FileType][OtherType]['EnabledSettings'].pop(FileName, None) + self.Database[FileType][ValidType]['PossibleSettings'][FileName] = UiName + if Enabled: + self.Database[FileType][ValidType]['EnabledSettings'][FileName] = UiName + return + + def NewModel(self): + self.Database['Platform'] = {'Valid': {'PossibleSettings':{}, 'EnabledSettings':{}},'Invalid': {'PossibleSettings':{}, 'EnabledSettings':{}}} + self.Database['Package'] = {'Valid': {'PossibleSettings':{}, 'EnabledSettings':{}},'Invalid': {'PossibleSettings':{}, 'EnabledSettings':{}}} + + def RevertModel(self): + self.Database = copy.deepcopy(self.OriginalDatabase) + + def RescanModel(self): + self.NewModel() + self.Fd = self.XmlParseFile ('Tools/Conf/FrameworkDatabase.db') + PackageList = XmlList (self.Fd, '/FrameworkDatabase/PackageList/Filename') + for File in PackageList: + SpdFileName = XmlElementData(File) + self.AddFile ('', SpdFileName, 'Package', True) + PlatformList = XmlList (self.Fd, '/FrameworkDatabase/PlatformList/Filename') + for File in PlatformList: + FpdFileName = XmlElementData(File) + self.AddFile ('', FpdFileName, 'Platform', True) + self.OriginalDatabase = copy.deepcopy(self.Database) + + def RefreshModel(self): + Temp = copy.deepcopy(self.Database) + for FileType in ['Package','Platform']: + for Valid in ['Valid','Invalid']: + for Item in Temp[FileType][Valid]['PossibleSettings']: + self.AddFile('',Item, FileType, Item in Temp[FileType][Valid]['EnabledSettings']) + return True + + def ModelModified(self): + if self.Database['Package']['Valid']['EnabledSettings'] != self.OriginalDatabase['Package']['Valid']['EnabledSettings']: + return True + if self.Database['Package']['Invalid']['EnabledSettings'] != self.OriginalDatabase['Package']['Invalid']['EnabledSettings']: + return True + if self.Database['Platform']['Valid']['EnabledSettings'] != self.OriginalDatabase['Platform']['Valid']['EnabledSettings']: + return True + if self.Database['Platform']['Invalid']['EnabledSettings'] != self.OriginalDatabase['Platform']['Invalid']['EnabledSettings']: + return True + return False + + def SaveModel(self, Filename='Tools/Conf/FrameworkDatabase.db'): + EnabledList = self.Database['Package']['Valid']['EnabledSettings'].keys() + EnabledList += self.Database['Package']['Invalid']['EnabledSettings'].keys() + PackageList = XmlList (self.Fd, '/FrameworkDatabase/PackageList/Filename') + for File in PackageList: + SpdFileName = XmlElementData(File) + if SpdFileName in EnabledList: + EnabledList.remove(SpdFileName) + continue + XmlRemoveElement(File) + + ParentNode = XmlList (self.Fd, '/FrameworkDatabase/PackageList')[0] + for SpdFileName in EnabledList: + XmlAppendChildElement(ParentNode, u'Filename', SpdFileName) + + EnabledList = self.Database['Platform']['Valid']['EnabledSettings'].keys() + EnabledList += self.Database['Platform']['Invalid']['EnabledSettings'].keys() + PlatformList = XmlList (self.Fd, '/FrameworkDatabase/PlatformList/Filename') + for File in PlatformList: + FpdFileName = XmlElementData(File) + if FpdFileName in EnabledList: + EnabledList.remove(FpdFileName) + continue + XmlRemoveElement(File) + + ParentNode = XmlList (self.Fd, '/FrameworkDatabase/PlatformList')[0] + for FpdFileName in EnabledList: + XmlAppendChildElement(ParentNode, u'Filename', FpdFileName) + + self.XmlSaveFile (self.Fd, Filename) + self.OriginalDatabase = copy.deepcopy(self.Database) + + def CloseModel(self): + pass + +class Frame(wx.Frame): + def __init__(self): + wx.Frame.__init__(self,None,-1,'EDK II Build System Framework Database Utility') + panel = wx.Panel(self, style=wx.SUNKEN_BORDER | wx.TAB_TRAVERSAL) + wx.HelpProvider_Set(wx.SimpleHelpProvider()) + + self.Model = FrameworkDatabaseModel() + + # + # Help text + # + PackagesHelpText = ( + "The set of packages that are active in the current WORKSPACE." + ) + + PlatformsHelpText = ( + "The set of platforms that are active in the current WORKSPACE." + ) + + InvalidPackagesHelpText = ( + "The set of packages that are in Framework Database, but not in the current WORKSPACE." + ) + + InvalidPlatformsHelpText = ( + "The set of platforms that are in Framework Database, but not in the current WORKSPACE." + ) + + # + # Status Bar + # + self.StatusBar = self.CreateStatusBar() + + # + # Build Menus + # + MenuBar = wx.MenuBar() + + FileMenu = wx.Menu() + NewMenuItem = FileMenu.Append(-1, "&New\tCtrl+N", "New FrameworkDatabase.db") + SaveMenuItem = FileMenu.Append(-1, "&Save\tCtrl+S", "Save FramdworkDatabase.db") + SaveAsMenuItem = FileMenu.Append(-1, "Save &As...", "Save FrameworkDatabase.db as...") + RevertMenuItem = FileMenu.Append(-1, "&Revert", "Revert to the original FrameworkDatabase.db") + ScanMenuItem = FileMenu.Append(-1, "Scan &WORKSPACE\tCtrl+W", "Scan WORKSPACE for additional packages and platforms") + ScanAndSyncMenuItem = FileMenu.Append(-1, "Scan &WORKSPACE and Sync\tCtrl+W", "Scan WORKSPACE for additional packages and platforms and sync FramdworkDatabase.db") + ExitMenuItem = FileMenu.Append(-1, "E&xit\tAlt+F4", "Exit Framework Database Tool") + MenuBar.Append(FileMenu, "&File") + self.Bind(wx.EVT_MENU, self.OnSaveClick, SaveMenuItem) + self.Bind(wx.EVT_MENU, self.OnSaveAsClick, SaveAsMenuItem) + self.Bind(wx.EVT_MENU, self.OnRevertClick, RevertMenuItem) + self.Bind(wx.EVT_MENU, self.OnScanClick, ScanMenuItem) + self.Bind(wx.EVT_MENU, self.OnScanAndSyncClick, ScanAndSyncMenuItem) + self.Bind(wx.EVT_MENU, self.OnExitClick, ExitMenuItem) + + EditMenu = wx.Menu() + SelectAllPlatformsMenuItem = EditMenu.Append (-1, "Select All Platforms", "Select all platforms") + ClearAllPlatformsMenuItem = EditMenu.Append (-1, "Clear All Platforms", "Clear all platforms") + SelectAllPackagesMenuItem = EditMenu.Append (-1, "Select All Packages", "Select all packages") + ClearAllPackagesMenuItem = EditMenu.Append (-1, "Clear All Packages", "Clear all packages") + SelectAllInvalidPlatformsMenuItem = EditMenu.Append (-1, "Select All Invalid Platforms", "Select all invalid platforms") + ClearAllInvalidPlatformsMenuItem = EditMenu.Append (-1, "Clear All Invalid Platforms", "Clear all invalid platforms") + SelectAllInvalidPackagesMenuItem = EditMenu.Append (-1, "Select All Invalid Packages", "Select all invalid packages") + ClearAllInvalidPackagesMenuItem = EditMenu.Append (-1, "Clear All Invalid Packages", "Clear all invalid packages") + MenuBar.Append(EditMenu, "&Edit") + self.Bind(wx.EVT_MENU, self.OnSelectAllPlatformsClick, SelectAllPlatformsMenuItem) + self.Bind(wx.EVT_MENU, self.OnClearAllPlatformsClick, ClearAllPlatformsMenuItem) + self.Bind(wx.EVT_MENU, self.OnSelectAllPackagesClick, SelectAllPackagesMenuItem) + self.Bind(wx.EVT_MENU, self.OnClearAllPackagesClick, ClearAllPackagesMenuItem) + self.Bind(wx.EVT_MENU, self.OnSelectAllInvalidPlatformsClick, SelectAllInvalidPlatformsMenuItem) + self.Bind(wx.EVT_MENU, self.OnClearAllInvalidPlatformsClick, ClearAllInvalidPlatformsMenuItem) + self.Bind(wx.EVT_MENU, self.OnSelectAllInvalidPackagesClick, SelectAllInvalidPackagesMenuItem) + self.Bind(wx.EVT_MENU, self.OnClearAllInvalidPackagesClick, ClearAllInvalidPackagesMenuItem) + + ViewMenu = wx.Menu() + RefreshMenuItem = ViewMenu.Append (-1, "&Refresh\tF5", "Rescan FrameworkDatabase.db") + ShowToolBarMenuItem = ViewMenu.AppendCheckItem (-1, "Show &Toolbar", "Shows or hides the toolbar") + ShowToolBarMenuItem.Check(True) + MenuBar.Append(ViewMenu, "&View") + self.Bind(wx.EVT_MENU, self.OnViewRefreshClick, RefreshMenuItem) + self.Bind(wx.EVT_MENU, self.OnShowToolBarClick, ShowToolBarMenuItem) + + HelpMenu = wx.Menu() + AboutMenuItem = HelpMenu.Append (-1, "&About...", "About") + MenuBar.Append(HelpMenu, "&Help") + self.Bind(wx.EVT_MENU, self.OnAboutClick, AboutMenuItem) + + self.SetMenuBar (MenuBar) + + # + # Build Toolbar + # + self.ShowToolBar = False + self.OnShowToolBarClick(self) + + # + # Target, ToolChain, and Arch Check List Boxes + # + PackagesLabel = wx.StaticText(panel, -1, 'Packages') + PackagesLabel.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD)) + PackagesLabel.SetHelpText(PackagesHelpText) + + PlatformsLabel = wx.StaticText(panel, -1, 'Platforms') + PlatformsLabel.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD)) + PlatformsLabel.SetHelpText(PlatformsHelpText) + + # + # Buttons + # + self.SelectAllPackagesButton = wx.Button(panel, -1, 'Select All') + self.ClearAllPackagesButton = wx.Button(panel, -1, 'Clear All') + self.SelectAllPackagesButton.Bind (wx.EVT_BUTTON, self.OnSelectAllPackagesClick) + self.ClearAllPackagesButton.Bind (wx.EVT_BUTTON, self.OnClearAllPackagesClick) + + self.PackagesCheckListBox = wx.CheckListBox(panel, -1) + self.PackagesCheckListBox.Bind(wx.EVT_CHECKLISTBOX, self.OnPackagesCheckListClick) + self.PackagesCheckListBox.Bind(wx.EVT_SET_FOCUS, self.OnPackagesSetFocus) + self.PackagesCheckListBox.Bind(wx.EVT_KILL_FOCUS, self.OnPackagesKillFocus) + self.PackagesCheckListBox.SetHelpText(PackagesHelpText) + + + self.SelectAllPlatformsButton = wx.Button(panel, -1, 'Select All') + self.ClearAllPlatformsButton = wx.Button(panel, -1, 'Clear All') + self.SelectAllPlatformsButton.Bind(wx.EVT_BUTTON, self.OnSelectAllPlatformsClick) + self.ClearAllPlatformsButton.Bind (wx.EVT_BUTTON, self.OnClearAllPlatformsClick) + + self.PlatformsCheckListBox = wx.CheckListBox(panel, -1) + self.PlatformsCheckListBox.Bind(wx.EVT_CHECKLISTBOX, self.OnPlatformsCheckListClick) + self.PlatformsCheckListBox.Bind(wx.EVT_SET_FOCUS, self.OnPlatformsSetFocus) + self.PlatformsCheckListBox.Bind(wx.EVT_KILL_FOCUS, self.OnPlatformsKillFocus) + self.PlatformsCheckListBox.SetHelpText(PlatformsHelpText) + + InvalidPackagesLabel = wx.StaticText(panel, -1, 'Invalid Packages') + InvalidPackagesLabel.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD)) + InvalidPackagesLabel.SetHelpText(InvalidPackagesHelpText) + + InvalidPlatformsLabel = wx.StaticText(panel, -1, 'Invalid Platforms') + InvalidPlatformsLabel.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD)) + InvalidPlatformsLabel.SetHelpText(InvalidPlatformsHelpText) + + self.SelectAllInvalidPackagesButton = wx.Button(panel, -1, 'Select All') + self.ClearAllInvalidPackagesButton = wx.Button(panel, -1, 'Clear All') + self.SelectAllInvalidPackagesButton.Bind (wx.EVT_BUTTON, self.OnSelectAllInvalidPackagesClick) + self.ClearAllInvalidPackagesButton.Bind (wx.EVT_BUTTON, self.OnClearAllInvalidPackagesClick) + + self.InvalidPackagesCheckListBox = wx.CheckListBox(panel, -1) + self.InvalidPackagesCheckListBox.Bind(wx.EVT_CHECKLISTBOX, self.OnInvalidPackagesCheckListClick) + self.InvalidPackagesCheckListBox.Bind(wx.EVT_SET_FOCUS, self.OnInvalidPackagesSetFocus) + self.InvalidPackagesCheckListBox.Bind(wx.EVT_KILL_FOCUS, self.OnInvalidPackagesKillFocus) + self.InvalidPackagesCheckListBox.SetHelpText(PackagesHelpText) + + self.SelectAllInvalidPlatformsButton = wx.Button(panel, -1, 'Select All') + self.ClearAllInvalidPlatformsButton = wx.Button(panel, -1, 'Clear All') + self.SelectAllInvalidPlatformsButton.Bind(wx.EVT_BUTTON, self.OnSelectAllInvalidPlatformsClick) + self.ClearAllInvalidPlatformsButton.Bind (wx.EVT_BUTTON, self.OnClearAllInvalidPlatformsClick) + + self.InvalidPlatformsCheckListBox = wx.CheckListBox(panel, -1) + self.InvalidPlatformsCheckListBox.Bind(wx.EVT_CHECKLISTBOX, self.OnInvalidPlatformsCheckListClick) + self.InvalidPlatformsCheckListBox.Bind(wx.EVT_SET_FOCUS, self.OnInvalidPlatformsSetFocus) + self.InvalidPlatformsCheckListBox.Bind(wx.EVT_KILL_FOCUS, self.OnInvalidPlatformsKillFocus) + self.InvalidPlatformsCheckListBox.SetHelpText(PlatformsHelpText) + + # + # Define layout using sizers + # + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + + listSizer = wx.GridBagSizer(hgap=5, vgap=5) + listSizer.Add(PackagesLabel, pos=(0,0), span=(1,2), flag=wx.ALIGN_CENTER) + listSizer.Add(PlatformsLabel, pos=(0,2), span=(1,2), flag=wx.ALIGN_CENTER) + listSizer.Add(self.SelectAllPackagesButton, pos=(1,0), flag=wx.ALIGN_CENTER) + listSizer.Add(self.ClearAllPackagesButton, pos=(1,1), flag=wx.ALIGN_CENTER) + listSizer.Add(self.SelectAllPlatformsButton, pos=(1,2), flag=wx.ALIGN_CENTER) + listSizer.Add(self.ClearAllPlatformsButton, pos=(1,3), flag=wx.ALIGN_CENTER) + listSizer.Add(self.PackagesCheckListBox, pos=(2,0), span=(1,2), flag=wx.ALL | wx.EXPAND) + listSizer.Add(self.PlatformsCheckListBox, pos=(2,2), span=(1,2), flag=wx.ALL | wx.EXPAND) + + listSizer.Add(InvalidPackagesLabel, pos=(3,0), span=(1,2), flag=wx.ALIGN_CENTER) + listSizer.Add(InvalidPlatformsLabel, pos=(3,2), span=(1,2), flag=wx.ALIGN_CENTER) + listSizer.Add(self.SelectAllInvalidPackagesButton, pos=(4,0), flag=wx.ALIGN_CENTER) + listSizer.Add(self.ClearAllInvalidPackagesButton, pos=(4,1), flag=wx.ALIGN_CENTER) + listSizer.Add(self.SelectAllInvalidPlatformsButton, pos=(4,2), flag=wx.ALIGN_CENTER) + listSizer.Add(self.ClearAllInvalidPlatformsButton, pos=(4,3), flag=wx.ALIGN_CENTER) + listSizer.Add(self.InvalidPackagesCheckListBox, pos=(5,0), span=(1,2), flag=wx.ALL | wx.EXPAND) + listSizer.Add(self.InvalidPlatformsCheckListBox, pos=(5,2), span=(1,2), flag=wx.ALL | wx.EXPAND) + + listSizer.AddGrowableRow(2) + listSizer.AddGrowableRow(5) + listSizer.AddGrowableCol(0) + listSizer.AddGrowableCol(1) + listSizer.AddGrowableCol(2) + listSizer.AddGrowableCol(3) + + self.mainSizer.Add (listSizer, wx.EXPAND | wx.ALL, wx.EXPAND | wx.ALL, 10) + + panel.SetSizer (self.mainSizer) + + self.OnViewRefreshClick(self) + + def CheckListFocus(self, CheckListBox, Set): + Index = 0 + while Index < CheckListBox.GetCount(): + CheckListBox.SetSelection(Index, False) + Index += 1 + if Set and CheckListBox.GetCount() > 0: + CheckListBox.SetSelection(0, True) + + def CheckListClick(self, CheckListBox, Database): + Index = 0 + Database['EnabledSettings'] = {} + while Index < CheckListBox.GetCount(): + if CheckListBox.IsChecked(Index): + for Item in Database['PossibleSettings']: + if Database['PossibleSettings'][Item] == CheckListBox.GetString(Index): + Database['EnabledSettings'][Item] = Database['PossibleSettings'][Item] + Index += 1 + + def OnPackagesCheckListClick(self, event): + self.CheckListClick(self.PackagesCheckListBox, self.Model.Database['Package']['Valid']) + + def OnPackagesSetFocus(self, event): + self.CheckListFocus(self.PackagesCheckListBox, True) + + def OnPackagesKillFocus(self, event): + self.CheckListFocus(self.PackagesCheckListBox, False) + + def OnPlatformsCheckListClick(self, event): + self.CheckListClick(self.PlatformsCheckListBox, self.Model.Database['Platform']['Valid']) + + def OnPlatformsSetFocus(self, event): + self.CheckListFocus(self.PlatformsCheckListBox, True) + + def OnPlatformsKillFocus(self, event): + self.CheckListFocus(self.PlatformsCheckListBox, False) + + def OnInvalidPackagesCheckListClick(self, event): + self.CheckListClick(self.InvalidPackagesCheckListBox, self.Model.Database['Package']['Invalid']) + + def OnInvalidPackagesSetFocus(self, event): + self.CheckListFocus(self.InvalidPackagesCheckListBox, True) + + def OnInvalidPackagesKillFocus(self, event): + self.CheckListFocus(self.InvalidPackagesCheckListBox, False) + + def OnInvalidPlatformsCheckListClick(self, event): + self.CheckListClick(self.InvalidPlatformsCheckListBox, self.Model.Database['Platform']['Invalid']) + + def OnInvalidPlatformsSetFocus(self, event): + self.CheckListFocus(self.InvalidPlatformsCheckListBox, True) + + def OnInvalidPlatformsKillFocus(self, event): + self.CheckListFocus(self.InvalidPlatformsCheckListBox, False) + + def OnRevertClick(self, event): + self.Model.RevertModel() + self.StatusBar.SetFocus() + self.OnRefreshClick(self) + + def RefreshCheckListBox(self, CheckListBox, SelectAllButton, ClearAllButton, Database): + NameList = [] + for Item in Database['PossibleSettings']: + NameList.append(Database['PossibleSettings'][Item]) + NameList.sort() + CheckListBox.Set(NameList) + Index = 0 + MaximumString = '.' + while Index < CheckListBox.GetCount(): + String = CheckListBox.GetString(Index) + if len(String) > len(MaximumString): + MaximumString = String + Enabled = False + for Item in Database['EnabledSettings']: + if String == Database['EnabledSettings'][Item]: + Enabled = True + if Enabled: + CheckListBox.Check(Index, True) + else: + CheckListBox.Check(Index, False) + Index += 1 + Extents = CheckListBox.GetFullTextExtent (MaximumString) + CheckListBox.SetMinSize((Extents[0] + 30,(CheckListBox.GetCount()+2) * (Extents[1]+Extents[2]))) + if NameList == []: + CheckListBox.Disable() + SelectAllButton.Disable() + ClearAllButton.Disable() + else: + CheckListBox.Enable() + SelectAllButton.Enable() + ClearAllButton.Enable() + + def OnRefreshClick(self, event): + self.Model.RefreshModel() + self.RefreshCheckListBox (self.PackagesCheckListBox, self.SelectAllPackagesButton, self.ClearAllPackagesButton, self.Model.Database['Package']['Valid']) + self.RefreshCheckListBox (self.PlatformsCheckListBox, self.SelectAllPlatformsButton, self.ClearAllPlatformsButton, self.Model.Database['Platform']['Valid']) + self.RefreshCheckListBox (self.InvalidPackagesCheckListBox, self.SelectAllInvalidPackagesButton, self.ClearAllInvalidPackagesButton, self.Model.Database['Package']['Invalid']) + self.RefreshCheckListBox (self.InvalidPlatformsCheckListBox, self.SelectAllInvalidPlatformsButton, self.ClearAllInvalidPlatformsButton, self.Model.Database['Platform']['Invalid']) + self.mainSizer.SetSizeHints(self) + self.mainSizer.Fit(self) + self.Update() + + def OnViewRefreshClick(self, event): + self.Model.RescanModel() + self.StatusBar.SetFocus() + self.OnRefreshClick(self) + + def AddTool (self, Handler, ArtId, Label, HelpText): + Tool = self.ToolBar.AddSimpleTool( + -1, + wx.ArtProvider.GetBitmap(ArtId, wx.ART_TOOLBAR, self.ToolSize), + Label, + HelpText + ) + self.Bind(wx.EVT_MENU, Handler, Tool) + + def OnShowToolBarClick(self, event): + if self.ShowToolBar: + self.ShowToolBar = False + self.ToolBar.Destroy() + else: + self.ShowToolBar = True + self.ToolBar = self.CreateToolBar() + self.ToolSize = (24,24) + self.ToolBar.SetToolBitmapSize(self.ToolSize) + self.AddTool (self.OnNewClick, wx.ART_NEW, "New", "New FrameworkDatabase.db") + self.AddTool (self.OnScanAndSyncClick, wx.ART_HARDDISK, "Scan WORKSPACE and Sync", "Scan WORKSPACE for new Packages and Platforms and sync FrameworkDatabase.db") + self.AddTool (self.OnSaveClick, wx.ART_FILE_SAVE, "Save", "Save FrameworkDatabase.db") + self.AddTool (self.OnSaveAsClick, wx.ART_FILE_SAVE_AS, "Save As...", "Save FrameworkDatabase.db as...") + self.AddTool (self.OnRevertClick, wx.ART_UNDO, "Revert", "Revert to original FrameworkDatabase.db") + self.AddTool (self.OnHelpClick, wx.ART_HELP, "Help", "Context Sensitive Help") + self.AddTool (self.OnExitClick, wx.ART_QUIT, "Exit", "Exit EDK II Build System Framework Database Utility") + self.ToolBar.Realize() + + def OnNewClick(self, event): + self.Model.NewModel() + self.OnRefreshClick(self) + + def ScanDirectory(self, Data, DirName, FilesInDir): + WorkspaceDirName = self.Model.WorkspaceRelativePath(DirName) + self.StatusBar.SetStatusText('Scanning: ' + WorkspaceDirName) + RemoveList = [] + for File in FilesInDir: + if File[0] == '.': + RemoveList.insert(0, File) + for File in RemoveList: + FilesInDir.remove(File) + for File in FilesInDir: + if os.path.splitext(File)[1].lower() == '.spd': + self.Model.AddFile (WorkspaceDirName, File, 'Package', False) + self.OnRefreshClick(self) + if os.path.splitext(File)[1].lower() == '.fpd': + self.Model.AddFile (WorkspaceDirName, File, 'Platform', False) + self.OnRefreshClick(self) + + def OnScanClick(self, event): + os.path.walk(self.Model.WorkspaceFile(''), self.ScanDirectory, None) + self.StatusBar.SetStatusText('Scanning: Complete') + self.StatusBar.SetFocus() + self.OnRefreshClick(self) + + def OnScanAndSyncClick(self, event): + self.OnSelectAllPackagesClick(self) + self.OnSelectAllPlatformsClick(self) + self.OnClearAllInvalidPackagesClick(self) + self.OnClearAllInvalidPlatformsClick(self) + self.OnScanClick(self) + self.OnSelectAllPackagesClick(self) + self.OnSelectAllPlatformsClick(self) + self.OnClearAllInvalidPackagesClick(self) + self.OnClearAllInvalidPlatformsClick(self) + + def OnSelectAllPackagesClick(self, event): + self.Model.Database['Package']['Valid']['EnabledSettings'] = self.Model.Database['Package']['Valid']['PossibleSettings'] + self.OnRefreshClick(self) + + def OnClearAllPackagesClick(self, event): + self.Model.Database['Package']['Valid']['EnabledSettings'] = {} + self.OnRefreshClick(self) + + def OnSelectAllPlatformsClick(self, event): + self.Model.Database['Platform']['Valid']['EnabledSettings'] = self.Model.Database['Platform']['Valid']['PossibleSettings'] + self.OnRefreshClick(self) + + def OnClearAllPlatformsClick(self, event): + self.Model.Database['Platform']['Valid']['EnabledSettings'] = {} + self.OnRefreshClick(self) + + def OnSelectAllInvalidPackagesClick(self, event): + self.Model.Database['Package']['Invalid']['EnabledSettings'] = self.Model.Database['Package']['Invalid']['PossibleSettings'] + self.OnRefreshClick(self) + + def OnClearAllInvalidPackagesClick(self, event): + self.Model.Database['Package']['Invalid']['EnabledSettings'] = {} + self.OnRefreshClick(self) + + def OnSelectAllInvalidPlatformsClick(self, event): + self.Model.Database['Platform']['Invalid']['EnabledSettings'] = self.Model.Database['Platform']['Invalid']['PossibleSettings'] + self.OnRefreshClick(self) + + def OnClearAllInvalidPlatformsClick(self, event): + self.Model.Database['Platform']['Invalid']['EnabledSettings'] = {} + self.OnRefreshClick(self) + + def OnSaveClick(self, event): + self.Model.SaveModel() + + def OnSaveAsClick(self, event): + wildcard = "Text Documents (*.db)|*.db|" \ + "All files (*.*)|*.*" + dialog = wx.FileDialog (None, 'Save As', self.Model.WorkspaceFile('Tools/Conf'), '', wildcard, wx.SAVE | wx.OVERWRITE_PROMPT) + if dialog.ShowModal() == wx.ID_OK: + FrameworkDatabaseDbFile = self.Model.WorkspaceRelativePath(dialog.GetPath()) + if FrameworkDatabaseDbFile != '': + self.Model.SaveModel(FrameworkDatabaseDbFile) + dialog.Destroy() + + def OnExitClick(self, event): + if self.Model.ModelModified(): + dialog = wx.MessageDialog(None, 'The contents have changed.\nDo you want to save changes?', 'EDK II Build System Framework Databsase Utility', style = wx.YES_NO | wx.YES_DEFAULT | wx.CANCEL | wx.ICON_EXCLAMATION) + Status = dialog.ShowModal() + dialog.Destroy() + if Status == wx.ID_YES: + self.OnSaveClick (self) + elif Status == wx.ID_CANCEL: + return + self.Model.CloseModel() + self.Close() + + def OnHelpClick(self, event): + wx.ContextHelp().BeginContextHelp() + + def OnAboutClick(self, event): + AboutInfo = wx.AboutDialogInfo() + AboutInfo.Name = 'EDK II Build System Framework Database Utility' + AboutInfo.Version = '0.3' + AboutInfo.Copyright = 'Copyright (c) 2006, Intel Corporation' + AboutInfo.Description = """ + The EDK II Build System Framework Database Utility maintains FrameworkDatabase.db + settings in an EDK II Workspace.""" + AboutInfo.WebSite = ("http://tianocore.org", "Tiano Core home page") + AboutInfo.License = """ + All rights reserved. This program and the accompanying materials are + licensed and made available under the terms and conditions of the BSD + License which accompanies this distribution. The full text of the + license may be found at http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" + BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, + EITHER EXPRESS OR IMPLIED.""" + if self.Model.Icon != None: + AboutInfo.Icon = self.Model.Icon + wx.AboutBox(AboutInfo) + +if __name__ == '__main__': + app = wx.PySimpleApp() + frame = Frame() + frame.Show() + app.MainLoop() + \ No newline at end of file diff --git a/Tools/Python/XmlRoutines.py b/Tools/Python/XmlRoutines.py index 9d1ff4a0e3..2707bcbb97 100755 --- a/Tools/Python/XmlRoutines.py +++ b/Tools/Python/XmlRoutines.py @@ -27,13 +27,13 @@ def XmlList(Dom, String): def XmlElement (Dom, String): """Return a single element that matches the String which is XPath style syntax.""" try: - return XmlList (Dom, String)[0].firstChild.data.strip(' ') + return XmlList (Dom, String)[0].firstChild.data.strip() except: return '' def XmlElementData (Dom): """Get the text for this element.""" - return Dom.firstChild.data.strip(' ') + return Dom.firstChild.data.strip() def XmlAttribute (Dom, String): """Return a single attribute that named by String.""" @@ -44,7 +44,84 @@ def XmlAttribute (Dom, String): def XmlTopTag(Dom): """Return the name of the Root or top tag in the XML tree.""" - return Dom.documentElement.nodeName + return Dom.firstChild.nodeName + +def XmlParseFile (FileName): + """Parse an XML file into a DOM and return the DOM.""" + try: + f = open(FileName, 'r') + Dom = xml.dom.minidom.parse(f) + f.close() + return Dom + except: + return xml.dom.minidom.parseString('') + +def XmlParseFileSection (FileName, Tag): + """Parse a section of an XML file into a DOM(Document Object Model) and return the DOM.""" + try: + f = open(FileName, 'r') + except: + return xml.dom.minidom.parseString('') + Start = '<' + Tag + End = '' + File = '' + while File.find(Start) < 0 or File.find(End) < 0: + Section = f.read(0x1000) + if Section == '': + break + File += Section + f.close() + if File.find(Start) < 0 or File.find(End) < 0: + return xml.dom.minidom.parseString('') + File = File[File.find(Start):File.find(End)+len(End)] + try: + return xml.dom.minidom.parseString(File) + except: + return xml.dom.minidom.parseString('') + +def XmlSaveFile (Dom, FileName, Encoding='UTF-8'): + """Save a DOM(Document Object Model) into an XML file.""" + try: + f = open(FileName, 'w') + f.write(Dom.toxml(Encoding).replace('"','"').replace('>','>')) + f.close() + return True + except: + return False + +def XmlRemoveElement(Node): + """Remove an element node from DOM(Document Object Model) tree.""" + ParentNode = Node.parentNode + if ParentNode == None: + return False + PreviousSibling = Node.previousSibling + while PreviousSibling != None and PreviousSibling.nodeType == PreviousSibling.TEXT_NODE and PreviousSibling.data.strip() == '': + Temp = PreviousSibling + PreviousSibling = PreviousSibling.previousSibling + ParentNode.removeChild(Temp) + ParentNode.removeChild(Node) + return True + +def XmlAppendChildElement(ParentNode, TagName, ElementText='', AttributeDictionary = {}): + """Add a child element to a DOM(Document Object Model) tree with optional Attributes.""" + TagName = TagName.strip() + if TagName == '': + return False + Depth = 0 + Dom = ParentNode + while Dom != None and Dom.nodeType != Dom.DOCUMENT_NODE: + Dom = Dom.parentNode + Depth += 1 + if Dom == None: + return False + ParentNode.appendChild(Dom.createTextNode('\n%*s' % (Depth * 2, ''))) + ElementNode = Dom.createElement(TagName) + if ElementText != '': + ElementNode.appendChild(Dom.createTextNode(ElementText)) + for Item in AttributeDictionary: + ElementNode.setAttribute(Item, AttributeDictionary[Item]) + ParentNode.appendChild(ElementNode) + return True # This acts like the main() function for the script, unless it is 'import'ed into another -- 2.39.2