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