• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1## @file
2# This file is used to provide method for process AsBuilt INF file. It will consumed by InfParser
3#
4# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
5#
6# This program and the accompanying materials are licensed and made available
7# under the terms and conditions of the BSD License which accompanies this
8# distribution. The full text of the license may be found at
9# http://opensource.org/licenses/bsd-license.php
10#
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13'''
14InfAsBuiltProcess
15'''
16## Import modules
17#
18
19import os
20import re
21from Library import GlobalData
22import Logger.Log as Logger
23from Logger import StringTable as ST
24from Logger import ToolError
25
26from Library.String import GetSplitValueList
27from Library.Misc import GetHelpStringByRemoveHashKey
28from Library.Misc import ValidFile
29from Library.Misc import ProcessLineExtender
30from Library.ParserValidate import IsValidPath
31from Library.Parsing import MacroParser
32from Parser.InfParserMisc import InfExpandMacro
33
34from Library import DataType as DT
35
36## GetLibInstanceInfo
37#
38# Get the information from Library Instance INF file.
39#
40# @param string.  A string start with # and followed by INF file path
41# @param WorkSpace. The WorkSpace directory used to combined with INF file path.
42#
43# @return GUID, Version
44def GetLibInstanceInfo(String, WorkSpace, LineNo, CurrentInfFileName):
45
46    FileGuidString = ""
47    VerString = ""
48
49    OrignalString = String
50    String = String.strip()
51    if not String:
52        return None, None
53    #
54    # Remove "#" characters at the beginning
55    #
56    String = GetHelpStringByRemoveHashKey(String)
57    String = String.strip()
58
59    #
60    # To deal with library instance specified by GUID and version
61    #
62    RegFormatGuidPattern = re.compile("\s*([0-9a-fA-F]){8}-"
63                                       "([0-9a-fA-F]){4}-"
64                                       "([0-9a-fA-F]){4}-"
65                                       "([0-9a-fA-F]){4}-"
66                                       "([0-9a-fA-F]){12}\s*")
67    VersionPattern = re.compile('[\t\s]*\d+(\.\d+)?[\t\s]*')
68    GuidMatchedObj = RegFormatGuidPattern.search(String)
69
70    if String.upper().startswith('GUID') and GuidMatchedObj and 'Version' in String:
71        VersionStr = String[String.upper().find('VERSION') + 8:]
72        VersionMatchedObj = VersionPattern.search(VersionStr)
73        if VersionMatchedObj:
74            Guid = GuidMatchedObj.group().strip()
75            Version = VersionMatchedObj.group().strip()
76            return Guid, Version
77
78    #
79    # To deal with library instance specified by file name
80    #
81    FileLinesList = GetFileLineContent(String, WorkSpace, LineNo, OrignalString)
82
83
84    ReFindFileGuidPattern = re.compile("^\s*FILE_GUID\s*=.*$")
85    ReFindVerStringPattern = re.compile("^\s*VERSION_STRING\s*=.*$")
86
87    for Line in FileLinesList:
88        if ReFindFileGuidPattern.match(Line):
89            FileGuidString = Line
90        if ReFindVerStringPattern.match(Line):
91            VerString = Line
92
93    if FileGuidString:
94        FileGuidString = GetSplitValueList(FileGuidString, '=', 1)[1]
95    if VerString:
96        VerString = GetSplitValueList(VerString, '=', 1)[1]
97
98    return FileGuidString, VerString
99
100## GetPackageListInfo
101#
102# Get the package information from INF file.
103#
104# @param string.  A string start with # and followed by INF file path
105# @param WorkSpace. The WorkSpace directory used to combined with INF file path.
106#
107# @return GUID, Version
108def GetPackageListInfo(FileNameString, WorkSpace, LineNo):
109    PackageInfoList = []
110    DefineSectionMacros = {}
111    PackageSectionMacros = {}
112
113    FileLinesList = GetFileLineContent(FileNameString, WorkSpace, LineNo, '')
114
115    RePackageHeader = re.compile('^\s*\[Packages.*\].*$')
116    ReDefineHeader = re.compile('^\s*\[Defines].*$')
117
118    PackageHederFlag = False
119    DefineHeaderFlag = False
120    LineNo = -1
121    for Line in FileLinesList:
122        LineNo += 1
123        Line = Line.strip()
124
125        if Line.startswith('['):
126            PackageHederFlag = False
127            DefineHeaderFlag = False
128
129        if Line.startswith("#"):
130            continue
131
132        if not Line:
133            continue
134
135        #
136        # Found [Packages] section
137        #
138        if RePackageHeader.match(Line):
139            PackageHederFlag = True
140            continue
141
142        #
143        # Found [Define] section
144        #
145        if ReDefineHeader.match(Line):
146            DefineHeaderFlag = True
147            continue
148
149        if DefineHeaderFlag:
150            #
151            # Find Macro
152            #
153            Name, Value = MacroParser((Line, LineNo),
154                                      FileNameString,
155                                      DT.MODEL_META_DATA_HEADER,
156                                      DefineSectionMacros)
157
158            if Name != None:
159                DefineSectionMacros[Name] = Value
160                continue
161
162        if PackageHederFlag:
163
164            #
165            # Find Macro
166            #
167            Name, Value = MacroParser((Line, LineNo),
168                                      FileNameString,
169                                      DT.MODEL_META_DATA_PACKAGE,
170                                      DefineSectionMacros)
171            if Name != None:
172                PackageSectionMacros[Name] = Value
173                continue
174
175            #
176            # Replace with Local section Macro and [Defines] section Macro.
177            #
178            Line = InfExpandMacro(Line, (FileNameString, Line, LineNo), DefineSectionMacros, PackageSectionMacros, True)
179
180            Line = GetSplitValueList(Line, "#", 1)[0]
181            Line = GetSplitValueList(Line, "|", 1)[0]
182            PackageInfoList.append(Line)
183
184    return PackageInfoList
185
186def GetFileLineContent(FileName, WorkSpace, LineNo, OriginalString):
187
188    if not LineNo:
189        LineNo = -1
190
191    #
192    # Validate file name exist.
193    #
194    FullFileName = os.path.normpath(os.path.realpath(os.path.join(WorkSpace, FileName)))
195    if not (ValidFile(FullFileName)):
196        return []
197
198    #
199    # Validate file exist/format.
200    #
201    if not IsValidPath(FileName, WorkSpace):
202        return []
203
204    FileLinesList = []
205
206    try:
207        FullFileName = FullFileName.replace('\\', '/')
208        Inputfile = open(FullFileName, "rb", 0)
209        try:
210            FileLinesList = Inputfile.readlines()
211        except BaseException:
212            Logger.Error("InfParser", ToolError.FILE_READ_FAILURE, ST.ERR_FILE_OPEN_FAILURE, File=FullFileName)
213        finally:
214            Inputfile.close()
215    except BaseException:
216        Logger.Error("InfParser",
217                     ToolError.FILE_READ_FAILURE,
218                     ST.ERR_FILE_OPEN_FAILURE,
219                     File=FullFileName)
220
221    FileLinesList = ProcessLineExtender(FileLinesList)
222
223    return FileLinesList
224
225##
226# Get all INF files from current workspace
227#
228#
229def GetInfsFromWorkSpace(WorkSpace):
230    InfFiles = []
231    for top, dirs, files in os.walk(WorkSpace):
232        dirs = dirs # just for pylint
233        for File in files:
234            if File.upper().endswith(".INF"):
235                InfFiles.append(os.path.join(top, File))
236
237    return InfFiles
238
239##
240# Get GUID and version from library instance file
241#
242#
243def GetGuidVerFormLibInstance(Guid, Version, WorkSpace, CurrentInfFileName):
244    for InfFile in GetInfsFromWorkSpace(WorkSpace):
245        try:
246            if InfFile.strip().upper() == CurrentInfFileName.strip().upper():
247                continue
248            InfFile = InfFile.replace('\\', '/')
249            if InfFile not in GlobalData.gLIBINSTANCEDICT:
250                InfFileObj = open(InfFile, "rb", 0)
251                GlobalData.gLIBINSTANCEDICT[InfFile] = InfFileObj
252            else:
253                InfFileObj = GlobalData.gLIBINSTANCEDICT[InfFile]
254
255        except BaseException:
256            Logger.Error("InfParser",
257                         ToolError.FILE_READ_FAILURE,
258                         ST.ERR_FILE_OPEN_FAILURE,
259                         File=InfFile)
260        try:
261            FileLinesList = InfFileObj.readlines()
262            FileLinesList = ProcessLineExtender(FileLinesList)
263
264            ReFindFileGuidPattern = re.compile("^\s*FILE_GUID\s*=.*$")
265            ReFindVerStringPattern = re.compile("^\s*VERSION_STRING\s*=.*$")
266
267            for Line in FileLinesList:
268                if ReFindFileGuidPattern.match(Line):
269                    FileGuidString = Line
270                if ReFindVerStringPattern.match(Line):
271                    VerString = Line
272
273            if FileGuidString:
274                FileGuidString = GetSplitValueList(FileGuidString, '=', 1)[1]
275            if VerString:
276                VerString = GetSplitValueList(VerString, '=', 1)[1]
277
278            if FileGuidString.strip().upper() == Guid.upper() and \
279                VerString.strip().upper() == Version.upper():
280                return Guid, Version
281
282        except BaseException:
283            Logger.Error("InfParser", ToolError.FILE_READ_FAILURE, ST.ERR_FILE_OPEN_FAILURE, File=InfFile)
284        finally:
285            InfFileObj.close()
286
287    return '', ''
288
289
290