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 # 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
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.
18 from CommonDataClass
.DataClass
import *
19 from DataType
import *
23 # Search whole table to find all defined Macro and replaced them with the real values
25 def ParseDefineMacro2(Table
, RecordSets
, GlobalMacro
):
28 # Find all DEFINE macros in section [Header] and its section
30 SqlCommand
= """select Value1, Value2, BelongsToItem, StartLine, Arch from %s
32 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_DEFINE
)
33 RecordSet
= Table
.Exec(SqlCommand
)
34 for Record
in RecordSet
:
35 Macros
[Record
[0]] = Record
[1]
38 # Overrided by Global Macros
40 Macros
.update(GlobalMacro
)
45 for Value
in (v
for v
in RecordSets
.values() if v
):
47 Item
[0] = ReplaceMacro(Item
[0], Macros
)
51 # Search whole table to find all defined Macro and replaced them with the real values
53 def ParseDefineMacro(Table
, GlobalMacro
):
56 # Find all DEFINE macros
58 SqlCommand
= """select Value1, Value2, BelongsToItem, StartLine, Arch from %s
60 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_DEFINE
)
61 RecordSet
= Table
.Exec(SqlCommand
)
62 for Record
in RecordSet
:
63 #***************************************************************************************************************************************************
64 # The follow SqlCommand (expr replace) is not supported in Sqlite 3.3.4 which is used in Python 2.5 *
66 # SqlCommand = """update %s set Value1 = replace(Value1, '%s', '%s') *
67 # where ID in (select ID from %s *
69 # and Value1 like '%%%s%%' *
70 # and StartLine > %s *
72 # and Arch = '%s')""" % \ *
73 # (self.TblDsc.Table, Record[0], Record[1], self.TblDsc.Table, Record[2], Record[1], Record[3], Record[4]) *
74 #***************************************************************************************************************************************************
75 Macros
[Record
[0]] = Record
[1]
78 # Overrided by Global Macros
80 Macros
.update(GlobalMacro
)
83 # Found all defined macro and replaced
85 SqlCommand
= """select ID, Value1 from %s
87 and Value1 like '%%$(%%' and Value1 like '%%)%%'
88 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_DEFINE
)
89 FoundRecords
= Table
.Exec(SqlCommand
)
90 for FoundRecord
in FoundRecords
:
91 NewValue
= ReplaceMacro(FoundRecord
[1], Macros
)
92 SqlCommand
= """update %s set Value1 = '%s'
93 where ID = %s""" % (Table
.Table
, ConvertToSqlString2(NewValue
), FoundRecord
[0])
94 Table
.Exec(SqlCommand
)
98 # Search item of section [Defines] by name, return its values
100 # @param Table: The Table to be executed
101 # @param Name: The Name of item of section [Defines]
102 # @param Arch: The Arch of item of section [Defines]
104 # @retval RecordSet: A list of all matched records
106 def QueryDefinesItem(Table
, Name
, Arch
, BelongsToFile
):
107 SqlCommand
= """select Value2 from %s
111 and BelongsToFile = %s
112 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_HEADER
, ConvertToSqlString2(Name
), ConvertToSqlString2(Arch
), BelongsToFile
)
113 RecordSet
= Table
.Exec(SqlCommand
)
114 if len(RecordSet
) < 1:
115 SqlCommand
= """select Value2 from %s
119 and BelongsToFile = %s
120 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_HEADER
, ConvertToSqlString2(Name
), ConvertToSqlString2(TAB_ARCH_COMMON
.upper()), BelongsToFile
)
121 RecordSet
= Table
.Exec(SqlCommand
)
122 if len(RecordSet
) == 1:
123 if Name
== TAB_INF_DEFINES_LIBRARY_CLASS
:
124 return [RecordSet
[0][0]]
126 return GetSplitValueList(RecordSet
[0][0])
127 elif len(RecordSet
) < 1:
129 elif len(RecordSet
) > 1:
131 for Record
in RecordSet
:
132 if Name
== TAB_INF_DEFINES_LIBRARY_CLASS
:
133 RetVal
.append(Record
[0])
135 Items
= GetSplitValueList(Record
[0])
142 # Search item of section [Defines] by name, return its values
144 # @param Table: The Table to be executed
145 # @param Name: The Name of item of section [Defines]
146 # @param Arch: The Arch of item of section [Defines]
148 # @retval RecordSet: A list of all matched records
150 def QueryDefinesItem2(Table
, Arch
, BelongsToFile
):
151 SqlCommand
= """select Value1, Value2, StartLine from %s
154 and BelongsToFile = %s
155 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_HEADER
, ConvertToSqlString2(Arch
), BelongsToFile
)
156 RecordSet
= Table
.Exec(SqlCommand
)
157 if len(RecordSet
) < 1:
158 SqlCommand
= """select Value1, Value2, StartLine from %s
161 and BelongsToFile = %s
162 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_HEADER
, ConvertToSqlString2(TAB_ARCH_COMMON
), BelongsToFile
)
163 RecordSet
= Table
.Exec(SqlCommand
)
169 # Search all dsc item for a specific section
171 # @param Table: The Table to be executed
172 # @param Model: The type of section
174 # @retval RecordSet: A list of all matched records
176 def QueryDscItem(Table
, Model
, BelongsToItem
, BelongsToFile
):
177 SqlCommand
= """select Value1, Arch, StartLine, ID, Value2 from %s
179 and BelongsToItem = %s
180 and BelongsToFile = %s
181 and Enabled > -1""" % (Table
.Table
, Model
, BelongsToItem
, BelongsToFile
)
182 return Table
.Exec(SqlCommand
)
186 # Search all dec item for a specific section
188 # @param Table: The Table to be executed
189 # @param Model: The type of section
191 # @retval RecordSet: A list of all matched records
193 def QueryDecItem(Table
, Model
, BelongsToItem
):
194 SqlCommand
= """select Value1, Arch, StartLine, ID, Value2 from %s
196 and BelongsToItem = %s
197 and Enabled > -1""" % (Table
.Table
, Model
, BelongsToItem
)
198 return Table
.Exec(SqlCommand
)
202 # Search all dec item for a specific section
204 # @param Table: The Table to be executed
205 # @param Model: The type of section
207 # @retval RecordSet: A list of all matched records
209 def QueryInfItem(Table
, Model
, BelongsToItem
):
210 SqlCommand
= """select Value1, Arch, StartLine, ID, Value2 from %s
212 and BelongsToItem = %s
213 and Enabled > -1""" % (Table
.Table
, Model
, BelongsToItem
)
214 return Table
.Exec(SqlCommand
)
218 # Parse a string with format "[<Family>:]<ToolFlag>=Flag"
219 # Return (Family, ToolFlag, Flag)
221 # @param String: String with BuildOption statement
222 # @param File: The file which defines build option, used in error report
224 # @retval truple() A truple structure as (Family, ToolChain, Flag)
226 def GetBuildOption(String
, File
, LineNo
= -1):
227 (Family
, ToolChain
, Flag
) = ('', '', '')
228 if String
.find(TAB_EQUAL_SPLIT
) < 0:
229 RaiseParserError(String
, 'BuildOptions', File
, '[<Family>:]<ToolFlag>=Flag', LineNo
)
231 List
= GetSplitValueList(String
, TAB_EQUAL_SPLIT
, MaxSplit
= 1)
232 if List
[0].find(':') > -1:
233 Family
= List
[0][ : List
[0].find(':')].strip()
234 ToolChain
= List
[0][List
[0].find(':') + 1 : ].strip()
236 ToolChain
= List
[0].strip()
237 Flag
= List
[1].strip()
238 return (Family
, ToolChain
, Flag
)
242 # Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance>
244 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
245 # @param ContainerFile: The file which describes the library class, used for error report
247 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item
249 def GetLibraryClass(Item
, ContainerFile
, WorkspaceDir
, LineNo
= -1):
250 List
= GetSplitValueList(Item
[0])
251 SupMod
= SUP_MODULE_LIST_STRING
253 RaiseParserError(Item
[0], 'LibraryClasses', ContainerFile
, '<LibraryClassKeyWord>|<LibraryInstance>')
255 CheckFileType(List
[1], '.Inf', ContainerFile
, 'library class instance', Item
[0], LineNo
)
256 CheckFileExist(WorkspaceDir
, List
[1], ContainerFile
, 'LibraryClasses', Item
[0], LineNo
)
260 return (List
[0], List
[1], SupMod
)
264 # Get Library of Dsc as <LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]
266 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
267 # @param ContainerFile: The file which describes the library class, used for error report
269 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item
271 def GetLibraryClassOfInf(Item
, ContainerFile
, WorkspaceDir
, LineNo
= -1):
272 ItemList
= GetSplitValueList((Item
[0] + DataType
.TAB_VALUE_SPLIT
* 2))
273 SupMod
= SUP_MODULE_LIST_STRING
275 if len(ItemList
) > 5:
276 RaiseParserError(Item
[0], 'LibraryClasses', ContainerFile
, '<LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]')
278 CheckFileType(ItemList
[1], '.Inf', ContainerFile
, 'LibraryClasses', Item
[0], LineNo
)
279 CheckFileExist(WorkspaceDir
, ItemList
[1], ContainerFile
, 'LibraryClasses', Item
[0], LineNo
)
280 if ItemList
[2] != '':
281 CheckPcdTokenInfo(ItemList
[2], 'LibraryClasses', ContainerFile
, LineNo
)
285 return (ItemList
[0], ItemList
[1], ItemList
[2], SupMod
)
289 # Check if PcdTokenInfo is following <TokenSpaceGuidCName>.<PcdCName>
291 # @param TokenInfoString: String to be checked
292 # @param Section: Used for error report
293 # @param File: Used for error report
295 # @retval True PcdTokenInfo is in correct format
297 def CheckPcdTokenInfo(TokenInfoString
, Section
, File
, LineNo
= -1):
298 Format
= '<TokenSpaceGuidCName>.<PcdCName>'
299 if TokenInfoString
!= '' and TokenInfoString
is not None:
300 TokenInfoList
= GetSplitValueList(TokenInfoString
, TAB_SPLIT
)
301 if len(TokenInfoList
) == 2:
304 RaiseParserError(TokenInfoString
, Section
, File
, Format
, LineNo
)
308 # Get Pcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]
310 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]
311 # @param ContainerFile: The file which describes the pcd, used for error report
313 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)
315 def GetPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
316 TokenGuid
, TokenName
, Value
, MaximumDatumSize
, Token
= '', '', '', '', ''
317 List
= GetSplitValueList(Item
+ TAB_VALUE_SPLIT
* 2)
319 if len(List
) < 4 or len(List
) > 6:
320 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]', LineNo
)
323 MaximumDatumSize
= List
[2]
326 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
327 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], TAB_SPLIT
)
329 return (TokenName
, TokenGuid
, Value
, MaximumDatumSize
, Token
, Type
)
331 ## Get FeatureFlagPcd
333 # Get FeatureFlagPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
335 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
336 # @param ContainerFile: The file which describes the pcd, used for error report
338 # @retval (TokenInfo[1], TokenInfo[0], List[1], Type)
340 def GetFeatureFlagPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
341 TokenGuid
, TokenName
, Value
= '', '', ''
342 List
= GetSplitValueList(Item
)
344 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE', LineNo
)
347 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
348 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
350 return (TokenName
, TokenGuid
, Value
, Type
)
352 ## Get DynamicDefaultPcd
354 # Get DynamicDefaultPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]
356 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
357 # @param ContainerFile: The file which describes the pcd, used for error report
359 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)
361 def GetDynamicDefaultPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
362 TokenGuid
, TokenName
, Value
, DatumTyp
, MaxDatumSize
= '', '', '', '', ''
363 List
= GetSplitValueList(Item
+ TAB_VALUE_SPLIT
* 2)
364 if len(List
) < 4 or len(List
) > 8:
365 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]', LineNo
)
369 MaxDatumSize
= List
[3]
370 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
371 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], TAB_SPLIT
)
373 return (TokenName
, TokenGuid
, Value
, DatumTyp
, MaxDatumSize
, Type
)
377 # Get DynamicHiiPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]
379 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
380 # @param ContainerFile: The file which describes the pcd, used for error report
382 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], List[4], List[5], Type)
384 def GetDynamicHiiPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
385 TokenGuid
, TokenName
, L1
, L2
, L3
, L4
, L5
= '', '', '', '', '', '', ''
386 List
= GetSplitValueList(Item
+ TAB_VALUE_SPLIT
* 2)
387 if len(List
) < 6 or len(List
) > 8:
388 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]', LineNo
)
390 L1
, L2
, L3
, L4
, L5
= List
[1], List
[2], List
[3], List
[4], List
[5]
391 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
392 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
394 return (TokenName
, TokenGuid
, L1
, L2
, L3
, L4
, L5
, Type
)
398 # Get DynamicVpdPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]
400 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
401 # @param ContainerFile: The file which describes the pcd, used for error report
403 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], Type)
405 def GetDynamicVpdPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
406 TokenGuid
, TokenName
, L1
, L2
= '', '', '', ''
407 List
= GetSplitValueList(Item
+ TAB_VALUE_SPLIT
)
408 if len(List
) < 3 or len(List
) > 4:
409 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]', LineNo
)
411 L1
, L2
= List
[1], List
[2]
412 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
413 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
415 return (TokenName
, TokenGuid
, L1
, L2
, Type
)
419 # Parse block of the components defined in dsc file
420 # Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]
422 # @param Lines: The content to be parsed
423 # @param KeyValues: To store data after parsing
425 # @retval True Get component successfully
427 def GetComponent(Lines
, KeyValues
):
428 (findBlock
, findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, False, False)
430 LibraryClassItem
= []
438 # Ignore !include statement
440 if Line
.upper().find(TAB_INCLUDE
.upper() + ' ') > -1 or Line
.upper().find(TAB_DEFINE
+ ' ') > -1:
443 if findBlock
== False:
446 # find '{' at line tail
448 if Line
.endswith('{'):
450 ListItem
= CleanString(Line
.rsplit('{', 1)[0], DataType
.TAB_COMMENT_SPLIT
)
453 # Parse a block content
456 if Line
.find('<LibraryClasses>') != -1:
457 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (True, False, False, False, False, False, False)
459 if Line
.find('<BuildOptions>') != -1:
460 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, True, False, False, False, False, False)
462 if Line
.find('<PcdsFeatureFlag>') != -1:
463 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, True, False, False, False, False)
465 if Line
.find('<PcdsPatchableInModule>') != -1:
466 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, True, False, False, False)
468 if Line
.find('<PcdsFixedAtBuild>') != -1:
469 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, True, False, False)
471 if Line
.find('<PcdsDynamic>') != -1:
472 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, True, False)
474 if Line
.find('<PcdsDynamicEx>') != -1:
475 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, True)
477 if Line
.endswith('}'):
479 # find '}' at line tail
481 KeyValues
.append([ListItem
, LibraryClassItem
, BuildOption
, Pcd
])
482 (findBlock
, findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, False, False)
483 LibraryClassItem
, BuildOption
, Pcd
= [], [], []
488 LibraryClassItem
.append(Line
)
489 elif findBuildOption
:
490 BuildOption
.append(Line
)
491 elif findPcdsFeatureFlag
:
492 Pcd
.append((DataType
.TAB_PCDS_FEATURE_FLAG_NULL
, Line
))
493 elif findPcdsPatchableInModule
:
494 Pcd
.append((DataType
.TAB_PCDS_PATCHABLE_IN_MODULE_NULL
, Line
))
495 elif findPcdsFixedAtBuild
:
496 Pcd
.append((DataType
.TAB_PCDS_FIXED_AT_BUILD_NULL
, Line
))
497 elif findPcdsDynamic
:
498 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_DEFAULT_NULL
, Line
))
499 elif findPcdsDynamicEx
:
500 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
, Line
))
502 KeyValues
.append([ListItem
, [], [], []])
508 # Parse a string with format "InfFilename [EXEC = ExecFilename]"
509 # Return (InfFilename, ExecFilename)
511 # @param String: String with EXEC statement
513 # @retval truple() A pair as (InfFilename, ExecFilename)
518 if String
.find('EXEC') > -1:
519 InfFilename
= String
[ : String
.find('EXEC')].strip()
520 ExecFilename
= String
[String
.find('EXEC') + len('EXEC') : ].strip()
522 InfFilename
= String
.strip()
524 return (InfFilename
, ExecFilename
)
528 # Parse block of the components defined in dsc file
529 # Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]
531 # @param Lines: The content to be parsed
532 # @param Key: Reserved
533 # @param KeyValues: To store data after parsing
534 # @param CommentCharacter: Comment char, used to ignore comment content
536 # @retval True Get component successfully
538 def GetComponents(Lines
, Key
, KeyValues
, CommentCharacter
):
539 if Lines
.find(DataType
.TAB_SECTION_END
) > -1:
540 Lines
= Lines
.split(DataType
.TAB_SECTION_END
, 1)[1]
541 (findBlock
, findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, False, False)
543 LibraryClassItem
= []
547 LineList
= Lines
.split('\n')
548 for Line
in LineList
:
549 Line
= CleanString(Line
, CommentCharacter
)
550 if Line
is None or Line
== '':
553 if findBlock
== False:
556 # find '{' at line tail
558 if Line
.endswith('{'):
560 ListItem
= CleanString(Line
.rsplit('{', 1)[0], CommentCharacter
)
563 # Parse a block content
566 if Line
.find('<LibraryClasses>') != -1:
567 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (True, False, False, False, False, False, False)
569 if Line
.find('<BuildOptions>') != -1:
570 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, True, False, False, False, False, False)
572 if Line
.find('<PcdsFeatureFlag>') != -1:
573 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, True, False, False, False, False)
575 if Line
.find('<PcdsPatchableInModule>') != -1:
576 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, True, False, False, False)
578 if Line
.find('<PcdsFixedAtBuild>') != -1:
579 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, True, False, False)
581 if Line
.find('<PcdsDynamic>') != -1:
582 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, True, False)
584 if Line
.find('<PcdsDynamicEx>') != -1:
585 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, True)
587 if Line
.endswith('}'):
589 # find '}' at line tail
591 KeyValues
.append([ListItem
, LibraryClassItem
, BuildOption
, Pcd
])
592 (findBlock
, findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, False, False)
593 LibraryClassItem
, BuildOption
, Pcd
= [], [], []
598 LibraryClassItem
.append(Line
)
599 elif findBuildOption
:
600 BuildOption
.append(Line
)
601 elif findPcdsFeatureFlag
:
602 Pcd
.append((DataType
.TAB_PCDS_FEATURE_FLAG
, Line
))
603 elif findPcdsPatchableInModule
:
604 Pcd
.append((DataType
.TAB_PCDS_PATCHABLE_IN_MODULE
, Line
))
605 elif findPcdsFixedAtBuild
:
606 Pcd
.append((DataType
.TAB_PCDS_FIXED_AT_BUILD
, Line
))
607 elif findPcdsDynamic
:
608 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC
, Line
))
609 elif findPcdsDynamicEx
:
610 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_EX
, Line
))
612 KeyValues
.append([ListItem
, [], [], []])
618 # Get Source of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
620 # @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
621 # @param ContainerFile: The file which describes the library class, used for error report
623 # @retval (List[0], List[1], List[2], List[3], List[4])
625 def GetSource(Item
, ContainerFile
, FileRelativePath
, LineNo
= -1):
626 ItemNew
= Item
+ DataType
.TAB_VALUE_SPLIT
* 4
627 List
= GetSplitValueList(ItemNew
)
628 if len(List
) < 5 or len(List
) > 9:
629 RaiseParserError(Item
, 'Sources', ContainerFile
, '<Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]', LineNo
)
630 List
[0] = NormPath(List
[0])
631 CheckFileExist(FileRelativePath
, List
[0], ContainerFile
, 'Sources', Item
, LineNo
)
633 CheckPcdTokenInfo(List
[4], 'Sources', ContainerFile
, LineNo
)
635 return (List
[0], List
[1], List
[2], List
[3], List
[4])
639 # Get Binary of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
641 # @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
642 # @param ContainerFile: The file which describes the library class, used for error report
644 # @retval (List[0], List[1], List[2], List[3])
647 def GetBinary(Item
, ContainerFile
, FileRelativePath
, LineNo
= -1):
648 ItemNew
= Item
+ DataType
.TAB_VALUE_SPLIT
649 List
= GetSplitValueList(ItemNew
)
650 if len(List
) != 4 and len(List
) != 5:
651 RaiseParserError(Item
, 'Binaries', ContainerFile
, "<FileType>|<Filename>|<Target>[|<TokenSpaceGuidCName>.<PcdCName>]", LineNo
)
654 CheckPcdTokenInfo(List
[3], 'Binaries', ContainerFile
, LineNo
)
657 return (List
[0], List
[1], List
[2], List
[3])
659 return (List
[0], List
[1], List
[2], '')
661 return (List
[0], List
[1], '', '')
663 return (List
[0], '', '', '')
665 ## Get Guids/Protocols/Ppis
667 # Get Guids/Protocols/Ppis of Inf as <GuidCName>[|<PcdFeatureFlag>]
669 # @param Item: String as <GuidCName>[|<PcdFeatureFlag>]
670 # @param Type: Type of parsing string
671 # @param ContainerFile: The file which describes the library class, used for error report
673 # @retval (List[0], List[1])
675 def GetGuidsProtocolsPpisOfInf(Item
, Type
, ContainerFile
, LineNo
= -1):
676 ItemNew
= Item
+ TAB_VALUE_SPLIT
677 List
= GetSplitValueList(ItemNew
)
679 CheckPcdTokenInfo(List
[1], Type
, ContainerFile
, LineNo
)
681 return (List
[0], List
[1])
683 ## Get Guids/Protocols/Ppis
685 # Get Guids/Protocols/Ppis of Dec as <GuidCName>=<GuidValue>
687 # @param Item: String as <GuidCName>=<GuidValue>
688 # @param Type: Type of parsing string
689 # @param ContainerFile: The file which describes the library class, used for error report
691 # @retval (List[0], List[1])
693 def GetGuidsProtocolsPpisOfDec(Item
, Type
, ContainerFile
, LineNo
= -1):
694 List
= GetSplitValueList(Item
, DataType
.TAB_EQUAL_SPLIT
)
696 RaiseParserError(Item
, Type
, ContainerFile
, '<CName>=<GuidValue>', LineNo
)
698 return (List
[0], List
[1])
702 # Get Package of Inf as <PackagePath>[|<PcdFeatureFlag>]
704 # @param Item: String as <PackagePath>[|<PcdFeatureFlag>]
705 # @param Type: Type of parsing string
706 # @param ContainerFile: The file which describes the library class, used for error report
708 # @retval (List[0], List[1])
710 def GetPackage(Item
, ContainerFile
, FileRelativePath
, LineNo
= -1):
711 ItemNew
= Item
+ TAB_VALUE_SPLIT
712 List
= GetSplitValueList(ItemNew
)
713 CheckFileType(List
[0], '.Dec', ContainerFile
, 'package', List
[0], LineNo
)
714 CheckFileExist(FileRelativePath
, List
[0], ContainerFile
, 'Packages', List
[0], LineNo
)
717 CheckPcdTokenInfo(List
[1], 'Packages', ContainerFile
, LineNo
)
719 return (List
[0], List
[1])
721 ## Get Pcd Values of Inf
723 # Get Pcd of Inf as <TokenSpaceGuidCName>.<PcdCName>[|<Value>]
725 # @param Item: The string describes pcd
726 # @param Type: The type of Pcd
727 # @param File: The file which describes the pcd, used for error report
729 # @retval (TokenSpcCName, TokenCName, Value, ItemType) Formatted Pcd Item
731 def GetPcdOfInf(Item
, Type
, File
, LineNo
):
732 Format
= '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]'
733 TokenGuid
, TokenName
, Value
, InfType
= '', '', '', ''
735 if Type
== TAB_PCDS_FIXED_AT_BUILD
:
736 InfType
= TAB_INF_FIXED_PCD
737 elif Type
== TAB_PCDS_PATCHABLE_IN_MODULE
:
738 InfType
= TAB_INF_PATCH_PCD
739 elif Type
== TAB_PCDS_FEATURE_FLAG
:
740 InfType
= TAB_INF_FEATURE_PCD
741 elif Type
== TAB_PCDS_DYNAMIC_EX
:
742 InfType
= TAB_INF_PCD_EX
743 elif Type
== TAB_PCDS_DYNAMIC
:
744 InfType
= TAB_INF_PCD
745 List
= GetSplitValueList(Item
+ DataType
.TAB_VALUE_SPLIT
)
746 if len(List
) < 2 or len(List
) > 3:
747 RaiseParserError(Item
, InfType
, File
, Format
, LineNo
)
750 TokenInfo
= GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
751 if len(TokenInfo
) != 2:
752 RaiseParserError(Item
, InfType
, File
, Format
, LineNo
)
754 TokenGuid
= TokenInfo
[0]
755 TokenName
= TokenInfo
[1]
757 return (TokenGuid
, TokenName
, Value
, Type
)
760 ## Get Pcd Values of Dec
762 # Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
763 # @retval (TokenSpcCName, TokenCName, Value, DatumType, Token, ItemType) Formatted Pcd Item
765 def GetPcdOfDec(Item
, Type
, File
, LineNo
= -1):
766 Format
= '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>'
767 TokenGuid
, TokenName
, Value
, DatumType
, Token
= '', '', '', '', ''
768 List
= GetSplitValueList(Item
)
770 RaiseParserError(Item
, 'Pcds' + Type
, File
, Format
, LineNo
)
775 TokenInfo
= GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
776 if len(TokenInfo
) != 2:
777 RaiseParserError(Item
, 'Pcds' + Type
, File
, Format
, LineNo
)
779 TokenGuid
= TokenInfo
[0]
780 TokenName
= TokenInfo
[1]
782 return (TokenGuid
, TokenName
, Value
, DatumType
, Token
, Type
)
784 ## Parse DEFINE statement
788 # 1. Insert a record into TblDec
790 # Value2: Macro Value
792 def ParseDefine(LineValue
, StartLine
, Table
, FileID
, Filename
, SectionName
, SectionModel
, Arch
):
793 EdkLogger
.debug(EdkLogger
.DEBUG_2
, "DEFINE statement '%s' found in section %s" % (LineValue
, SectionName
))
794 Define
= GetSplitValueList(CleanString(LineValue
[LineValue
.upper().find(DataType
.TAB_DEFINE
.upper() + ' ') + len(DataType
.TAB_DEFINE
+ ' ') : ]), TAB_EQUAL_SPLIT
, 1)
795 Table
.Insert(MODEL_META_DATA_DEFINE
, Define
[0], Define
[1], '', '', '', Arch
, SectionModel
, FileID
, StartLine
, -1, StartLine
, -1, 0)
797 ## InsertSectionItems
799 # Insert item data of a section to a dict
801 def InsertSectionItems(Model
, CurrentSection
, SectionItemList
, ArchList
, ThirdList
, RecordSet
):
802 # Insert each item data of a section
803 for Index
in range(0, len(ArchList
)):
804 Arch
= ArchList
[Index
]
805 Third
= ThirdList
[Index
]
807 Arch
= TAB_ARCH_COMMON
809 Records
= RecordSet
[Model
]
810 for SectionItem
in SectionItemList
:
811 BelongsToItem
, EndLine
, EndColumn
= -1, -1, -1
812 LineValue
, StartLine
, EndLine
, Comment
= SectionItem
[0], SectionItem
[1], SectionItem
[1], SectionItem
[2]
814 EdkLogger
.debug(4, "Parsing %s ..." %LineValue
)
815 # And then parse DEFINE statement
816 if LineValue
.upper().find(DataType
.TAB_DEFINE
.upper() + ' ') > -1:
819 # At last parse other sections
821 Records
.append([LineValue
, Arch
, StartLine
, ID
, Third
, Comment
])
824 RecordSet
[Model
] = Records
826 ## Insert records to database
828 # Insert item data of a section to database
829 # @param Table: The Table to be inserted
830 # @param FileID: The ID of belonging file
831 # @param Filename: The name of belonging file
832 # @param CurrentSection: The name of currect section
833 # @param SectionItemList: A list of items of the section
834 # @param ArchList: A list of arches
835 # @param ThirdList: A list of third parameters, ModuleType for LibraryClass and SkuId for Dynamic Pcds
836 # @param IfDefList: A list of all conditional statements
837 # @param RecordSet: A dict of all parsed records
839 def InsertSectionItemsIntoDatabase(Table
, FileID
, Filename
, Model
, CurrentSection
, SectionItemList
, ArchList
, ThirdList
, IfDefList
, RecordSet
):
841 # Insert each item data of a section
843 for Index
in range(0, len(ArchList
)):
844 Arch
= ArchList
[Index
]
845 Third
= ThirdList
[Index
]
847 Arch
= TAB_ARCH_COMMON
849 Records
= RecordSet
[Model
]
850 for SectionItem
in SectionItemList
:
851 BelongsToItem
, EndLine
, EndColumn
= -1, -1, -1
852 LineValue
, StartLine
, EndLine
= SectionItem
[0], SectionItem
[1], SectionItem
[1]
854 EdkLogger
.debug(4, "Parsing %s ..." %LineValue
)
856 # And then parse DEFINE statement
858 if LineValue
.upper().find(DataType
.TAB_DEFINE
.upper() + ' ') > -1:
859 ParseDefine(LineValue
, StartLine
, Table
, FileID
, Filename
, CurrentSection
, Model
, Arch
)
863 # At last parse other sections
865 ID
= Table
.Insert(Model
, LineValue
, Third
, Third
, '', '', Arch
, -1, FileID
, StartLine
, -1, StartLine
, -1, 0)
866 Records
.append([LineValue
, Arch
, StartLine
, ID
, Third
])
869 RecordSet
[Model
] = Records
871 ## GenMetaDatSectionItem
872 def GenMetaDatSectionItem(Key
, Value
, List
):
876 List
[Key
].append(Value
)
880 # Check whether the word is valid.
881 # <Word> ::= (a-zA-Z0-9_)(a-zA-Z0-9_-){0,} Alphanumeric characters with
883 # dash "-" and/or underscore "_" characters. No whitespace
884 # characters are permitted.
886 # @param Word: The word string need to be checked.
888 def IsValidWord(Word
):
892 # The first char should be alpha, _ or Digit.
894 if not Word
[0].isalnum() and \
895 not Word
[0] == '_' and \
896 not Word
[0].isdigit():
900 for Char
in Word
[1:]:
901 if (not Char
.isalpha()) and \
902 (not Char
.isdigit()) and \
907 if Char
== '.' and LastChar
== '.':