]>
Commit | Line | Data |
---|---|---|
52302d4d LG |
1 | ## @file\r |
2 | # This file is used to define common parsing related functions used in parsing\r | |
3 | # Inf/Dsc/Makefile process\r | |
4 | #\r | |
47f15da1 | 5 | # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r |
40d841f6 | 6 | # This program and the accompanying materials\r |
52302d4d LG |
7 | # are licensed and made available under the terms and conditions of the BSD License\r |
8 | # which accompanies this 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 | |
14 | \r | |
15 | ##\r | |
16 | # Import Modules\r | |
17 | #\r | |
64429fbd | 18 | from __future__ import absolute_import\r |
1be2ed90 | 19 | import Common.LongFilePathOs as os, re\r |
52302d4d LG |
20 | import Common.EdkLogger as EdkLogger\r |
21 | from Common.DataType import *\r | |
22 | from CommonDataClass.DataClass import *\r | |
5a57246e | 23 | from Common.StringUtils import CleanString, GetSplitValueList, ReplaceMacro\r |
64429fbd | 24 | from . import EotGlobalData\r |
5a57246e | 25 | from Common.StringUtils import GetSplitList\r |
1be2ed90 | 26 | from Common.LongFilePathSupport import OpenLongFilePath as open\r |
52302d4d | 27 | \r |
47f15da1 HC |
28 | import subprocess\r |
29 | \r | |
30 | ## DeCompress\r | |
31 | #\r | |
32 | # Call external decompress tool to decompress the fv section\r | |
33 | #\r | |
34 | def DeCompress(Method, Input):\r | |
35 | # Write the input to a temp file\r | |
36 | open('_Temp.bin', 'wb').write(Input)\r | |
37 | cmd = ''\r | |
38 | if Method == 'Lzma':\r | |
39 | cmd = r'LzmaCompress -o _New.bin -d _Temp.bin'\r | |
40 | if Method == 'Efi':\r | |
41 | cmd = r'TianoCompress -d --uefi -o _New.bin _Temp.bin'\r | |
42 | if Method == 'Framework':\r | |
43 | cmd = r'TianoCompress -d -o _New.bin _Temp.bin'\r | |
44 | \r | |
45 | # Call tool to create the decompressed output file\r | |
46 | Process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)\r | |
47 | Process.communicate()[0]\r | |
48 | \r | |
49 | # Return the beffer of New.bin\r | |
50 | if os.path.exists('_New.bin'):\r | |
51 | return open('_New.bin', 'rb').read()\r | |
52 | \r | |
53 | \r | |
52302d4d LG |
54 | ## PreProcess() method\r |
55 | #\r | |
56 | # Pre process a file\r | |
57 | #\r | |
58 | # 1. Remove all comments\r | |
59 | # 2. Merge multiple lines code to one line\r | |
60 | #\r | |
61 | # @param Filename: Name of the file to be parsed\r | |
62 | # @param MergeMultipleLines: Switch for if merge multiple lines\r | |
63 | # @param LineNo: Default line no\r | |
64 | #\r | |
fb0b35e0 | 65 | # @return Lines: The file contents after removing comments\r |
52302d4d LG |
66 | #\r |
67 | def PreProcess(Filename, MergeMultipleLines = True, LineNo = -1):\r | |
68 | Lines = []\r | |
69 | Filename = os.path.normpath(Filename)\r | |
70 | if not os.path.isfile(Filename):\r | |
71 | EdkLogger.error("Eot", EdkLogger.FILE_NOT_FOUND, ExtraData=Filename)\r | |
72 | \r | |
73 | IsFindBlockComment = False\r | |
74 | IsFindBlockCode = False\r | |
75 | ReservedLine = ''\r | |
76 | ReservedLineLength = 0\r | |
77 | for Line in open(Filename, 'r'):\r | |
78 | Line = Line.strip()\r | |
79 | # Remove comment block\r | |
b36d134f | 80 | if Line.find(TAB_COMMENT_EDK_START) > -1:\r |
d40b2ee6 | 81 | ReservedLine = GetSplitList(Line, TAB_COMMENT_EDK_START, 1)[0]\r |
52302d4d | 82 | IsFindBlockComment = True\r |
b36d134f | 83 | if Line.find(TAB_COMMENT_EDK_END) > -1:\r |
d40b2ee6 | 84 | Line = ReservedLine + GetSplitList(Line, TAB_COMMENT_EDK_END, 1)[1]\r |
52302d4d LG |
85 | ReservedLine = ''\r |
86 | IsFindBlockComment = False\r | |
87 | if IsFindBlockComment:\r | |
88 | Lines.append('')\r | |
89 | continue\r | |
90 | \r | |
91 | # Remove comments at tail and remove spaces again\r | |
92 | Line = CleanString(Line)\r | |
93 | if Line == '':\r | |
94 | Lines.append('')\r | |
95 | continue\r | |
96 | \r | |
97 | if MergeMultipleLines:\r | |
98 | # Add multiple lines to one line\r | |
99 | if IsFindBlockCode and Line[-1] != TAB_SLASH:\r | |
100 | ReservedLine = (ReservedLine + TAB_SPACE_SPLIT + Line).strip()\r | |
101 | Lines.append(ReservedLine)\r | |
102 | for Index in (0, ReservedLineLength):\r | |
103 | Lines.append('')\r | |
104 | ReservedLine = ''\r | |
105 | ReservedLineLength = 0\r | |
106 | IsFindBlockCode = False\r | |
107 | continue\r | |
108 | if Line[-1] == TAB_SLASH:\r | |
109 | ReservedLine = ReservedLine + TAB_SPACE_SPLIT + Line[0:-1].strip()\r | |
110 | ReservedLineLength = ReservedLineLength + 1\r | |
111 | IsFindBlockCode = True\r | |
112 | continue\r | |
113 | \r | |
114 | Lines.append(Line)\r | |
115 | \r | |
116 | return Lines\r | |
117 | \r | |
118 | ## AddToGlobalMacro() method\r | |
119 | #\r | |
120 | # Add a macro to EotGlobalData.gMACRO\r | |
121 | #\r | |
122 | # @param Name: Name of the macro\r | |
123 | # @param Value: Value of the macro\r | |
124 | #\r | |
125 | def AddToGlobalMacro(Name, Value):\r | |
126 | Value = ReplaceMacro(Value, EotGlobalData.gMACRO, True)\r | |
127 | EotGlobalData.gMACRO[Name] = Value\r | |
128 | \r | |
129 | ## AddToSelfMacro() method\r | |
130 | #\r | |
131 | # Parse a line of macro definition and add it to a macro set\r | |
132 | #\r | |
133 | # @param SelfMacro: The self macro set\r | |
134 | # @param Line: The line of a macro definition\r | |
135 | #\r | |
136 | # @return Name: Name of macro\r | |
137 | # @return Value: Value of macro\r | |
138 | #\r | |
139 | def AddToSelfMacro(SelfMacro, Line):\r | |
140 | Name, Value = '', ''\r | |
141 | List = GetSplitValueList(Line, TAB_EQUAL_SPLIT, 1)\r | |
142 | if len(List) == 2:\r | |
143 | Name = List[0]\r | |
144 | Value = List[1]\r | |
145 | Value = ReplaceMacro(Value, EotGlobalData.gMACRO, True)\r | |
146 | Value = ReplaceMacro(Value, SelfMacro, True)\r | |
147 | SelfMacro[Name] = Value\r | |
148 | \r | |
149 | return (Name, Value)\r | |
150 | \r | |
151 | ## GetIncludeListOfFile() method\r | |
152 | #\r | |
153 | # Get the include path list for a source file\r | |
154 | #\r | |
155 | # 1. Find the source file belongs to which INF file\r | |
156 | # 2. Find the inf's package\r | |
157 | # 3. Return the include path list of the package\r | |
158 | #\r | |
159 | # @param WorkSpace: WORKSPACE path\r | |
160 | # @param Filepath: File path\r | |
161 | # @param Db: Eot database\r | |
162 | #\r | |
163 | # @return IncludeList: A list of include directories\r | |
164 | #\r | |
165 | def GetIncludeListOfFile(WorkSpace, Filepath, Db):\r | |
166 | IncludeList = []\r | |
167 | Filepath = os.path.normpath(Filepath)\r | |
168 | SqlCommand = """\r | |
169 | select Value1 from Inf where Model = %s and BelongsToFile in(\r | |
170 | select distinct B.BelongsToFile from File as A left join Inf as B\r | |
171 | where A.ID = B.BelongsToFile and B.Model = %s and (A.Path || '%s' || B.Value1) = '%s')""" \\r | |
172 | % (MODEL_META_DATA_PACKAGE, MODEL_EFI_SOURCE_FILE, '\\', Filepath)\r | |
173 | RecordSet = Db.TblFile.Exec(SqlCommand)\r | |
174 | for Record in RecordSet:\r | |
175 | DecFullPath = os.path.normpath(os.path.join(WorkSpace, Record[0]))\r | |
176 | (DecPath, DecName) = os.path.split(DecFullPath)\r | |
177 | SqlCommand = """select Value1 from Dec where BelongsToFile =\r | |
178 | (select ID from File where FullPath = '%s') and Model = %s""" \\r | |
179 | % (DecFullPath, MODEL_EFI_INCLUDE)\r | |
180 | NewRecordSet = Db.TblDec.Exec(SqlCommand)\r | |
181 | for NewRecord in NewRecordSet:\r | |
182 | IncludePath = os.path.normpath(os.path.join(DecPath, NewRecord[0]))\r | |
183 | if IncludePath not in IncludeList:\r | |
184 | IncludeList.append(IncludePath)\r | |
185 | \r | |
186 | return IncludeList\r | |
187 | \r | |
188 | ## GetTableList() method\r | |
189 | #\r | |
190 | # Search table file and find all small tables\r | |
191 | #\r | |
192 | # @param FileModelList: Model code for the file list\r | |
193 | # @param Table: Table to insert records\r | |
194 | # @param Db: Eot database\r | |
195 | #\r | |
196 | # @return TableList: A list of tables\r | |
197 | #\r | |
198 | def GetTableList(FileModelList, Table, Db):\r | |
199 | TableList = []\r | |
200 | SqlCommand = """select ID, FullPath from File where Model in %s""" % str(FileModelList)\r | |
201 | RecordSet = Db.TblFile.Exec(SqlCommand)\r | |
202 | for Record in RecordSet:\r | |
203 | TableName = Table + str(Record[0])\r | |
204 | TableList.append([TableName, Record[1]])\r | |
205 | \r | |
206 | return TableList\r | |
207 | \r | |
208 | ## GetAllIncludeDir() method\r | |
209 | #\r | |
210 | # Find all Include directories\r | |
211 | #\r | |
212 | # @param Db: Eot database\r | |
213 | #\r | |
214 | # @return IncludeList: A list of include directories\r | |
215 | #\r | |
216 | def GetAllIncludeDirs(Db):\r | |
217 | IncludeList = []\r | |
218 | SqlCommand = """select distinct Value1 from Inf where Model = %s order by Value1""" % MODEL_EFI_INCLUDE\r | |
219 | RecordSet = Db.TblInf.Exec(SqlCommand)\r | |
220 | \r | |
221 | for Record in RecordSet:\r | |
222 | IncludeList.append(Record[0])\r | |
223 | \r | |
224 | return IncludeList\r | |
225 | \r | |
226 | ## GetAllIncludeFiles() method\r | |
227 | #\r | |
228 | # Find all Include files\r | |
229 | #\r | |
230 | # @param Db: Eot database\r | |
231 | #\r | |
232 | # @return IncludeFileList: A list of include files\r | |
233 | #\r | |
234 | def GetAllIncludeFiles(Db):\r | |
235 | IncludeList = GetAllIncludeDirs(Db)\r | |
236 | IncludeFileList = []\r | |
237 | \r | |
238 | for Dir in IncludeList:\r | |
239 | if os.path.isdir(Dir):\r | |
240 | SubDir = os.listdir(Dir)\r | |
241 | for Item in SubDir:\r | |
242 | if os.path.isfile(Item):\r | |
243 | IncludeFileList.append(Item)\r | |
244 | \r | |
245 | return IncludeFileList\r | |
246 | \r | |
247 | ## GetAllSourceFiles() method\r | |
248 | #\r | |
249 | # Find all source files\r | |
250 | #\r | |
251 | # @param Db: Eot database\r | |
252 | #\r | |
253 | # @return SourceFileList: A list of source files\r | |
254 | #\r | |
255 | def GetAllSourceFiles(Db):\r | |
256 | SourceFileList = []\r | |
257 | SqlCommand = """select distinct Value1 from Inf where Model = %s order by Value1""" % MODEL_EFI_SOURCE_FILE\r | |
258 | RecordSet = Db.TblInf.Exec(SqlCommand)\r | |
259 | \r | |
260 | for Record in RecordSet:\r | |
261 | SourceFileList.append(Record[0])\r | |
262 | \r | |
263 | return SourceFileList\r | |
264 | \r | |
265 | ## GetAllFiles() method\r | |
266 | #\r | |
267 | # Find all files, both source files and include files\r | |
268 | #\r | |
269 | # @param Db: Eot database\r | |
270 | #\r | |
271 | # @return FileList: A list of files\r | |
272 | #\r | |
273 | def GetAllFiles(Db):\r | |
274 | FileList = []\r | |
275 | IncludeFileList = GetAllIncludeFiles(Db)\r | |
276 | SourceFileList = GetAllSourceFiles(Db)\r | |
277 | for Item in IncludeFileList:\r | |
278 | if os.path.isfile(Item) and Item not in FileList:\r | |
279 | FileList.append(Item)\r | |
280 | for Item in SourceFileList:\r | |
281 | if os.path.isfile(Item) and Item not in FileList:\r | |
282 | FileList.append(Item)\r | |
283 | \r | |
284 | return FileList\r | |
285 | \r | |
286 | ## ParseConditionalStatement() method\r | |
287 | #\r | |
288 | # Parse conditional statement\r | |
289 | #\r | |
290 | # @param Line: One line to be parsed\r | |
291 | # @param Macros: A set of all macro\r | |
292 | # @param StatusSet: A set of all status\r | |
293 | #\r | |
294 | # @retval True: Find keyword of conditional statement\r | |
295 | # @retval False: Not find keyword of conditional statement\r | |
296 | #\r | |
297 | def ParseConditionalStatement(Line, Macros, StatusSet):\r | |
298 | NewLine = Line.upper()\r | |
299 | if NewLine.find(TAB_IF_EXIST.upper()) > -1:\r | |
300 | IfLine = Line[NewLine.find(TAB_IF_EXIST) + len(TAB_IF_EXIST) + 1:].strip()\r | |
301 | IfLine = ReplaceMacro(IfLine, EotGlobalData.gMACRO, True)\r | |
302 | IfLine = ReplaceMacro(IfLine, Macros, True)\r | |
303 | IfLine = IfLine.replace("\"", '')\r | |
304 | IfLine = IfLine.replace("(", '')\r | |
305 | IfLine = IfLine.replace(")", '')\r | |
306 | Status = os.path.exists(os.path.normpath(IfLine))\r | |
307 | StatusSet.append([Status])\r | |
308 | return True\r | |
309 | if NewLine.find(TAB_IF_DEF.upper()) > -1:\r | |
310 | IfLine = Line[NewLine.find(TAB_IF_DEF) + len(TAB_IF_DEF) + 1:].strip()\r | |
311 | Status = False\r | |
312 | if IfLine in Macros or IfLine in EotGlobalData.gMACRO:\r | |
313 | Status = True\r | |
314 | StatusSet.append([Status])\r | |
315 | return True\r | |
316 | if NewLine.find(TAB_IF_N_DEF.upper()) > -1:\r | |
317 | IfLine = Line[NewLine.find(TAB_IF_N_DEF) + len(TAB_IF_N_DEF) + 1:].strip()\r | |
318 | Status = False\r | |
319 | if IfLine not in Macros and IfLine not in EotGlobalData.gMACRO:\r | |
320 | Status = True\r | |
321 | StatusSet.append([Status])\r | |
322 | return True\r | |
323 | if NewLine.find(TAB_IF.upper()) > -1:\r | |
324 | IfLine = Line[NewLine.find(TAB_IF) + len(TAB_IF) + 1:].strip()\r | |
325 | Status = ParseConditionalStatementMacros(IfLine, Macros)\r | |
326 | StatusSet.append([Status])\r | |
327 | return True\r | |
328 | if NewLine.find(TAB_ELSE_IF.upper()) > -1:\r | |
329 | IfLine = Line[NewLine.find(TAB_ELSE_IF) + len(TAB_ELSE_IF) + 1:].strip()\r | |
330 | Status = ParseConditionalStatementMacros(IfLine, Macros)\r | |
331 | StatusSet[-1].append(Status)\r | |
332 | return True\r | |
333 | if NewLine.find(TAB_ELSE.upper()) > -1:\r | |
334 | Status = False\r | |
335 | for Item in StatusSet[-1]:\r | |
336 | Status = Status or Item\r | |
337 | StatusSet[-1].append(not Status)\r | |
338 | return True\r | |
339 | if NewLine.find(TAB_END_IF.upper()) > -1:\r | |
340 | StatusSet.pop()\r | |
341 | return True\r | |
342 | \r | |
343 | return False\r | |
344 | \r | |
345 | ## ParseConditionalStatement() method\r | |
346 | #\r | |
347 | # Parse conditional statement with Macros\r | |
348 | #\r | |
349 | # @param Line: One line to be parsed\r | |
350 | # @param Macros: A set of macros\r | |
351 | #\r | |
352 | # @return Line: New line after replacing macros\r | |
353 | #\r | |
354 | def ParseConditionalStatementMacros(Line, Macros):\r | |
355 | if Line.upper().find('DEFINED(') > -1 or Line.upper().find('EXIST') > -1:\r | |
356 | return False\r | |
357 | Line = ReplaceMacro(Line, EotGlobalData.gMACRO, True)\r | |
358 | Line = ReplaceMacro(Line, Macros, True)\r | |
359 | Line = Line.replace("&&", "and")\r | |
360 | Line = Line.replace("||", "or")\r | |
361 | return eval(Line)\r | |
362 | \r | |
363 | ## GetConditionalStatementStatus() method\r | |
364 | #\r | |
365 | # 1. Assume the latest status as True\r | |
366 | # 2. Pop the top status of status set, previous status\r | |
367 | # 3. Compare the latest one and the previous one and get new status\r | |
368 | #\r | |
369 | # @param StatusSet: A set of all status\r | |
370 | #\r | |
371 | # @return Status: The final status\r | |
372 | #\r | |
373 | def GetConditionalStatementStatus(StatusSet):\r | |
374 | Status = True\r | |
375 | for Item in StatusSet:\r | |
376 | Status = Status and Item[-1]\r | |
377 | \r | |
378 | return Status\r | |
379 | \r | |
380 | ## SearchBelongsToFunction() method\r | |
381 | #\r | |
382 | # Search all functions belong to the file\r | |
383 | #\r | |
384 | # @param BelongsToFile: File id\r | |
385 | # @param StartLine: Start line of search scope\r | |
386 | # @param EndLine: End line of search scope\r | |
387 | #\r | |
388 | # @return: The found function\r | |
389 | #\r | |
390 | def SearchBelongsToFunction(BelongsToFile, StartLine, EndLine):\r | |
391 | SqlCommand = """select ID, Name from Function where BelongsToFile = %s and StartLine <= %s and EndLine >= %s""" %(BelongsToFile, StartLine, EndLine)\r | |
392 | RecordSet = EotGlobalData.gDb.TblFunction.Exec(SqlCommand)\r | |
393 | if RecordSet != []:\r | |
394 | return RecordSet[0][0], RecordSet[0][1]\r | |
395 | else:\r | |
396 | return -1, ''\r | |
397 | \r | |
398 | ## SearchPpiCallFunction() method\r | |
399 | #\r | |
400 | # Search all used PPI calling function 'PeiServicesReInstallPpi' and 'PeiServicesInstallPpi'\r | |
401 | # Store the result to database\r | |
402 | #\r | |
403 | # @param Identifier: Table id\r | |
404 | # @param SourceFileID: Source file id\r | |
405 | # @param SourceFileFullPath: Source file full path\r | |
406 | # @param ItemMode: Mode of the item\r | |
407 | #\r | |
408 | def SearchPpiCallFunction(Identifier, SourceFileID, SourceFileFullPath, ItemMode):\r | |
409 | ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''\r | |
410 | SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r | |
411 | where (Name like '%%%s%%' and Model = %s)""" \\r | |
412 | % (Identifier, 'PeiServicesReInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r | |
413 | BelongsToFunctionID, BelongsToFunction = -1, ''\r | |
414 | Db = EotGlobalData.gDb.TblReport\r | |
415 | RecordSet = Db.Exec(SqlCommand)\r | |
416 | for Record in RecordSet:\r | |
417 | Index = 0\r | |
418 | BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]\r | |
419 | BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)\r | |
420 | VariableList = Record[0].split(',')\r | |
421 | for Variable in VariableList:\r | |
422 | Variable = Variable.strip()\r | |
423 | # Get index of the variable\r | |
424 | if Variable.find('[') > -1:\r | |
425 | Index = int(Variable[Variable.find('[') + 1 : Variable.find(']')])\r | |
426 | Variable = Variable[:Variable.find('[')]\r | |
427 | # Get variable name\r | |
428 | if Variable.startswith('&'):\r | |
429 | Variable = Variable[1:]\r | |
430 | # Get variable value\r | |
431 | SqlCommand = """select Value from %s where (Name like '%%%s%%') and Model = %s""" \\r | |
432 | % (Identifier, Variable, MODEL_IDENTIFIER_VARIABLE)\r | |
433 | NewRecordSet = Db.Exec(SqlCommand)\r | |
434 | if NewRecordSet:\r | |
435 | NewRecord = NewRecordSet[0][0]\r | |
436 | VariableValueList = NewRecord.split('},')\r | |
437 | if len(VariableValueList) > Index:\r | |
438 | VariableValue = VariableValueList[Index]\r | |
439 | NewVariableValueList = VariableValue.split(',')\r | |
440 | if len(NewVariableValueList) > 1:\r | |
441 | NewVariableValue = NewVariableValueList[1].strip()\r | |
442 | if NewVariableValue.startswith('&'):\r | |
443 | Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, NewVariableValue[1:], GuidMacro, GuidValue, BelongsToFunction, 0)\r | |
444 | continue\r | |
445 | else:\r | |
446 | EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, NewParameter))\r | |
447 | \r | |
448 | ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''\r | |
449 | SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r | |
450 | where (Value like '%%%s%%' and Model = %s)""" \\r | |
451 | % (Identifier, 'PeiServicesInstallPpi', MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)\r | |
452 | BelongsToFunctionID, BelongsToFunction = -1, ''\r | |
453 | Db = EotGlobalData.gDb.TblReport\r | |
454 | RecordSet = Db.Exec(SqlCommand)\r | |
455 | \r | |
456 | SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r | |
457 | where (Name like '%%%s%%' and Model = %s)""" \\r | |
458 | % (Identifier, 'PeiServicesInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r | |
459 | Db = EotGlobalData.gDb.TblReport\r | |
460 | RecordSet2 = Db.Exec(SqlCommand)\r | |
461 | \r | |
462 | for Record in RecordSet + RecordSet2:\r | |
463 | if Record == []:\r | |
464 | continue\r | |
465 | Index = 0\r | |
466 | BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]\r | |
467 | BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)\r | |
468 | Variable = Record[0].replace('PeiServicesInstallPpi', '').replace('(', '').replace(')', '').replace('&', '').strip()\r | |
469 | Variable = Variable[Variable.find(',') + 1:].strip()\r | |
470 | # Get index of the variable\r | |
471 | if Variable.find('[') > -1:\r | |
472 | Index = int(Variable[Variable.find('[') + 1 : Variable.find(']')])\r | |
473 | Variable = Variable[:Variable.find('[')]\r | |
474 | # Get variable name\r | |
475 | if Variable.startswith('&'):\r | |
476 | Variable = Variable[1:]\r | |
477 | # Get variable value\r | |
478 | SqlCommand = """select Value from %s where (Name like '%%%s%%') and Model = %s""" \\r | |
479 | % (Identifier, Variable, MODEL_IDENTIFIER_VARIABLE)\r | |
480 | NewRecordSet = Db.Exec(SqlCommand)\r | |
481 | if NewRecordSet:\r | |
482 | NewRecord = NewRecordSet[0][0]\r | |
483 | VariableValueList = NewRecord.split('},')\r | |
40d841f6 | 484 | for VariableValue in VariableValueList[Index:]:\r |
52302d4d LG |
485 | NewVariableValueList = VariableValue.split(',')\r |
486 | if len(NewVariableValueList) > 1:\r | |
487 | NewVariableValue = NewVariableValueList[1].strip()\r | |
488 | if NewVariableValue.startswith('&'):\r | |
489 | Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, NewVariableValue[1:], GuidMacro, GuidValue, BelongsToFunction, 0)\r | |
490 | continue\r | |
491 | else:\r | |
492 | EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, NewParameter))\r | |
493 | \r | |
494 | ## SearchPpis() method\r | |
495 | #\r | |
496 | # Search all used PPI calling function\r | |
497 | # Store the result to database\r | |
498 | #\r | |
499 | # @param SqlCommand: SQL command statement\r | |
500 | # @param Table: Table id\r | |
501 | # @param SourceFileID: Source file id\r | |
502 | # @param SourceFileFullPath: Source file full path\r | |
503 | # @param ItemMode: Mode of the item\r | |
504 | # @param PpiMode: Mode of PPI\r | |
505 | #\r | |
506 | def SearchPpi(SqlCommand, Table, SourceFileID, SourceFileFullPath, ItemMode, PpiMode = 1):\r | |
507 | ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''\r | |
508 | BelongsToFunctionID, BelongsToFunction = -1, ''\r | |
509 | Db = EotGlobalData.gDb.TblReport\r | |
510 | RecordSet = Db.Exec(SqlCommand)\r | |
511 | for Record in RecordSet:\r | |
512 | Parameter = GetPpiParameter(Record[0], PpiMode)\r | |
513 | BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]\r | |
514 | # Get BelongsToFunction\r | |
515 | BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)\r | |
516 | \r | |
517 | # Default is Not Found\r | |
518 | IsFound = False\r | |
519 | \r | |
520 | # For Consumed Ppi\r | |
521 | if ItemMode == 'Consumed':\r | |
522 | if Parameter.startswith('g'):\r | |
523 | Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, Parameter, GuidMacro, GuidValue, BelongsToFunction, 0)\r | |
524 | else:\r | |
525 | EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))\r | |
526 | continue\r | |
527 | \r | |
528 | # Direct Parameter.Guid\r | |
529 | SqlCommand = """select Value from %s where (Name like '%%%s.Guid%%' or Name like '%%%s->Guid%%') and Model = %s""" % (Table, Parameter, Parameter, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)\r | |
530 | NewRecordSet = Db.Exec(SqlCommand)\r | |
531 | for NewRecord in NewRecordSet:\r | |
532 | GuidName = GetParameterName(NewRecord[0])\r | |
533 | Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r | |
534 | IsFound = True\r | |
535 | \r | |
536 | # Defined Parameter\r | |
537 | if not IsFound:\r | |
538 | Key = Parameter\r | |
539 | if Key.rfind(' ') > -1:\r | |
540 | Key = Key[Key.rfind(' ') : ].strip().replace('&', '')\r | |
541 | Value = FindKeyValue(EotGlobalData.gDb.TblFile, Table, Key)\r | |
542 | List = GetSplitValueList(Value.replace('\n', ''), TAB_COMMA_SPLIT)\r | |
543 | if len(List) > 1:\r | |
544 | GuidName = GetParameterName(List[1])\r | |
545 | Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r | |
546 | IsFound = True\r | |
547 | \r | |
548 | # A list Parameter\r | |
549 | if not IsFound:\r | |
550 | Start = Parameter.find('[')\r | |
551 | End = Parameter.find(']')\r | |
552 | if Start > -1 and End > -1 and Start < End:\r | |
553 | try:\r | |
554 | Index = int(Parameter[Start + 1 : End])\r | |
555 | Parameter = Parameter[0 : Start]\r | |
556 | SqlCommand = """select Value from %s where Name = '%s' and Model = %s""" % (Table, Parameter, MODEL_IDENTIFIER_VARIABLE)\r | |
557 | NewRecordSet = Db.Exec(SqlCommand)\r | |
558 | for NewRecord in NewRecordSet:\r | |
559 | NewParameter = GetSplitValueList(NewRecord[0], '}')[Index]\r | |
560 | GuidName = GetPpiParameter(NewParameter[NewParameter.find('{') : ])\r | |
561 | Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r | |
562 | IsFound = True\r | |
563 | except Exception:\r | |
564 | pass\r | |
565 | \r | |
566 | # A External Parameter\r | |
567 | if not IsFound:\r | |
568 | SqlCommand = """select File.ID from Inf, File\r | |
569 | where BelongsToFile = (select BelongsToFile from Inf where Value1 = '%s')\r | |
570 | and Inf.Model = %s and Inf.Value1 = File.FullPath and File.Model = %s""" % (SourceFileFullPath, MODEL_EFI_SOURCE_FILE, MODEL_FILE_C)\r | |
571 | NewRecordSet = Db.Exec(SqlCommand)\r | |
572 | for NewRecord in NewRecordSet:\r | |
573 | Table = 'Identifier' + str(NewRecord[0])\r | |
574 | SqlCommand = """select Value from %s where Name = '%s' and Modifier = 'EFI_PEI_PPI_DESCRIPTOR' and Model = %s""" % (Table, Parameter, MODEL_IDENTIFIER_VARIABLE)\r | |
575 | PpiSet = Db.Exec(SqlCommand)\r | |
576 | if PpiSet != []:\r | |
577 | GuidName = GetPpiParameter(PpiSet[0][0])\r | |
578 | if GuidName != '':\r | |
579 | Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r | |
580 | IsFound = True\r | |
581 | break\r | |
582 | \r | |
583 | if not IsFound:\r | |
584 | EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))\r | |
585 | \r | |
586 | ## SearchProtocols() method\r | |
587 | #\r | |
588 | # Search all used PROTOCOL calling function\r | |
589 | # Store the result to database\r | |
590 | #\r | |
591 | # @param SqlCommand: SQL command statement\r | |
592 | # @param Table: Table id\r | |
593 | # @param SourceFileID: Source file id\r | |
594 | # @param SourceFileFullPath: Source file full path\r | |
595 | # @param ItemMode: Mode of the item\r | |
596 | # @param ProtocolMode: Mode of PROTOCOL\r | |
597 | #\r | |
598 | def SearchProtocols(SqlCommand, Table, SourceFileID, SourceFileFullPath, ItemMode, ProtocolMode):\r | |
599 | ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Protocol', '', '', ''\r | |
600 | BelongsToFunctionID, BelongsToFunction = -1, ''\r | |
601 | Db = EotGlobalData.gDb.TblReport\r | |
602 | RecordSet = Db.Exec(SqlCommand)\r | |
603 | for Record in RecordSet:\r | |
604 | Parameter = ''\r | |
605 | BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]\r | |
606 | # Get BelongsToFunction\r | |
607 | BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)\r | |
608 | \r | |
609 | # Default is Not Found\r | |
610 | IsFound = False\r | |
611 | \r | |
612 | if ProtocolMode == 0 or ProtocolMode == 1:\r | |
613 | Parameter = GetProtocolParameter(Record[0], ProtocolMode)\r | |
614 | if Parameter.startswith('g') or Parameter.endswith('Guid') or Parameter == 'ShellEnvProtocol' or Parameter == 'ShellInterfaceProtocol':\r | |
615 | GuidName = GetParameterName(Parameter)\r | |
616 | Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r | |
617 | IsFound = True\r | |
618 | \r | |
619 | if ProtocolMode == 2:\r | |
620 | Protocols = GetSplitValueList(Record[0], TAB_COMMA_SPLIT)\r | |
621 | for Protocol in Protocols:\r | |
622 | if Protocol.startswith('&') and Protocol.endswith('Guid'):\r | |
623 | GuidName = GetParameterName(Protocol)\r | |
624 | Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r | |
625 | IsFound = True\r | |
626 | else:\r | |
627 | NewValue = FindKeyValue(EotGlobalData.gDb.TblFile, Table, Protocol)\r | |
628 | if Protocol != NewValue and NewValue.endswith('Guid'):\r | |
629 | GuidName = GetParameterName(NewValue)\r | |
630 | Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r | |
631 | IsFound = True\r | |
632 | \r | |
633 | if not IsFound:\r | |
634 | if BelongsToFunction in EotGlobalData.gProducedProtocolLibrary or BelongsToFunction in EotGlobalData.gConsumedProtocolLibrary:\r | |
635 | EotGlobalData.gOP_UN_MATCHED_IN_LIBRARY_CALLING.write('%s, %s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter, BelongsToFunction))\r | |
636 | else:\r | |
637 | EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))\r | |
638 | \r | |
639 | ## SearchFunctionCalling() method\r | |
640 | #\r | |
641 | # Search all used PPI/PROTOCOL calling function by library\r | |
642 | # Store the result to database\r | |
643 | #\r | |
644 | # @param SqlCommand: SQL command statement\r | |
645 | # @param Table: Table id\r | |
646 | # @param SourceFileID: Source file id\r | |
647 | # @param SourceFileFullPath: Source file full path\r | |
648 | # @param ItemType: Type of the item, PPI or PROTOCOL\r | |
649 | # @param ItemMode: Mode of item\r | |
650 | #\r | |
651 | def SearchFunctionCalling(Table, SourceFileID, SourceFileFullPath, ItemType, ItemMode):\r | |
6e6d767e | 652 | LibraryList = {}\r |
52302d4d LG |
653 | Db = EotGlobalData.gDb.TblReport\r |
654 | Parameters, ItemName, GuidName, GuidMacro, GuidValue, BelongsToFunction = [], '', '', '', '', ''\r | |
655 | if ItemType == 'Protocol' and ItemMode == 'Produced':\r | |
656 | LibraryList = EotGlobalData.gProducedProtocolLibrary\r | |
657 | elif ItemType == 'Protocol' and ItemMode == 'Consumed':\r | |
658 | LibraryList = EotGlobalData.gConsumedProtocolLibrary\r | |
659 | elif ItemType == 'Protocol' and ItemMode == 'Callback':\r | |
660 | LibraryList = EotGlobalData.gCallbackProtocolLibrary\r | |
661 | elif ItemType == 'Ppi' and ItemMode == 'Produced':\r | |
662 | LibraryList = EotGlobalData.gProducedPpiLibrary\r | |
663 | elif ItemType == 'Ppi' and ItemMode == 'Consumed':\r | |
664 | LibraryList = EotGlobalData.gConsumedPpiLibrary\r | |
665 | \r | |
666 | for Library in LibraryList:\r | |
667 | Index = LibraryList[Library]\r | |
668 | SqlCommand = """select Value, StartLine from %s\r | |
669 | where Name like '%%%s%%' and Model = %s""" \\r | |
670 | % (Table, Library, MODEL_IDENTIFIER_FUNCTION_CALLING)\r | |
671 | RecordSet = Db.Exec(SqlCommand)\r | |
672 | for Record in RecordSet:\r | |
673 | IsFound = False\r | |
674 | if Index == -1:\r | |
675 | ParameterList = GetSplitValueList(Record[0], TAB_COMMA_SPLIT)\r | |
676 | for Parameter in ParameterList:\r | |
677 | Parameters.append(GetParameterName(Parameter))\r | |
678 | else:\r | |
679 | Parameters = [GetProtocolParameter(Record[0], Index)]\r | |
680 | StartLine = Record[1]\r | |
681 | for Parameter in Parameters:\r | |
682 | if Parameter.startswith('g') or Parameter.endswith('Guid') or Parameter == 'ShellEnvProtocol' or Parameter == 'ShellInterfaceProtocol':\r | |
683 | GuidName = GetParameterName(Parameter)\r | |
684 | Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r | |
685 | IsFound = True\r | |
686 | \r | |
687 | if not IsFound:\r | |
688 | EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))\r | |
689 | \r | |
690 | ## FindProtocols() method\r | |
691 | #\r | |
692 | # Find defined protocols\r | |
693 | #\r | |
694 | # @param SqlCommand: SQL command statement\r | |
695 | # @param Table: Table id\r | |
696 | # @param SourceFileID: Source file id\r | |
697 | # @param SourceFileFullPath: Source file full path\r | |
698 | # @param ItemName: String of protocol definition\r | |
699 | # @param ItemType: Type of the item, PPI or PROTOCOL\r | |
700 | # @param ItemMode: Mode of item\r | |
701 | #\r | |
702 | #def FindProtocols(Db, SqlCommand, Table, SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue):\r | |
703 | # BelongsToFunction = ''\r | |
704 | # RecordSet = Db.Exec(SqlCommand)\r | |
705 | # for Record in RecordSet:\r | |
706 | # IsFound = True\r | |
707 | # Parameter = GetProtocolParameter(Record[0])\r | |
708 | \r | |
709 | ## GetProtocolParameter() method\r | |
710 | #\r | |
711 | # Parse string of protocol and find parameters\r | |
712 | #\r | |
713 | # @param Parameter: Parameter to be parsed\r | |
714 | # @param Index: The index of the parameter\r | |
715 | #\r | |
716 | # @return: call common GetParameter\r | |
717 | #\r | |
718 | def GetProtocolParameter(Parameter, Index = 1):\r | |
719 | return GetParameter(Parameter, Index)\r | |
720 | \r | |
721 | ## GetPpiParameter() method\r | |
722 | #\r | |
723 | # Parse string of ppi and find parameters\r | |
724 | #\r | |
725 | # @param Parameter: Parameter to be parsed\r | |
726 | # @param Index: The index of the parameter\r | |
727 | #\r | |
728 | # @return: call common GetParameter\r | |
729 | #\r | |
730 | def GetPpiParameter(Parameter, Index = 1):\r | |
731 | return GetParameter(Parameter, Index)\r | |
732 | \r | |
733 | ## GetParameter() method\r | |
734 | #\r | |
735 | # Get a parameter by index\r | |
736 | #\r | |
737 | # @param Parameter: Parameter to be parsed\r | |
738 | # @param Index: The index of the parameter\r | |
739 | #\r | |
740 | # @return Parameter: The found parameter\r | |
741 | #\r | |
742 | def GetParameter(Parameter, Index = 1):\r | |
743 | ParameterList = GetSplitValueList(Parameter, TAB_COMMA_SPLIT)\r | |
744 | if len(ParameterList) > Index:\r | |
745 | Parameter = GetParameterName(ParameterList[Index])\r | |
746 | \r | |
747 | return Parameter\r | |
748 | \r | |
749 | return ''\r | |
750 | \r | |
751 | ## GetParameterName() method\r | |
752 | #\r | |
753 | # Get a parameter name\r | |
754 | #\r | |
755 | # @param Parameter: Parameter to be parsed\r | |
756 | #\r | |
757 | # @return: The name of parameter\r | |
758 | #\r | |
759 | def GetParameterName(Parameter):\r | |
0d1f5b2b | 760 | if isinstance(Parameter, type('')) and Parameter.startswith('&'):\r |
52302d4d LG |
761 | return Parameter[1:].replace('{', '').replace('}', '').replace('\r', '').replace('\n', '').strip()\r |
762 | else:\r | |
763 | return Parameter.strip()\r | |
764 | \r | |
765 | ## FindKeyValue() method\r | |
766 | #\r | |
767 | # Find key value of a variable\r | |
768 | #\r | |
769 | # @param Db: Database to be searched\r | |
770 | # @param Table: Table to be searched\r | |
771 | # @param Key: The keyword\r | |
772 | #\r | |
fb0b35e0 | 773 | # @return Value: The value of the keyword\r |
52302d4d LG |
774 | #\r |
775 | def FindKeyValue(Db, Table, Key):\r | |
776 | SqlCommand = """select Value from %s where Name = '%s' and (Model = %s or Model = %s)""" % (Table, Key, MODEL_IDENTIFIER_VARIABLE, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)\r | |
777 | RecordSet = Db.Exec(SqlCommand)\r | |
778 | Value = ''\r | |
779 | for Record in RecordSet:\r | |
780 | if Record[0] != 'NULL':\r | |
781 | Value = FindKeyValue(Db, Table, GetParameterName(Record[0]))\r | |
782 | \r | |
783 | if Value != '':\r | |
784 | return Value\r | |
785 | else:\r | |
786 | return Key\r | |
787 | \r | |
788 | ## ParseMapFile() method\r | |
789 | #\r | |
790 | # Parse map files to get a dict of 'ModuleName' : {FunName : FunAddress}\r | |
791 | #\r | |
792 | # @param Files: A list of map files\r | |
793 | #\r | |
794 | # @return AllMaps: An object of all map files\r | |
795 | #\r | |
796 | def ParseMapFile(Files):\r | |
797 | AllMaps = {}\r | |
798 | CurrentModule = ''\r | |
799 | CurrentMaps = {}\r | |
800 | for File in Files:\r | |
801 | Content = open(File, 'r').readlines()\r | |
802 | for Line in Content:\r | |
803 | Line = CleanString(Line)\r | |
804 | # skip empty line\r | |
805 | if Line == '':\r | |
806 | continue\r | |
807 | \r | |
808 | if Line.find('(') > -1 and Line.find(')') > -1:\r | |
809 | if CurrentModule != '' and CurrentMaps != {}:\r | |
810 | AllMaps[CurrentModule] = CurrentMaps\r | |
811 | CurrentModule = Line[:Line.find('(')]\r | |
812 | CurrentMaps = {}\r | |
813 | continue\r | |
814 | else:\r | |
815 | Name = ''\r | |
816 | Address = ''\r | |
817 | List = Line.split()\r | |
818 | Address = List[0]\r | |
819 | if List[1] == 'F' or List[1] == 'FS':\r | |
820 | Name = List[2]\r | |
821 | else:\r | |
822 | Name = List[1]\r | |
823 | CurrentMaps[Name] = Address\r | |
824 | continue\r | |
825 | \r | |
826 | return AllMaps\r | |
827 | \r | |
828 | ## ConvertGuid\r | |
829 | #\r | |
830 | # Convert a GUID to a GUID with all upper letters\r | |
831 | #\r | |
832 | # @param guid: The GUID to be converted\r | |
833 | #\r | |
834 | # @param newGuid: The GUID with all upper letters.\r | |
835 | #\r | |
836 | def ConvertGuid(guid):\r | |
837 | numList = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']\r | |
838 | newGuid = ''\r | |
839 | if guid.startswith('g'):\r | |
840 | guid = guid[1:]\r | |
841 | for i in guid:\r | |
842 | if i.upper() == i and i not in numList:\r | |
843 | newGuid = newGuid + ('_' + i)\r | |
844 | else:\r | |
845 | newGuid = newGuid + i.upper()\r | |
846 | if newGuid.startswith('_'):\r | |
847 | newGuid = newGuid[1:]\r | |
848 | if newGuid.endswith('_'):\r | |
849 | newGuid = newGuid[:-1]\r | |
850 | \r | |
851 | return newGuid\r | |
852 | \r | |
853 | ## ConvertGuid2() method\r | |
854 | #\r | |
855 | # Convert a GUID to a GUID with new string instead of old string\r | |
856 | #\r | |
857 | # @param guid: The GUID to be converted\r | |
858 | # @param old: Old string to be replaced\r | |
859 | # @param new: New string to replace the old one\r | |
860 | #\r | |
861 | # @param newGuid: The GUID after replacement\r | |
862 | #\r | |
863 | def ConvertGuid2(guid, old, new):\r | |
864 | newGuid = ConvertGuid(guid)\r | |
865 | newGuid = newGuid.replace(old, new)\r | |
866 | \r | |
867 | return newGuid\r | |
868 | \r | |
869 | ##\r | |
870 | #\r | |
871 | # This acts like the main() function for the script, unless it is 'import'ed into another\r | |
872 | # script.\r | |
873 | #\r | |
874 | if __name__ == '__main__':\r | |
875 | pass\r |