]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Common/EdkIIWorkspace.py
There is a limitation on WINDOWS OS for the length of entire file path can’t be large...
[mirror_edk2.git] / BaseTools / Source / Python / Common / EdkIIWorkspace.py
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 #
17 import Common.LongFilePathOs as os, sys, time
18 from DataType import *
19 from Common.LongFilePathSupport import OpenLongFilePath as open
20
21 ## EdkIIWorkspace
22 #
23 # Collect WorkspaceDir from the environment, the Verbose command line flag, and detect an icon bitmap file.
24 #
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
29 #
30 class EdkIIWorkspace:
31 def __init__(self):
32 self.StartTime = time.time()
33 self.PrintRunTime = False
34 self.PrintRunStatus = False
35 self.RunStatus = ''
36
37 #
38 # Check environment valiable 'WORKSPACE'
39 #
40 if os.environ.get('WORKSPACE') == None:
41 print 'ERROR: WORKSPACE not defined. Please run EdkSetup from the EDK II install directory.'
42 return False
43
44 self.CurrentWorkingDir = os.getcwd()
45
46 self.WorkspaceDir = os.path.realpath(os.environ.get('WORKSPACE'))
47 (Drive, Path) = os.path.splitdrive(self.WorkspaceDir)
48 if Drive == '':
49 (Drive, CwdPath) = os.path.splitdrive(self.CurrentWorkingDir)
50 if Drive != '':
51 self.WorkspaceDir = Drive + Path
52 else:
53 self.WorkspaceDir = Drive.upper() + Path
54
55 self.WorkspaceRelativeWorkingDir = self.WorkspaceRelativePath (self.CurrentWorkingDir)
56
57 try:
58 #
59 # Load TianoCoreOrgLogo, used for GUI tool
60 #
61 self.Icon = wx.Icon(self.WorkspaceFile('tools/Python/TianoCoreOrgLogo.gif'),wx.BITMAP_TYPE_GIF)
62 except:
63 self.Icon = None
64
65 self.Verbose = False
66 for Arg in sys.argv:
67 if Arg.lower() == '-v':
68 self.Verbose = True
69
70 ## Close build system
71 #
72 # Close build system and print running time and status
73 #
74 def Close(self):
75 if self.PrintRunTime:
76 Seconds = int(time.time() - self.StartTime)
77 if Seconds < 60:
78 print 'Run Time: %d seconds' % (Seconds)
79 else:
80 Minutes = Seconds / 60
81 Seconds = Seconds % 60
82 if Minutes < 60:
83 print 'Run Time: %d minutes %d seconds' % (Minutes, Seconds)
84 else:
85 Hours = Minutes / 60
86 Minutes = Minutes % 60
87 print 'Run Time: %d hours %d minutes %d seconds' % (Hours, Minutes, Seconds)
88 if self.RunStatus != '':
89 print self.RunStatus
90
91 ## Convert to a workspace relative filename
92 #
93 # Convert a full path filename to a workspace relative filename.
94 #
95 # @param FileName: The filename to be Converted
96 #
97 # @retval None Workspace dir is not found in the full path
98 # @retval string The relative filename
99 #
100 def WorkspaceRelativePath(self, FileName):
101 FileName = os.path.realpath(FileName)
102 if FileName.find(self.WorkspaceDir) != 0:
103 return None
104 return FileName.replace (self.WorkspaceDir, '').strip('\\').strip('/')
105
106 ## Convert to a full path filename
107 #
108 # Convert a workspace relative filename to a full path filename.
109 #
110 # @param FileName: The filename to be Converted
111 #
112 # @retval string The full path filename
113 #
114 def WorkspaceFile(self, FileName):
115 return os.path.realpath(os.path.join(self.WorkspaceDir,FileName))
116
117 ## Convert to a real path filename
118 #
119 # Convert ${WORKSPACE} to real path
120 #
121 # @param FileName: The filename to be Converted
122 #
123 # @retval string The full path filename
124 #
125 def WorkspacePathConvert(self, FileName):
126 return os.path.realpath(FileName.replace(TAB_WORKSPACE, self.WorkspaceDir))
127
128 ## Convert XML into a DOM
129 #
130 # Parse an XML file into a DOM and return the DOM.
131 #
132 # @param FileName: The filename to be parsed
133 #
134 # @retval XmlParseFile (self.WorkspaceFile(FileName))
135 #
136 def XmlParseFile (self, FileName):
137 if self.Verbose:
138 print FileName
139 return XmlParseFile (self.WorkspaceFile(FileName))
140
141 ## Convert a XML section
142 #
143 # Parse a section of an XML file into a DOM(Document Object Model) and return the DOM.
144 #
145 # @param FileName: The filename to be parsed
146 # @param SectionTag: The tag name of the section to be parsed
147 #
148 # @retval XmlParseFileSection (self.WorkspaceFile(FileName), SectionTag)
149 #
150 def XmlParseFileSection (self, FileName, SectionTag):
151 if self.Verbose:
152 print FileName
153 return XmlParseFileSection (self.WorkspaceFile(FileName), SectionTag)
154
155 ## Save a XML file
156 #
157 # Save a DOM(Document Object Model) into an XML file.
158 #
159 # @param Dom: The Dom to be saved
160 # @param FileName: The filename
161 #
162 # @retval XmlSaveFile (Dom, self.WorkspaceFile(FileName))
163 #
164 def XmlSaveFile (self, Dom, FileName):
165 if self.Verbose:
166 print FileName
167 return XmlSaveFile (Dom, self.WorkspaceFile(FileName))
168
169 ## Convert Text File To Dictionary
170 #
171 # Convert a workspace relative text file to a dictionary of (name:value) pairs.
172 #
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
179 #
180 # @retval ConvertTextFileToDictionary(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter)
181 #
182 def ConvertTextFileToDictionary(self, FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter):
183 if self.Verbose:
184 print FileName
185 return ConvertTextFileToDictionary(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter)
186
187 ## Convert Dictionary To Text File
188 #
189 # Convert a dictionary of (name:value) pairs to a workspace relative text file.
190 #
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
197 #
198 # @retval ConvertDictionaryToTextFile(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter)
199 #
200 def ConvertDictionaryToTextFile(self, FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter):
201 if self.Verbose:
202 print FileName
203 return ConvertDictionaryToTextFile(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter)
204
205 ## Convert Text File To Dictionary
206 #
207 # Convert a text file to a dictionary of (name:value) pairs.
208 #
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
215 #
216 # @retval True Convert successfully
217 # @retval False Open file failed
218 #
219 def ConvertTextFileToDictionary(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter):
220 try:
221 F = open(FileName,'r')
222 except:
223 return False
224 Keys = []
225 for Line in F:
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:
230 if ValueSplitFlag:
231 Dictionary[Key[0]] = LineList[1].replace('\\','/').split(ValueSplitCharacter)
232 else:
233 Dictionary[Key[0]] = LineList[1].strip().replace('\\','/')
234 Keys += [Key[0]]
235 F.close()
236 return True
237
238 ## Convert Dictionary To Text File
239 #
240 # Convert a dictionary of (name:value) pairs to a text file.
241 #
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
248 #
249 # @retval True Convert successfully
250 # @retval False Open file failed
251 #
252 def ConvertDictionaryToTextFile(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter):
253 try:
254 F = open(FileName,'r')
255 Lines = []
256 Lines = F.readlines()
257 F.close()
258 except:
259 Lines = []
260 Keys = Dictionary.keys()
261 MaxLength = 0
262 for Key in Keys:
263 if len(Key) > MaxLength:
264 MaxLength = len(Key)
265 Index = 0
266 for Line in Lines:
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:
271 if ValueSplitFlag:
272 Line = '%-*s %c %s\n' % (MaxLength, Key[0], KeySplitCharacter, ' '.join(Dictionary[Key[0]]))
273 else:
274 Line = '%-*s %c %s\n' % (MaxLength, Key[0], KeySplitCharacter, Dictionary[Key[0]])
275 Lines.pop(Index)
276 if Key[0] in Keys:
277 Lines.insert(Index,Line)
278 Keys.remove(Key[0])
279 Index += 1
280 for RemainingKey in Keys:
281 if ValueSplitFlag:
282 Line = '%-*s %c %s\n' % (MaxLength, RemainingKey, KeySplitCharacter,' '.join(Dictionary[RemainingKey]))
283 else:
284 Line = '%-*s %c %s\n' % (MaxLength, RemainingKey, KeySplitCharacter, Dictionary[RemainingKey])
285 Lines.append(Line)
286 try:
287 F = open(FileName,'w')
288 except:
289 return False
290 F.writelines(Lines)
291 F.close()
292 return True
293
294 ## Create a new directory
295 #
296 # @param Directory: Directory to be created
297 #
298 def CreateDirectory(Directory):
299 if not os.access(Directory, os.F_OK):
300 os.makedirs (Directory)
301
302 ## Create a new file
303 #
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'
307 #
308 def CreateFile(Directory, FileName, Mode='w'):
309 CreateDirectory (Directory)
310 return open(os.path.join(Directory, FileName), Mode)
311
312 ##
313 #
314 # This acts like the main() function for the script, unless it is 'import'ed into another
315 # script.
316 #
317 if __name__ == '__main__':
318 # Nothing to do here. Could do some unit tests
319 pass