## @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 |