1## @file 2# This is the base class for applications that operate on an EDK II Workspace 3# 4# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> 5# This program and the accompanying materials 6# are licensed and made available under the terms and conditions of the BSD License 7# which accompanies this distribution. The full text of the license may be found at 8# http://opensource.org/licenses/bsd-license.php 9# 10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12# 13 14## 15# Import Modules 16# 17import Common.LongFilePathOs as os, sys, time 18from DataType import * 19from Common.LongFilePathSupport import OpenLongFilePath as open 20from Common.MultipleWorkspace import MultipleWorkspace as mws 21 22## EdkIIWorkspace 23# 24# Collect WorkspaceDir from the environment, the Verbose command line flag, and detect an icon bitmap file. 25# 26# @var StartTime: Time of build system starting 27# @var PrintRunTime: Printable time of build system running 28# @var PrintRunStatus: Printable status of build system running 29# @var RunStatus: Status of build system running 30# 31class EdkIIWorkspace: 32 def __init__(self): 33 self.StartTime = time.time() 34 self.PrintRunTime = False 35 self.PrintRunStatus = False 36 self.RunStatus = '' 37 38 # 39 # Check environment valiable 'WORKSPACE' 40 # 41 if os.environ.get('WORKSPACE') == None: 42 print 'ERROR: WORKSPACE not defined. Please run EdkSetup from the EDK II install directory.' 43 return False 44 45 self.CurrentWorkingDir = os.getcwd() 46 47 self.WorkspaceDir = os.path.realpath(os.environ.get('WORKSPACE')) 48 (Drive, Path) = os.path.splitdrive(self.WorkspaceDir) 49 if Drive == '': 50 (Drive, CwdPath) = os.path.splitdrive(self.CurrentWorkingDir) 51 if Drive != '': 52 self.WorkspaceDir = Drive + Path 53 else: 54 self.WorkspaceDir = Drive.upper() + Path 55 56 self.WorkspaceRelativeWorkingDir = self.WorkspaceRelativePath (self.CurrentWorkingDir) 57 58 try: 59 # 60 # Load TianoCoreOrgLogo, used for GUI tool 61 # 62 self.Icon = wx.Icon(self.WorkspaceFile('tools/Python/TianoCoreOrgLogo.gif'), wx.BITMAP_TYPE_GIF) 63 except: 64 self.Icon = None 65 66 self.Verbose = False 67 for Arg in sys.argv: 68 if Arg.lower() == '-v': 69 self.Verbose = True 70 71 ## Close build system 72 # 73 # Close build system and print running time and status 74 # 75 def Close(self): 76 if self.PrintRunTime: 77 Seconds = int(time.time() - self.StartTime) 78 if Seconds < 60: 79 print 'Run Time: %d seconds' % (Seconds) 80 else: 81 Minutes = Seconds / 60 82 Seconds = Seconds % 60 83 if Minutes < 60: 84 print 'Run Time: %d minutes %d seconds' % (Minutes, Seconds) 85 else: 86 Hours = Minutes / 60 87 Minutes = Minutes % 60 88 print 'Run Time: %d hours %d minutes %d seconds' % (Hours, Minutes, Seconds) 89 if self.RunStatus != '': 90 print self.RunStatus 91 92 ## Convert to a workspace relative filename 93 # 94 # Convert a full path filename to a workspace relative filename. 95 # 96 # @param FileName: The filename to be Converted 97 # 98 # @retval None Workspace dir is not found in the full path 99 # @retval string The relative filename 100 # 101 def WorkspaceRelativePath(self, FileName): 102 FileName = os.path.realpath(FileName) 103 if FileName.find(self.WorkspaceDir) != 0: 104 return None 105 return FileName.replace (self.WorkspaceDir, '').strip('\\').strip('/') 106 107 ## Convert to a full path filename 108 # 109 # Convert a workspace relative filename to a full path filename. 110 # 111 # @param FileName: The filename to be Converted 112 # 113 # @retval string The full path filename 114 # 115 def WorkspaceFile(self, FileName): 116 return os.path.realpath(mws.join(self.WorkspaceDir,FileName)) 117 118 ## Convert to a real path filename 119 # 120 # Convert ${WORKSPACE} to real path 121 # 122 # @param FileName: The filename to be Converted 123 # 124 # @retval string The full path filename 125 # 126 def WorkspacePathConvert(self, FileName): 127 return os.path.realpath(FileName.replace(TAB_WORKSPACE, self.WorkspaceDir)) 128 129 ## Convert XML into a DOM 130 # 131 # Parse an XML file into a DOM and return the DOM. 132 # 133 # @param FileName: The filename to be parsed 134 # 135 # @retval XmlParseFile (self.WorkspaceFile(FileName)) 136 # 137 def XmlParseFile (self, FileName): 138 if self.Verbose: 139 print FileName 140 return XmlParseFile (self.WorkspaceFile(FileName)) 141 142 ## Convert a XML section 143 # 144 # Parse a section of an XML file into a DOM(Document Object Model) and return the DOM. 145 # 146 # @param FileName: The filename to be parsed 147 # @param SectionTag: The tag name of the section to be parsed 148 # 149 # @retval XmlParseFileSection (self.WorkspaceFile(FileName), SectionTag) 150 # 151 def XmlParseFileSection (self, FileName, SectionTag): 152 if self.Verbose: 153 print FileName 154 return XmlParseFileSection (self.WorkspaceFile(FileName), SectionTag) 155 156 ## Save a XML file 157 # 158 # Save a DOM(Document Object Model) into an XML file. 159 # 160 # @param Dom: The Dom to be saved 161 # @param FileName: The filename 162 # 163 # @retval XmlSaveFile (Dom, self.WorkspaceFile(FileName)) 164 # 165 def XmlSaveFile (self, Dom, FileName): 166 if self.Verbose: 167 print FileName 168 return XmlSaveFile (Dom, self.WorkspaceFile(FileName)) 169 170 ## Convert Text File To Dictionary 171 # 172 # Convert a workspace relative text file to a dictionary of (name:value) pairs. 173 # 174 # @param FileName: Text filename 175 # @param Dictionary: Dictionary to store data 176 # @param CommentCharacter: Comment char, be used to ignore comment content 177 # @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char 178 # @param ValueSplitFlag: Value split flag, be used to decide if has multiple values 179 # @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char 180 # 181 # @retval ConvertTextFileToDictionary(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter) 182 # 183 def ConvertTextFileToDictionary(self, FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): 184 if self.Verbose: 185 print FileName 186 return ConvertTextFileToDictionary(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter) 187 188 ## Convert Dictionary To Text File 189 # 190 # Convert a dictionary of (name:value) pairs to a workspace relative text file. 191 # 192 # @param FileName: Text filename 193 # @param Dictionary: Dictionary to store data 194 # @param CommentCharacter: Comment char, be used to ignore comment content 195 # @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char 196 # @param ValueSplitFlag: Value split flag, be used to decide if has multiple values 197 # @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char 198 # 199 # @retval ConvertDictionaryToTextFile(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter) 200 # 201 def ConvertDictionaryToTextFile(self, FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): 202 if self.Verbose: 203 print FileName 204 return ConvertDictionaryToTextFile(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter) 205 206## Convert Text File To Dictionary 207# 208# Convert a text file to a dictionary of (name:value) pairs. 209# 210# @param FileName: Text filename 211# @param Dictionary: Dictionary to store data 212# @param CommentCharacter: Comment char, be used to ignore comment content 213# @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char 214# @param ValueSplitFlag: Value split flag, be used to decide if has multiple values 215# @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char 216# 217# @retval True Convert successfully 218# @retval False Open file failed 219# 220def ConvertTextFileToDictionary(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): 221 try: 222 F = open(FileName, 'r') 223 except: 224 return False 225 Keys = [] 226 for Line in F: 227 LineList = Line.split(KeySplitCharacter, 1) 228 if len(LineList) >= 2: 229 Key = LineList[0].split() 230 if len(Key) == 1 and Key[0][0] != CommentCharacter and Key[0] not in Keys: 231 if ValueSplitFlag: 232 Dictionary[Key[0]] = LineList[1].replace('\\', '/').split(ValueSplitCharacter) 233 else: 234 Dictionary[Key[0]] = LineList[1].strip().replace('\\', '/') 235 Keys += [Key[0]] 236 F.close() 237 return True 238 239## Convert Dictionary To Text File 240# 241# Convert a dictionary of (name:value) pairs to a text file. 242# 243# @param FileName: Text filename 244# @param Dictionary: Dictionary to store data 245# @param CommentCharacter: Comment char, be used to ignore comment content 246# @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char 247# @param ValueSplitFlag: Value split flag, be used to decide if has multiple values 248# @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char 249# 250# @retval True Convert successfully 251# @retval False Open file failed 252# 253def ConvertDictionaryToTextFile(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): 254 try: 255 F = open(FileName, 'r') 256 Lines = [] 257 Lines = F.readlines() 258 F.close() 259 except: 260 Lines = [] 261 Keys = Dictionary.keys() 262 MaxLength = 0 263 for Key in Keys: 264 if len(Key) > MaxLength: 265 MaxLength = len(Key) 266 Index = 0 267 for Line in Lines: 268 LineList = Line.split(KeySplitCharacter, 1) 269 if len(LineList) >= 2: 270 Key = LineList[0].split() 271 if len(Key) == 1 and Key[0][0] != CommentCharacter and Key[0] in Dictionary: 272 if ValueSplitFlag: 273 Line = '%-*s %c %s\n' % (MaxLength, Key[0], KeySplitCharacter, ' '.join(Dictionary[Key[0]])) 274 else: 275 Line = '%-*s %c %s\n' % (MaxLength, Key[0], KeySplitCharacter, Dictionary[Key[0]]) 276 Lines.pop(Index) 277 if Key[0] in Keys: 278 Lines.insert(Index, Line) 279 Keys.remove(Key[0]) 280 Index += 1 281 for RemainingKey in Keys: 282 if ValueSplitFlag: 283 Line = '%-*s %c %s\n' % (MaxLength, RemainingKey, KeySplitCharacter, ' '.join(Dictionary[RemainingKey])) 284 else: 285 Line = '%-*s %c %s\n' % (MaxLength, RemainingKey, KeySplitCharacter, Dictionary[RemainingKey]) 286 Lines.append(Line) 287 try: 288 F = open(FileName, 'w') 289 except: 290 return False 291 F.writelines(Lines) 292 F.close() 293 return True 294 295## Create a new directory 296# 297# @param Directory: Directory to be created 298# 299def CreateDirectory(Directory): 300 if not os.access(Directory, os.F_OK): 301 os.makedirs (Directory) 302 303## Create a new file 304# 305# @param Directory: Directory to be created 306# @param FileName: Filename to be created 307# @param Mode: The mode of open file, defautl is 'w' 308# 309def CreateFile(Directory, FileName, Mode='w'): 310 CreateDirectory (Directory) 311 return open(os.path.join(Directory, FileName), Mode) 312 313## 314# 315# This acts like the main() function for the script, unless it is 'import'ed into another 316# script. 317# 318if __name__ == '__main__': 319 # Nothing to do here. Could do some unit tests 320 pass