2 # This is the base class for applications that operate on an EDK II Workspace
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
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.
17 import Common
.LongFilePathOs
as os
, sys
, time
18 from DataType
import *
19 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
23 # Collect WorkspaceDir from the environment, the Verbose command line flag, and detect an icon bitmap file.
25 # @var StartTime: Time of build system starting
26 # @var PrintRunTime: Printable time of build system running
27 # @var PrintRunStatus: Printable status of build system running
28 # @var RunStatus: Status of build system running
32 self
.StartTime
= time
.time()
33 self
.PrintRunTime
= False
34 self
.PrintRunStatus
= False
38 # Check environment valiable 'WORKSPACE'
40 if os
.environ
.get('WORKSPACE') == None:
41 print 'ERROR: WORKSPACE not defined. Please run EdkSetup from the EDK II install directory.'
44 self
.CurrentWorkingDir
= os
.getcwd()
46 self
.WorkspaceDir
= os
.path
.realpath(os
.environ
.get('WORKSPACE'))
47 (Drive
, Path
) = os
.path
.splitdrive(self
.WorkspaceDir
)
49 (Drive
, CwdPath
) = os
.path
.splitdrive(self
.CurrentWorkingDir
)
51 self
.WorkspaceDir
= Drive
+ Path
53 self
.WorkspaceDir
= Drive
.upper() + Path
55 self
.WorkspaceRelativeWorkingDir
= self
.WorkspaceRelativePath (self
.CurrentWorkingDir
)
59 # Load TianoCoreOrgLogo, used for GUI tool
61 self
.Icon
= wx
.Icon(self
.WorkspaceFile('tools/Python/TianoCoreOrgLogo.gif'),wx
.BITMAP_TYPE_GIF
)
67 if Arg
.lower() == '-v':
72 # Close build system and print running time and status
76 Seconds
= int(time
.time() - self
.StartTime
)
78 print 'Run Time: %d seconds' % (Seconds
)
80 Minutes
= Seconds
/ 60
81 Seconds
= Seconds
% 60
83 print 'Run Time: %d minutes %d seconds' % (Minutes
, Seconds
)
86 Minutes
= Minutes
% 60
87 print 'Run Time: %d hours %d minutes %d seconds' % (Hours
, Minutes
, Seconds
)
88 if self
.RunStatus
!= '':
91 ## Convert to a workspace relative filename
93 # Convert a full path filename to a workspace relative filename.
95 # @param FileName: The filename to be Converted
97 # @retval None Workspace dir is not found in the full path
98 # @retval string The relative filename
100 def WorkspaceRelativePath(self
, FileName
):
101 FileName
= os
.path
.realpath(FileName
)
102 if FileName
.find(self
.WorkspaceDir
) != 0:
104 return FileName
.replace (self
.WorkspaceDir
, '').strip('\\').strip('/')
106 ## Convert to a full path filename
108 # Convert a workspace relative filename to a full path filename.
110 # @param FileName: The filename to be Converted
112 # @retval string The full path filename
114 def WorkspaceFile(self
, FileName
):
115 return os
.path
.realpath(os
.path
.join(self
.WorkspaceDir
,FileName
))
117 ## Convert to a real path filename
119 # Convert ${WORKSPACE} to real path
121 # @param FileName: The filename to be Converted
123 # @retval string The full path filename
125 def WorkspacePathConvert(self
, FileName
):
126 return os
.path
.realpath(FileName
.replace(TAB_WORKSPACE
, self
.WorkspaceDir
))
128 ## Convert XML into a DOM
130 # Parse an XML file into a DOM and return the DOM.
132 # @param FileName: The filename to be parsed
134 # @retval XmlParseFile (self.WorkspaceFile(FileName))
136 def XmlParseFile (self
, FileName
):
139 return XmlParseFile (self
.WorkspaceFile(FileName
))
141 ## Convert a XML section
143 # Parse a section of an XML file into a DOM(Document Object Model) and return the DOM.
145 # @param FileName: The filename to be parsed
146 # @param SectionTag: The tag name of the section to be parsed
148 # @retval XmlParseFileSection (self.WorkspaceFile(FileName), SectionTag)
150 def XmlParseFileSection (self
, FileName
, SectionTag
):
153 return XmlParseFileSection (self
.WorkspaceFile(FileName
), SectionTag
)
157 # Save a DOM(Document Object Model) into an XML file.
159 # @param Dom: The Dom to be saved
160 # @param FileName: The filename
162 # @retval XmlSaveFile (Dom, self.WorkspaceFile(FileName))
164 def XmlSaveFile (self
, Dom
, FileName
):
167 return XmlSaveFile (Dom
, self
.WorkspaceFile(FileName
))
169 ## Convert Text File To Dictionary
171 # Convert a workspace relative text file to a dictionary of (name:value) pairs.
173 # @param FileName: Text filename
174 # @param Dictionary: Dictionary to store data
175 # @param CommentCharacter: Comment char, be used to ignore comment content
176 # @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char
177 # @param ValueSplitFlag: Value split flag, be used to decide if has multiple values
178 # @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char
180 # @retval ConvertTextFileToDictionary(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter)
182 def ConvertTextFileToDictionary(self
, FileName
, Dictionary
, CommentCharacter
, KeySplitCharacter
, ValueSplitFlag
, ValueSplitCharacter
):
185 return ConvertTextFileToDictionary(self
.WorkspaceFile(FileName
), Dictionary
, CommentCharacter
, KeySplitCharacter
, ValueSplitFlag
, ValueSplitCharacter
)
187 ## Convert Dictionary To Text File
189 # Convert a dictionary of (name:value) pairs to a workspace relative text file.
191 # @param FileName: Text filename
192 # @param Dictionary: Dictionary to store data
193 # @param CommentCharacter: Comment char, be used to ignore comment content
194 # @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char
195 # @param ValueSplitFlag: Value split flag, be used to decide if has multiple values
196 # @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char
198 # @retval ConvertDictionaryToTextFile(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter)
200 def ConvertDictionaryToTextFile(self
, FileName
, Dictionary
, CommentCharacter
, KeySplitCharacter
, ValueSplitFlag
, ValueSplitCharacter
):
203 return ConvertDictionaryToTextFile(self
.WorkspaceFile(FileName
), Dictionary
, CommentCharacter
, KeySplitCharacter
, ValueSplitFlag
, ValueSplitCharacter
)
205 ## Convert Text File To Dictionary
207 # Convert a text file to a dictionary of (name:value) pairs.
209 # @param FileName: Text filename
210 # @param Dictionary: Dictionary to store data
211 # @param CommentCharacter: Comment char, be used to ignore comment content
212 # @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char
213 # @param ValueSplitFlag: Value split flag, be used to decide if has multiple values
214 # @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char
216 # @retval True Convert successfully
217 # @retval False Open file failed
219 def ConvertTextFileToDictionary(FileName
, Dictionary
, CommentCharacter
, KeySplitCharacter
, ValueSplitFlag
, ValueSplitCharacter
):
221 F
= open(FileName
,'r')
226 LineList
= Line
.split(KeySplitCharacter
,1)
227 if len(LineList
) >= 2:
228 Key
= LineList
[0].split()
229 if len(Key
) == 1 and Key
[0][0] != CommentCharacter
and Key
[0] not in Keys
:
231 Dictionary
[Key
[0]] = LineList
[1].replace('\\','/').split(ValueSplitCharacter
)
233 Dictionary
[Key
[0]] = LineList
[1].strip().replace('\\','/')
238 ## Convert Dictionary To Text File
240 # Convert a dictionary of (name:value) pairs to a text file.
242 # @param FileName: Text filename
243 # @param Dictionary: Dictionary to store data
244 # @param CommentCharacter: Comment char, be used to ignore comment content
245 # @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char
246 # @param ValueSplitFlag: Value split flag, be used to decide if has multiple values
247 # @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char
249 # @retval True Convert successfully
250 # @retval False Open file failed
252 def ConvertDictionaryToTextFile(FileName
, Dictionary
, CommentCharacter
, KeySplitCharacter
, ValueSplitFlag
, ValueSplitCharacter
):
254 F
= open(FileName
,'r')
256 Lines
= F
.readlines()
260 Keys
= Dictionary
.keys()
263 if len(Key
) > MaxLength
:
267 LineList
= Line
.split(KeySplitCharacter
,1)
268 if len(LineList
) >= 2:
269 Key
= LineList
[0].split()
270 if len(Key
) == 1 and Key
[0][0] != CommentCharacter
and Key
[0] in Dictionary
:
272 Line
= '%-*s %c %s\n' % (MaxLength
, Key
[0], KeySplitCharacter
, ' '.join(Dictionary
[Key
[0]]))
274 Line
= '%-*s %c %s\n' % (MaxLength
, Key
[0], KeySplitCharacter
, Dictionary
[Key
[0]])
277 Lines
.insert(Index
,Line
)
280 for RemainingKey
in Keys
:
282 Line
= '%-*s %c %s\n' % (MaxLength
, RemainingKey
, KeySplitCharacter
,' '.join(Dictionary
[RemainingKey
]))
284 Line
= '%-*s %c %s\n' % (MaxLength
, RemainingKey
, KeySplitCharacter
, Dictionary
[RemainingKey
])
287 F
= open(FileName
,'w')
294 ## Create a new directory
296 # @param Directory: Directory to be created
298 def CreateDirectory(Directory
):
299 if not os
.access(Directory
, os
.F_OK
):
300 os
.makedirs (Directory
)
304 # @param Directory: Directory to be created
305 # @param FileName: Filename to be created
306 # @param Mode: The mode of open file, defautl is 'w'
308 def CreateFile(Directory
, FileName
, Mode
='w'):
309 CreateDirectory (Directory
)
310 return open(os
.path
.join(Directory
, FileName
), Mode
)
314 # This acts like the main() function for the script, unless it is 'import'ed into another
317 if __name__
== '__main__':
318 # Nothing to do here. Could do some unit tests