2 # This file is used to define common parsing related functions used in parsing INF/DEC/DSC process
4 # Copyright (c) 2008 - 2014, 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 for Key
in GlobalMacro
.keys():
41 Macros
[Key
] = GlobalMacro
[Key
]
46 for Key
in RecordSets
.keys():
47 if RecordSets
[Key
] != []:
48 for Item
in RecordSets
[Key
]:
49 Item
[0] = ReplaceMacro(Item
[0], Macros
)
53 # Search whole table to find all defined Macro and replaced them with the real values
55 def ParseDefineMacro(Table
, GlobalMacro
):
58 # Find all DEFINE macros
60 SqlCommand
= """select Value1, Value2, BelongsToItem, StartLine, Arch from %s
62 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_DEFINE
)
63 RecordSet
= Table
.Exec(SqlCommand
)
64 for Record
in RecordSet
:
65 #***************************************************************************************************************************************************
66 # The follow SqlCommand (expr replace) is not supported in Sqlite 3.3.4 which is used in Python 2.5 *
68 # SqlCommand = """update %s set Value1 = replace(Value1, '%s', '%s') *
69 # where ID in (select ID from %s *
71 # and Value1 like '%%%s%%' *
72 # and StartLine > %s *
74 # and Arch = '%s')""" % \ *
75 # (self.TblDsc.Table, Record[0], Record[1], self.TblDsc.Table, Record[2], Record[1], Record[3], Record[4]) *
76 #***************************************************************************************************************************************************
77 Macros
[Record
[0]] = Record
[1]
80 # Overrided by Global Macros
82 for Key
in GlobalMacro
.keys():
83 Macros
[Key
] = GlobalMacro
[Key
]
86 # Found all defined macro and replaced
88 SqlCommand
= """select ID, Value1 from %s
90 and Value1 like '%%$(%%' and Value1 like '%%)%%'
91 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_DEFINE
)
92 FoundRecords
= Table
.Exec(SqlCommand
)
93 for FoundRecord
in FoundRecords
:
94 NewValue
= ReplaceMacro(FoundRecord
[1], Macros
)
95 SqlCommand
= """update %s set Value1 = '%s'
96 where ID = %s""" % (Table
.Table
, ConvertToSqlString2(NewValue
), FoundRecord
[0])
97 Table
.Exec(SqlCommand
)
101 # Search item of section [Defines] by name, return its values
103 # @param Table: The Table to be executed
104 # @param Name: The Name of item of section [Defines]
105 # @param Arch: The Arch of item of section [Defines]
107 # @retval RecordSet: A list of all matched records
109 def QueryDefinesItem(Table
, Name
, Arch
, BelongsToFile
):
110 SqlCommand
= """select Value2 from %s
114 and BelongsToFile = %s
115 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_HEADER
, ConvertToSqlString2(Name
), ConvertToSqlString2(Arch
), BelongsToFile
)
116 RecordSet
= Table
.Exec(SqlCommand
)
117 if len(RecordSet
) < 1:
118 SqlCommand
= """select Value2 from %s
122 and BelongsToFile = %s
123 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_HEADER
, ConvertToSqlString2(Name
), ConvertToSqlString2(TAB_ARCH_COMMON
.upper()), BelongsToFile
)
124 RecordSet
= Table
.Exec(SqlCommand
)
125 if len(RecordSet
) == 1:
126 if Name
== TAB_INF_DEFINES_LIBRARY_CLASS
:
127 return [RecordSet
[0][0]]
129 return GetSplitValueList(RecordSet
[0][0])
130 elif len(RecordSet
) < 1:
132 elif len(RecordSet
) > 1:
134 for Record
in RecordSet
:
135 if Name
== TAB_INF_DEFINES_LIBRARY_CLASS
:
136 RetVal
.append(Record
[0])
138 Items
= GetSplitValueList(Record
[0])
145 # Search item of section [Defines] by name, return its values
147 # @param Table: The Table to be executed
148 # @param Name: The Name of item of section [Defines]
149 # @param Arch: The Arch of item of section [Defines]
151 # @retval RecordSet: A list of all matched records
153 def QueryDefinesItem2(Table
, Arch
, BelongsToFile
):
154 SqlCommand
= """select Value1, Value2, StartLine from %s
157 and BelongsToFile = %s
158 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_HEADER
, ConvertToSqlString2(Arch
), BelongsToFile
)
159 RecordSet
= Table
.Exec(SqlCommand
)
160 if len(RecordSet
) < 1:
161 SqlCommand
= """select Value1, Value2, StartLine from %s
164 and BelongsToFile = %s
165 and Enabled > -1""" % (Table
.Table
, MODEL_META_DATA_HEADER
, ConvertToSqlString2(TAB_ARCH_COMMON
), BelongsToFile
)
166 RecordSet
= Table
.Exec(SqlCommand
)
172 # Search all dsc item for a specific section
174 # @param Table: The Table to be executed
175 # @param Model: The type of section
177 # @retval RecordSet: A list of all matched records
179 def QueryDscItem(Table
, Model
, BelongsToItem
, BelongsToFile
):
180 SqlCommand
= """select Value1, Arch, StartLine, ID, Value2 from %s
182 and BelongsToItem = %s
183 and BelongsToFile = %s
184 and Enabled > -1""" % (Table
.Table
, Model
, BelongsToItem
, BelongsToFile
)
185 return Table
.Exec(SqlCommand
)
189 # Search all dec item for a specific section
191 # @param Table: The Table to be executed
192 # @param Model: The type of section
194 # @retval RecordSet: A list of all matched records
196 def QueryDecItem(Table
, Model
, BelongsToItem
):
197 SqlCommand
= """select Value1, Arch, StartLine, ID, Value2 from %s
199 and BelongsToItem = %s
200 and Enabled > -1""" % (Table
.Table
, Model
, BelongsToItem
)
201 return Table
.Exec(SqlCommand
)
205 # Search all dec item for a specific section
207 # @param Table: The Table to be executed
208 # @param Model: The type of section
210 # @retval RecordSet: A list of all matched records
212 def QueryInfItem(Table
, Model
, BelongsToItem
):
213 SqlCommand
= """select Value1, Arch, StartLine, ID, Value2 from %s
215 and BelongsToItem = %s
216 and Enabled > -1""" % (Table
.Table
, Model
, BelongsToItem
)
217 return Table
.Exec(SqlCommand
)
221 # Parse a string with format "[<Family>:]<ToolFlag>=Flag"
222 # Return (Family, ToolFlag, Flag)
224 # @param String: String with BuildOption statement
225 # @param File: The file which defines build option, used in error report
227 # @retval truple() A truple structure as (Family, ToolChain, Flag)
229 def GetBuildOption(String
, File
, LineNo
= -1):
230 (Family
, ToolChain
, Flag
) = ('', '', '')
231 if String
.find(TAB_EQUAL_SPLIT
) < 0:
232 RaiseParserError(String
, 'BuildOptions', File
, '[<Family>:]<ToolFlag>=Flag', LineNo
)
234 List
= GetSplitValueList(String
, TAB_EQUAL_SPLIT
, MaxSplit
= 1)
235 if List
[0].find(':') > -1:
236 Family
= List
[0][ : List
[0].find(':')].strip()
237 ToolChain
= List
[0][List
[0].find(':') + 1 : ].strip()
239 ToolChain
= List
[0].strip()
240 Flag
= List
[1].strip()
241 return (Family
, ToolChain
, Flag
)
245 # Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance>
247 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
248 # @param ContainerFile: The file which describes the library class, used for error report
250 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item
252 def GetLibraryClass(Item
, ContainerFile
, WorkspaceDir
, LineNo
= -1):
253 List
= GetSplitValueList(Item
[0])
254 SupMod
= SUP_MODULE_LIST_STRING
256 RaiseParserError(Item
[0], 'LibraryClasses', ContainerFile
, '<LibraryClassKeyWord>|<LibraryInstance>')
258 CheckFileType(List
[1], '.Inf', ContainerFile
, 'library class instance', Item
[0], LineNo
)
259 CheckFileExist(WorkspaceDir
, List
[1], ContainerFile
, 'LibraryClasses', Item
[0], LineNo
)
263 return (List
[0], List
[1], SupMod
)
267 # Get Library of Dsc as <LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]
269 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
270 # @param ContainerFile: The file which describes the library class, used for error report
272 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item
274 def GetLibraryClassOfInf(Item
, ContainerFile
, WorkspaceDir
, LineNo
= -1):
275 ItemList
= GetSplitValueList((Item
[0] + DataType
.TAB_VALUE_SPLIT
* 2))
276 SupMod
= SUP_MODULE_LIST_STRING
278 if len(ItemList
) > 5:
279 RaiseParserError(Item
[0], 'LibraryClasses', ContainerFile
, '<LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]')
281 CheckFileType(ItemList
[1], '.Inf', ContainerFile
, 'LibraryClasses', Item
[0], LineNo
)
282 CheckFileExist(WorkspaceDir
, ItemList
[1], ContainerFile
, 'LibraryClasses', Item
[0], LineNo
)
283 if ItemList
[2] != '':
284 CheckPcdTokenInfo(ItemList
[2], 'LibraryClasses', ContainerFile
, LineNo
)
288 return (ItemList
[0], ItemList
[1], ItemList
[2], SupMod
)
292 # Check if PcdTokenInfo is following <TokenSpaceGuidCName>.<PcdCName>
294 # @param TokenInfoString: String to be checked
295 # @param Section: Used for error report
296 # @param File: Used for error report
298 # @retval True PcdTokenInfo is in correct format
300 def CheckPcdTokenInfo(TokenInfoString
, Section
, File
, LineNo
= -1):
301 Format
= '<TokenSpaceGuidCName>.<PcdCName>'
302 if TokenInfoString
!= '' and TokenInfoString
!= None:
303 TokenInfoList
= GetSplitValueList(TokenInfoString
, TAB_SPLIT
)
304 if len(TokenInfoList
) == 2:
307 RaiseParserError(TokenInfoString
, Section
, File
, Format
, LineNo
)
311 # Get Pcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]
313 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]
314 # @param ContainerFile: The file which describes the pcd, used for error report
316 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)
318 def GetPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
319 TokenGuid
, TokenName
, Value
, MaximumDatumSize
, Token
= '', '', '', '', ''
320 List
= GetSplitValueList(Item
+ TAB_VALUE_SPLIT
* 2)
322 if len(List
) < 4 or len(List
) > 6:
323 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]', LineNo
)
326 MaximumDatumSize
= List
[2]
329 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
330 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], TAB_SPLIT
)
332 return (TokenName
, TokenGuid
, Value
, MaximumDatumSize
, Token
, Type
)
334 ## Get FeatureFlagPcd
336 # Get FeatureFlagPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
338 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
339 # @param ContainerFile: The file which describes the pcd, used for error report
341 # @retval (TokenInfo[1], TokenInfo[0], List[1], Type)
343 def GetFeatureFlagPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
344 TokenGuid
, TokenName
, Value
= '', '', ''
345 List
= GetSplitValueList(Item
)
347 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE', LineNo
)
350 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
351 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
353 return (TokenName
, TokenGuid
, Value
, Type
)
355 ## Get DynamicDefaultPcd
357 # Get DynamicDefaultPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]
359 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
360 # @param ContainerFile: The file which describes the pcd, used for error report
362 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)
364 def GetDynamicDefaultPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
365 TokenGuid
, TokenName
, Value
, DatumTyp
, MaxDatumSize
= '', '', '', '', ''
366 List
= GetSplitValueList(Item
+ TAB_VALUE_SPLIT
* 2)
367 if len(List
) < 4 or len(List
) > 8:
368 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]', LineNo
)
372 MaxDatumSize
= List
[3]
373 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
374 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], TAB_SPLIT
)
376 return (TokenName
, TokenGuid
, Value
, DatumTyp
, MaxDatumSize
, Type
)
380 # Get DynamicHiiPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]
382 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
383 # @param ContainerFile: The file which describes the pcd, used for error report
385 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], List[4], List[5], Type)
387 def GetDynamicHiiPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
388 TokenGuid
, TokenName
, L1
, L2
, L3
, L4
, L5
= '', '', '', '', '', '', ''
389 List
= GetSplitValueList(Item
+ TAB_VALUE_SPLIT
* 2)
390 if len(List
) < 6 or len(List
) > 8:
391 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]', LineNo
)
393 L1
, L2
, L3
, L4
, L5
= List
[1], List
[2], List
[3], List
[4], List
[5]
394 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
395 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
397 return (TokenName
, TokenGuid
, L1
, L2
, L3
, L4
, L5
, Type
)
401 # Get DynamicVpdPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]
403 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
404 # @param ContainerFile: The file which describes the pcd, used for error report
406 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], Type)
408 def GetDynamicVpdPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
409 TokenGuid
, TokenName
, L1
, L2
= '', '', '', ''
410 List
= GetSplitValueList(Item
+ TAB_VALUE_SPLIT
)
411 if len(List
) < 3 or len(List
) > 4:
412 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]', LineNo
)
414 L1
, L2
= List
[1], List
[2]
415 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
416 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
418 return (TokenName
, TokenGuid
, L1
, L2
, Type
)
422 # Parse block of the components defined in dsc file
423 # Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]
425 # @param Lines: The content to be parsed
426 # @param KeyValues: To store data after parsing
428 # @retval True Get component successfully
430 def GetComponent(Lines
, KeyValues
):
431 (findBlock
, findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, False, False)
433 LibraryClassItem
= []
441 # Ignore !include statement
443 if Line
.upper().find(TAB_INCLUDE
.upper() + ' ') > -1 or Line
.upper().find(TAB_DEFINE
+ ' ') > -1:
446 if findBlock
== False:
449 # find '{' at line tail
451 if Line
.endswith('{'):
453 ListItem
= CleanString(Line
.rsplit('{', 1)[0], DataType
.TAB_COMMENT_SPLIT
)
456 # Parse a block content
459 if Line
.find('<LibraryClasses>') != -1:
460 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (True, False, False, False, False, False, False)
462 if Line
.find('<BuildOptions>') != -1:
463 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, True, False, False, False, False, False)
465 if Line
.find('<PcdsFeatureFlag>') != -1:
466 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, True, False, False, False, False)
468 if Line
.find('<PcdsPatchableInModule>') != -1:
469 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, True, False, False, False)
471 if Line
.find('<PcdsFixedAtBuild>') != -1:
472 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, True, False, False)
474 if Line
.find('<PcdsDynamic>') != -1:
475 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, True, False)
477 if Line
.find('<PcdsDynamicEx>') != -1:
478 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, True)
480 if Line
.endswith('}'):
482 # find '}' at line tail
484 KeyValues
.append([ListItem
, LibraryClassItem
, BuildOption
, Pcd
])
485 (findBlock
, findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, False, False)
486 LibraryClassItem
, BuildOption
, Pcd
= [], [], []
491 LibraryClassItem
.append(Line
)
492 elif findBuildOption
:
493 BuildOption
.append(Line
)
494 elif findPcdsFeatureFlag
:
495 Pcd
.append((DataType
.TAB_PCDS_FEATURE_FLAG_NULL
, Line
))
496 elif findPcdsPatchableInModule
:
497 Pcd
.append((DataType
.TAB_PCDS_PATCHABLE_IN_MODULE_NULL
, Line
))
498 elif findPcdsFixedAtBuild
:
499 Pcd
.append((DataType
.TAB_PCDS_FIXED_AT_BUILD_NULL
, Line
))
500 elif findPcdsDynamic
:
501 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_DEFAULT_NULL
, Line
))
502 elif findPcdsDynamicEx
:
503 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
, Line
))
505 KeyValues
.append([ListItem
, [], [], []])
511 # Parse a string with format "InfFilename [EXEC = ExecFilename]"
512 # Return (InfFilename, ExecFilename)
514 # @param String: String with EXEC statement
516 # @retval truple() A pair as (InfFilename, ExecFilename)
521 if String
.find('EXEC') > -1:
522 InfFilename
= String
[ : String
.find('EXEC')].strip()
523 ExecFilename
= String
[String
.find('EXEC') + len('EXEC') : ].strip()
525 InfFilename
= String
.strip()
527 return (InfFilename
, ExecFilename
)
531 # Parse block of the components defined in dsc file
532 # Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]
534 # @param Lines: The content to be parsed
535 # @param Key: Reserved
536 # @param KeyValues: To store data after parsing
537 # @param CommentCharacter: Comment char, used to ignore comment content
539 # @retval True Get component successfully
541 def GetComponents(Lines
, Key
, KeyValues
, CommentCharacter
):
542 if Lines
.find(DataType
.TAB_SECTION_END
) > -1:
543 Lines
= Lines
.split(DataType
.TAB_SECTION_END
, 1)[1]
544 (findBlock
, findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, False, False)
546 LibraryClassItem
= []
550 LineList
= Lines
.split('\n')
551 for Line
in LineList
:
552 Line
= CleanString(Line
, CommentCharacter
)
553 if Line
== None or Line
== '':
556 if findBlock
== False:
559 # find '{' at line tail
561 if Line
.endswith('{'):
563 ListItem
= CleanString(Line
.rsplit('{', 1)[0], CommentCharacter
)
566 # Parse a block content
569 if Line
.find('<LibraryClasses>') != -1:
570 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (True, False, False, False, False, False, False)
572 if Line
.find('<BuildOptions>') != -1:
573 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, True, False, False, False, False, False)
575 if Line
.find('<PcdsFeatureFlag>') != -1:
576 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, True, False, False, False, False)
578 if Line
.find('<PcdsPatchableInModule>') != -1:
579 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, True, False, False, False)
581 if Line
.find('<PcdsFixedAtBuild>') != -1:
582 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, True, False, False)
584 if Line
.find('<PcdsDynamic>') != -1:
585 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, True, False)
587 if Line
.find('<PcdsDynamicEx>') != -1:
588 (findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, True)
590 if Line
.endswith('}'):
592 # find '}' at line tail
594 KeyValues
.append([ListItem
, LibraryClassItem
, BuildOption
, Pcd
])
595 (findBlock
, findLibraryClass
, findBuildOption
, findPcdsFeatureFlag
, findPcdsPatchableInModule
, findPcdsFixedAtBuild
, findPcdsDynamic
, findPcdsDynamicEx
) = (False, False, False, False, False, False, False, False)
596 LibraryClassItem
, BuildOption
, Pcd
= [], [], []
601 LibraryClassItem
.append(Line
)
602 elif findBuildOption
:
603 BuildOption
.append(Line
)
604 elif findPcdsFeatureFlag
:
605 Pcd
.append((DataType
.TAB_PCDS_FEATURE_FLAG
, Line
))
606 elif findPcdsPatchableInModule
:
607 Pcd
.append((DataType
.TAB_PCDS_PATCHABLE_IN_MODULE
, Line
))
608 elif findPcdsFixedAtBuild
:
609 Pcd
.append((DataType
.TAB_PCDS_FIXED_AT_BUILD
, Line
))
610 elif findPcdsDynamic
:
611 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC
, Line
))
612 elif findPcdsDynamicEx
:
613 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_EX
, Line
))
615 KeyValues
.append([ListItem
, [], [], []])
621 # Get Source of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
623 # @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
624 # @param ContainerFile: The file which describes the library class, used for error report
626 # @retval (List[0], List[1], List[2], List[3], List[4])
628 def GetSource(Item
, ContainerFile
, FileRelativePath
, LineNo
= -1):
629 ItemNew
= Item
+ DataType
.TAB_VALUE_SPLIT
* 4
630 List
= GetSplitValueList(ItemNew
)
631 if len(List
) < 5 or len(List
) > 9:
632 RaiseParserError(Item
, 'Sources', ContainerFile
, '<Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]', LineNo
)
633 List
[0] = NormPath(List
[0])
634 CheckFileExist(FileRelativePath
, List
[0], ContainerFile
, 'Sources', Item
, LineNo
)
636 CheckPcdTokenInfo(List
[4], 'Sources', ContainerFile
, LineNo
)
638 return (List
[0], List
[1], List
[2], List
[3], List
[4])
642 # Get Binary of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
644 # @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
645 # @param ContainerFile: The file which describes the library class, used for error report
647 # @retval (List[0], List[1], List[2], List[3])
650 def GetBinary(Item
, ContainerFile
, FileRelativePath
, LineNo
= -1):
651 ItemNew
= Item
+ DataType
.TAB_VALUE_SPLIT
652 List
= GetSplitValueList(ItemNew
)
653 if len(List
) != 4 and len(List
) != 5:
654 RaiseParserError(Item
, 'Binaries', ContainerFile
, "<FileType>|<Filename>|<Target>[|<TokenSpaceGuidCName>.<PcdCName>]", LineNo
)
657 CheckPcdTokenInfo(List
[3], 'Binaries', ContainerFile
, LineNo
)
660 return (List
[0], List
[1], List
[2], List
[3])
662 return (List
[0], List
[1], List
[2], '')
664 return (List
[0], List
[1], '', '')
666 return (List
[0], '', '', '')
668 ## Get Guids/Protocols/Ppis
670 # Get Guids/Protocols/Ppis of Inf as <GuidCName>[|<PcdFeatureFlag>]
672 # @param Item: String as <GuidCName>[|<PcdFeatureFlag>]
673 # @param Type: Type of parsing string
674 # @param ContainerFile: The file which describes the library class, used for error report
676 # @retval (List[0], List[1])
678 def GetGuidsProtocolsPpisOfInf(Item
, Type
, ContainerFile
, LineNo
= -1):
679 ItemNew
= Item
+ TAB_VALUE_SPLIT
680 List
= GetSplitValueList(ItemNew
)
682 CheckPcdTokenInfo(List
[1], Type
, ContainerFile
, LineNo
)
684 return (List
[0], List
[1])
686 ## Get Guids/Protocols/Ppis
688 # Get Guids/Protocols/Ppis of Dec as <GuidCName>=<GuidValue>
690 # @param Item: String as <GuidCName>=<GuidValue>
691 # @param Type: Type of parsing string
692 # @param ContainerFile: The file which describes the library class, used for error report
694 # @retval (List[0], List[1])
696 def GetGuidsProtocolsPpisOfDec(Item
, Type
, ContainerFile
, LineNo
= -1):
697 List
= GetSplitValueList(Item
, DataType
.TAB_EQUAL_SPLIT
)
699 RaiseParserError(Item
, Type
, ContainerFile
, '<CName>=<GuidValue>', LineNo
)
701 return (List
[0], List
[1])
705 # Get Package of Inf as <PackagePath>[|<PcdFeatureFlag>]
707 # @param Item: String as <PackagePath>[|<PcdFeatureFlag>]
708 # @param Type: Type of parsing string
709 # @param ContainerFile: The file which describes the library class, used for error report
711 # @retval (List[0], List[1])
713 def GetPackage(Item
, ContainerFile
, FileRelativePath
, LineNo
= -1):
714 ItemNew
= Item
+ TAB_VALUE_SPLIT
715 List
= GetSplitValueList(ItemNew
)
716 CheckFileType(List
[0], '.Dec', ContainerFile
, 'package', List
[0], LineNo
)
717 CheckFileExist(FileRelativePath
, List
[0], ContainerFile
, 'Packages', List
[0], LineNo
)
720 CheckPcdTokenInfo(List
[1], 'Packages', ContainerFile
, LineNo
)
722 return (List
[0], List
[1])
724 ## Get Pcd Values of Inf
726 # Get Pcd of Inf as <TokenSpaceGuidCName>.<PcdCName>[|<Value>]
728 # @param Item: The string describes pcd
729 # @param Type: The type of Pcd
730 # @param File: The file which describes the pcd, used for error report
732 # @retval (TokenSpcCName, TokenCName, Value, ItemType) Formatted Pcd Item
734 def GetPcdOfInf(Item
, Type
, File
, LineNo
):
735 Format
= '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]'
736 TokenGuid
, TokenName
, Value
, InfType
= '', '', '', ''
738 if Type
== TAB_PCDS_FIXED_AT_BUILD
:
739 InfType
= TAB_INF_FIXED_PCD
740 elif Type
== TAB_PCDS_PATCHABLE_IN_MODULE
:
741 InfType
= TAB_INF_PATCH_PCD
742 elif Type
== TAB_PCDS_FEATURE_FLAG
:
743 InfType
= TAB_INF_FEATURE_PCD
744 elif Type
== TAB_PCDS_DYNAMIC_EX
:
745 InfType
= TAB_INF_PCD_EX
746 elif Type
== TAB_PCDS_DYNAMIC
:
747 InfType
= TAB_INF_PCD
748 List
= GetSplitValueList(Item
+ DataType
.TAB_VALUE_SPLIT
)
749 if len(List
) < 2 or len(List
) > 3:
750 RaiseParserError(Item
, InfType
, File
, Format
, LineNo
)
753 TokenInfo
= GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
754 if len(TokenInfo
) != 2:
755 RaiseParserError(Item
, InfType
, File
, Format
, LineNo
)
757 TokenGuid
= TokenInfo
[0]
758 TokenName
= TokenInfo
[1]
760 return (TokenGuid
, TokenName
, Value
, Type
)
763 ## Get Pcd Values of Dec
765 # Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
766 # @retval (TokenSpcCName, TokenCName, Value, DatumType, Token, ItemType) Formatted Pcd Item
768 def GetPcdOfDec(Item
, Type
, File
, LineNo
= -1):
769 Format
= '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>'
770 TokenGuid
, TokenName
, Value
, DatumType
, Token
= '', '', '', '', ''
771 List
= GetSplitValueList(Item
)
773 RaiseParserError(Item
, 'Pcds' + Type
, File
, Format
, LineNo
)
778 TokenInfo
= GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
779 if len(TokenInfo
) != 2:
780 RaiseParserError(Item
, 'Pcds' + Type
, File
, Format
, LineNo
)
782 TokenGuid
= TokenInfo
[0]
783 TokenName
= TokenInfo
[1]
785 return (TokenGuid
, TokenName
, Value
, DatumType
, Token
, Type
)
787 ## Parse DEFINE statement
791 # 1. Insert a record into TblDec
793 # Value2: Macro Value
795 def ParseDefine(LineValue
, StartLine
, Table
, FileID
, Filename
, SectionName
, SectionModel
, Arch
):
796 EdkLogger
.debug(EdkLogger
.DEBUG_2
, "DEFINE statement '%s' found in section %s" % (LineValue
, SectionName
))
797 Define
= GetSplitValueList(CleanString(LineValue
[LineValue
.upper().find(DataType
.TAB_DEFINE
.upper() + ' ') + len(DataType
.TAB_DEFINE
+ ' ') : ]), TAB_EQUAL_SPLIT
, 1)
798 Table
.Insert(MODEL_META_DATA_DEFINE
, Define
[0], Define
[1], '', '', '', Arch
, SectionModel
, FileID
, StartLine
, -1, StartLine
, -1, 0)
800 ## InsertSectionItems
802 # Insert item data of a section to a dict
804 def InsertSectionItems(Model
, CurrentSection
, SectionItemList
, ArchList
, ThirdList
, RecordSet
):
805 # Insert each item data of a section
806 for Index
in range(0, len(ArchList
)):
807 Arch
= ArchList
[Index
]
808 Third
= ThirdList
[Index
]
810 Arch
= TAB_ARCH_COMMON
812 Records
= RecordSet
[Model
]
813 for SectionItem
in SectionItemList
:
814 BelongsToItem
, EndLine
, EndColumn
= -1, -1, -1
815 LineValue
, StartLine
, EndLine
, Comment
= SectionItem
[0], SectionItem
[1], SectionItem
[1], SectionItem
[2]
817 EdkLogger
.debug(4, "Parsing %s ..." %LineValue
)
818 # And then parse DEFINE statement
819 if LineValue
.upper().find(DataType
.TAB_DEFINE
.upper() + ' ') > -1:
822 # At last parse other sections
824 Records
.append([LineValue
, Arch
, StartLine
, ID
, Third
, Comment
])
827 RecordSet
[Model
] = Records
829 ## Insert records to database
831 # Insert item data of a section to database
832 # @param Table: The Table to be inserted
833 # @param FileID: The ID of belonging file
834 # @param Filename: The name of belonging file
835 # @param CurrentSection: The name of currect section
836 # @param SectionItemList: A list of items of the section
837 # @param ArchList: A list of arches
838 # @param ThirdList: A list of third parameters, ModuleType for LibraryClass and SkuId for Dynamic Pcds
839 # @param IfDefList: A list of all conditional statements
840 # @param RecordSet: A dict of all parsed records
842 def InsertSectionItemsIntoDatabase(Table
, FileID
, Filename
, Model
, CurrentSection
, SectionItemList
, ArchList
, ThirdList
, IfDefList
, RecordSet
):
844 # Insert each item data of a section
846 for Index
in range(0, len(ArchList
)):
847 Arch
= ArchList
[Index
]
848 Third
= ThirdList
[Index
]
850 Arch
= TAB_ARCH_COMMON
852 Records
= RecordSet
[Model
]
853 for SectionItem
in SectionItemList
:
854 BelongsToItem
, EndLine
, EndColumn
= -1, -1, -1
855 LineValue
, StartLine
, EndLine
= SectionItem
[0], SectionItem
[1], SectionItem
[1]
857 EdkLogger
.debug(4, "Parsing %s ..." %LineValue
)
859 # And then parse DEFINE statement
861 if LineValue
.upper().find(DataType
.TAB_DEFINE
.upper() + ' ') > -1:
862 ParseDefine(LineValue
, StartLine
, Table
, FileID
, Filename
, CurrentSection
, Model
, Arch
)
866 # At last parse other sections
868 ID
= Table
.Insert(Model
, LineValue
, Third
, Third
, '', '', Arch
, -1, FileID
, StartLine
, -1, StartLine
, -1, 0)
869 Records
.append([LineValue
, Arch
, StartLine
, ID
, Third
])
872 RecordSet
[Model
] = Records
874 ## GenMetaDatSectionItem
875 def GenMetaDatSectionItem(Key
, Value
, List
):
879 List
[Key
].append(Value
)
883 # Check whether the word is valid.
884 # <Word> ::= (a-zA-Z0-9_)(a-zA-Z0-9_-){0,} Alphanumeric characters with
886 # dash "-" and/or underscore "_" characters. No whitespace
887 # characters are permitted.
889 # @param Word: The word string need to be checked.
891 def IsValidWord(Word
):
895 # The first char should be alpha, _ or Digit.
897 if not Word
[0].isalnum() and \
898 not Word
[0] == '_' and \
899 not Word
[0].isdigit():
903 for Char
in Word
[1:]:
904 if (not Char
.isalpha()) and \
905 (not Char
.isdigit()) and \
910 if Char
== '.' and LastChar
== '.':