2 # This file is used to define common parsing related functions used in parsing INF/DEC/DSC process
4 # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
5 # SPDX-License-Identifier: BSD-2-Clause-Patent
11 from __future__
import absolute_import
12 from .StringUtils
import *
13 from CommonDataClass
.DataClass
import *
14 from .DataType
import *
18 # Search whole table to find all defined Macro and replaced them with the real values
20 def ParseDefineMacro2(Table
, RecordSets
, GlobalMacro
):
23 # Find all DEFINE macros in section [Header] and its section
25 SqlCommand
= """select Value1, Value2, BelongsToItem, StartLine, Arch from %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]
33 # Overridden by Global Macros
35 Macros
.update(GlobalMacro
)
40 for Value
in (v
for v
in RecordSets
.values() if v
):
42 Item
[0] = ReplaceMacro(Item
[0], Macros
)
46 # Search whole table to find all defined Macro and replaced them with the real values
48 def ParseDefineMacro(Table
, GlobalMacro
):
51 # Find all DEFINE macros
53 SqlCommand
= """select Value1, Value2, BelongsToItem, StartLine, Arch from %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 *
61 # SqlCommand = """update %s set Value1 = replace(Value1, '%s', '%s') *
62 # where ID in (select ID from %s *
64 # and Value1 like '%%%s%%' *
65 # and StartLine > %s *
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]
73 # Overridden by Global Macros
75 Macros
.update(GlobalMacro
)
78 # Found all defined macro and replaced
80 SqlCommand
= """select ID, Value1 from %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
)
93 # Search item of section [Defines] by name, return its values
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]
99 # @retval RecordSet: A list of all matched records
101 def QueryDefinesItem(Table
, Name
, Arch
, BelongsToFile
):
102 SqlCommand
= """select Value2 from %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
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]]
121 return GetSplitValueList(RecordSet
[0][0])
122 elif len(RecordSet
) < 1:
124 elif len(RecordSet
) > 1:
126 for Record
in RecordSet
:
127 if Name
== TAB_INF_DEFINES_LIBRARY_CLASS
:
128 RetVal
.append(Record
[0])
130 Items
= GetSplitValueList(Record
[0])
137 # Search item of section [Defines] by name, return its values
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]
143 # @retval RecordSet: A list of all matched records
145 def QueryDefinesItem2(Table
, Arch
, BelongsToFile
):
146 SqlCommand
= """select Value1, Value2, StartLine from %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
156 and BelongsToFile = %s
157 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_HEADER
, ConvertToSqlString2(TAB_ARCH_COMMON
), BelongsToFile
)
158 RecordSet
= Table
.Exec(SqlCommand
)
164 # Search all dsc item for a specific section
166 # @param Table: The Table to be executed
167 # @param Model: The type of section
169 # @retval RecordSet: A list of all matched records
171 def QueryDscItem(Table
, Model
, BelongsToItem
, BelongsToFile
):
172 SqlCommand
= """select Value1, Arch, StartLine, ID, Value2 from %s
174 and BelongsToItem = %s
175 and BelongsToFile = %s
176 and Enabled > -1""" % (Table
.Table
, Model
, BelongsToItem
, BelongsToFile
)
177 return Table
.Exec(SqlCommand
)
181 # Search all dec item for a specific section
183 # @param Table: The Table to be executed
184 # @param Model: The type of section
186 # @retval RecordSet: A list of all matched records
188 def QueryDecItem(Table
, Model
, BelongsToItem
):
189 SqlCommand
= """select Value1, Arch, StartLine, ID, Value2 from %s
191 and BelongsToItem = %s
192 and Enabled > -1""" % (Table
.Table
, Model
, BelongsToItem
)
193 return Table
.Exec(SqlCommand
)
197 # Search all dec item for a specific section
199 # @param Table: The Table to be executed
200 # @param Model: The type of section
202 # @retval RecordSet: A list of all matched records
204 def QueryInfItem(Table
, Model
, BelongsToItem
):
205 SqlCommand
= """select Value1, Arch, StartLine, ID, Value2 from %s
207 and BelongsToItem = %s
208 and Enabled > -1""" % (Table
.Table
, Model
, BelongsToItem
)
209 return Table
.Exec(SqlCommand
)
213 # Parse a string with format "[<Family>:]<ToolFlag>=Flag"
214 # Return (Family, ToolFlag, Flag)
216 # @param String: String with BuildOption statement
217 # @param File: The file which defines build option, used in error report
219 # @retval truple() A truple structure as (Family, ToolChain, Flag)
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
)
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()
231 ToolChain
= List
[0].strip()
232 Flag
= List
[1].strip()
233 return (Family
, ToolChain
, Flag
)
237 # Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance>
239 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
240 # @param ContainerFile: The file which describes the library class, used for error report
242 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item
244 def GetLibraryClass(Item
, ContainerFile
, WorkspaceDir
, LineNo
= -1):
245 List
= GetSplitValueList(Item
[0])
246 SupMod
= SUP_MODULE_LIST_STRING
248 RaiseParserError(Item
[0], 'LibraryClasses', ContainerFile
, '<LibraryClassKeyWord>|<LibraryInstance>')
250 CheckFileType(List
[1], '.Inf', ContainerFile
, 'library class instance', Item
[0], LineNo
)
251 CheckFileExist(WorkspaceDir
, List
[1], ContainerFile
, 'LibraryClasses', Item
[0], LineNo
)
255 return (List
[0], List
[1], SupMod
)
259 # Get Library of Dsc as <LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]
261 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
262 # @param ContainerFile: The file which describes the library class, used for error report
264 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item
266 def GetLibraryClassOfInf(Item
, ContainerFile
, WorkspaceDir
, LineNo
= -1):
267 ItemList
= GetSplitValueList((Item
[0] + DataType
.TAB_VALUE_SPLIT
* 2))
268 SupMod
= SUP_MODULE_LIST_STRING
270 if len(ItemList
) > 5:
271 RaiseParserError(Item
[0], 'LibraryClasses', ContainerFile
, '<LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]')
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
)
280 return (ItemList
[0], ItemList
[1], ItemList
[2], SupMod
)
284 # Check if PcdTokenInfo is following <TokenSpaceGuidCName>.<PcdCName>
286 # @param TokenInfoString: String to be checked
287 # @param Section: Used for error report
288 # @param File: Used for error report
290 # @retval True PcdTokenInfo is in correct format
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:
299 RaiseParserError(TokenInfoString
, Section
, File
, Format
, LineNo
)
303 # Get Pcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]
305 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]
306 # @param ContainerFile: The file which describes the pcd, used for error report
308 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)
310 def GetPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
311 TokenGuid
, TokenName
, Value
, MaximumDatumSize
, Token
= '', '', '', '', ''
312 List
= GetSplitValueList(Item
+ TAB_VALUE_SPLIT
* 2)
314 if len(List
) < 4 or len(List
) > 6:
315 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]', LineNo
)
318 MaximumDatumSize
= List
[2]
321 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
322 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], TAB_SPLIT
)
324 return (TokenName
, TokenGuid
, Value
, MaximumDatumSize
, Token
, Type
)
326 ## Get FeatureFlagPcd
328 # Get FeatureFlagPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
330 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
331 # @param ContainerFile: The file which describes the pcd, used for error report
333 # @retval (TokenInfo[1], TokenInfo[0], List[1], Type)
335 def GetFeatureFlagPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
336 TokenGuid
, TokenName
, Value
= '', '', ''
337 List
= GetSplitValueList(Item
)
339 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE', LineNo
)
342 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
343 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
345 return (TokenName
, TokenGuid
, Value
, Type
)
347 ## Get DynamicDefaultPcd
349 # Get DynamicDefaultPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]
351 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
352 # @param ContainerFile: The file which describes the pcd, used for error report
354 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)
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
)
364 MaxDatumSize
= List
[3]
365 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
366 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], TAB_SPLIT
)
368 return (TokenName
, TokenGuid
, Value
, DatumTyp
, MaxDatumSize
, Type
)
372 # Get DynamicHiiPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]
374 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
375 # @param ContainerFile: The file which describes the pcd, used for error report
377 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], List[4], List[5], Type)
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
)
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
)
389 return (TokenName
, TokenGuid
, L1
, L2
, L3
, L4
, L5
, Type
)
393 # Get DynamicVpdPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]
395 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
396 # @param ContainerFile: The file which describes the pcd, used for error report
398 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], Type)
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
)
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
)
410 return (TokenName
, TokenGuid
, L1
, L2
, Type
)
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]], ...]
417 # @param Lines: The content to be parsed
418 # @param KeyValues: To store data after parsing
420 # @retval True Get component successfully
422 def GetComponent(Lines
, KeyValues
):
423 (findBlock
, findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, False, False)
425 LibraryClassItem
= []
433 # Ignore !include statement
435 if Line
.upper().find(TAB_INCLUDE
.upper() + ' ') > -1 or Line
.upper().find(TAB_DEFINE
+ ' ') > -1:
438 if findBlock
== False:
441 # find '{' at line tail
443 if Line
.endswith('{'):
445 ListItem
= CleanString(Line
.rsplit('{', 1)[0], DataType
.TAB_COMMENT_SPLIT
)
448 # Parse a block content
451 if Line
.find('<LibraryClasses>') != -1:
452 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (True, False, False, False, False, False, False)
454 if Line
.find('<BuildOptions>') != -1:
455 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, True, False, False, False, False, False)
457 if Line
.find('<PcdsFeatureFlag>') != -1:
458 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, True, False, False, False, False)
460 if Line
.find('<PcdsPatchableInModule>') != -1:
461 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, True, False, False, False)
463 if Line
.find('<PcdsFixedAtBuild>') != -1:
464 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, True, False, False)
466 if Line
.find('<PcdsDynamic>') != -1:
467 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, True, False)
469 if Line
.find('<PcdsDynamicEx>') != -1:
470 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, True)
472 if Line
.endswith('}'):
474 # find '}' at line tail
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
= [], [], []
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
))
497 KeyValues
.append([ListItem
, [], [], []])
503 # Parse a string with format "InfFilename [EXEC = ExecFilename]"
504 # Return (InfFilename, ExecFilename)
506 # @param String: String with EXEC statement
508 # @retval truple() A pair as (InfFilename, ExecFilename)
513 if String
.find('EXEC') > -1:
514 InfFilename
= String
[ : String
.find('EXEC')].strip()
515 ExecFilename
= String
[String
.find('EXEC') + len('EXEC') : ].strip()
517 InfFilename
= String
.strip()
519 return (InfFilename
, ExecFilename
)
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]], ...]
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
531 # @retval True Get component successfully
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)
538 LibraryClassItem
= []
542 LineList
= Lines
.split('\n')
543 for Line
in LineList
:
544 Line
= CleanString(Line
, CommentCharacter
)
545 if Line
is None or Line
== '':
548 if findBlock
== False:
551 # find '{' at line tail
553 if Line
.endswith('{'):
555 ListItem
= CleanString(Line
.rsplit('{', 1)[0], CommentCharacter
)
558 # Parse a block content
561 if Line
.find('<LibraryClasses>') != -1:
562 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (True, False, False, False, False, False, False)
564 if Line
.find('<BuildOptions>') != -1:
565 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, True, False, False, False, False, False)
567 if Line
.find('<PcdsFeatureFlag>') != -1:
568 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, True, False, False, False, False)
570 if Line
.find('<PcdsPatchableInModule>') != -1:
571 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, True, False, False, False)
573 if Line
.find('<PcdsFixedAtBuild>') != -1:
574 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, True, False, False)
576 if Line
.find('<PcdsDynamic>') != -1:
577 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, True, False)
579 if Line
.find('<PcdsDynamicEx>') != -1:
580 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, True)
582 if Line
.endswith('}'):
584 # find '}' at line tail
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
= [], [], []
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
))
607 KeyValues
.append([ListItem
, [], [], []])
613 # Get Source of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
615 # @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
616 # @param ContainerFile: The file which describes the library class, used for error report
618 # @retval (List[0], List[1], List[2], List[3], List[4])
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
)
628 CheckPcdTokenInfo(List
[4], 'Sources', ContainerFile
, LineNo
)
630 return (List
[0], List
[1], List
[2], List
[3], List
[4])
634 # Get Binary of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
636 # @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
637 # @param ContainerFile: The file which describes the library class, used for error report
639 # @retval (List[0], List[1], List[2], List[3])
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
)
649 CheckPcdTokenInfo(List
[3], 'Binaries', ContainerFile
, LineNo
)
652 return (List
[0], List
[1], List
[2], List
[3])
654 return (List
[0], List
[1], List
[2], '')
656 return (List
[0], List
[1], '', '')
658 return (List
[0], '', '', '')
660 ## Get Guids/Protocols/Ppis
662 # Get Guids/Protocols/Ppis of Inf as <GuidCName>[|<PcdFeatureFlag>]
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
668 # @retval (List[0], List[1])
670 def GetGuidsProtocolsPpisOfInf(Item
, Type
, ContainerFile
, LineNo
= -1):
671 ItemNew
= Item
+ TAB_VALUE_SPLIT
672 List
= GetSplitValueList(ItemNew
)
674 CheckPcdTokenInfo(List
[1], Type
, ContainerFile
, LineNo
)
676 return (List
[0], List
[1])
678 ## Get Guids/Protocols/Ppis
680 # Get Guids/Protocols/Ppis of Dec as <GuidCName>=<GuidValue>
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
686 # @retval (List[0], List[1])
688 def GetGuidsProtocolsPpisOfDec(Item
, Type
, ContainerFile
, LineNo
= -1):
689 List
= GetSplitValueList(Item
, DataType
.TAB_EQUAL_SPLIT
)
691 RaiseParserError(Item
, Type
, ContainerFile
, '<CName>=<GuidValue>', LineNo
)
693 return (List
[0], List
[1])
697 # Get Package of Inf as <PackagePath>[|<PcdFeatureFlag>]
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
703 # @retval (List[0], List[1])
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
)
712 CheckPcdTokenInfo(List
[1], 'Packages', ContainerFile
, LineNo
)
714 return (List
[0], List
[1])
716 ## Get Pcd Values of Inf
718 # Get Pcd of Inf as <TokenSpaceGuidCName>.<PcdCName>[|<Value>]
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
724 # @retval (TokenSpcCName, TokenCName, Value, ItemType) Formatted Pcd Item
726 def GetPcdOfInf(Item
, Type
, File
, LineNo
):
727 Format
= '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]'
728 TokenGuid
, TokenName
, Value
, InfType
= '', '', '', ''
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
)
745 TokenInfo
= GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
746 if len(TokenInfo
) != 2:
747 RaiseParserError(Item
, InfType
, File
, Format
, LineNo
)
749 TokenGuid
= TokenInfo
[0]
750 TokenName
= TokenInfo
[1]
752 return (TokenGuid
, TokenName
, Value
, Type
)
755 ## Get Pcd Values of Dec
757 # Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
758 # @retval (TokenSpcCName, TokenCName, Value, DatumType, Token, ItemType) Formatted Pcd Item
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
)
765 RaiseParserError(Item
, 'Pcds' + Type
, File
, Format
, LineNo
)
770 TokenInfo
= GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
771 if len(TokenInfo
) != 2:
772 RaiseParserError(Item
, 'Pcds' + Type
, File
, Format
, LineNo
)
774 TokenGuid
= TokenInfo
[0]
775 TokenName
= TokenInfo
[1]
777 return (TokenGuid
, TokenName
, Value
, DatumType
, Token
, Type
)
779 ## Parse DEFINE statement
783 # 1. Insert a record into TblDec
785 # Value2: Macro Value
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)
792 ## InsertSectionItems
794 # Insert item data of a section to a dict
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
]
802 Arch
= TAB_ARCH_COMMON
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]
809 EdkLogger
.debug(4, "Parsing %s ..." %LineValue
)
810 # And then parse DEFINE statement
811 if LineValue
.upper().find(DataType
.TAB_DEFINE
.upper() + ' ') > -1:
814 # At last parse other sections
816 Records
.append([LineValue
, Arch
, StartLine
, ID
, Third
, Comment
])
819 RecordSet
[Model
] = Records
821 ## Insert records to database
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
834 def InsertSectionItemsIntoDatabase(Table
, FileID
, Filename
, Model
, CurrentSection
, SectionItemList
, ArchList
, ThirdList
, IfDefList
, RecordSet
):
836 # Insert each item data of a section
838 for Index
in range(0, len(ArchList
)):
839 Arch
= ArchList
[Index
]
840 Third
= ThirdList
[Index
]
842 Arch
= TAB_ARCH_COMMON
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]
849 EdkLogger
.debug(4, "Parsing %s ..." %LineValue
)
851 # And then parse DEFINE statement
853 if LineValue
.upper().find(DataType
.TAB_DEFINE
.upper() + ' ') > -1:
854 ParseDefine(LineValue
, StartLine
, Table
, FileID
, Filename
, CurrentSection
, Model
, Arch
)
858 # At last parse other sections
860 ID
= Table
.Insert(Model
, LineValue
, Third
, Third
, '', '', Arch
, -1, FileID
, StartLine
, -1, StartLine
, -1, 0)
861 Records
.append([LineValue
, Arch
, StartLine
, ID
, Third
])
864 RecordSet
[Model
] = Records
866 ## GenMetaDatSectionItem
867 def GenMetaDatSectionItem(Key
, Value
, List
):
871 List
[Key
].append(Value
)
875 # Check whether the word is valid.
876 # <Word> ::= (a-zA-Z0-9_)(a-zA-Z0-9_-){0,} Alphanumeric characters with
878 # dash "-" and/or underscore "_" characters. No whitespace
879 # characters are permitted.
881 # @param Word: The word string need to be checked.
883 def IsValidWord(Word
):
887 # The first char should be alpha, _ or Digit.
889 if not Word
[0].isalnum() and \
890 not Word
[0] == '_' and \
891 not Word
[0].isdigit():
895 for Char
in Word
[1:]:
896 if (not Char
.isalpha()) and \
897 (not Char
.isdigit()) and \
902 if Char
== '.' and LastChar
== '.':