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.
17 from __future__
import absolute_import
18 from .StringUtils
import *
19 from CommonDataClass
.DataClass
import *
20 from .DataType
import *
24 # Search whole table to find all defined Macro and replaced them with the real values
26 def ParseDefineMacro2(Table
, RecordSets
, GlobalMacro
):
29 # Find all DEFINE macros in section [Header] and its section
31 SqlCommand
= """select Value1, Value2, BelongsToItem, StartLine, Arch from %s
33 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_DEFINE
)
34 RecordSet
= Table
.Exec(SqlCommand
)
35 for Record
in RecordSet
:
36 Macros
[Record
[0]] = Record
[1]
39 # Overrided by Global Macros
41 Macros
.update(GlobalMacro
)
46 for Value
in (v
for v
in RecordSets
.values() if v
):
48 Item
[0] = ReplaceMacro(Item
[0], Macros
)
52 # Search whole table to find all defined Macro and replaced them with the real values
54 def ParseDefineMacro(Table
, GlobalMacro
):
57 # Find all DEFINE macros
59 SqlCommand
= """select Value1, Value2, BelongsToItem, StartLine, Arch from %s
61 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_DEFINE
)
62 RecordSet
= Table
.Exec(SqlCommand
)
63 for Record
in RecordSet
:
64 #***************************************************************************************************************************************************
65 # The follow SqlCommand (expr replace) is not supported in Sqlite 3.3.4 which is used in Python 2.5 *
67 # SqlCommand = """update %s set Value1 = replace(Value1, '%s', '%s') *
68 # where ID in (select ID from %s *
70 # and Value1 like '%%%s%%' *
71 # and StartLine > %s *
73 # and Arch = '%s')""" % \ *
74 # (self.TblDsc.Table, Record[0], Record[1], self.TblDsc.Table, Record[2], Record[1], Record[3], Record[4]) *
75 #***************************************************************************************************************************************************
76 Macros
[Record
[0]] = Record
[1]
79 # Overrided by Global Macros
81 Macros
.update(GlobalMacro
)
84 # Found all defined macro and replaced
86 SqlCommand
= """select ID, Value1 from %s
88 and Value1 like '%%$(%%' and Value1 like '%%)%%'
89 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_DEFINE
)
90 FoundRecords
= Table
.Exec(SqlCommand
)
91 for FoundRecord
in FoundRecords
:
92 NewValue
= ReplaceMacro(FoundRecord
[1], Macros
)
93 SqlCommand
= """update %s set Value1 = '%s'
94 where ID = %s""" % (Table
.Table
, ConvertToSqlString2(NewValue
), FoundRecord
[0])
95 Table
.Exec(SqlCommand
)
99 # Search item of section [Defines] by name, return its values
101 # @param Table: The Table to be executed
102 # @param Name: The Name of item of section [Defines]
103 # @param Arch: The Arch of item of section [Defines]
105 # @retval RecordSet: A list of all matched records
107 def QueryDefinesItem(Table
, Name
, Arch
, BelongsToFile
):
108 SqlCommand
= """select Value2 from %s
112 and BelongsToFile = %s
113 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_HEADER
, ConvertToSqlString2(Name
), ConvertToSqlString2(Arch
), BelongsToFile
)
114 RecordSet
= Table
.Exec(SqlCommand
)
115 if len(RecordSet
) < 1:
116 SqlCommand
= """select Value2 from %s
120 and BelongsToFile = %s
121 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_HEADER
, ConvertToSqlString2(Name
), ConvertToSqlString2(TAB_ARCH_COMMON
.upper()), BelongsToFile
)
122 RecordSet
= Table
.Exec(SqlCommand
)
123 if len(RecordSet
) == 1:
124 if Name
== TAB_INF_DEFINES_LIBRARY_CLASS
:
125 return [RecordSet
[0][0]]
127 return GetSplitValueList(RecordSet
[0][0])
128 elif len(RecordSet
) < 1:
130 elif len(RecordSet
) > 1:
132 for Record
in RecordSet
:
133 if Name
== TAB_INF_DEFINES_LIBRARY_CLASS
:
134 RetVal
.append(Record
[0])
136 Items
= GetSplitValueList(Record
[0])
143 # Search item of section [Defines] by name, return its values
145 # @param Table: The Table to be executed
146 # @param Name: The Name of item of section [Defines]
147 # @param Arch: The Arch of item of section [Defines]
149 # @retval RecordSet: A list of all matched records
151 def QueryDefinesItem2(Table
, Arch
, BelongsToFile
):
152 SqlCommand
= """select Value1, Value2, StartLine from %s
155 and BelongsToFile = %s
156 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_HEADER
, ConvertToSqlString2(Arch
), BelongsToFile
)
157 RecordSet
= Table
.Exec(SqlCommand
)
158 if len(RecordSet
) < 1:
159 SqlCommand
= """select Value1, Value2, StartLine from %s
162 and BelongsToFile = %s
163 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_HEADER
, ConvertToSqlString2(TAB_ARCH_COMMON
), BelongsToFile
)
164 RecordSet
= Table
.Exec(SqlCommand
)
170 # Search all dsc item for a specific section
172 # @param Table: The Table to be executed
173 # @param Model: The type of section
175 # @retval RecordSet: A list of all matched records
177 def QueryDscItem(Table
, Model
, BelongsToItem
, BelongsToFile
):
178 SqlCommand
= """select Value1, Arch, StartLine, ID, Value2 from %s
180 and BelongsToItem = %s
181 and BelongsToFile = %s
182 and Enabled > -1""" % (Table
.Table
, Model
, BelongsToItem
, BelongsToFile
)
183 return Table
.Exec(SqlCommand
)
187 # Search all dec item for a specific section
189 # @param Table: The Table to be executed
190 # @param Model: The type of section
192 # @retval RecordSet: A list of all matched records
194 def QueryDecItem(Table
, Model
, BelongsToItem
):
195 SqlCommand
= """select Value1, Arch, StartLine, ID, Value2 from %s
197 and BelongsToItem = %s
198 and Enabled > -1""" % (Table
.Table
, Model
, BelongsToItem
)
199 return Table
.Exec(SqlCommand
)
203 # Search all dec item for a specific section
205 # @param Table: The Table to be executed
206 # @param Model: The type of section
208 # @retval RecordSet: A list of all matched records
210 def QueryInfItem(Table
, Model
, BelongsToItem
):
211 SqlCommand
= """select Value1, Arch, StartLine, ID, Value2 from %s
213 and BelongsToItem = %s
214 and Enabled > -1""" % (Table
.Table
, Model
, BelongsToItem
)
215 return Table
.Exec(SqlCommand
)
219 # Parse a string with format "[<Family>:]<ToolFlag>=Flag"
220 # Return (Family, ToolFlag, Flag)
222 # @param String: String with BuildOption statement
223 # @param File: The file which defines build option, used in error report
225 # @retval truple() A truple structure as (Family, ToolChain, Flag)
227 def GetBuildOption(String
, File
, LineNo
= -1):
228 (Family
, ToolChain
, Flag
) = ('', '', '')
229 if String
.find(TAB_EQUAL_SPLIT
) < 0:
230 RaiseParserError(String
, 'BuildOptions', File
, '[<Family>:]<ToolFlag>=Flag', LineNo
)
232 List
= GetSplitValueList(String
, TAB_EQUAL_SPLIT
, MaxSplit
= 1)
233 if List
[0].find(':') > -1:
234 Family
= List
[0][ : List
[0].find(':')].strip()
235 ToolChain
= List
[0][List
[0].find(':') + 1 : ].strip()
237 ToolChain
= List
[0].strip()
238 Flag
= List
[1].strip()
239 return (Family
, ToolChain
, Flag
)
243 # Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance>
245 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
246 # @param ContainerFile: The file which describes the library class, used for error report
248 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item
250 def GetLibraryClass(Item
, ContainerFile
, WorkspaceDir
, LineNo
= -1):
251 List
= GetSplitValueList(Item
[0])
252 SupMod
= SUP_MODULE_LIST_STRING
254 RaiseParserError(Item
[0], 'LibraryClasses', ContainerFile
, '<LibraryClassKeyWord>|<LibraryInstance>')
256 CheckFileType(List
[1], '.Inf', ContainerFile
, 'library class instance', Item
[0], LineNo
)
257 CheckFileExist(WorkspaceDir
, List
[1], ContainerFile
, 'LibraryClasses', Item
[0], LineNo
)
261 return (List
[0], List
[1], SupMod
)
265 # Get Library of Dsc as <LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]
267 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
268 # @param ContainerFile: The file which describes the library class, used for error report
270 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item
272 def GetLibraryClassOfInf(Item
, ContainerFile
, WorkspaceDir
, LineNo
= -1):
273 ItemList
= GetSplitValueList((Item
[0] + DataType
.TAB_VALUE_SPLIT
* 2))
274 SupMod
= SUP_MODULE_LIST_STRING
276 if len(ItemList
) > 5:
277 RaiseParserError(Item
[0], 'LibraryClasses', ContainerFile
, '<LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]')
279 CheckFileType(ItemList
[1], '.Inf', ContainerFile
, 'LibraryClasses', Item
[0], LineNo
)
280 CheckFileExist(WorkspaceDir
, ItemList
[1], ContainerFile
, 'LibraryClasses', Item
[0], LineNo
)
281 if ItemList
[2] != '':
282 CheckPcdTokenInfo(ItemList
[2], 'LibraryClasses', ContainerFile
, LineNo
)
286 return (ItemList
[0], ItemList
[1], ItemList
[2], SupMod
)
290 # Check if PcdTokenInfo is following <TokenSpaceGuidCName>.<PcdCName>
292 # @param TokenInfoString: String to be checked
293 # @param Section: Used for error report
294 # @param File: Used for error report
296 # @retval True PcdTokenInfo is in correct format
298 def CheckPcdTokenInfo(TokenInfoString
, Section
, File
, LineNo
= -1):
299 Format
= '<TokenSpaceGuidCName>.<PcdCName>'
300 if TokenInfoString
!= '' and TokenInfoString
is not None:
301 TokenInfoList
= GetSplitValueList(TokenInfoString
, TAB_SPLIT
)
302 if len(TokenInfoList
) == 2:
305 RaiseParserError(TokenInfoString
, Section
, File
, Format
, LineNo
)
309 # Get Pcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]
311 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]
312 # @param ContainerFile: The file which describes the pcd, used for error report
314 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)
316 def GetPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
317 TokenGuid
, TokenName
, Value
, MaximumDatumSize
, Token
= '', '', '', '', ''
318 List
= GetSplitValueList(Item
+ TAB_VALUE_SPLIT
* 2)
320 if len(List
) < 4 or len(List
) > 6:
321 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]', LineNo
)
324 MaximumDatumSize
= List
[2]
327 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
328 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], TAB_SPLIT
)
330 return (TokenName
, TokenGuid
, Value
, MaximumDatumSize
, Token
, Type
)
332 ## Get FeatureFlagPcd
334 # Get FeatureFlagPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
336 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
337 # @param ContainerFile: The file which describes the pcd, used for error report
339 # @retval (TokenInfo[1], TokenInfo[0], List[1], Type)
341 def GetFeatureFlagPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
342 TokenGuid
, TokenName
, Value
= '', '', ''
343 List
= GetSplitValueList(Item
)
345 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE', LineNo
)
348 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
349 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
351 return (TokenName
, TokenGuid
, Value
, Type
)
353 ## Get DynamicDefaultPcd
355 # Get DynamicDefaultPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]
357 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
358 # @param ContainerFile: The file which describes the pcd, used for error report
360 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)
362 def GetDynamicDefaultPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
363 TokenGuid
, TokenName
, Value
, DatumTyp
, MaxDatumSize
= '', '', '', '', ''
364 List
= GetSplitValueList(Item
+ TAB_VALUE_SPLIT
* 2)
365 if len(List
) < 4 or len(List
) > 8:
366 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]', LineNo
)
370 MaxDatumSize
= List
[3]
371 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
372 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], TAB_SPLIT
)
374 return (TokenName
, TokenGuid
, Value
, DatumTyp
, MaxDatumSize
, Type
)
378 # Get DynamicHiiPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]
380 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
381 # @param ContainerFile: The file which describes the pcd, used for error report
383 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], List[4], List[5], Type)
385 def GetDynamicHiiPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
386 TokenGuid
, TokenName
, L1
, L2
, L3
, L4
, L5
= '', '', '', '', '', '', ''
387 List
= GetSplitValueList(Item
+ TAB_VALUE_SPLIT
* 2)
388 if len(List
) < 6 or len(List
) > 8:
389 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]', LineNo
)
391 L1
, L2
, L3
, L4
, L5
= List
[1], List
[2], List
[3], List
[4], List
[5]
392 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
393 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
395 return (TokenName
, TokenGuid
, L1
, L2
, L3
, L4
, L5
, Type
)
399 # Get DynamicVpdPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]
401 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
402 # @param ContainerFile: The file which describes the pcd, used for error report
404 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], Type)
406 def GetDynamicVpdPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
407 TokenGuid
, TokenName
, L1
, L2
= '', '', '', ''
408 List
= GetSplitValueList(Item
+ TAB_VALUE_SPLIT
)
409 if len(List
) < 3 or len(List
) > 4:
410 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]', LineNo
)
412 L1
, L2
= List
[1], List
[2]
413 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
414 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
416 return (TokenName
, TokenGuid
, L1
, L2
, Type
)
420 # Parse block of the components defined in dsc file
421 # Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]
423 # @param Lines: The content to be parsed
424 # @param KeyValues: To store data after parsing
426 # @retval True Get component successfully
428 def GetComponent(Lines
, KeyValues
):
429 (findBlock
, findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, False, False)
431 LibraryClassItem
= []
439 # Ignore !include statement
441 if Line
.upper().find(TAB_INCLUDE
.upper() + ' ') > -1 or Line
.upper().find(TAB_DEFINE
+ ' ') > -1:
444 if findBlock
== False:
447 # find '{' at line tail
449 if Line
.endswith('{'):
451 ListItem
= CleanString(Line
.rsplit('{', 1)[0], DataType
.TAB_COMMENT_SPLIT
)
454 # Parse a block content
457 if Line
.find('<LibraryClasses>') != -1:
458 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (True, False, False, False, False, False, False)
460 if Line
.find('<BuildOptions>') != -1:
461 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, True, False, False, False, False, False)
463 if Line
.find('<PcdsFeatureFlag>') != -1:
464 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, True, False, False, False, False)
466 if Line
.find('<PcdsPatchableInModule>') != -1:
467 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, True, False, False, False)
469 if Line
.find('<PcdsFixedAtBuild>') != -1:
470 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, True, False, False)
472 if Line
.find('<PcdsDynamic>') != -1:
473 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, True, False)
475 if Line
.find('<PcdsDynamicEx>') != -1:
476 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, True)
478 if Line
.endswith('}'):
480 # find '}' at line tail
482 KeyValues
.append([ListItem
, LibraryClassItem
, BuildOption
, Pcd
])
483 (findBlock
, findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, False, False)
484 LibraryClassItem
, BuildOption
, Pcd
= [], [], []
489 LibraryClassItem
.append(Line
)
490 elif findBuildOption
:
491 BuildOption
.append(Line
)
492 elif findPcdsFeatureFlag
:
493 Pcd
.append((DataType
.TAB_PCDS_FEATURE_FLAG_NULL
, Line
))
494 elif findPcdsPatchableInModule
:
495 Pcd
.append((DataType
.TAB_PCDS_PATCHABLE_IN_MODULE_NULL
, Line
))
496 elif findPcdsFixedAtBuild
:
497 Pcd
.append((DataType
.TAB_PCDS_FIXED_AT_BUILD_NULL
, Line
))
498 elif findPcdsDynamic
:
499 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_DEFAULT_NULL
, Line
))
500 elif findPcdsDynamicEx
:
501 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
, Line
))
503 KeyValues
.append([ListItem
, [], [], []])
509 # Parse a string with format "InfFilename [EXEC = ExecFilename]"
510 # Return (InfFilename, ExecFilename)
512 # @param String: String with EXEC statement
514 # @retval truple() A pair as (InfFilename, ExecFilename)
519 if String
.find('EXEC') > -1:
520 InfFilename
= String
[ : String
.find('EXEC')].strip()
521 ExecFilename
= String
[String
.find('EXEC') + len('EXEC') : ].strip()
523 InfFilename
= String
.strip()
525 return (InfFilename
, ExecFilename
)
529 # Parse block of the components defined in dsc file
530 # Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]
532 # @param Lines: The content to be parsed
533 # @param Key: Reserved
534 # @param KeyValues: To store data after parsing
535 # @param CommentCharacter: Comment char, used to ignore comment content
537 # @retval True Get component successfully
539 def GetComponents(Lines
, Key
, KeyValues
, CommentCharacter
):
540 if Lines
.find(DataType
.TAB_SECTION_END
) > -1:
541 Lines
= Lines
.split(DataType
.TAB_SECTION_END
, 1)[1]
542 (findBlock
, findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, False, False)
544 LibraryClassItem
= []
548 LineList
= Lines
.split('\n')
549 for Line
in LineList
:
550 Line
= CleanString(Line
, CommentCharacter
)
551 if Line
is None or Line
== '':
554 if findBlock
== False:
557 # find '{' at line tail
559 if Line
.endswith('{'):
561 ListItem
= CleanString(Line
.rsplit('{', 1)[0], CommentCharacter
)
564 # Parse a block content
567 if Line
.find('<LibraryClasses>') != -1:
568 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (True, False, False, False, False, False, False)
570 if Line
.find('<BuildOptions>') != -1:
571 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, True, False, False, False, False, False)
573 if Line
.find('<PcdsFeatureFlag>') != -1:
574 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, True, False, False, False, False)
576 if Line
.find('<PcdsPatchableInModule>') != -1:
577 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, True, False, False, False)
579 if Line
.find('<PcdsFixedAtBuild>') != -1:
580 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, True, False, False)
582 if Line
.find('<PcdsDynamic>') != -1:
583 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, True, False)
585 if Line
.find('<PcdsDynamicEx>') != -1:
586 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, True)
588 if Line
.endswith('}'):
590 # find '}' at line tail
592 KeyValues
.append([ListItem
, LibraryClassItem
, BuildOption
, Pcd
])
593 (findBlock
, findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, False, False)
594 LibraryClassItem
, BuildOption
, Pcd
= [], [], []
599 LibraryClassItem
.append(Line
)
600 elif findBuildOption
:
601 BuildOption
.append(Line
)
602 elif findPcdsFeatureFlag
:
603 Pcd
.append((DataType
.TAB_PCDS_FEATURE_FLAG
, Line
))
604 elif findPcdsPatchableInModule
:
605 Pcd
.append((DataType
.TAB_PCDS_PATCHABLE_IN_MODULE
, Line
))
606 elif findPcdsFixedAtBuild
:
607 Pcd
.append((DataType
.TAB_PCDS_FIXED_AT_BUILD
, Line
))
608 elif findPcdsDynamic
:
609 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC
, Line
))
610 elif findPcdsDynamicEx
:
611 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_EX
, Line
))
613 KeyValues
.append([ListItem
, [], [], []])
619 # Get Source of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
621 # @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
622 # @param ContainerFile: The file which describes the library class, used for error report
624 # @retval (List[0], List[1], List[2], List[3], List[4])
626 def GetSource(Item
, ContainerFile
, FileRelativePath
, LineNo
= -1):
627 ItemNew
= Item
+ DataType
.TAB_VALUE_SPLIT
* 4
628 List
= GetSplitValueList(ItemNew
)
629 if len(List
) < 5 or len(List
) > 9:
630 RaiseParserError(Item
, 'Sources', ContainerFile
, '<Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]', LineNo
)
631 List
[0] = NormPath(List
[0])
632 CheckFileExist(FileRelativePath
, List
[0], ContainerFile
, 'Sources', Item
, LineNo
)
634 CheckPcdTokenInfo(List
[4], 'Sources', ContainerFile
, LineNo
)
636 return (List
[0], List
[1], List
[2], List
[3], List
[4])
640 # Get Binary of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
642 # @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
643 # @param ContainerFile: The file which describes the library class, used for error report
645 # @retval (List[0], List[1], List[2], List[3])
648 def GetBinary(Item
, ContainerFile
, FileRelativePath
, LineNo
= -1):
649 ItemNew
= Item
+ DataType
.TAB_VALUE_SPLIT
650 List
= GetSplitValueList(ItemNew
)
651 if len(List
) != 4 and len(List
) != 5:
652 RaiseParserError(Item
, 'Binaries', ContainerFile
, "<FileType>|<Filename>|<Target>[|<TokenSpaceGuidCName>.<PcdCName>]", LineNo
)
655 CheckPcdTokenInfo(List
[3], 'Binaries', ContainerFile
, LineNo
)
658 return (List
[0], List
[1], List
[2], List
[3])
660 return (List
[0], List
[1], List
[2], '')
662 return (List
[0], List
[1], '', '')
664 return (List
[0], '', '', '')
666 ## Get Guids/Protocols/Ppis
668 # Get Guids/Protocols/Ppis of Inf as <GuidCName>[|<PcdFeatureFlag>]
670 # @param Item: String as <GuidCName>[|<PcdFeatureFlag>]
671 # @param Type: Type of parsing string
672 # @param ContainerFile: The file which describes the library class, used for error report
674 # @retval (List[0], List[1])
676 def GetGuidsProtocolsPpisOfInf(Item
, Type
, ContainerFile
, LineNo
= -1):
677 ItemNew
= Item
+ TAB_VALUE_SPLIT
678 List
= GetSplitValueList(ItemNew
)
680 CheckPcdTokenInfo(List
[1], Type
, ContainerFile
, LineNo
)
682 return (List
[0], List
[1])
684 ## Get Guids/Protocols/Ppis
686 # Get Guids/Protocols/Ppis of Dec as <GuidCName>=<GuidValue>
688 # @param Item: String as <GuidCName>=<GuidValue>
689 # @param Type: Type of parsing string
690 # @param ContainerFile: The file which describes the library class, used for error report
692 # @retval (List[0], List[1])
694 def GetGuidsProtocolsPpisOfDec(Item
, Type
, ContainerFile
, LineNo
= -1):
695 List
= GetSplitValueList(Item
, DataType
.TAB_EQUAL_SPLIT
)
697 RaiseParserError(Item
, Type
, ContainerFile
, '<CName>=<GuidValue>', LineNo
)
699 return (List
[0], List
[1])
703 # Get Package of Inf as <PackagePath>[|<PcdFeatureFlag>]
705 # @param Item: String as <PackagePath>[|<PcdFeatureFlag>]
706 # @param Type: Type of parsing string
707 # @param ContainerFile: The file which describes the library class, used for error report
709 # @retval (List[0], List[1])
711 def GetPackage(Item
, ContainerFile
, FileRelativePath
, LineNo
= -1):
712 ItemNew
= Item
+ TAB_VALUE_SPLIT
713 List
= GetSplitValueList(ItemNew
)
714 CheckFileType(List
[0], '.Dec', ContainerFile
, 'package', List
[0], LineNo
)
715 CheckFileExist(FileRelativePath
, List
[0], ContainerFile
, 'Packages', List
[0], LineNo
)
718 CheckPcdTokenInfo(List
[1], 'Packages', ContainerFile
, LineNo
)
720 return (List
[0], List
[1])
722 ## Get Pcd Values of Inf
724 # Get Pcd of Inf as <TokenSpaceGuidCName>.<PcdCName>[|<Value>]
726 # @param Item: The string describes pcd
727 # @param Type: The type of Pcd
728 # @param File: The file which describes the pcd, used for error report
730 # @retval (TokenSpcCName, TokenCName, Value, ItemType) Formatted Pcd Item
732 def GetPcdOfInf(Item
, Type
, File
, LineNo
):
733 Format
= '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]'
734 TokenGuid
, TokenName
, Value
, InfType
= '', '', '', ''
736 if Type
== TAB_PCDS_FIXED_AT_BUILD
:
737 InfType
= TAB_INF_FIXED_PCD
738 elif Type
== TAB_PCDS_PATCHABLE_IN_MODULE
:
739 InfType
= TAB_INF_PATCH_PCD
740 elif Type
== TAB_PCDS_FEATURE_FLAG
:
741 InfType
= TAB_INF_FEATURE_PCD
742 elif Type
== TAB_PCDS_DYNAMIC_EX
:
743 InfType
= TAB_INF_PCD_EX
744 elif Type
== TAB_PCDS_DYNAMIC
:
745 InfType
= TAB_INF_PCD
746 List
= GetSplitValueList(Item
+ DataType
.TAB_VALUE_SPLIT
)
747 if len(List
) < 2 or len(List
) > 3:
748 RaiseParserError(Item
, InfType
, File
, Format
, LineNo
)
751 TokenInfo
= GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
752 if len(TokenInfo
) != 2:
753 RaiseParserError(Item
, InfType
, File
, Format
, LineNo
)
755 TokenGuid
= TokenInfo
[0]
756 TokenName
= TokenInfo
[1]
758 return (TokenGuid
, TokenName
, Value
, Type
)
761 ## Get Pcd Values of Dec
763 # Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
764 # @retval (TokenSpcCName, TokenCName, Value, DatumType, Token, ItemType) Formatted Pcd Item
766 def GetPcdOfDec(Item
, Type
, File
, LineNo
= -1):
767 Format
= '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>'
768 TokenGuid
, TokenName
, Value
, DatumType
, Token
= '', '', '', '', ''
769 List
= GetSplitValueList(Item
)
771 RaiseParserError(Item
, 'Pcds' + Type
, File
, Format
, LineNo
)
776 TokenInfo
= GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
777 if len(TokenInfo
) != 2:
778 RaiseParserError(Item
, 'Pcds' + Type
, File
, Format
, LineNo
)
780 TokenGuid
= TokenInfo
[0]
781 TokenName
= TokenInfo
[1]
783 return (TokenGuid
, TokenName
, Value
, DatumType
, Token
, Type
)
785 ## Parse DEFINE statement
789 # 1. Insert a record into TblDec
791 # Value2: Macro Value
793 def ParseDefine(LineValue
, StartLine
, Table
, FileID
, Filename
, SectionName
, SectionModel
, Arch
):
794 EdkLogger
.debug(EdkLogger
.DEBUG_2
, "DEFINE statement '%s' found in section %s" % (LineValue
, SectionName
))
795 Define
= GetSplitValueList(CleanString(LineValue
[LineValue
.upper().find(DataType
.TAB_DEFINE
.upper() + ' ') + len(DataType
.TAB_DEFINE
+ ' ') : ]), TAB_EQUAL_SPLIT
, 1)
796 Table
.Insert(MODEL_META_DATA_DEFINE
, Define
[0], Define
[1], '', '', '', Arch
, SectionModel
, FileID
, StartLine
, -1, StartLine
, -1, 0)
798 ## InsertSectionItems
800 # Insert item data of a section to a dict
802 def InsertSectionItems(Model
, CurrentSection
, SectionItemList
, ArchList
, ThirdList
, RecordSet
):
803 # Insert each item data of a section
804 for Index
in range(0, len(ArchList
)):
805 Arch
= ArchList
[Index
]
806 Third
= ThirdList
[Index
]
808 Arch
= TAB_ARCH_COMMON
810 Records
= RecordSet
[Model
]
811 for SectionItem
in SectionItemList
:
812 BelongsToItem
, EndLine
, EndColumn
= -1, -1, -1
813 LineValue
, StartLine
, EndLine
, Comment
= SectionItem
[0], SectionItem
[1], SectionItem
[1], SectionItem
[2]
815 EdkLogger
.debug(4, "Parsing %s ..." %LineValue
)
816 # And then parse DEFINE statement
817 if LineValue
.upper().find(DataType
.TAB_DEFINE
.upper() + ' ') > -1:
820 # At last parse other sections
822 Records
.append([LineValue
, Arch
, StartLine
, ID
, Third
, Comment
])
825 RecordSet
[Model
] = Records
827 ## Insert records to database
829 # Insert item data of a section to database
830 # @param Table: The Table to be inserted
831 # @param FileID: The ID of belonging file
832 # @param Filename: The name of belonging file
833 # @param CurrentSection: The name of currect section
834 # @param SectionItemList: A list of items of the section
835 # @param ArchList: A list of arches
836 # @param ThirdList: A list of third parameters, ModuleType for LibraryClass and SkuId for Dynamic Pcds
837 # @param IfDefList: A list of all conditional statements
838 # @param RecordSet: A dict of all parsed records
840 def InsertSectionItemsIntoDatabase(Table
, FileID
, Filename
, Model
, CurrentSection
, SectionItemList
, ArchList
, ThirdList
, IfDefList
, RecordSet
):
842 # Insert each item data of a section
844 for Index
in range(0, len(ArchList
)):
845 Arch
= ArchList
[Index
]
846 Third
= ThirdList
[Index
]
848 Arch
= TAB_ARCH_COMMON
850 Records
= RecordSet
[Model
]
851 for SectionItem
in SectionItemList
:
852 BelongsToItem
, EndLine
, EndColumn
= -1, -1, -1
853 LineValue
, StartLine
, EndLine
= SectionItem
[0], SectionItem
[1], SectionItem
[1]
855 EdkLogger
.debug(4, "Parsing %s ..." %LineValue
)
857 # And then parse DEFINE statement
859 if LineValue
.upper().find(DataType
.TAB_DEFINE
.upper() + ' ') > -1:
860 ParseDefine(LineValue
, StartLine
, Table
, FileID
, Filename
, CurrentSection
, Model
, Arch
)
864 # At last parse other sections
866 ID
= Table
.Insert(Model
, LineValue
, Third
, Third
, '', '', Arch
, -1, FileID
, StartLine
, -1, StartLine
, -1, 0)
867 Records
.append([LineValue
, Arch
, StartLine
, ID
, Third
])
870 RecordSet
[Model
] = Records
872 ## GenMetaDatSectionItem
873 def GenMetaDatSectionItem(Key
, Value
, List
):
877 List
[Key
].append(Value
)
881 # Check whether the word is valid.
882 # <Word> ::= (a-zA-Z0-9_)(a-zA-Z0-9_-){0,} Alphanumeric characters with
884 # dash "-" and/or underscore "_" characters. No whitespace
885 # characters are permitted.
887 # @param Word: The word string need to be checked.
889 def IsValidWord(Word
):
893 # The first char should be alpha, _ or Digit.
895 if not Word
[0].isalnum() and \
896 not Word
[0] == '_' and \
897 not Word
[0].isdigit():
901 for Char
in Word
[1:]:
902 if (not Char
.isalpha()) and \
903 (not Char
.isdigit()) and \
908 if Char
== '.' and LastChar
== '.':