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