]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Common/Parsing.py
BaseTools: use set instead of list for a variable to be used with in
[mirror_edk2.git] / BaseTools / Source / Python / Common / Parsing.py
1 ## @file
2 # This file is used to define common parsing related functions used in parsing INF/DEC/DSC process
3 #
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
9 #
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.
12 #
13
14 ##
15 # Import Modules
16 #
17 from String import *
18 from CommonDataClass.DataClass import *
19 from DataType import *
20
21 ## ParseDefineMacro
22 #
23 # Search whole table to find all defined Macro and replaced them with the real values
24 #
25 def ParseDefineMacro2(Table, RecordSets, GlobalMacro):
26 Macros = {}
27 #
28 # Find all DEFINE macros in section [Header] and its section
29 #
30 SqlCommand = """select Value1, Value2, BelongsToItem, StartLine, Arch from %s
31 where Model = %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]
36
37 #
38 # Overrided by Global Macros
39 #
40 for Key in GlobalMacro.keys():
41 Macros[Key] = GlobalMacro[Key]
42
43 #
44 # Replace the Macros
45 #
46 for Key in RecordSets.keys():
47 if RecordSets[Key] != []:
48 for Item in RecordSets[Key]:
49 Item[0] = ReplaceMacro(Item[0], Macros)
50
51 ## ParseDefineMacro
52 #
53 # Search whole table to find all defined Macro and replaced them with the real values
54 #
55 def ParseDefineMacro(Table, GlobalMacro):
56 Macros = {}
57 #
58 # Find all DEFINE macros
59 #
60 SqlCommand = """select Value1, Value2, BelongsToItem, StartLine, Arch from %s
61 where Model = %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 *
67 # Reserved Only *
68 # SqlCommand = """update %s set Value1 = replace(Value1, '%s', '%s') *
69 # where ID in (select ID from %s *
70 # where Model = %s *
71 # and Value1 like '%%%s%%' *
72 # and StartLine > %s *
73 # and Enabled > -1 *
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]
78
79 #
80 # Overrided by Global Macros
81 #
82 for Key in GlobalMacro.keys():
83 Macros[Key] = GlobalMacro[Key]
84
85 #
86 # Found all defined macro and replaced
87 #
88 SqlCommand = """select ID, Value1 from %s
89 where Model != %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)
98
99 ##QueryDefinesItem
100 #
101 # Search item of section [Defines] by name, return its values
102 #
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]
106 #
107 # @retval RecordSet: A list of all matched records
108 #
109 def QueryDefinesItem(Table, Name, Arch, BelongsToFile):
110 SqlCommand = """select Value2 from %s
111 where Model = %s
112 and Value1 = '%s'
113 and Arch = '%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
119 where Model = %s
120 and Value1 = '%s'
121 and Arch = '%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]]
128 else:
129 return GetSplitValueList(RecordSet[0][0])
130 elif len(RecordSet) < 1:
131 return ['']
132 elif len(RecordSet) > 1:
133 RetVal = []
134 for Record in RecordSet:
135 if Name == TAB_INF_DEFINES_LIBRARY_CLASS:
136 RetVal.append(Record[0])
137 else:
138 Items = GetSplitValueList(Record[0])
139 for Item in Items:
140 RetVal.append(Item)
141 return RetVal
142
143 ##QueryDefinesItem
144 #
145 # Search item of section [Defines] by name, return its values
146 #
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]
150 #
151 # @retval RecordSet: A list of all matched records
152 #
153 def QueryDefinesItem2(Table, Arch, BelongsToFile):
154 SqlCommand = """select Value1, Value2, StartLine from %s
155 where Model = %s
156 and Arch = '%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
162 where Model = %s
163 and Arch = '%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)
167
168 return RecordSet
169
170 ##QueryDscItem
171 #
172 # Search all dsc item for a specific section
173 #
174 # @param Table: The Table to be executed
175 # @param Model: The type of section
176 #
177 # @retval RecordSet: A list of all matched records
178 #
179 def QueryDscItem(Table, Model, BelongsToItem, BelongsToFile):
180 SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s
181 where Model = %s
182 and BelongsToItem = %s
183 and BelongsToFile = %s
184 and Enabled > -1""" % (Table.Table, Model, BelongsToItem, BelongsToFile)
185 return Table.Exec(SqlCommand)
186
187 ##QueryDecItem
188 #
189 # Search all dec item for a specific section
190 #
191 # @param Table: The Table to be executed
192 # @param Model: The type of section
193 #
194 # @retval RecordSet: A list of all matched records
195 #
196 def QueryDecItem(Table, Model, BelongsToItem):
197 SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s
198 where Model = %s
199 and BelongsToItem = %s
200 and Enabled > -1""" % (Table.Table, Model, BelongsToItem)
201 return Table.Exec(SqlCommand)
202
203 ##QueryInfItem
204 #
205 # Search all dec item for a specific section
206 #
207 # @param Table: The Table to be executed
208 # @param Model: The type of section
209 #
210 # @retval RecordSet: A list of all matched records
211 #
212 def QueryInfItem(Table, Model, BelongsToItem):
213 SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s
214 where Model = %s
215 and BelongsToItem = %s
216 and Enabled > -1""" % (Table.Table, Model, BelongsToItem)
217 return Table.Exec(SqlCommand)
218
219 ## GetBuildOption
220 #
221 # Parse a string with format "[<Family>:]<ToolFlag>=Flag"
222 # Return (Family, ToolFlag, Flag)
223 #
224 # @param String: String with BuildOption statement
225 # @param File: The file which defines build option, used in error report
226 #
227 # @retval truple() A truple structure as (Family, ToolChain, Flag)
228 #
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)
233 else:
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()
238 else:
239 ToolChain = List[0].strip()
240 Flag = List[1].strip()
241 return (Family, ToolChain, Flag)
242
243 ## Get Library Class
244 #
245 # Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance>
246 #
247 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
248 # @param ContainerFile: The file which describes the library class, used for error report
249 #
250 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item
251 #
252 def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo = -1):
253 List = GetSplitValueList(Item[0])
254 SupMod = SUP_MODULE_LIST_STRING
255 if len(List) != 2:
256 RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, '<LibraryClassKeyWord>|<LibraryInstance>')
257 else:
258 CheckFileType(List[1], '.Inf', ContainerFile, 'library class instance', Item[0], LineNo)
259 CheckFileExist(WorkspaceDir, List[1], ContainerFile, 'LibraryClasses', Item[0], LineNo)
260 if Item[1] != '':
261 SupMod = Item[1]
262
263 return (List[0], List[1], SupMod)
264
265 ## Get Library Class
266 #
267 # Get Library of Dsc as <LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]
268 #
269 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
270 # @param ContainerFile: The file which describes the library class, used for error report
271 #
272 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item
273 #
274 def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo = -1):
275 ItemList = GetSplitValueList((Item[0] + DataType.TAB_VALUE_SPLIT * 2))
276 SupMod = SUP_MODULE_LIST_STRING
277
278 if len(ItemList) > 5:
279 RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, '<LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]')
280 else:
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)
285 if Item[1] != '':
286 SupMod = Item[1]
287
288 return (ItemList[0], ItemList[1], ItemList[2], SupMod)
289
290 ## CheckPcdTokenInfo
291 #
292 # Check if PcdTokenInfo is following <TokenSpaceGuidCName>.<PcdCName>
293 #
294 # @param TokenInfoString: String to be checked
295 # @param Section: Used for error report
296 # @param File: Used for error report
297 #
298 # @retval True PcdTokenInfo is in correct format
299 #
300 def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo = -1):
301 Format = '<TokenSpaceGuidCName>.<PcdCName>'
302 if TokenInfoString != '' and TokenInfoString is not None:
303 TokenInfoList = GetSplitValueList(TokenInfoString, TAB_SPLIT)
304 if len(TokenInfoList) == 2:
305 return True
306
307 RaiseParserError(TokenInfoString, Section, File, Format, LineNo)
308
309 ## Get Pcd
310 #
311 # Get Pcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]
312 #
313 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]
314 # @param ContainerFile: The file which describes the pcd, used for error report
315 #
316 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)
317 #
318 def GetPcd(Item, Type, ContainerFile, LineNo = -1):
319 TokenGuid, TokenName, Value, MaximumDatumSize, Token = '', '', '', '', ''
320 List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2)
321
322 if len(List) < 4 or len(List) > 6:
323 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]', LineNo)
324 else:
325 Value = List[1]
326 MaximumDatumSize = List[2]
327 Token = List[3]
328
329 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
330 (TokenGuid, TokenName) = GetSplitValueList(List[0], TAB_SPLIT)
331
332 return (TokenName, TokenGuid, Value, MaximumDatumSize, Token, Type)
333
334 ## Get FeatureFlagPcd
335 #
336 # Get FeatureFlagPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
337 #
338 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
339 # @param ContainerFile: The file which describes the pcd, used for error report
340 #
341 # @retval (TokenInfo[1], TokenInfo[0], List[1], Type)
342 #
343 def GetFeatureFlagPcd(Item, Type, ContainerFile, LineNo = -1):
344 TokenGuid, TokenName, Value = '', '', ''
345 List = GetSplitValueList(Item)
346 if len(List) != 2:
347 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE', LineNo)
348 else:
349 Value = List[1]
350 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
351 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)
352
353 return (TokenName, TokenGuid, Value, Type)
354
355 ## Get DynamicDefaultPcd
356 #
357 # Get DynamicDefaultPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]
358 #
359 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
360 # @param ContainerFile: The file which describes the pcd, used for error report
361 #
362 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)
363 #
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)
369 else:
370 Value = List[1]
371 DatumTyp = List[2]
372 MaxDatumSize = List[3]
373 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
374 (TokenGuid, TokenName) = GetSplitValueList(List[0], TAB_SPLIT)
375
376 return (TokenName, TokenGuid, Value, DatumTyp, MaxDatumSize, Type)
377
378 ## Get DynamicHiiPcd
379 #
380 # Get DynamicHiiPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]
381 #
382 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
383 # @param ContainerFile: The file which describes the pcd, used for error report
384 #
385 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], List[4], List[5], Type)
386 #
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)
392 else:
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)
396
397 return (TokenName, TokenGuid, L1, L2, L3, L4, L5, Type)
398
399 ## Get DynamicVpdPcd
400 #
401 # Get DynamicVpdPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]
402 #
403 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
404 # @param ContainerFile: The file which describes the pcd, used for error report
405 #
406 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], Type)
407 #
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)
413 else:
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)
417
418 return (TokenName, TokenGuid, L1, L2, Type)
419
420 ## GetComponent
421 #
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]], ...]
424 #
425 # @param Lines: The content to be parsed
426 # @param KeyValues: To store data after parsing
427 #
428 # @retval True Get component successfully
429 #
430 def GetComponent(Lines, KeyValues):
431 (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False)
432 ListItem = None
433 LibraryClassItem = []
434 BuildOption = []
435 Pcd = []
436
437 for Line in Lines:
438 Line = Line[0]
439
440 #
441 # Ignore !include statement
442 #
443 if Line.upper().find(TAB_INCLUDE.upper() + ' ') > -1 or Line.upper().find(TAB_DEFINE + ' ') > -1:
444 continue
445
446 if findBlock == False:
447 ListItem = Line
448 #
449 # find '{' at line tail
450 #
451 if Line.endswith('{'):
452 findBlock = True
453 ListItem = CleanString(Line.rsplit('{', 1)[0], DataType.TAB_COMMENT_SPLIT)
454
455 #
456 # Parse a block content
457 #
458 if findBlock:
459 if Line.find('<LibraryClasses>') != -1:
460 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (True, False, False, False, False, False, False)
461 continue
462 if Line.find('<BuildOptions>') != -1:
463 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, True, False, False, False, False, False)
464 continue
465 if Line.find('<PcdsFeatureFlag>') != -1:
466 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, True, False, False, False, False)
467 continue
468 if Line.find('<PcdsPatchableInModule>') != -1:
469 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, True, False, False, False)
470 continue
471 if Line.find('<PcdsFixedAtBuild>') != -1:
472 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, True, False, False)
473 continue
474 if Line.find('<PcdsDynamic>') != -1:
475 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, True, False)
476 continue
477 if Line.find('<PcdsDynamicEx>') != -1:
478 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, True)
479 continue
480 if Line.endswith('}'):
481 #
482 # find '}' at line tail
483 #
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 = [], [], []
487 continue
488
489 if findBlock:
490 if findLibraryClass:
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))
504 else:
505 KeyValues.append([ListItem, [], [], []])
506
507 return True
508
509 ## GetExec
510 #
511 # Parse a string with format "InfFilename [EXEC = ExecFilename]"
512 # Return (InfFilename, ExecFilename)
513 #
514 # @param String: String with EXEC statement
515 #
516 # @retval truple() A pair as (InfFilename, ExecFilename)
517 #
518 def GetExec(String):
519 InfFilename = ''
520 ExecFilename = ''
521 if String.find('EXEC') > -1:
522 InfFilename = String[ : String.find('EXEC')].strip()
523 ExecFilename = String[String.find('EXEC') + len('EXEC') : ].strip()
524 else:
525 InfFilename = String.strip()
526
527 return (InfFilename, ExecFilename)
528
529 ## GetComponents
530 #
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]], ...]
533 #
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
538 #
539 # @retval True Get component successfully
540 #
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)
545 ListItem = None
546 LibraryClassItem = []
547 BuildOption = []
548 Pcd = []
549
550 LineList = Lines.split('\n')
551 for Line in LineList:
552 Line = CleanString(Line, CommentCharacter)
553 if Line is None or Line == '':
554 continue
555
556 if findBlock == False:
557 ListItem = Line
558 #
559 # find '{' at line tail
560 #
561 if Line.endswith('{'):
562 findBlock = True
563 ListItem = CleanString(Line.rsplit('{', 1)[0], CommentCharacter)
564
565 #
566 # Parse a block content
567 #
568 if findBlock:
569 if Line.find('<LibraryClasses>') != -1:
570 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (True, False, False, False, False, False, False)
571 continue
572 if Line.find('<BuildOptions>') != -1:
573 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, True, False, False, False, False, False)
574 continue
575 if Line.find('<PcdsFeatureFlag>') != -1:
576 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, True, False, False, False, False)
577 continue
578 if Line.find('<PcdsPatchableInModule>') != -1:
579 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, True, False, False, False)
580 continue
581 if Line.find('<PcdsFixedAtBuild>') != -1:
582 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, True, False, False)
583 continue
584 if Line.find('<PcdsDynamic>') != -1:
585 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, True, False)
586 continue
587 if Line.find('<PcdsDynamicEx>') != -1:
588 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, True)
589 continue
590 if Line.endswith('}'):
591 #
592 # find '}' at line tail
593 #
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 = [], [], []
597 continue
598
599 if findBlock:
600 if findLibraryClass:
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))
614 else:
615 KeyValues.append([ListItem, [], [], []])
616
617 return True
618
619 ## Get Source
620 #
621 # Get Source of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
622 #
623 # @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
624 # @param ContainerFile: The file which describes the library class, used for error report
625 #
626 # @retval (List[0], List[1], List[2], List[3], List[4])
627 #
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)
635 if List[4] != '':
636 CheckPcdTokenInfo(List[4], 'Sources', ContainerFile, LineNo)
637
638 return (List[0], List[1], List[2], List[3], List[4])
639
640 ## Get Binary
641 #
642 # Get Binary of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
643 #
644 # @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
645 # @param ContainerFile: The file which describes the library class, used for error report
646 #
647 # @retval (List[0], List[1], List[2], List[3])
648 # @retval List
649 #
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)
655 else:
656 if List[3] != '':
657 CheckPcdTokenInfo(List[3], 'Binaries', ContainerFile, LineNo)
658
659 if len(List) == 4:
660 return (List[0], List[1], List[2], List[3])
661 elif len(List) == 3:
662 return (List[0], List[1], List[2], '')
663 elif len(List) == 2:
664 return (List[0], List[1], '', '')
665 elif len(List) == 1:
666 return (List[0], '', '', '')
667
668 ## Get Guids/Protocols/Ppis
669 #
670 # Get Guids/Protocols/Ppis of Inf as <GuidCName>[|<PcdFeatureFlag>]
671 #
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
675 #
676 # @retval (List[0], List[1])
677 #
678 def GetGuidsProtocolsPpisOfInf(Item, Type, ContainerFile, LineNo = -1):
679 ItemNew = Item + TAB_VALUE_SPLIT
680 List = GetSplitValueList(ItemNew)
681 if List[1] != '':
682 CheckPcdTokenInfo(List[1], Type, ContainerFile, LineNo)
683
684 return (List[0], List[1])
685
686 ## Get Guids/Protocols/Ppis
687 #
688 # Get Guids/Protocols/Ppis of Dec as <GuidCName>=<GuidValue>
689 #
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
693 #
694 # @retval (List[0], List[1])
695 #
696 def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo = -1):
697 List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT)
698 if len(List) != 2:
699 RaiseParserError(Item, Type, ContainerFile, '<CName>=<GuidValue>', LineNo)
700
701 return (List[0], List[1])
702
703 ## GetPackage
704 #
705 # Get Package of Inf as <PackagePath>[|<PcdFeatureFlag>]
706 #
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
710 #
711 # @retval (List[0], List[1])
712 #
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)
718
719 if List[1] != '':
720 CheckPcdTokenInfo(List[1], 'Packages', ContainerFile, LineNo)
721
722 return (List[0], List[1])
723
724 ## Get Pcd Values of Inf
725 #
726 # Get Pcd of Inf as <TokenSpaceGuidCName>.<PcdCName>[|<Value>]
727 #
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
731 #
732 # @retval (TokenSpcCName, TokenCName, Value, ItemType) Formatted Pcd Item
733 #
734 def GetPcdOfInf(Item, Type, File, LineNo):
735 Format = '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]'
736 TokenGuid, TokenName, Value, InfType = '', '', '', ''
737
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)
751 else:
752 Value = List[1]
753 TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT)
754 if len(TokenInfo) != 2:
755 RaiseParserError(Item, InfType, File, Format, LineNo)
756 else:
757 TokenGuid = TokenInfo[0]
758 TokenName = TokenInfo[1]
759
760 return (TokenGuid, TokenName, Value, Type)
761
762
763 ## Get Pcd Values of Dec
764 #
765 # Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
766 # @retval (TokenSpcCName, TokenCName, Value, DatumType, Token, ItemType) Formatted Pcd Item
767 #
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)
772 if len(List) != 4:
773 RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo)
774 else:
775 Value = List[1]
776 DatumType = List[2]
777 Token = List[3]
778 TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT)
779 if len(TokenInfo) != 2:
780 RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo)
781 else:
782 TokenGuid = TokenInfo[0]
783 TokenName = TokenInfo[1]
784
785 return (TokenGuid, TokenName, Value, DatumType, Token, Type)
786
787 ## Parse DEFINE statement
788 #
789 # Get DEFINE macros
790 #
791 # 1. Insert a record into TblDec
792 # Value1: Macro Name
793 # Value2: Macro Value
794 #
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)
799
800 ## InsertSectionItems
801 #
802 # Insert item data of a section to a dict
803 #
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]
809 if Arch == '':
810 Arch = TAB_ARCH_COMMON
811
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]
816
817 EdkLogger.debug(4, "Parsing %s ..." %LineValue)
818 # And then parse DEFINE statement
819 if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1:
820 continue
821
822 # At last parse other sections
823 ID = -1
824 Records.append([LineValue, Arch, StartLine, ID, Third, Comment])
825
826 if RecordSet != {}:
827 RecordSet[Model] = Records
828
829 ## Insert records to database
830 #
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
841 #
842 def InsertSectionItemsIntoDatabase(Table, FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, RecordSet):
843 #
844 # Insert each item data of a section
845 #
846 for Index in range(0, len(ArchList)):
847 Arch = ArchList[Index]
848 Third = ThirdList[Index]
849 if Arch == '':
850 Arch = TAB_ARCH_COMMON
851
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]
856
857 EdkLogger.debug(4, "Parsing %s ..." %LineValue)
858 #
859 # And then parse DEFINE statement
860 #
861 if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1:
862 ParseDefine(LineValue, StartLine, Table, FileID, Filename, CurrentSection, Model, Arch)
863 continue
864
865 #
866 # At last parse other sections
867 #
868 ID = Table.Insert(Model, LineValue, Third, Third, '', '', Arch, -1, FileID, StartLine, -1, StartLine, -1, 0)
869 Records.append([LineValue, Arch, StartLine, ID, Third])
870
871 if RecordSet != {}:
872 RecordSet[Model] = Records
873
874 ## GenMetaDatSectionItem
875 def GenMetaDatSectionItem(Key, Value, List):
876 if Key not in List:
877 List[Key] = [Value]
878 else:
879 List[Key].append(Value)
880
881 ## IsValidWord
882 #
883 # Check whether the word is valid.
884 # <Word> ::= (a-zA-Z0-9_)(a-zA-Z0-9_-){0,} Alphanumeric characters with
885 # optional
886 # dash "-" and/or underscore "_" characters. No whitespace
887 # characters are permitted.
888 #
889 # @param Word: The word string need to be checked.
890 #
891 def IsValidWord(Word):
892 if not Word:
893 return False
894 #
895 # The first char should be alpha, _ or Digit.
896 #
897 if not Word[0].isalnum() and \
898 not Word[0] == '_' and \
899 not Word[0].isdigit():
900 return False
901
902 LastChar = ''
903 for Char in Word[1:]:
904 if (not Char.isalpha()) and \
905 (not Char.isdigit()) and \
906 Char != '-' and \
907 Char != '_' and \
908 Char != '.':
909 return False
910 if Char == '.' and LastChar == '.':
911 return False
912 LastChar = Char
913
914 return True