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
20 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
24 # Collect WorkspaceDir from the environment, the Verbose command line flag, and detect an icon bitmap file.
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
33 self
.StartTime
= time
.time()
34 self
.PrintRunTime
= False
35 self
.PrintRunStatus
= False
39 # Check environment valiable 'WORKSPACE'
41 if os
.environ
.get('WORKSPACE') == None:
42 print 'ERROR: WORKSPACE not defined. Please run EdkSetup from the EDK II install directory.'
45 self
.CurrentWorkingDir
= os
.getcwd()
47 self
.WorkspaceDir
= os
.path
.realpath(os
.environ
.get('WORKSPACE'))
48 (Drive
, Path
) = os
.path
.splitdrive(self
.WorkspaceDir
)
50 (Drive
, CwdPath
) = os
.path
.splitdrive(self
.CurrentWorkingDir
)
52 self
.WorkspaceDir
= Drive
+ Path
54 self
.WorkspaceDir
= Drive
.upper() + Path
56 self
.WorkspaceRelativeWorkingDir
= self
.WorkspaceRelativePath (self
.CurrentWorkingDir
)
60 # Load TianoCoreOrgLogo, used for GUI tool
62 self
.Icon
= wx
.Icon(self
.WorkspaceFile('tools/Python/TianoCoreOrgLogo.gif'), wx
.BITMAP_TYPE_GIF
)
68 if Arg
.lower() == '-v':
73 # Close build system and print running time and status
77 Seconds
= int(time
.time() - self
.StartTime
)
79 print 'Run Time: %d seconds' % (Seconds
)
81 Minutes
= Seconds
/ 60
82 Seconds
= Seconds
% 60
84 print 'Run Time: %d minutes %d seconds' % (Minutes
, Seconds
)
87 Minutes
= Minutes
% 60
88 print 'Run Time: %d hours %d minutes %d seconds' % (Hours
, Minutes
, Seconds
)
89 if self
.RunStatus
!= '':
92 ## Convert to a workspace relative filename
94 # Convert a full path filename to a workspace relative filename.
96 # @param FileName: The filename to be Converted
98 # @retval None Workspace dir is not found in the full path
99 # @retval string The relative filename
101 def WorkspaceRelativePath(self
, FileName
):
102 FileName
= os
.path
.realpath(FileName
)
103 if FileName
.find(self
.WorkspaceDir
) != 0:
105 return FileName
.replace (self
.WorkspaceDir
, '').strip('\\').strip('/')
107 ## Convert to a full path filename
109 # Convert a workspace relative filename to a full path filename.
111 # @param FileName: The filename to be Converted
113 # @retval string The full path filename
115 def WorkspaceFile(self
, FileName
):
116 return os
.path
.realpath(mws
.join(self
.WorkspaceDir
,FileName
))
118 ## Convert to a real path filename
120 # Convert ${WORKSPACE} to real path
122 # @param FileName: The filename to be Converted
124 # @retval string The full path filename
126 def WorkspacePathConvert(self
, FileName
):
127 return os
.path
.realpath(FileName
.replace(TAB_WORKSPACE
, self
.WorkspaceDir
))
129 ## Convert XML into a DOM
131 # Parse an XML file into a DOM and return the DOM.
133 # @param FileName: The filename to be parsed
135 # @retval XmlParseFile (self.WorkspaceFile(FileName))
137 def XmlParseFile (self
, FileName
):
140 return XmlParseFile (self
.WorkspaceFile(FileName
))
142 ## Convert a XML section
144 # Parse a section of an XML file into a DOM(Document Object Model) and return the DOM.
146 # @param FileName: The filename to be parsed
147 # @param SectionTag: The tag name of the section to be parsed
149 # @retval XmlParseFileSection (self.WorkspaceFile(FileName), SectionTag)
151 def XmlParseFileSection (self
, FileName
, SectionTag
):
154 return XmlParseFileSection (self
.WorkspaceFile(FileName
), SectionTag
)
158 # Save a DOM(Document Object Model) into an XML file.
160 # @param Dom: The Dom to be saved
161 # @param FileName: The filename
163 # @retval XmlSaveFile (Dom, self.WorkspaceFile(FileName))
165 def XmlSaveFile (self
, Dom
, FileName
):
168 return XmlSaveFile (Dom
, self
.WorkspaceFile(FileName
))
170 ## Convert Text File To Dictionary
172 # Convert a workspace relative text file to a dictionary of (name:value) pairs.
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
181 # @retval ConvertTextFileToDictionary(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter)
183 def ConvertTextFileToDictionary(self
, FileName
, Dictionary
, CommentCharacter
, KeySplitCharacter
, ValueSplitFlag
, ValueSplitCharacter
):
186 return ConvertTextFileToDictionary(self
.WorkspaceFile(FileName
), Dictionary
, CommentCharacter
, KeySplitCharacter
, ValueSplitFlag
, ValueSplitCharacter
)
188 ## Convert Dictionary To Text File
190 # Convert a dictionary of (name:value) pairs to a workspace relative text file.
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
199 # @retval ConvertDictionaryToTextFile(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter)
201 def ConvertDictionaryToTextFile(self
, FileName
, Dictionary
, CommentCharacter
, KeySplitCharacter
, ValueSplitFlag
, ValueSplitCharacter
):
204 return ConvertDictionaryToTextFile(self
.WorkspaceFile(FileName
), Dictionary
, CommentCharacter
, KeySplitCharacter
, ValueSplitFlag
, ValueSplitCharacter
)
206 ## Convert Text File To Dictionary
208 # Convert a text file to a dictionary of (name:value) pairs.
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
217 # @retval True Convert successfully
218 # @retval False Open file failed
220 def ConvertTextFileToDictionary(FileName
, Dictionary
, CommentCharacter
, KeySplitCharacter
, ValueSplitFlag
, ValueSplitCharacter
):
222 F
= open(FileName
, 'r')
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
:
232 Dictionary
[Key
[0]] = LineList
[1].replace('\\', '/').split(ValueSplitCharacter
)
234 Dictionary
[Key
[0]] = LineList
[1].strip().replace('\\', '/')
239 ## Convert Dictionary To Text File
241 # Convert a dictionary of (name:value) pairs to a text file.
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
250 # @retval True Convert successfully
251 # @retval False Open file failed
253 def ConvertDictionaryToTextFile(FileName
, Dictionary
, CommentCharacter
, KeySplitCharacter
, ValueSplitFlag
, ValueSplitCharacter
):
255 F
= open(FileName
, 'r')
257 Lines
= F
.readlines()
261 Keys
= Dictionary
.keys()
264 if len(Key
) > MaxLength
:
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
:
273 Line
= '%-*s %c %s\n' % (MaxLength
, Key
[0], KeySplitCharacter
, ' '.join(Dictionary
[Key
[0]]))
275 Line
= '%-*s %c %s\n' % (MaxLength
, Key
[0], KeySplitCharacter
, Dictionary
[Key
[0]])
278 Lines
.insert(Index
, Line
)
281 for RemainingKey
in Keys
:
283 Line
= '%-*s %c %s\n' % (MaxLength
, RemainingKey
, KeySplitCharacter
, ' '.join(Dictionary
[RemainingKey
]))
285 Line
= '%-*s %c %s\n' % (MaxLength
, RemainingKey
, KeySplitCharacter
, Dictionary
[RemainingKey
])
288 F
= open(FileName
, 'w')
295 ## Create a new directory
297 # @param Directory: Directory to be created
299 def CreateDirectory(Directory
):
300 if not os
.access(Directory
, os
.F_OK
):
301 os
.makedirs (Directory
)
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'
309 def CreateFile(Directory
, FileName
, Mode
='w'):
310 CreateDirectory (Directory
)
311 return open(os
.path
.join(Directory
, FileName
), Mode
)
315 # This acts like the main() function for the script, unless it is 'import'ed into another
318 if __name__
== '__main__':
319 # Nothing to do here. Could do some unit tests