| ## @file | |
| # This is the base class for applications that operate on an EDK II Workspace | |
| # | |
| # Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> | |
| # 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. | |
| # | |
| ## | |
| # Import Modules | |
| # | |
| import Common.LongFilePathOs as os, sys, time | |
| from DataType import * | |
| from Common.LongFilePathSupport import OpenLongFilePath as open | |
| from Common.MultipleWorkspace import MultipleWorkspace as mws | |
| ## EdkIIWorkspace | |
| # | |
| # Collect WorkspaceDir from the environment, the Verbose command line flag, and detect an icon bitmap file. | |
| # | |
| # @var StartTime: Time of build system starting | |
| # @var PrintRunTime: Printable time of build system running | |
| # @var PrintRunStatus: Printable status of build system running | |
| # @var RunStatus: Status of build system running | |
| # | |
| class EdkIIWorkspace: | |
| def __init__(self): | |
| self.StartTime = time.time() | |
| self.PrintRunTime = False | |
| self.PrintRunStatus = False | |
| self.RunStatus = '' | |
| # | |
| # Check environment valiable 'WORKSPACE' | |
| # | |
| if os.environ.get('WORKSPACE') == None: | |
| print 'ERROR: WORKSPACE not defined. Please run EdkSetup from the EDK II install directory.' | |
| return False | |
| self.CurrentWorkingDir = os.getcwd() | |
| self.WorkspaceDir = os.path.realpath(os.environ.get('WORKSPACE')) | |
| (Drive, Path) = os.path.splitdrive(self.WorkspaceDir) | |
| if Drive == '': | |
| (Drive, CwdPath) = os.path.splitdrive(self.CurrentWorkingDir) | |
| if Drive != '': | |
| self.WorkspaceDir = Drive + Path | |
| else: | |
| self.WorkspaceDir = Drive.upper() + Path | |
| self.WorkspaceRelativeWorkingDir = self.WorkspaceRelativePath (self.CurrentWorkingDir) | |
| try: | |
| # | |
| # Load TianoCoreOrgLogo, used for GUI tool | |
| # | |
| 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 | |
| ## Close build system | |
| # | |
| # Close build system and print running time and status | |
| # | |
| def Close(self): | |
| if self.PrintRunTime: | |
| Seconds = int(time.time() - self.StartTime) | |
| if Seconds < 60: | |
| print 'Run Time: %d seconds' % (Seconds) | |
| else: | |
| Minutes = Seconds / 60 | |
| Seconds = Seconds % 60 | |
| if Minutes < 60: | |
| print 'Run Time: %d minutes %d seconds' % (Minutes, Seconds) | |
| else: | |
| Hours = Minutes / 60 | |
| Minutes = Minutes % 60 | |
| print 'Run Time: %d hours %d minutes %d seconds' % (Hours, Minutes, Seconds) | |
| if self.RunStatus != '': | |
| print self.RunStatus | |
| ## Convert to a workspace relative filename | |
| # | |
| # Convert a full path filename to a workspace relative filename. | |
| # | |
| # @param FileName: The filename to be Converted | |
| # | |
| # @retval None Workspace dir is not found in the full path | |
| # @retval string The relative filename | |
| # | |
| def WorkspaceRelativePath(self, FileName): | |
| FileName = os.path.realpath(FileName) | |
| if FileName.find(self.WorkspaceDir) != 0: | |
| return None | |
| return FileName.replace (self.WorkspaceDir, '').strip('\\').strip('/') | |
| ## Convert to a full path filename | |
| # | |
| # Convert a workspace relative filename to a full path filename. | |
| # | |
| # @param FileName: The filename to be Converted | |
| # | |
| # @retval string The full path filename | |
| # | |
| def WorkspaceFile(self, FileName): | |
| return os.path.realpath(mws.join(self.WorkspaceDir,FileName)) | |
| ## Convert to a real path filename | |
| # | |
| # Convert ${WORKSPACE} to real path | |
| # | |
| # @param FileName: The filename to be Converted | |
| # | |
| # @retval string The full path filename | |
| # | |
| def WorkspacePathConvert(self, FileName): | |
| return os.path.realpath(FileName.replace(TAB_WORKSPACE, self.WorkspaceDir)) | |
| ## Convert XML into a DOM | |
| # | |
| # Parse an XML file into a DOM and return the DOM. | |
| # | |
| # @param FileName: The filename to be parsed | |
| # | |
| # @retval XmlParseFile (self.WorkspaceFile(FileName)) | |
| # | |
| def XmlParseFile (self, FileName): | |
| if self.Verbose: | |
| print FileName | |
| return XmlParseFile (self.WorkspaceFile(FileName)) | |
| ## Convert a XML section | |
| # | |
| # Parse a section of an XML file into a DOM(Document Object Model) and return the DOM. | |
| # | |
| # @param FileName: The filename to be parsed | |
| # @param SectionTag: The tag name of the section to be parsed | |
| # | |
| # @retval XmlParseFileSection (self.WorkspaceFile(FileName), SectionTag) | |
| # | |
| def XmlParseFileSection (self, FileName, SectionTag): | |
| if self.Verbose: | |
| print FileName | |
| return XmlParseFileSection (self.WorkspaceFile(FileName), SectionTag) | |
| ## Save a XML file | |
| # | |
| # Save a DOM(Document Object Model) into an XML file. | |
| # | |
| # @param Dom: The Dom to be saved | |
| # @param FileName: The filename | |
| # | |
| # @retval XmlSaveFile (Dom, self.WorkspaceFile(FileName)) | |
| # | |
| def XmlSaveFile (self, Dom, FileName): | |
| if self.Verbose: | |
| print FileName | |
| return XmlSaveFile (Dom, self.WorkspaceFile(FileName)) | |
| ## Convert Text File To Dictionary | |
| # | |
| # Convert a workspace relative text file to a dictionary of (name:value) pairs. | |
| # | |
| # @param FileName: Text filename | |
| # @param Dictionary: Dictionary to store data | |
| # @param CommentCharacter: Comment char, be used to ignore comment content | |
| # @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char | |
| # @param ValueSplitFlag: Value split flag, be used to decide if has multiple values | |
| # @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char | |
| # | |
| # @retval ConvertTextFileToDictionary(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter) | |
| # | |
| def ConvertTextFileToDictionary(self, FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): | |
| if self.Verbose: | |
| print FileName | |
| return ConvertTextFileToDictionary(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter) | |
| ## Convert Dictionary To Text File | |
| # | |
| # Convert a dictionary of (name:value) pairs to a workspace relative text file. | |
| # | |
| # @param FileName: Text filename | |
| # @param Dictionary: Dictionary to store data | |
| # @param CommentCharacter: Comment char, be used to ignore comment content | |
| # @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char | |
| # @param ValueSplitFlag: Value split flag, be used to decide if has multiple values | |
| # @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char | |
| # | |
| # @retval ConvertDictionaryToTextFile(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter) | |
| # | |
| def ConvertDictionaryToTextFile(self, FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): | |
| if self.Verbose: | |
| print FileName | |
| return ConvertDictionaryToTextFile(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter) | |
| ## Convert Text File To Dictionary | |
| # | |
| # Convert a text file to a dictionary of (name:value) pairs. | |
| # | |
| # @param FileName: Text filename | |
| # @param Dictionary: Dictionary to store data | |
| # @param CommentCharacter: Comment char, be used to ignore comment content | |
| # @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char | |
| # @param ValueSplitFlag: Value split flag, be used to decide if has multiple values | |
| # @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char | |
| # | |
| # @retval True Convert successfully | |
| # @retval False Open file failed | |
| # | |
| def ConvertTextFileToDictionary(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): | |
| 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 | |
| ## Convert Dictionary To Text File | |
| # | |
| # Convert a dictionary of (name:value) pairs to a text file. | |
| # | |
| # @param FileName: Text filename | |
| # @param Dictionary: Dictionary to store data | |
| # @param CommentCharacter: Comment char, be used to ignore comment content | |
| # @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char | |
| # @param ValueSplitFlag: Value split flag, be used to decide if has multiple values | |
| # @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char | |
| # | |
| # @retval True Convert successfully | |
| # @retval False Open file failed | |
| # | |
| def ConvertDictionaryToTextFile(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): | |
| 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 | |
| ## Create a new directory | |
| # | |
| # @param Directory: Directory to be created | |
| # | |
| def CreateDirectory(Directory): | |
| if not os.access(Directory, os.F_OK): | |
| os.makedirs (Directory) | |
| ## Create a new file | |
| # | |
| # @param Directory: Directory to be created | |
| # @param FileName: Filename to be created | |
| # @param Mode: The mode of open file, defautl is 'w' | |
| # | |
| def CreateFile(Directory, FileName, Mode='w'): | |
| CreateDirectory (Directory) | |
| return open(os.path.join(Directory, FileName), Mode) | |
| ## | |
| # | |
| # 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 |