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