1. Add -m and -s to support only scanning meta-data files or source code files
[people/mcb30/basetools.git] / Source / Python / Common / Parsing.py
1 ## @file\r
2 # This file is used to define common parsing related functions used in parsing INF/DEC/DSC process \r
3 #\r
4 # Copyright (c) 2008, Intel Corporation\r
5 # All rights reserved. This program and the accompanying materials\r
6 # are licensed and made available under the terms and conditions of the BSD License\r
7 # which accompanies this distribution.  The full text of the license may be found at\r
8 # http://opensource.org/licenses/bsd-license.php\r
9 #\r
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12 #\r
13 \r
14 ##\r
15 # Import Modules\r
16 #\r
17 from String import *\r
18 from CommonDataClass.DataClass import *\r
19 from DataType import *\r
20 \r
21 ## ParseContent\r
22 #\r
23 # Parse content of a DSC/INF/DEC file\r
24 #\r
25 def ParseContent(Lines, ):\r
26     for Line in Lines:\r
27         LineNo = LineNo + 1\r
28         #\r
29         # Remove comments at tail and remove spaces again\r
30         #\r
31         Line = CleanString(Line)\r
32         if Line == '':\r
33             continue\r
34         \r
35         #\r
36         # Find a new section tab\r
37         # First insert previous section items\r
38         # And then parse the content of the new section\r
39         #\r
40         if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END):\r
41             #\r
42             # Insert items data of previous section\r
43             #\r
44             self.InsertSectionItemsIntoDatabase(FileID, Filename, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList)\r
45             #\r
46             # Parse the new section\r
47             #\r
48             SectionItemList = []\r
49             ArchList = []\r
50             ThirdList = []\r
51             \r
52             LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT)\r
53             for Item in LineList:\r
54                 ItemList = GetSplitValueList(Item, TAB_SPLIT)\r
55                 CurrentSection = ItemList[0]\r
56                 if CurrentSection.upper() not in self.KeyList:\r
57                     RaiseParserError(Line, CurrentSection, Filename, '', LineNo)\r
58                 ItemList.append('')\r
59                 ItemList.append('')\r
60                 if len(ItemList) > 5:\r
61                     RaiseParserError(Line, CurrentSection, Filename, '', LineNo)\r
62                 else:\r
63                     if ItemList[1] != '' and ItemList[1].upper() not in ARCH_LIST_FULL:\r
64                         EdkLogger.error("Parser", PARSER_ERROR, "Invalid Arch definition '%s' found" % ItemList[1], File=Filename, Line=LineNo)\r
65                     ArchList.append(ItemList[1].upper())\r
66                     ThirdList.append(ItemList[2])\r
67 \r
68             continue\r
69         \r
70         #\r
71         # Not in any defined section\r
72         #\r
73         if CurrentSection == TAB_UNKNOWN:\r
74             ErrorMsg = "%s is not in any defined section" % Line\r
75             EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, File=Filename, Line=LineNo)\r
76 \r
77         #\r
78         # Add a section item\r
79         #\r
80         SectionItemList.append([Line, LineNo])\r
81         # End of parse\r
82     #End of For\r
83 \r
84 \r
85 ## ParseDefineMacro\r
86 #\r
87 # Search whole table to find all defined Macro and replaced them with the real values\r
88 #\r
89 def ParseDefineMacro2(Table, RecordSets, GlobalMacro):\r
90     Macros = {}\r
91     #\r
92     # Find all DEFINE macros in section [Header] and its section\r
93     #\r
94     SqlCommand = """select Value1, Value2, BelongsToItem, StartLine, Arch from %s\r
95                     where Model = %s\r
96                     and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE)\r
97     RecordSet = Table.Exec(SqlCommand)\r
98     for Record in RecordSet:\r
99         Macros[Record[0]] = Record[1]\r
100     \r
101     #\r
102     # Overrided by Global Macros\r
103     #\r
104     for Key in GlobalMacro.keys():\r
105         Macros[Key] = GlobalMacro[Key]\r
106     \r
107     #\r
108     # Replace the Macros\r
109     #\r
110     for Key in RecordSets.keys():\r
111         if RecordSets[Key] != []:\r
112             for Item in RecordSets[Key]:\r
113                 Item[0] = ReplaceMacro(Item[0], Macros)\r
114     \r
115 ## ParseDefineMacro\r
116 #\r
117 # Search whole table to find all defined Macro and replaced them with the real values\r
118 #\r
119 def ParseDefineMacro(Table, GlobalMacro):\r
120     Macros = {}\r
121     #\r
122     # Find all DEFINE macros\r
123     #\r
124     SqlCommand = """select Value1, Value2, BelongsToItem, StartLine, Arch from %s\r
125                     where Model = %s\r
126                     and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE)\r
127     RecordSet = Table.Exec(SqlCommand)\r
128     for Record in RecordSet:\r
129 #***************************************************************************************************************************************************\r
130 #            The follow SqlCommand (expr replace) is not supported in Sqlite 3.3.4 which is used in Python 2.5                                     *\r
131 #            Reserved Only                                                                                                                         *\r
132 #            SqlCommand = """update %s set Value1 = replace(Value1, '%s', '%s')                                                                    *\r
133 #                            where ID in (select ID from %s                                                                                        * \r
134 #                                         where Model = %s                                                                                         *\r
135 #                                         and Value1 like '%%%s%%'                                                                                 *\r
136 #                                         and StartLine > %s                                                                                       *\r
137 #                                         and Enabled > -1                                                                                         *\r
138 #                                         and Arch = '%s')""" % \                                                                                  *  \r
139 #                                         (self.TblDsc.Table, Record[0], Record[1], self.TblDsc.Table, Record[2], Record[1], Record[3], Record[4]) *\r
140 #***************************************************************************************************************************************************\r
141         Macros[Record[0]] = Record[1]\r
142     \r
143     #\r
144     # Overrided by Global Macros\r
145     #\r
146     for Key in GlobalMacro.keys():\r
147         Macros[Key] = GlobalMacro[Key]\r
148     \r
149     #\r
150     # Found all defined macro and replaced\r
151     #\r
152     SqlCommand = """select ID, Value1 from %s\r
153                     where Model != %s\r
154                     and Value1 like '%%$(%%' and Value1 like '%%)%%'\r
155                     and Enabled > -1"""  % (Table.Table, MODEL_META_DATA_DEFINE)\r
156     FoundRecords = Table.Exec(SqlCommand)\r
157     for FoundRecord in FoundRecords:\r
158         NewValue = ReplaceMacro(FoundRecord[1], Macros)\r
159         SqlCommand = """update %s set Value1 = '%s'\r
160                         where ID = %s""" % (Table.Table, ConvertToSqlString2(NewValue), FoundRecord[0])\r
161         Table.Exec(SqlCommand)\r
162 \r
163 ##QueryDefinesItem\r
164 #\r
165 # Search item of section [Defines] by name, return its values\r
166 #\r
167 # @param Table: The Table to be executed\r
168 # @param Name:  The Name of item of section [Defines]\r
169 # @param Arch:  The Arch of item of section [Defines]\r
170 #\r
171 # @retval RecordSet: A list of all matched records\r
172 #\r
173 def QueryDefinesItem(Table, Name, Arch, BelongsToFile):\r
174     SqlCommand = """select Value2 from %s\r
175                     where Model = %s\r
176                     and Value1 = '%s'\r
177                     and Arch = '%s'\r
178                     and BelongsToFile = %s\r
179                     and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Name), ConvertToSqlString2(Arch), BelongsToFile)\r
180     RecordSet = Table.Exec(SqlCommand)\r
181     if len(RecordSet) < 1:\r
182         SqlCommand = """select Value2 from %s\r
183                     where Model = %s\r
184                     and Value1 = '%s'\r
185                     and Arch = '%s'\r
186                     and BelongsToFile = %s\r
187                     and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Name), ConvertToSqlString2(TAB_ARCH_COMMON.upper()), BelongsToFile)\r
188         RecordSet = Table.Exec(SqlCommand)\r
189     if len(RecordSet) == 1:\r
190         if Name == TAB_INF_DEFINES_LIBRARY_CLASS:\r
191             return [RecordSet[0][0]]\r
192         else:\r
193             return GetSplitValueList(RecordSet[0][0])\r
194     elif len(RecordSet) < 1:\r
195         return ['']\r
196     elif len(RecordSet) > 1:\r
197         RetVal = []\r
198         for Record in RecordSet:\r
199             if Name == TAB_INF_DEFINES_LIBRARY_CLASS:\r
200                 RetVal.append(Record[0])\r
201             else:\r
202                 Items = GetSplitValueList(Record[0])\r
203                 for Item in Items:\r
204                     RetVal.append(Item)\r
205         return RetVal\r
206 \r
207 ##QueryDefinesItem\r
208 #\r
209 # Search item of section [Defines] by name, return its values\r
210 #\r
211 # @param Table: The Table to be executed\r
212 # @param Name:  The Name of item of section [Defines]\r
213 # @param Arch:  The Arch of item of section [Defines]\r
214 #\r
215 # @retval RecordSet: A list of all matched records\r
216 #\r
217 def QueryDefinesItem2(Table, Arch, BelongsToFile):\r
218     SqlCommand = """select Value1, Value2, StartLine from %s\r
219                     where Model = %s\r
220                     and Arch = '%s'\r
221                     and BelongsToFile = %s\r
222                     and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Arch), BelongsToFile)\r
223     RecordSet = Table.Exec(SqlCommand)\r
224     if len(RecordSet) < 1:\r
225         SqlCommand = """select Value1, Value2, StartLine from %s\r
226                     where Model = %s\r
227                     and Arch = '%s'\r
228                     and BelongsToFile = %s\r
229                     and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(TAB_ARCH_COMMON), BelongsToFile)\r
230         RecordSet = Table.Exec(SqlCommand)\r
231     \r
232     return RecordSet\r
233 \r
234 ##QueryDscItem\r
235 #\r
236 # Search all dsc item for a specific section\r
237 #\r
238 # @param Table: The Table to be executed\r
239 # @param Model:  The type of section\r
240 #\r
241 # @retval RecordSet: A list of all matched records\r
242 #\r
243 def QueryDscItem(Table, Model, BelongsToItem, BelongsToFile):\r
244     SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s\r
245                     where Model = %s\r
246                     and BelongsToItem = %s\r
247                     and BelongsToFile = %s\r
248                     and Enabled > -1""" % (Table.Table, Model, BelongsToItem, BelongsToFile)\r
249     return Table.Exec(SqlCommand)\r
250 \r
251 ##QueryDecItem\r
252 #\r
253 # Search all dec item for a specific section\r
254 #\r
255 # @param Table: The Table to be executed\r
256 # @param Model:  The type of section\r
257 #\r
258 # @retval RecordSet: A list of all matched records\r
259 #\r
260 def QueryDecItem(Table, Model, BelongsToItem):\r
261     SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s\r
262                     where Model = %s\r
263                     and BelongsToItem = %s\r
264                     and Enabled > -1""" % (Table.Table, Model, BelongsToItem)\r
265     return Table.Exec(SqlCommand)\r
266 \r
267 ##QueryInfItem\r
268 #\r
269 # Search all dec item for a specific section\r
270 #\r
271 # @param Table: The Table to be executed\r
272 # @param Model: The type of section\r
273 #\r
274 # @retval RecordSet: A list of all matched records\r
275 #\r
276 def QueryInfItem(Table, Model, BelongsToItem):\r
277     SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s\r
278                     where Model = %s\r
279                     and BelongsToItem = %s\r
280                     and Enabled > -1""" % (Table.Table, Model, BelongsToItem)\r
281     return Table.Exec(SqlCommand)\r
282 \r
283 ## GetBuildOption\r
284 #\r
285 # Parse a string with format "[<Family>:]<ToolFlag>=Flag"\r
286 # Return (Family, ToolFlag, Flag)\r
287 #\r
288 # @param String:  String with BuildOption statement\r
289 # @param File:    The file which defines build option, used in error report\r
290 #\r
291 # @retval truple() A truple structure as (Family, ToolChain, Flag)\r
292 #\r
293 def GetBuildOption(String, File, LineNo = -1):\r
294     if String.find(TAB_EQUAL_SPLIT) < 0:\r
295         RaiseParserError(String, 'BuildOptions', File, '[<Family>:]<ToolFlag>=Flag', LineNo)\r
296     (Family, ToolChain, Flag) = ('', '', '')\r
297     List = GetSplitValueList(String, TAB_EQUAL_SPLIT, MaxSplit = 1)\r
298     if List[0].find(':') > -1:\r
299         Family = List[0][ : List[0].find(':')].strip()\r
300         ToolChain = List[0][List[0].find(':') + 1 : ].strip()\r
301     else:\r
302         ToolChain = List[0].strip()\r
303     Flag = List[1].strip()\r
304 \r
305     return (Family, ToolChain, Flag)\r
306 \r
307 ## Get Library Class\r
308 #\r
309 # Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance>\r
310\r
311 # @param Item:           String as <LibraryClassKeyWord>|<LibraryInstance>\r
312 # @param ContainerFile:  The file which describes the library class, used for error report\r
313 #\r
314 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item\r
315 #\r
316 def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo = -1):\r
317     List = GetSplitValueList(Item[0])\r
318     SupMod = SUP_MODULE_LIST_STRING\r
319     if len(List) != 2:\r
320         RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, '<LibraryClassKeyWord>|<LibraryInstance>')\r
321     else:\r
322         CheckFileType(List[1], '.Inf', ContainerFile, 'library class instance', Item[0], LineNo)\r
323         CheckFileExist(WorkspaceDir, List[1], ContainerFile, 'LibraryClasses', Item[0], LineNo)\r
324         if Item[1] != '':\r
325             SupMod = Item[1]\r
326 \r
327     return (List[0], List[1], SupMod)\r
328 \r
329 ## Get Library Class\r
330 #\r
331 # Get Library of Dsc as <LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]\r
332\r
333 # @param Item:           String as <LibraryClassKeyWord>|<LibraryInstance>\r
334 # @param ContainerFile:  The file which describes the library class, used for error report\r
335 #\r
336 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item\r
337 #\r
338 def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo = -1):\r
339     ItemList = GetSplitValueList((Item[0] + DataType.TAB_VALUE_SPLIT * 2))\r
340     SupMod = SUP_MODULE_LIST_STRING\r
341 \r
342     if len(ItemList) > 5:\r
343         RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, '<LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]')\r
344     else:\r
345         CheckFileType(ItemList[1], '.Inf', ContainerFile, 'LibraryClasses', Item[0], LineNo)\r
346         CheckFileExist(WorkspaceDir, ItemList[1], ContainerFile, 'LibraryClasses', Item[0], LineNo)\r
347         if ItemList[2] != '':\r
348             CheckPcdTokenInfo(ItemList[2], 'LibraryClasses', ContainerFile, LineNo)\r
349         if Item[1] != '':\r
350             SupMod = Item[1]\r
351 \r
352     return (ItemList[0], ItemList[1], ItemList[2], SupMod)    \r
353 \r
354 ## CheckPcdTokenInfo\r
355 #\r
356 # Check if PcdTokenInfo is following <TokenSpaceGuidCName>.<PcdCName>\r
357 #\r
358 # @param TokenInfoString:  String to be checked\r
359 # @param Section:          Used for error report\r
360 # @param File:             Used for error report\r
361 #\r
362 # @retval True PcdTokenInfo is in correct format\r
363 #\r
364 def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo = -1):\r
365     Format = '<TokenSpaceGuidCName>.<PcdCName>'\r
366     if TokenInfoString != '' and TokenInfoString != None:\r
367         TokenInfoList = GetSplitValueList(TokenInfoString, TAB_SPLIT)\r
368         if len(TokenInfoList) == 2:\r
369             return True\r
370 \r
371     RaiseParserError(TokenInfoString, Section, File, Format, LineNo)\r
372 \r
373 ## Get Pcd\r
374 #\r
375 # Get Pcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]\r
376\r
377 # @param Item:           String as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]\r
378 # @param ContainerFile:  The file which describes the pcd, used for error report\r
379 #\r
380 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)\r
381 #\r
382 def GetPcd(Item, Type, ContainerFile, LineNo = -1):\r
383     TokenGuid, TokenName, Value, MaximumDatumSize, Token = '', '', '', '', ''\r
384     List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2)\r
385     \r
386     if len(List) < 4 or len(List) > 6:\r
387         RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]', LineNo)\r
388     else:\r
389         Value = List[1]\r
390         MaximumDatumSize = List[2]\r
391         Token = List[3]\r
392         \r
393     if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):\r
394         (TokenGuid, TokenName) = GetSplitValueList(List[0], TAB_SPLIT)\r
395     \r
396     return (TokenName, TokenGuid, Value, MaximumDatumSize, Token, Type)\r
397 \r
398 ## Get FeatureFlagPcd\r
399 #\r
400 # Get FeatureFlagPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE\r
401\r
402 # @param Item:           String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE\r
403 # @param ContainerFile:  The file which describes the pcd, used for error report\r
404 #\r
405 # @retval (TokenInfo[1], TokenInfo[0], List[1], Type)\r
406 #\r
407 def GetFeatureFlagPcd(Item, Type, ContainerFile, LineNo = -1):\r
408     TokenGuid, TokenName, Value = '', '', ''\r
409     List = GetSplitValueList(Item)\r
410     if len(List) != 2:\r
411         RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE', LineNo)\r
412     else:\r
413         Value = List[1]\r
414     if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):\r
415         (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
416     \r
417     return (TokenName, TokenGuid, Value, Type)\r
418 \r
419 ## Get DynamicDefaultPcd\r
420 #\r
421 # Get DynamicDefaultPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]\r
422\r
423 # @param Item:           String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE\r
424 # @param ContainerFile:  The file which describes the pcd, used for error report\r
425 #\r
426 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)\r
427 #\r
428 def GetDynamicDefaultPcd(Item, Type, ContainerFile, LineNo = -1):\r
429     TokenGuid, TokenName, Value, DatumTyp, MaxDatumSize = '', '', '', '', ''\r
430     List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2)\r
431     if len(List) < 4 or len(List) > 8:\r
432         RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]', LineNo)\r
433     else:\r
434         Value = List[1]\r
435         DatumTyp = List[2]\r
436         MaxDatumSize = List[3]\r
437     if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):\r
438         (TokenGuid, TokenName) = GetSplitValueList(List[0], TAB_SPLIT)\r
439     \r
440     return (TokenName, TokenGuid, Value, DatumTyp, MaxDatumSize, Type)\r
441 \r
442 ## Get DynamicHiiPcd\r
443 #\r
444 # Get DynamicHiiPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]\r
445\r
446 # @param Item:           String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE\r
447 # @param ContainerFile:  The file which describes the pcd, used for error report\r
448 #\r
449 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], List[4], List[5], Type)\r
450 #\r
451 def GetDynamicHiiPcd(Item, Type, ContainerFile, LineNo = -1):\r
452     TokenGuid, TokenName, L1, L2, L3, L4, L5 = '', '', '', '', '', '', ''\r
453     List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2)\r
454     if len(List) < 6 or len(List) > 8:\r
455         RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]', LineNo)\r
456     else:\r
457         L1, L2, L3, L4, L5 = List[1], List[2], List[3], List[4], List[5]\r
458     if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):\r
459         (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
460     \r
461     return (TokenName, TokenGuid, L1, L2, L3, L4, L5, Type)\r
462 \r
463 ## Get DynamicVpdPcd\r
464 #\r
465 # Get DynamicVpdPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]\r
466\r
467 # @param Item:           String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE\r
468 # @param ContainerFile:  The file which describes the pcd, used for error report\r
469 #\r
470 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], Type)\r
471 #\r
472 def GetDynamicVpdPcd(Item, Type, ContainerFile, LineNo = -1):\r
473     TokenGuid, TokenName, L1, L2 = '', '', '', ''\r
474     List = GetSplitValueList(Item + TAB_VALUE_SPLIT)\r
475     if len(List) < 3 or len(List) > 4:\r
476         RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]', LineNo)\r
477     else:\r
478         L1, L2 = List[1], List[2]\r
479     if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):\r
480         (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
481     \r
482     return (TokenName, TokenGuid, L1, L2, Type)\r
483 \r
484 ## GetComponent\r
485 #\r
486 # Parse block of the components defined in dsc file\r
487 # Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]\r
488 #\r
489 # @param Lines:             The content to be parsed\r
490 # @param KeyValues:         To store data after parsing\r
491 #\r
492 # @retval True Get component successfully\r
493 #\r
494 def GetComponent(Lines, KeyValues):\r
495     (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False)\r
496     ListItem = None\r
497     LibraryClassItem = []\r
498     BuildOption = []\r
499     Pcd = []\r
500 \r
501     for Line in Lines:\r
502         Line = Line[0]\r
503         \r
504         #\r
505         # Ignore !include statement\r
506         #\r
507         if Line.upper().find(TAB_INCLUDE.upper() + ' ') > -1 or Line.upper().find(TAB_DEFINE + ' ') > -1:\r
508             continue\r
509         \r
510         if findBlock == False:\r
511             ListItem = Line\r
512             #\r
513             # find '{' at line tail\r
514             #\r
515             if Line.endswith('{'):\r
516                 findBlock = True\r
517                 ListItem = CleanString(Line.rsplit('{', 1)[0], DataType.TAB_COMMENT_SPLIT)\r
518 \r
519         #\r
520         # Parse a block content\r
521         #\r
522         if findBlock:\r
523             if Line.find('<LibraryClasses>') != -1:\r
524                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (True, False, False, False, False, False, False)\r
525                 continue\r
526             if Line.find('<BuildOptions>') != -1:\r
527                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, True, False, False, False, False, False)\r
528                 continue\r
529             if Line.find('<PcdsFeatureFlag>') != -1:\r
530                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, True, False, False, False, False)\r
531                 continue\r
532             if Line.find('<PcdsPatchableInModule>') != -1:\r
533                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, True, False, False, False)\r
534                 continue\r
535             if Line.find('<PcdsFixedAtBuild>') != -1:\r
536                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, True, False, False)\r
537                 continue\r
538             if Line.find('<PcdsDynamic>') != -1:\r
539                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, True, False)\r
540                 continue\r
541             if Line.find('<PcdsDynamicEx>') != -1:\r
542                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, True)\r
543                 continue\r
544             if Line.endswith('}'):\r
545                 #\r
546                 # find '}' at line tail\r
547                 #\r
548                 KeyValues.append([ListItem, LibraryClassItem, BuildOption, Pcd])\r
549                 (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False)\r
550                 LibraryClassItem, BuildOption, Pcd = [], [], []\r
551                 continue\r
552 \r
553         if findBlock:\r
554             if findLibraryClass:\r
555                 LibraryClassItem.append(Line)\r
556             elif findBuildOption:\r
557                 BuildOption.append(Line)\r
558             elif findPcdsFeatureFlag:\r
559                 Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG_NULL, Line))\r
560             elif findPcdsPatchableInModule:\r
561                 Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE_NULL, Line))\r
562             elif findPcdsFixedAtBuild:\r
563                 Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD_NULL, Line))\r
564             elif findPcdsDynamic:\r
565                 Pcd.append((DataType.TAB_PCDS_DYNAMIC_DEFAULT_NULL, Line))\r
566             elif findPcdsDynamicEx:\r
567                 Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL, Line))\r
568         else:\r
569             KeyValues.append([ListItem, [], [], []])\r
570 \r
571     return True\r
572 \r
573 ## GetExec\r
574 #\r
575 # Parse a string with format "InfFilename [EXEC = ExecFilename]"\r
576 # Return (InfFilename, ExecFilename)\r
577 #\r
578 # @param String:  String with EXEC statement\r
579 #\r
580 # @retval truple() A pair as (InfFilename, ExecFilename)\r
581 #\r
582 def GetExec(String):\r
583     InfFilename = ''\r
584     ExecFilename = ''\r
585     if String.find('EXEC') > -1:\r
586         InfFilename = String[ : String.find('EXEC')].strip()\r
587         ExecFilename = String[String.find('EXEC') + len('EXEC') : ].strip()\r
588     else:\r
589         InfFilename = String.strip()\r
590 \r
591     return (InfFilename, ExecFilename)\r
592 \r
593 ## GetComponents\r
594 #\r
595 # Parse block of the components defined in dsc file\r
596 # Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]\r
597 #\r
598 # @param Lines:             The content to be parsed\r
599 # @param Key:               Reserved \r
600 # @param KeyValues:         To store data after parsing\r
601 # @param CommentCharacter:  Comment char, used to ignore comment content\r
602 #\r
603 # @retval True Get component successfully\r
604 #\r
605 def GetComponents(Lines, Key, KeyValues, CommentCharacter):\r
606     if Lines.find(DataType.TAB_SECTION_END) > -1:\r
607         Lines = Lines.split(DataType.TAB_SECTION_END, 1)[1]\r
608     (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False)\r
609     ListItem = None\r
610     LibraryClassItem = []\r
611     BuildOption = []\r
612     Pcd = []\r
613 \r
614     LineList = Lines.split('\n')\r
615     for Line in LineList:\r
616         Line = CleanString(Line, CommentCharacter)\r
617         if Line == None or Line == '':\r
618             continue\r
619 \r
620         if findBlock == False:\r
621             ListItem = Line\r
622             #\r
623             # find '{' at line tail\r
624             #\r
625             if Line.endswith('{'):\r
626                 findBlock = True\r
627                 ListItem = CleanString(Line.rsplit('{', 1)[0], CommentCharacter)\r
628 \r
629         #\r
630         # Parse a block content\r
631         #\r
632         if findBlock:\r
633             if Line.find('<LibraryClasses>') != -1:\r
634                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (True, False, False, False, False, False, False)\r
635                 continue\r
636             if Line.find('<BuildOptions>') != -1:\r
637                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, True, False, False, False, False, False)\r
638                 continue\r
639             if Line.find('<PcdsFeatureFlag>') != -1:\r
640                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, True, False, False, False, False)\r
641                 continue\r
642             if Line.find('<PcdsPatchableInModule>') != -1:\r
643                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, True, False, False, False)\r
644                 continue\r
645             if Line.find('<PcdsFixedAtBuild>') != -1:\r
646                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, True, False, False)\r
647                 continue\r
648             if Line.find('<PcdsDynamic>') != -1:\r
649                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, True, False)\r
650                 continue\r
651             if Line.find('<PcdsDynamicEx>') != -1:\r
652                 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, True)\r
653                 continue\r
654             if Line.endswith('}'):\r
655                 #\r
656                 # find '}' at line tail\r
657                 #\r
658                 KeyValues.append([ListItem, LibraryClassItem, BuildOption, Pcd])\r
659                 (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False)\r
660                 LibraryClassItem, BuildOption, Pcd = [], [], []\r
661                 continue\r
662 \r
663         if findBlock:\r
664             if findLibraryClass:\r
665                 LibraryClassItem.append(Line)\r
666             elif findBuildOption:\r
667                 BuildOption.append(Line)\r
668             elif findPcdsFeatureFlag:\r
669                 Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG, Line))\r
670             elif findPcdsPatchableInModule:\r
671                 Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE, Line))\r
672             elif findPcdsFixedAtBuild:\r
673                 Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD, Line))\r
674             elif findPcdsDynamic:\r
675                 Pcd.append((DataType.TAB_PCDS_DYNAMIC, Line))\r
676             elif findPcdsDynamicEx:\r
677                 Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX, Line))\r
678         else:\r
679             KeyValues.append([ListItem, [], [], []])\r
680 \r
681     return True\r
682 \r
683 ## Get Source\r
684 #\r
685 # Get Source of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]\r
686\r
687 # @param Item:           String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]\r
688 # @param ContainerFile:  The file which describes the library class, used for error report\r
689 #\r
690 # @retval (List[0], List[1], List[2], List[3], List[4])\r
691 #\r
692 def GetSource(Item, ContainerFile, FileRelativePath, LineNo = -1):\r
693     ItemNew = Item + DataType.TAB_VALUE_SPLIT * 4\r
694     List = GetSplitValueList(ItemNew)\r
695     if len(List) < 5 or len(List) > 9:\r
696         RaiseParserError(Item, 'Sources', ContainerFile, '<Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]', LineNo)\r
697     List[0] = NormPath(List[0])\r
698     CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Sources', Item, LineNo)\r
699     if List[4] != '':\r
700         CheckPcdTokenInfo(List[4], 'Sources', ContainerFile, LineNo)\r
701 \r
702     return (List[0], List[1], List[2], List[3], List[4])\r
703 \r
704 ## Get Binary\r
705 #\r
706 # Get Binary of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]\r
707\r
708 # @param Item:           String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]\r
709 # @param ContainerFile:  The file which describes the library class, used for error report\r
710 #\r
711 # @retval (List[0], List[1], List[2], List[3])\r
712 #\r
713 def GetBinary(Item, ContainerFile, FileRelativePath, LineNo = -1):\r
714     ItemNew = Item + DataType.TAB_VALUE_SPLIT\r
715     List = GetSplitValueList(ItemNew)\r
716     if len(List) != 4 and len(List) != 5:\r
717         RaiseParserError(Item, 'Binaries', ContainerFile, "<FileType>|<Filename>|<Target>[|<TokenSpaceGuidCName>.<PcdCName>]", LineNo)\r
718     else:\r
719         if List[3] != '':\r
720             CheckPcdTokenInfo(List[3], 'Binaries', ContainerFile, LineNo)\r
721     \r
722     return (List[0], List[1], List[2], List[3])\r
723 \r
724 ## Get Guids/Protocols/Ppis\r
725 #\r
726 # Get Guids/Protocols/Ppis of Inf as <GuidCName>[|<PcdFeatureFlag>]\r
727 #\r
728 # @param Item:           String as <GuidCName>[|<PcdFeatureFlag>]\r
729 # @param Type:           Type of parsing string \r
730 # @param ContainerFile:  The file which describes the library class, used for error report\r
731 #\r
732 # @retval (List[0], List[1])\r
733 #\r
734 def GetGuidsProtocolsPpisOfInf(Item, Type, ContainerFile, LineNo = -1):\r
735     ItemNew = Item + TAB_VALUE_SPLIT\r
736     List = GetSplitValueList(ItemNew)\r
737     if List[1] != '':\r
738         CheckPcdTokenInfo(List[1], Type, ContainerFile, LineNo)\r
739     \r
740     return (List[0], List[1])\r
741 \r
742 ## Get Guids/Protocols/Ppis\r
743 #\r
744 # Get Guids/Protocols/Ppis of Dec as <GuidCName>=<GuidValue>\r
745 #\r
746 # @param Item:           String as <GuidCName>=<GuidValue>\r
747 # @param Type:           Type of parsing string \r
748 # @param ContainerFile:  The file which describes the library class, used for error report\r
749 #\r
750 # @retval (List[0], List[1])\r
751 #\r
752 def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo = -1):\r
753     List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT)\r
754     if len(List) != 2:\r
755         RaiseParserError(Item, Type, ContainerFile, '<CName>=<GuidValue>', LineNo)\r
756     \r
757     return (List[0], List[1])\r
758 \r
759 ## GetPackage\r
760 #\r
761 # Get Package of Inf as <PackagePath>[|<PcdFeatureFlag>]\r
762 #\r
763 # @param Item:           String as <PackagePath>[|<PcdFeatureFlag>]\r
764 # @param Type:           Type of parsing string \r
765 # @param ContainerFile:  The file which describes the library class, used for error report\r
766 #\r
767 # @retval (List[0], List[1])\r
768 #\r
769 def GetPackage(Item, ContainerFile, FileRelativePath, LineNo = -1):\r
770     ItemNew = Item + TAB_VALUE_SPLIT\r
771     List = GetSplitValueList(ItemNew)\r
772     CheckFileType(List[0], '.Dec', ContainerFile, 'package', List[0], LineNo)\r
773     CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Packages', List[0], LineNo)\r
774     \r
775     if List[1] != '':\r
776         CheckPcdTokenInfo(List[1], 'Packages', ContainerFile, LineNo)\r
777     \r
778     return (List[0], List[1])\r
779 \r
780 ## Get Pcd Values of Inf\r
781 #\r
782 # Get Pcd of Inf as <TokenSpaceGuidCName>.<PcdCName>[|<Value>]\r
783 #\r
784 # @param Item:  The string describes pcd\r
785 # @param Type:  The type of Pcd\r
786 # @param File:  The file which describes the pcd, used for error report\r
787 #\r
788 # @retval (TokenSpcCName, TokenCName, Value, ItemType) Formatted Pcd Item\r
789 #\r
790 def GetPcdOfInf(Item, Type, File, LineNo):\r
791     Format = '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]'\r
792     TokenGuid, TokenName, Value, InfType = '', '', '', ''\r
793     \r
794     if Type == TAB_PCDS_FIXED_AT_BUILD:\r
795         InfType = TAB_INF_FIXED_PCD\r
796     elif Type == TAB_PCDS_PATCHABLE_IN_MODULE:\r
797         InfType = TAB_INF_PATCH_PCD\r
798     elif Type == TAB_PCDS_FEATURE_FLAG:\r
799         InfType = TAB_INF_FEATURE_PCD        \r
800     elif Type == TAB_PCDS_DYNAMIC_EX:\r
801         InfType = TAB_INF_PCD_EX        \r
802     elif Type == TAB_PCDS_DYNAMIC:\r
803         InfType = TAB_INF_PCD\r
804     List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT)\r
805     if len(List) < 2 or len(List) > 3:\r
806         RaiseParserError(Item, InfType, File, Format, LineNo)\r
807     else:\r
808         Value = List[1]\r
809     TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
810     if len(TokenInfo) != 2:\r
811         RaiseParserError(Item, InfType, File, Format, LineNo)\r
812     else:\r
813         TokenGuid = TokenInfo[0]\r
814         TokenName = TokenInfo[1]\r
815 \r
816     return (TokenGuid, TokenName, Value, Type)\r
817 \r
818     \r
819 ## Get Pcd Values of Dec\r
820 #\r
821 # Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>\r
822 # @retval (TokenSpcCName, TokenCName, Value, DatumType, Token, ItemType) Formatted Pcd Item\r
823 #\r
824 def GetPcdOfDec(Item, Type, File, LineNo = -1):\r
825     Format = '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>'\r
826     TokenGuid, TokenName, Value, DatumType, Token = '', '', '', '', ''\r
827     List = GetSplitValueList(Item)\r
828     if len(List) != 4:\r
829         RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo)\r
830     else:\r
831         Value = List[1]\r
832         DatumType = List[2]\r
833         Token = List[3]\r
834     TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
835     if len(TokenInfo) != 2:\r
836         RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo)\r
837     else:\r
838         TokenGuid = TokenInfo[0]\r
839         TokenName = TokenInfo[1]\r
840     \r
841     return (TokenGuid, TokenName, Value, DatumType, Token, Type)\r
842 \r
843 ## Parse DEFINE statement\r
844 #\r
845 # Get DEFINE macros\r
846 #\r
847 # 1. Insert a record into TblDec\r
848 # Value1: Macro Name\r
849 # Value2: Macro Value\r
850 #\r
851 def ParseDefine(LineValue, StartLine, Table, FileID, Filename, SectionName, SectionModel, Arch):\r
852     EdkLogger.debug(EdkLogger.DEBUG_2, "DEFINE statement '%s' found in section %s" % (LineValue, SectionName))\r
853     Define = GetSplitValueList(CleanString(LineValue[LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') + len(DataType.TAB_DEFINE + ' ') : ]), TAB_EQUAL_SPLIT, 1)\r
854     Table.Insert(MODEL_META_DATA_DEFINE, Define[0], Define[1], '', '', '', Arch, SectionModel, FileID, StartLine, -1, StartLine, -1, 0)\r
855 \r
856 ## Insert records to database\r
857\r
858 # Insert item data of a section to database\r
859 # @param Table:            The Table to be inserted \r
860 # @param FileID:           The ID of belonging file\r
861 # @param Filename:         The name of belonging file\r
862 # @param CurrentSection:   The name of currect section\r
863 # @param SectionItemList:  A list of items of the section\r
864 # @param ArchList:         A list of arches\r
865 # @param ThirdList:        A list of third parameters, ModuleType for LibraryClass and SkuId for Dynamic Pcds\r
866 # @param IfDefList:        A list of all conditional statements\r
867 # @param RecordSet:        A dict of all parsed records \r
868 #\r
869 def InsertSectionItemsIntoDatabase(Table, FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, RecordSet):\r
870     #\r
871     # Insert each item data of a section\r
872     #\r
873     for Index in range(0, len(ArchList)):\r
874         Arch = ArchList[Index]\r
875         Third = ThirdList[Index]\r
876         if Arch == '':\r
877             Arch = TAB_ARCH_COMMON\r
878 \r
879         Records = RecordSet[Model]\r
880         for SectionItem in SectionItemList:\r
881             BelongsToItem, EndLine, EndColumn = -1, -1, -1\r
882             LineValue, StartLine, EndLine = SectionItem[0], SectionItem[1], SectionItem[1]\r
883             \r
884             EdkLogger.debug(4, "Parsing %s ..." %LineValue)\r
885             #\r
886             # And then parse DEFINE statement\r
887             #\r
888             if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1:\r
889                 ParseDefine(LineValue, StartLine, Table, FileID, Filename, CurrentSection, Model, Arch)\r
890                 continue\r
891             \r
892             #\r
893             # At last parse other sections\r
894             #\r
895             ID = Table.Insert(Model, LineValue, Third, Third, '', '', Arch, -1, FileID, StartLine, -1, StartLine, -1, 0)\r
896             Records.append([LineValue, Arch, StartLine, ID, Third])\r
897         \r
898         if RecordSet != {}:\r
899             RecordSet[Model] = Records\r