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