2 # This file is used to define common parsing related functions used in parsing INF/DEC/DSC process
4 # Copyright (c) 2008, Intel Corporation
5 # All rights reserved. This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
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 # Parse content of a DSC/INF/DEC file
25 def ParseContent(Lines
, ):
29 # Remove comments at tail and remove spaces again
31 Line
= CleanString(Line
)
36 # Find a new section tab
37 # First insert previous section items
38 # And then parse the content of the new section
40 if Line
.startswith(TAB_SECTION_START
) and Line
.endswith(TAB_SECTION_END
):
42 # Insert items data of previous section
44 self
.InsertSectionItemsIntoDatabase(FileID
, Filename
, CurrentSection
, SectionItemList
, ArchList
, ThirdList
, IfDefList
)
46 # Parse the new section
52 LineList
= GetSplitValueList(Line
[len(TAB_SECTION_START
):len(Line
) - len(TAB_SECTION_END
)], TAB_COMMA_SPLIT
)
54 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
)
55 CurrentSection
= ItemList
[0]
56 if CurrentSection
.upper() not in self
.KeyList
:
57 RaiseParserError(Line
, CurrentSection
, Filename
, '', LineNo
)
61 RaiseParserError(Line
, CurrentSection
, Filename
, '', LineNo
)
63 if ItemList
[1] != '' and ItemList
[1].upper() not in ARCH_LIST_FULL
:
64 EdkLogger
.error("Parser", PARSER_ERROR
, "Invalid Arch definition '%s' found" % ItemList
[1], File
=Filename
, Line
=LineNo
)
65 ArchList
.append(ItemList
[1].upper())
66 ThirdList
.append(ItemList
[2])
71 # Not in any defined section
73 if CurrentSection
== TAB_UNKNOWN
:
74 ErrorMsg
= "%s is not in any defined section" % Line
75 EdkLogger
.error("Parser", PARSER_ERROR
, ErrorMsg
, File
=Filename
, Line
=LineNo
)
80 SectionItemList
.append([Line
, LineNo
])
87 # Search whole table to find all defined Macro and replaced them with the real values
89 def ParseDefineMacro2(Table
, RecordSets
, GlobalMacro
):
92 # Find all DEFINE macros in section [Header] and its section
94 SqlCommand
= """select Value1, Value2, BelongsToItem, StartLine, Arch from %s
96 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_DEFINE
)
97 RecordSet
= Table
.Exec(SqlCommand
)
98 for Record
in RecordSet
:
99 Macros
[Record
[0]] = Record
[1]
102 # Overrided by Global Macros
104 for Key
in GlobalMacro
.keys():
105 Macros
[Key
] = GlobalMacro
[Key
]
110 for Key
in RecordSets
.keys():
111 if RecordSets
[Key
] != []:
112 for Item
in RecordSets
[Key
]:
113 Item
[0] = ReplaceMacro(Item
[0], Macros
)
117 # Search whole table to find all defined Macro and replaced them with the real values
119 def ParseDefineMacro(Table
, GlobalMacro
):
122 # Find all DEFINE macros
124 SqlCommand
= """select Value1, Value2, BelongsToItem, StartLine, Arch from %s
126 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_DEFINE
)
127 RecordSet
= Table
.Exec(SqlCommand
)
128 for Record
in RecordSet
:
129 #***************************************************************************************************************************************************
130 # The follow SqlCommand (expr replace) is not supported in Sqlite 3.3.4 which is used in Python 2.5 *
132 # SqlCommand = """update %s set Value1 = replace(Value1, '%s', '%s') *
133 # where ID in (select ID from %s *
135 # and Value1 like '%%%s%%' *
136 # and StartLine > %s *
138 # and Arch = '%s')""" % \ *
139 # (self.TblDsc.Table, Record[0], Record[1], self.TblDsc.Table, Record[2], Record[1], Record[3], Record[4]) *
140 #***************************************************************************************************************************************************
141 Macros
[Record
[0]] = Record
[1]
144 # Overrided by Global Macros
146 for Key
in GlobalMacro
.keys():
147 Macros
[Key
] = GlobalMacro
[Key
]
150 # Found all defined macro and replaced
152 SqlCommand
= """select ID, Value1 from %s
154 and Value1 like '%%$(%%' and Value1 like '%%)%%'
155 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_DEFINE
)
156 FoundRecords
= Table
.Exec(SqlCommand
)
157 for FoundRecord
in FoundRecords
:
158 NewValue
= ReplaceMacro(FoundRecord
[1], Macros
)
159 SqlCommand
= """update %s set Value1 = '%s'
160 where ID = %s""" % (Table
.Table
, ConvertToSqlString2(NewValue
), FoundRecord
[0])
161 Table
.Exec(SqlCommand
)
165 # Search item of section [Defines] by name, return its values
167 # @param Table: The Table to be executed
168 # @param Name: The Name of item of section [Defines]
169 # @param Arch: The Arch of item of section [Defines]
171 # @retval RecordSet: A list of all matched records
173 def QueryDefinesItem(Table
, Name
, Arch
, BelongsToFile
):
174 SqlCommand
= """select Value2 from %s
178 and BelongsToFile = %s
179 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_HEADER
, ConvertToSqlString2(Name
), ConvertToSqlString2(Arch
), BelongsToFile
)
180 RecordSet
= Table
.Exec(SqlCommand
)
181 if len(RecordSet
) < 1:
182 SqlCommand
= """select Value2 from %s
186 and BelongsToFile = %s
187 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_HEADER
, ConvertToSqlString2(Name
), ConvertToSqlString2(TAB_ARCH_COMMON
.upper()), BelongsToFile
)
188 RecordSet
= Table
.Exec(SqlCommand
)
189 if len(RecordSet
) == 1:
190 if Name
== TAB_INF_DEFINES_LIBRARY_CLASS
:
191 return [RecordSet
[0][0]]
193 return GetSplitValueList(RecordSet
[0][0])
194 elif len(RecordSet
) < 1:
196 elif len(RecordSet
) > 1:
198 for Record
in RecordSet
:
199 if Name
== TAB_INF_DEFINES_LIBRARY_CLASS
:
200 RetVal
.append(Record
[0])
202 Items
= GetSplitValueList(Record
[0])
209 # Search item of section [Defines] by name, return its values
211 # @param Table: The Table to be executed
212 # @param Name: The Name of item of section [Defines]
213 # @param Arch: The Arch of item of section [Defines]
215 # @retval RecordSet: A list of all matched records
217 def QueryDefinesItem2(Table
, Arch
, BelongsToFile
):
218 SqlCommand
= """select Value1, Value2, StartLine from %s
221 and BelongsToFile = %s
222 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_HEADER
, ConvertToSqlString2(Arch
), BelongsToFile
)
223 RecordSet
= Table
.Exec(SqlCommand
)
224 if len(RecordSet
) < 1:
225 SqlCommand
= """select Value1, Value2, StartLine from %s
228 and BelongsToFile = %s
229 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_HEADER
, ConvertToSqlString2(TAB_ARCH_COMMON
), BelongsToFile
)
230 RecordSet
= Table
.Exec(SqlCommand
)
236 # Search all dsc item for a specific section
238 # @param Table: The Table to be executed
239 # @param Model: The type of section
241 # @retval RecordSet: A list of all matched records
243 def QueryDscItem(Table
, Model
, BelongsToItem
, BelongsToFile
):
244 SqlCommand
= """select Value1, Arch, StartLine, ID, Value2 from %s
246 and BelongsToItem = %s
247 and BelongsToFile = %s
248 and Enabled > -1""" % (Table
.Table
, Model
, BelongsToItem
, BelongsToFile
)
249 return Table
.Exec(SqlCommand
)
253 # Search all dec item for a specific section
255 # @param Table: The Table to be executed
256 # @param Model: The type of section
258 # @retval RecordSet: A list of all matched records
260 def QueryDecItem(Table
, Model
, BelongsToItem
):
261 SqlCommand
= """select Value1, Arch, StartLine, ID, Value2 from %s
263 and BelongsToItem = %s
264 and Enabled > -1""" % (Table
.Table
, Model
, BelongsToItem
)
265 return Table
.Exec(SqlCommand
)
269 # Search all dec item for a specific section
271 # @param Table: The Table to be executed
272 # @param Model: The type of section
274 # @retval RecordSet: A list of all matched records
276 def QueryInfItem(Table
, Model
, BelongsToItem
):
277 SqlCommand
= """select Value1, Arch, StartLine, ID, Value2 from %s
279 and BelongsToItem = %s
280 and Enabled > -1""" % (Table
.Table
, Model
, BelongsToItem
)
281 return Table
.Exec(SqlCommand
)
285 # Parse a string with format "[<Family>:]<ToolFlag>=Flag"
286 # Return (Family, ToolFlag, Flag)
288 # @param String: String with BuildOption statement
289 # @param File: The file which defines build option, used in error report
291 # @retval truple() A truple structure as (Family, ToolChain, Flag)
293 def GetBuildOption(String
, File
, LineNo
= -1):
294 if String
.find(TAB_EQUAL_SPLIT
) < 0:
295 RaiseParserError(String
, 'BuildOptions', File
, '[<Family>:]<ToolFlag>=Flag', LineNo
)
296 (Family
, ToolChain
, Flag
) = ('', '', '')
297 List
= GetSplitValueList(String
, TAB_EQUAL_SPLIT
, MaxSplit
= 1)
298 if List
[0].find(':') > -1:
299 Family
= List
[0][ : List
[0].find(':')].strip()
300 ToolChain
= List
[0][List
[0].find(':') + 1 : ].strip()
302 ToolChain
= List
[0].strip()
303 Flag
= List
[1].strip()
305 return (Family
, ToolChain
, Flag
)
309 # Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance>
311 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
312 # @param ContainerFile: The file which describes the library class, used for error report
314 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item
316 def GetLibraryClass(Item
, ContainerFile
, WorkspaceDir
, LineNo
= -1):
317 List
= GetSplitValueList(Item
[0])
318 SupMod
= SUP_MODULE_LIST_STRING
320 RaiseParserError(Item
[0], 'LibraryClasses', ContainerFile
, '<LibraryClassKeyWord>|<LibraryInstance>')
322 CheckFileType(List
[1], '.Inf', ContainerFile
, 'library class instance', Item
[0], LineNo
)
323 CheckFileExist(WorkspaceDir
, List
[1], ContainerFile
, 'LibraryClasses', Item
[0], LineNo
)
327 return (List
[0], List
[1], SupMod
)
331 # Get Library of Dsc as <LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]
333 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
334 # @param ContainerFile: The file which describes the library class, used for error report
336 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item
338 def GetLibraryClassOfInf(Item
, ContainerFile
, WorkspaceDir
, LineNo
= -1):
339 ItemList
= GetSplitValueList((Item
[0] + DataType
.TAB_VALUE_SPLIT
* 2))
340 SupMod
= SUP_MODULE_LIST_STRING
342 if len(ItemList
) > 5:
343 RaiseParserError(Item
[0], 'LibraryClasses', ContainerFile
, '<LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]')
345 CheckFileType(ItemList
[1], '.Inf', ContainerFile
, 'LibraryClasses', Item
[0], LineNo
)
346 CheckFileExist(WorkspaceDir
, ItemList
[1], ContainerFile
, 'LibraryClasses', Item
[0], LineNo
)
347 if ItemList
[2] != '':
348 CheckPcdTokenInfo(ItemList
[2], 'LibraryClasses', ContainerFile
, LineNo
)
352 return (ItemList
[0], ItemList
[1], ItemList
[2], SupMod
)
356 # Check if PcdTokenInfo is following <TokenSpaceGuidCName>.<PcdCName>
358 # @param TokenInfoString: String to be checked
359 # @param Section: Used for error report
360 # @param File: Used for error report
362 # @retval True PcdTokenInfo is in correct format
364 def CheckPcdTokenInfo(TokenInfoString
, Section
, File
, LineNo
= -1):
365 Format
= '<TokenSpaceGuidCName>.<PcdCName>'
366 if TokenInfoString
!= '' and TokenInfoString
!= None:
367 TokenInfoList
= GetSplitValueList(TokenInfoString
, TAB_SPLIT
)
368 if len(TokenInfoList
) == 2:
371 RaiseParserError(TokenInfoString
, Section
, File
, Format
, LineNo
)
375 # Get Pcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]
377 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]
378 # @param ContainerFile: The file which describes the pcd, used for error report
380 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)
382 def GetPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
383 TokenGuid
, TokenName
, Value
, MaximumDatumSize
, Token
= '', '', '', '', ''
384 List
= GetSplitValueList(Item
+ TAB_VALUE_SPLIT
* 2)
386 if len(List
) < 4 or len(List
) > 6:
387 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]', LineNo
)
390 MaximumDatumSize
= List
[2]
393 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
394 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], TAB_SPLIT
)
396 return (TokenName
, TokenGuid
, Value
, MaximumDatumSize
, Token
, Type
)
398 ## Get FeatureFlagPcd
400 # Get FeatureFlagPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
402 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
403 # @param ContainerFile: The file which describes the pcd, used for error report
405 # @retval (TokenInfo[1], TokenInfo[0], List[1], Type)
407 def GetFeatureFlagPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
408 TokenGuid
, TokenName
, Value
= '', '', ''
409 List
= GetSplitValueList(Item
)
411 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE', LineNo
)
414 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
415 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
417 return (TokenName
, TokenGuid
, Value
, Type
)
419 ## Get DynamicDefaultPcd
421 # Get DynamicDefaultPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]
423 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
424 # @param ContainerFile: The file which describes the pcd, used for error report
426 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)
428 def GetDynamicDefaultPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
429 TokenGuid
, TokenName
, Value
, DatumTyp
, MaxDatumSize
= '', '', '', '', ''
430 List
= GetSplitValueList(Item
+ TAB_VALUE_SPLIT
* 2)
431 if len(List
) < 4 or len(List
) > 8:
432 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]', LineNo
)
436 MaxDatumSize
= List
[3]
437 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
438 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], TAB_SPLIT
)
440 return (TokenName
, TokenGuid
, Value
, DatumTyp
, MaxDatumSize
, Type
)
444 # Get DynamicHiiPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]
446 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
447 # @param ContainerFile: The file which describes the pcd, used for error report
449 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], List[4], List[5], Type)
451 def GetDynamicHiiPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
452 TokenGuid
, TokenName
, L1
, L2
, L3
, L4
, L5
= '', '', '', '', '', '', ''
453 List
= GetSplitValueList(Item
+ TAB_VALUE_SPLIT
* 2)
454 if len(List
) < 6 or len(List
) > 8:
455 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]', LineNo
)
457 L1
, L2
, L3
, L4
, L5
= List
[1], List
[2], List
[3], List
[4], List
[5]
458 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
459 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
461 return (TokenName
, TokenGuid
, L1
, L2
, L3
, L4
, L5
, Type
)
465 # Get DynamicVpdPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]
467 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
468 # @param ContainerFile: The file which describes the pcd, used for error report
470 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], Type)
472 def GetDynamicVpdPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
473 TokenGuid
, TokenName
, L1
, L2
= '', '', '', ''
474 List
= GetSplitValueList(Item
+ TAB_VALUE_SPLIT
)
475 if len(List
) < 3 or len(List
) > 4:
476 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]', LineNo
)
478 L1
, L2
= List
[1], List
[2]
479 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
480 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
482 return (TokenName
, TokenGuid
, L1
, L2
, Type
)
486 # Parse block of the components defined in dsc file
487 # Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]
489 # @param Lines: The content to be parsed
490 # @param KeyValues: To store data after parsing
492 # @retval True Get component successfully
494 def GetComponent(Lines
, KeyValues
):
495 (findBlock
, findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, False, False)
497 LibraryClassItem
= []
505 # Ignore !include statement
507 if Line
.upper().find(TAB_INCLUDE
.upper() + ' ') > -1 or Line
.upper().find(TAB_DEFINE
+ ' ') > -1:
510 if findBlock
== False:
513 # find '{' at line tail
515 if Line
.endswith('{'):
517 ListItem
= CleanString(Line
.rsplit('{', 1)[0], DataType
.TAB_COMMENT_SPLIT
)
520 # Parse a block content
523 if Line
.find('<LibraryClasses>') != -1:
524 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (True, False, False, False, False, False, False)
526 if Line
.find('<BuildOptions>') != -1:
527 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, True, False, False, False, False, False)
529 if Line
.find('<PcdsFeatureFlag>') != -1:
530 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, True, False, False, False, False)
532 if Line
.find('<PcdsPatchableInModule>') != -1:
533 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, True, False, False, False)
535 if Line
.find('<PcdsFixedAtBuild>') != -1:
536 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, True, False, False)
538 if Line
.find('<PcdsDynamic>') != -1:
539 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, True, False)
541 if Line
.find('<PcdsDynamicEx>') != -1:
542 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, True)
544 if Line
.endswith('}'):
546 # find '}' at line tail
548 KeyValues
.append([ListItem
, LibraryClassItem
, BuildOption
, Pcd
])
549 (findBlock
, findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, False, False)
550 LibraryClassItem
, BuildOption
, Pcd
= [], [], []
555 LibraryClassItem
.append(Line
)
556 elif findBuildOption
:
557 BuildOption
.append(Line
)
558 elif findPcdsFeatureFlag
:
559 Pcd
.append((DataType
.TAB_PCDS_FEATURE_FLAG_NULL
, Line
))
560 elif findPcdsPatchableInModule
:
561 Pcd
.append((DataType
.TAB_PCDS_PATCHABLE_IN_MODULE_NULL
, Line
))
562 elif findPcdsFixedAtBuild
:
563 Pcd
.append((DataType
.TAB_PCDS_FIXED_AT_BUILD_NULL
, Line
))
564 elif findPcdsDynamic
:
565 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_DEFAULT_NULL
, Line
))
566 elif findPcdsDynamicEx
:
567 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
, Line
))
569 KeyValues
.append([ListItem
, [], [], []])
575 # Parse a string with format "InfFilename [EXEC = ExecFilename]"
576 # Return (InfFilename, ExecFilename)
578 # @param String: String with EXEC statement
580 # @retval truple() A pair as (InfFilename, ExecFilename)
585 if String
.find('EXEC') > -1:
586 InfFilename
= String
[ : String
.find('EXEC')].strip()
587 ExecFilename
= String
[String
.find('EXEC') + len('EXEC') : ].strip()
589 InfFilename
= String
.strip()
591 return (InfFilename
, ExecFilename
)
595 # Parse block of the components defined in dsc file
596 # Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]
598 # @param Lines: The content to be parsed
599 # @param Key: Reserved
600 # @param KeyValues: To store data after parsing
601 # @param CommentCharacter: Comment char, used to ignore comment content
603 # @retval True Get component successfully
605 def GetComponents(Lines
, Key
, KeyValues
, CommentCharacter
):
606 if Lines
.find(DataType
.TAB_SECTION_END
) > -1:
607 Lines
= Lines
.split(DataType
.TAB_SECTION_END
, 1)[1]
608 (findBlock
, findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, False, False)
610 LibraryClassItem
= []
614 LineList
= Lines
.split('\n')
615 for Line
in LineList
:
616 Line
= CleanString(Line
, CommentCharacter
)
617 if Line
== None or Line
== '':
620 if findBlock
== False:
623 # find '{' at line tail
625 if Line
.endswith('{'):
627 ListItem
= CleanString(Line
.rsplit('{', 1)[0], CommentCharacter
)
630 # Parse a block content
633 if Line
.find('<LibraryClasses>') != -1:
634 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (True, False, False, False, False, False, False)
636 if Line
.find('<BuildOptions>') != -1:
637 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, True, False, False, False, False, False)
639 if Line
.find('<PcdsFeatureFlag>') != -1:
640 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, True, False, False, False, False)
642 if Line
.find('<PcdsPatchableInModule>') != -1:
643 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, True, False, False, False)
645 if Line
.find('<PcdsFixedAtBuild>') != -1:
646 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, True, False, False)
648 if Line
.find('<PcdsDynamic>') != -1:
649 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, True, False)
651 if Line
.find('<PcdsDynamicEx>') != -1:
652 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, True)
654 if Line
.endswith('}'):
656 # find '}' at line tail
658 KeyValues
.append([ListItem
, LibraryClassItem
, BuildOption
, Pcd
])
659 (findBlock
, findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, False, False)
660 LibraryClassItem
, BuildOption
, Pcd
= [], [], []
665 LibraryClassItem
.append(Line
)
666 elif findBuildOption
:
667 BuildOption
.append(Line
)
668 elif findPcdsFeatureFlag
:
669 Pcd
.append((DataType
.TAB_PCDS_FEATURE_FLAG
, Line
))
670 elif findPcdsPatchableInModule
:
671 Pcd
.append((DataType
.TAB_PCDS_PATCHABLE_IN_MODULE
, Line
))
672 elif findPcdsFixedAtBuild
:
673 Pcd
.append((DataType
.TAB_PCDS_FIXED_AT_BUILD
, Line
))
674 elif findPcdsDynamic
:
675 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC
, Line
))
676 elif findPcdsDynamicEx
:
677 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_EX
, Line
))
679 KeyValues
.append([ListItem
, [], [], []])
685 # Get Source of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
687 # @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
688 # @param ContainerFile: The file which describes the library class, used for error report
690 # @retval (List[0], List[1], List[2], List[3], List[4])
692 def GetSource(Item
, ContainerFile
, FileRelativePath
, LineNo
= -1):
693 ItemNew
= Item
+ DataType
.TAB_VALUE_SPLIT
* 4
694 List
= GetSplitValueList(ItemNew
)
695 if len(List
) < 5 or len(List
) > 9:
696 RaiseParserError(Item
, 'Sources', ContainerFile
, '<Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]', LineNo
)
697 List
[0] = NormPath(List
[0])
698 CheckFileExist(FileRelativePath
, List
[0], ContainerFile
, 'Sources', Item
, LineNo
)
700 CheckPcdTokenInfo(List
[4], 'Sources', ContainerFile
, LineNo
)
702 return (List
[0], List
[1], List
[2], List
[3], List
[4])
706 # Get Binary of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
708 # @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
709 # @param ContainerFile: The file which describes the library class, used for error report
711 # @retval (List[0], List[1], List[2], List[3])
713 def GetBinary(Item
, ContainerFile
, FileRelativePath
, LineNo
= -1):
714 ItemNew
= Item
+ DataType
.TAB_VALUE_SPLIT
715 List
= GetSplitValueList(ItemNew
)
716 if len(List
) != 4 and len(List
) != 5:
717 RaiseParserError(Item
, 'Binaries', ContainerFile
, "<FileType>|<Filename>|<Target>[|<TokenSpaceGuidCName>.<PcdCName>]", LineNo
)
720 CheckPcdTokenInfo(List
[3], 'Binaries', ContainerFile
, LineNo
)
722 return (List
[0], List
[1], List
[2], List
[3])
724 ## Get Guids/Protocols/Ppis
726 # Get Guids/Protocols/Ppis of Inf as <GuidCName>[|<PcdFeatureFlag>]
728 # @param Item: String as <GuidCName>[|<PcdFeatureFlag>]
729 # @param Type: Type of parsing string
730 # @param ContainerFile: The file which describes the library class, used for error report
732 # @retval (List[0], List[1])
734 def GetGuidsProtocolsPpisOfInf(Item
, Type
, ContainerFile
, LineNo
= -1):
735 ItemNew
= Item
+ TAB_VALUE_SPLIT
736 List
= GetSplitValueList(ItemNew
)
738 CheckPcdTokenInfo(List
[1], Type
, ContainerFile
, LineNo
)
740 return (List
[0], List
[1])
742 ## Get Guids/Protocols/Ppis
744 # Get Guids/Protocols/Ppis of Dec as <GuidCName>=<GuidValue>
746 # @param Item: String as <GuidCName>=<GuidValue>
747 # @param Type: Type of parsing string
748 # @param ContainerFile: The file which describes the library class, used for error report
750 # @retval (List[0], List[1])
752 def GetGuidsProtocolsPpisOfDec(Item
, Type
, ContainerFile
, LineNo
= -1):
753 List
= GetSplitValueList(Item
, DataType
.TAB_EQUAL_SPLIT
)
755 RaiseParserError(Item
, Type
, ContainerFile
, '<CName>=<GuidValue>', LineNo
)
757 return (List
[0], List
[1])
761 # Get Package of Inf as <PackagePath>[|<PcdFeatureFlag>]
763 # @param Item: String as <PackagePath>[|<PcdFeatureFlag>]
764 # @param Type: Type of parsing string
765 # @param ContainerFile: The file which describes the library class, used for error report
767 # @retval (List[0], List[1])
769 def GetPackage(Item
, ContainerFile
, FileRelativePath
, LineNo
= -1):
770 ItemNew
= Item
+ TAB_VALUE_SPLIT
771 List
= GetSplitValueList(ItemNew
)
772 CheckFileType(List
[0], '.Dec', ContainerFile
, 'package', List
[0], LineNo
)
773 CheckFileExist(FileRelativePath
, List
[0], ContainerFile
, 'Packages', List
[0], LineNo
)
776 CheckPcdTokenInfo(List
[1], 'Packages', ContainerFile
, LineNo
)
778 return (List
[0], List
[1])
780 ## Get Pcd Values of Inf
782 # Get Pcd of Inf as <TokenSpaceGuidCName>.<PcdCName>[|<Value>]
784 # @param Item: The string describes pcd
785 # @param Type: The type of Pcd
786 # @param File: The file which describes the pcd, used for error report
788 # @retval (TokenSpcCName, TokenCName, Value, ItemType) Formatted Pcd Item
790 def GetPcdOfInf(Item
, Type
, File
, LineNo
):
791 Format
= '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]'
792 TokenGuid
, TokenName
, Value
, InfType
= '', '', '', ''
794 if Type
== TAB_PCDS_FIXED_AT_BUILD
:
795 InfType
= TAB_INF_FIXED_PCD
796 elif Type
== TAB_PCDS_PATCHABLE_IN_MODULE
:
797 InfType
= TAB_INF_PATCH_PCD
798 elif Type
== TAB_PCDS_FEATURE_FLAG
:
799 InfType
= TAB_INF_FEATURE_PCD
800 elif Type
== TAB_PCDS_DYNAMIC_EX
:
801 InfType
= TAB_INF_PCD_EX
802 elif Type
== TAB_PCDS_DYNAMIC
:
803 InfType
= TAB_INF_PCD
804 List
= GetSplitValueList(Item
+ DataType
.TAB_VALUE_SPLIT
)
805 if len(List
) < 2 or len(List
) > 3:
806 RaiseParserError(Item
, InfType
, File
, Format
, LineNo
)
809 TokenInfo
= GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
810 if len(TokenInfo
) != 2:
811 RaiseParserError(Item
, InfType
, File
, Format
, LineNo
)
813 TokenGuid
= TokenInfo
[0]
814 TokenName
= TokenInfo
[1]
816 return (TokenGuid
, TokenName
, Value
, Type
)
819 ## Get Pcd Values of Dec
821 # Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
822 # @retval (TokenSpcCName, TokenCName, Value, DatumType, Token, ItemType) Formatted Pcd Item
824 def GetPcdOfDec(Item
, Type
, File
, LineNo
= -1):
825 Format
= '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>'
826 TokenGuid
, TokenName
, Value
, DatumType
, Token
= '', '', '', '', ''
827 List
= GetSplitValueList(Item
)
829 RaiseParserError(Item
, 'Pcds' + Type
, File
, Format
, LineNo
)
834 TokenInfo
= GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
835 if len(TokenInfo
) != 2:
836 RaiseParserError(Item
, 'Pcds' + Type
, File
, Format
, LineNo
)
838 TokenGuid
= TokenInfo
[0]
839 TokenName
= TokenInfo
[1]
841 return (TokenGuid
, TokenName
, Value
, DatumType
, Token
, Type
)
843 ## Parse DEFINE statement
847 # 1. Insert a record into TblDec
849 # Value2: Macro Value
851 def ParseDefine(LineValue
, StartLine
, Table
, FileID
, Filename
, SectionName
, SectionModel
, Arch
):
852 EdkLogger
.debug(EdkLogger
.DEBUG_2
, "DEFINE statement '%s' found in section %s" % (LineValue
, SectionName
))
853 Define
= GetSplitValueList(CleanString(LineValue
[LineValue
.upper().find(DataType
.TAB_DEFINE
.upper() + ' ') + len(DataType
.TAB_DEFINE
+ ' ') : ]), TAB_EQUAL_SPLIT
, 1)
854 Table
.Insert(MODEL_META_DATA_DEFINE
, Define
[0], Define
[1], '', '', '', Arch
, SectionModel
, FileID
, StartLine
, -1, StartLine
, -1, 0)
856 ## InsertSectionItems
858 # Insert item data of a section to a dict
860 def InsertSectionItems(Model
, CurrentSection
, SectionItemList
, ArchList
, ThirdList
, RecordSet
):
861 # Insert each item data of a section
862 for Index
in range(0, len(ArchList
)):
863 Arch
= ArchList
[Index
]
864 Third
= ThirdList
[Index
]
866 Arch
= TAB_ARCH_COMMON
868 Records
= RecordSet
[Model
]
869 for SectionItem
in SectionItemList
:
870 BelongsToItem
, EndLine
, EndColumn
= -1, -1, -1
871 LineValue
, StartLine
, EndLine
, Comment
= SectionItem
[0], SectionItem
[1], SectionItem
[1], SectionItem
[2]
873 EdkLogger
.debug(4, "Parsing %s ..." %LineValue
)
874 # And then parse DEFINE statement
875 if LineValue
.upper().find(DataType
.TAB_DEFINE
.upper() + ' ') > -1:
878 # At last parse other sections
880 Records
.append([LineValue
, Arch
, StartLine
, ID
, Third
, Comment
])
883 RecordSet
[Model
] = Records
885 ## Insert records to database
887 # Insert item data of a section to database
888 # @param Table: The Table to be inserted
889 # @param FileID: The ID of belonging file
890 # @param Filename: The name of belonging file
891 # @param CurrentSection: The name of currect section
892 # @param SectionItemList: A list of items of the section
893 # @param ArchList: A list of arches
894 # @param ThirdList: A list of third parameters, ModuleType for LibraryClass and SkuId for Dynamic Pcds
895 # @param IfDefList: A list of all conditional statements
896 # @param RecordSet: A dict of all parsed records
898 def InsertSectionItemsIntoDatabase(Table
, FileID
, Filename
, Model
, CurrentSection
, SectionItemList
, ArchList
, ThirdList
, IfDefList
, RecordSet
):
900 # Insert each item data of a section
902 for Index
in range(0, len(ArchList
)):
903 Arch
= ArchList
[Index
]
904 Third
= ThirdList
[Index
]
906 Arch
= TAB_ARCH_COMMON
908 Records
= RecordSet
[Model
]
909 for SectionItem
in SectionItemList
:
910 BelongsToItem
, EndLine
, EndColumn
= -1, -1, -1
911 LineValue
, StartLine
, EndLine
= SectionItem
[0], SectionItem
[1], SectionItem
[1]
913 EdkLogger
.debug(4, "Parsing %s ..." %LineValue
)
915 # And then parse DEFINE statement
917 if LineValue
.upper().find(DataType
.TAB_DEFINE
.upper() + ' ') > -1:
918 ParseDefine(LineValue
, StartLine
, Table
, FileID
, Filename
, CurrentSection
, Model
, Arch
)
922 # At last parse other sections
924 ID
= Table
.Insert(Model
, LineValue
, Third
, Third
, '', '', Arch
, -1, FileID
, StartLine
, -1, StartLine
, -1, 0)
925 Records
.append([LineValue
, Arch
, StartLine
, ID
, Third
])
928 RecordSet
[Model
] = Records
930 ## GenMetaDatSectionItem
931 def GenMetaDatSectionItem(Key
, Value
, List
):
935 List
[Key
].append(Value
)