]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Common/EdkIIWorkspace.py
BaseTools: use single RegExp for token matching
[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 from 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 #
31 class 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') is 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 #
220 def 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 #
253 def 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 #
299 def 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 #
309 def 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 #
318 if __name__ == '__main__':
319 # Nothing to do here. Could do some unit tests
320 pass