• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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