]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Common/Parsing.py
BaseTools: Various typo
[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 - 2018, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
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 __future__ import absolute_import
18 from .StringUtils import *
19 from CommonDataClass.DataClass import *
20 from .DataType import *
21
22 ## ParseDefineMacro
23 #
24 # Search whole table to find all defined Macro and replaced them with the real values
25 #
26 def ParseDefineMacro2(Table, RecordSets, GlobalMacro):
27 Macros = {}
28 #
29 # Find all DEFINE macros in section [Header] and its section
30 #
31 SqlCommand = """select Value1, Value2, BelongsToItem, StartLine, Arch from %s
32 where Model = %s
33 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE)
34 RecordSet = Table.Exec(SqlCommand)
35 for Record in RecordSet:
36 Macros[Record[0]] = Record[1]
37
38 #
39 # Overridden by Global Macros
40 #
41 Macros.update(GlobalMacro)
42
43 #
44 # Replace the Macros
45 #
46 for Value in (v for v in RecordSets.values() if v):
47 for Item in Value:
48 Item[0] = ReplaceMacro(Item[0], Macros)
49
50 ## ParseDefineMacro
51 #
52 # Search whole table to find all defined Macro and replaced them with the real values
53 #
54 def ParseDefineMacro(Table, GlobalMacro):
55 Macros = {}
56 #
57 # Find all DEFINE macros
58 #
59 SqlCommand = """select Value1, Value2, BelongsToItem, StartLine, Arch from %s
60 where Model = %s
61 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE)
62 RecordSet = Table.Exec(SqlCommand)
63 for Record in RecordSet:
64 #***************************************************************************************************************************************************
65 # The follow SqlCommand (expr replace) is not supported in Sqlite 3.3.4 which is used in Python 2.5 *
66 # Reserved Only *
67 # SqlCommand = """update %s set Value1 = replace(Value1, '%s', '%s') *
68 # where ID in (select ID from %s *
69 # where Model = %s *
70 # and Value1 like '%%%s%%' *
71 # and StartLine > %s *
72 # and Enabled > -1 *
73 # and Arch = '%s')""" % \ *
74 # (self.TblDsc.Table, Record[0], Record[1], self.TblDsc.Table, Record[2], Record[1], Record[3], Record[4]) *
75 #***************************************************************************************************************************************************
76 Macros[Record[0]] = Record[1]
77
78 #
79 # Overridden by Global Macros
80 #
81 Macros.update(GlobalMacro)
82
83 #
84 # Found all defined macro and replaced
85 #
86 SqlCommand = """select ID, Value1 from %s
87 where Model != %s
88 and Value1 like '%%$(%%' and Value1 like '%%)%%'
89 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE)
90 FoundRecords = Table.Exec(SqlCommand)
91 for FoundRecord in FoundRecords:
92 NewValue = ReplaceMacro(FoundRecord[1], Macros)
93 SqlCommand = """update %s set Value1 = '%s'
94 where ID = %s""" % (Table.Table, ConvertToSqlString2(NewValue), FoundRecord[0])
95 Table.Exec(SqlCommand)
96
97 ##QueryDefinesItem
98 #
99 # Search item of section [Defines] by name, return its values
100 #
101 # @param Table: The Table to be executed
102 # @param Name: The Name of item of section [Defines]
103 # @param Arch: The Arch of item of section [Defines]
104 #
105 # @retval RecordSet: A list of all matched records
106 #
107 def QueryDefinesItem(Table, Name, Arch, BelongsToFile):
108 SqlCommand = """select Value2 from %s
109 where Model = %s
110 and Value1 = '%s'
111 and Arch = '%s'
112 and BelongsToFile = %s
113 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Name), ConvertToSqlString2(Arch), BelongsToFile)
114 RecordSet = Table.Exec(SqlCommand)
115 if len(RecordSet) < 1:
116 SqlCommand = """select Value2 from %s
117 where Model = %s
118 and Value1 = '%s'
119 and Arch = '%s'
120 and BelongsToFile = %s
121 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Name), ConvertToSqlString2(TAB_ARCH_COMMON.upper()), BelongsToFile)
122 RecordSet = Table.Exec(SqlCommand)
123 if len(RecordSet) == 1:
124 if Name == TAB_INF_DEFINES_LIBRARY_CLASS:
125 return [RecordSet[0][0]]
126 else:
127 return GetSplitValueList(RecordSet[0][0])
128 elif len(RecordSet) < 1:
129 return ['']
130 elif len(RecordSet) > 1:
131 RetVal = []
132 for Record in RecordSet:
133 if Name == TAB_INF_DEFINES_LIBRARY_CLASS:
134 RetVal.append(Record[0])
135 else:
136 Items = GetSplitValueList(Record[0])
137 for Item in Items:
138 RetVal.append(Item)
139 return RetVal
140
141 ##QueryDefinesItem
142 #
143 # Search item of section [Defines] by name, return its values
144 #
145 # @param Table: The Table to be executed
146 # @param Name: The Name of item of section [Defines]
147 # @param Arch: The Arch of item of section [Defines]
148 #
149 # @retval RecordSet: A list of all matched records
150 #
151 def QueryDefinesItem2(Table, Arch, BelongsToFile):
152 SqlCommand = """select Value1, Value2, StartLine from %s
153 where Model = %s
154 and Arch = '%s'
155 and BelongsToFile = %s
156 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Arch), BelongsToFile)
157 RecordSet = Table.Exec(SqlCommand)
158 if len(RecordSet) < 1:
159 SqlCommand = """select Value1, Value2, StartLine from %s
160 where Model = %s
161 and Arch = '%s'
162 and BelongsToFile = %s
163 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(TAB_ARCH_COMMON), BelongsToFile)
164 RecordSet = Table.Exec(SqlCommand)
165
166 return RecordSet
167
168 ##QueryDscItem
169 #
170 # Search all dsc item for a specific section
171 #
172 # @param Table: The Table to be executed
173 # @param Model: The type of section
174 #
175 # @retval RecordSet: A list of all matched records
176 #
177 def QueryDscItem(Table, Model, BelongsToItem, BelongsToFile):
178 SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s
179 where Model = %s
180 and BelongsToItem = %s
181 and BelongsToFile = %s
182 and Enabled > -1""" % (Table.Table, Model, BelongsToItem, BelongsToFile)
183 return Table.Exec(SqlCommand)
184
185 ##QueryDecItem
186 #
187 # Search all dec item for a specific section
188 #
189 # @param Table: The Table to be executed
190 # @param Model: The type of section
191 #
192 # @retval RecordSet: A list of all matched records
193 #
194 def QueryDecItem(Table, Model, BelongsToItem):
195 SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s
196 where Model = %s
197 and BelongsToItem = %s
198 and Enabled > -1""" % (Table.Table, Model, BelongsToItem)
199 return Table.Exec(SqlCommand)
200
201 ##QueryInfItem
202 #
203 # Search all dec item for a specific section
204 #
205 # @param Table: The Table to be executed
206 # @param Model: The type of section
207 #
208 # @retval RecordSet: A list of all matched records
209 #
210 def QueryInfItem(Table, Model, BelongsToItem):
211 SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s
212 where Model = %s
213 and BelongsToItem = %s
214 and Enabled > -1""" % (Table.Table, Model, BelongsToItem)
215 return Table.Exec(SqlCommand)
216
217 ## GetBuildOption
218 #
219 # Parse a string with format "[<Family>:]<ToolFlag>=Flag"
220 # Return (Family, ToolFlag, Flag)
221 #
222 # @param String: String with BuildOption statement
223 # @param File: The file which defines build option, used in error report
224 #
225 # @retval truple() A truple structure as (Family, ToolChain, Flag)
226 #
227 def GetBuildOption(String, File, LineNo = -1):
228 (Family, ToolChain, Flag) = ('', '', '')
229 if String.find(TAB_EQUAL_SPLIT) < 0:
230 RaiseParserError(String, 'BuildOptions', File, '[<Family>:]<ToolFlag>=Flag', LineNo)
231 else:
232 List = GetSplitValueList(String, TAB_EQUAL_SPLIT, MaxSplit = 1)
233 if List[0].find(':') > -1:
234 Family = List[0][ : List[0].find(':')].strip()
235 ToolChain = List[0][List[0].find(':') + 1 : ].strip()
236 else:
237 ToolChain = List[0].strip()
238 Flag = List[1].strip()
239 return (Family, ToolChain, Flag)
240
241 ## Get Library Class
242 #
243 # Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance>
244 #
245 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
246 # @param ContainerFile: The file which describes the library class, used for error report
247 #
248 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item
249 #
250 def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo = -1):
251 List = GetSplitValueList(Item[0])
252 SupMod = SUP_MODULE_LIST_STRING
253 if len(List) != 2:
254 RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, '<LibraryClassKeyWord>|<LibraryInstance>')
255 else:
256 CheckFileType(List[1], '.Inf', ContainerFile, 'library class instance', Item[0], LineNo)
257 CheckFileExist(WorkspaceDir, List[1], ContainerFile, 'LibraryClasses', Item[0], LineNo)
258 if Item[1] != '':
259 SupMod = Item[1]
260
261 return (List[0], List[1], SupMod)
262
263 ## Get Library Class
264 #
265 # Get Library of Dsc as <LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]
266 #
267 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
268 # @param ContainerFile: The file which describes the library class, used for error report
269 #
270 # @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item
271 #
272 def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo = -1):
273 ItemList = GetSplitValueList((Item[0] + DataType.TAB_VALUE_SPLIT * 2))
274 SupMod = SUP_MODULE_LIST_STRING
275
276 if len(ItemList) > 5:
277 RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, '<LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]')
278 else:
279 CheckFileType(ItemList[1], '.Inf', ContainerFile, 'LibraryClasses', Item[0], LineNo)
280 CheckFileExist(WorkspaceDir, ItemList[1], ContainerFile, 'LibraryClasses', Item[0], LineNo)
281 if ItemList[2] != '':
282 CheckPcdTokenInfo(ItemList[2], 'LibraryClasses', ContainerFile, LineNo)
283 if Item[1] != '':
284 SupMod = Item[1]
285
286 return (ItemList[0], ItemList[1], ItemList[2], SupMod)
287
288 ## CheckPcdTokenInfo
289 #
290 # Check if PcdTokenInfo is following <TokenSpaceGuidCName>.<PcdCName>
291 #
292 # @param TokenInfoString: String to be checked
293 # @param Section: Used for error report
294 # @param File: Used for error report
295 #
296 # @retval True PcdTokenInfo is in correct format
297 #
298 def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo = -1):
299 Format = '<TokenSpaceGuidCName>.<PcdCName>'
300 if TokenInfoString != '' and TokenInfoString is not None:
301 TokenInfoList = GetSplitValueList(TokenInfoString, TAB_SPLIT)
302 if len(TokenInfoList) == 2:
303 return True
304
305 RaiseParserError(TokenInfoString, Section, File, Format, LineNo)
306
307 ## Get Pcd
308 #
309 # Get Pcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]
310 #
311 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]
312 # @param ContainerFile: The file which describes the pcd, used for error report
313 #
314 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)
315 #
316 def GetPcd(Item, Type, ContainerFile, LineNo = -1):
317 TokenGuid, TokenName, Value, MaximumDatumSize, Token = '', '', '', '', ''
318 List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2)
319
320 if len(List) < 4 or len(List) > 6:
321 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]', LineNo)
322 else:
323 Value = List[1]
324 MaximumDatumSize = List[2]
325 Token = List[3]
326
327 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
328 (TokenGuid, TokenName) = GetSplitValueList(List[0], TAB_SPLIT)
329
330 return (TokenName, TokenGuid, Value, MaximumDatumSize, Token, Type)
331
332 ## Get FeatureFlagPcd
333 #
334 # Get FeatureFlagPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
335 #
336 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
337 # @param ContainerFile: The file which describes the pcd, used for error report
338 #
339 # @retval (TokenInfo[1], TokenInfo[0], List[1], Type)
340 #
341 def GetFeatureFlagPcd(Item, Type, ContainerFile, LineNo = -1):
342 TokenGuid, TokenName, Value = '', '', ''
343 List = GetSplitValueList(Item)
344 if len(List) != 2:
345 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE', LineNo)
346 else:
347 Value = List[1]
348 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
349 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)
350
351 return (TokenName, TokenGuid, Value, Type)
352
353 ## Get DynamicDefaultPcd
354 #
355 # Get DynamicDefaultPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]
356 #
357 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
358 # @param ContainerFile: The file which describes the pcd, used for error report
359 #
360 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)
361 #
362 def GetDynamicDefaultPcd(Item, Type, ContainerFile, LineNo = -1):
363 TokenGuid, TokenName, Value, DatumTyp, MaxDatumSize = '', '', '', '', ''
364 List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2)
365 if len(List) < 4 or len(List) > 8:
366 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]', LineNo)
367 else:
368 Value = List[1]
369 DatumTyp = List[2]
370 MaxDatumSize = List[3]
371 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
372 (TokenGuid, TokenName) = GetSplitValueList(List[0], TAB_SPLIT)
373
374 return (TokenName, TokenGuid, Value, DatumTyp, MaxDatumSize, Type)
375
376 ## Get DynamicHiiPcd
377 #
378 # Get DynamicHiiPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]
379 #
380 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
381 # @param ContainerFile: The file which describes the pcd, used for error report
382 #
383 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], List[4], List[5], Type)
384 #
385 def GetDynamicHiiPcd(Item, Type, ContainerFile, LineNo = -1):
386 TokenGuid, TokenName, L1, L2, L3, L4, L5 = '', '', '', '', '', '', ''
387 List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2)
388 if len(List) < 6 or len(List) > 8:
389 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]', LineNo)
390 else:
391 L1, L2, L3, L4, L5 = List[1], List[2], List[3], List[4], List[5]
392 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
393 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)
394
395 return (TokenName, TokenGuid, L1, L2, L3, L4, L5, Type)
396
397 ## Get DynamicVpdPcd
398 #
399 # Get DynamicVpdPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]
400 #
401 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
402 # @param ContainerFile: The file which describes the pcd, used for error report
403 #
404 # @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], Type)
405 #
406 def GetDynamicVpdPcd(Item, Type, ContainerFile, LineNo = -1):
407 TokenGuid, TokenName, L1, L2 = '', '', '', ''
408 List = GetSplitValueList(Item + TAB_VALUE_SPLIT)
409 if len(List) < 3 or len(List) > 4:
410 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]', LineNo)
411 else:
412 L1, L2 = List[1], List[2]
413 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
414 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)
415
416 return (TokenName, TokenGuid, L1, L2, Type)
417
418 ## GetComponent
419 #
420 # Parse block of the components defined in dsc file
421 # Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]
422 #
423 # @param Lines: The content to be parsed
424 # @param KeyValues: To store data after parsing
425 #
426 # @retval True Get component successfully
427 #
428 def GetComponent(Lines, KeyValues):
429 (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False)
430 ListItem = None
431 LibraryClassItem = []
432 BuildOption = []
433 Pcd = []
434
435 for Line in Lines:
436 Line = Line[0]
437
438 #
439 # Ignore !include statement
440 #
441 if Line.upper().find(TAB_INCLUDE.upper() + ' ') > -1 or Line.upper().find(TAB_DEFINE + ' ') > -1:
442 continue
443
444 if findBlock == False:
445 ListItem = Line
446 #
447 # find '{' at line tail
448 #
449 if Line.endswith('{'):
450 findBlock = True
451 ListItem = CleanString(Line.rsplit('{', 1)[0], DataType.TAB_COMMENT_SPLIT)
452
453 #
454 # Parse a block content
455 #
456 if findBlock:
457 if Line.find('<LibraryClasses>') != -1:
458 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (True, False, False, False, False, False, False)
459 continue
460 if Line.find('<BuildOptions>') != -1:
461 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, True, False, False, False, False, False)
462 continue
463 if Line.find('<PcdsFeatureFlag>') != -1:
464 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, True, False, False, False, False)
465 continue
466 if Line.find('<PcdsPatchableInModule>') != -1:
467 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, True, False, False, False)
468 continue
469 if Line.find('<PcdsFixedAtBuild>') != -1:
470 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, True, False, False)
471 continue
472 if Line.find('<PcdsDynamic>') != -1:
473 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, True, False)
474 continue
475 if Line.find('<PcdsDynamicEx>') != -1:
476 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, True)
477 continue
478 if Line.endswith('}'):
479 #
480 # find '}' at line tail
481 #
482 KeyValues.append([ListItem, LibraryClassItem, BuildOption, Pcd])
483 (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False)
484 LibraryClassItem, BuildOption, Pcd = [], [], []
485 continue
486
487 if findBlock:
488 if findLibraryClass:
489 LibraryClassItem.append(Line)
490 elif findBuildOption:
491 BuildOption.append(Line)
492 elif findPcdsFeatureFlag:
493 Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG_NULL, Line))
494 elif findPcdsPatchableInModule:
495 Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE_NULL, Line))
496 elif findPcdsFixedAtBuild:
497 Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD_NULL, Line))
498 elif findPcdsDynamic:
499 Pcd.append((DataType.TAB_PCDS_DYNAMIC_DEFAULT_NULL, Line))
500 elif findPcdsDynamicEx:
501 Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL, Line))
502 else:
503 KeyValues.append([ListItem, [], [], []])
504
505 return True
506
507 ## GetExec
508 #
509 # Parse a string with format "InfFilename [EXEC = ExecFilename]"
510 # Return (InfFilename, ExecFilename)
511 #
512 # @param String: String with EXEC statement
513 #
514 # @retval truple() A pair as (InfFilename, ExecFilename)
515 #
516 def GetExec(String):
517 InfFilename = ''
518 ExecFilename = ''
519 if String.find('EXEC') > -1:
520 InfFilename = String[ : String.find('EXEC')].strip()
521 ExecFilename = String[String.find('EXEC') + len('EXEC') : ].strip()
522 else:
523 InfFilename = String.strip()
524
525 return (InfFilename, ExecFilename)
526
527 ## GetComponents
528 #
529 # Parse block of the components defined in dsc file
530 # Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]
531 #
532 # @param Lines: The content to be parsed
533 # @param Key: Reserved
534 # @param KeyValues: To store data after parsing
535 # @param CommentCharacter: Comment char, used to ignore comment content
536 #
537 # @retval True Get component successfully
538 #
539 def GetComponents(Lines, Key, KeyValues, CommentCharacter):
540 if Lines.find(DataType.TAB_SECTION_END) > -1:
541 Lines = Lines.split(DataType.TAB_SECTION_END, 1)[1]
542 (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False)
543 ListItem = None
544 LibraryClassItem = []
545 BuildOption = []
546 Pcd = []
547
548 LineList = Lines.split('\n')
549 for Line in LineList:
550 Line = CleanString(Line, CommentCharacter)
551 if Line is None or Line == '':
552 continue
553
554 if findBlock == False:
555 ListItem = Line
556 #
557 # find '{' at line tail
558 #
559 if Line.endswith('{'):
560 findBlock = True
561 ListItem = CleanString(Line.rsplit('{', 1)[0], CommentCharacter)
562
563 #
564 # Parse a block content
565 #
566 if findBlock:
567 if Line.find('<LibraryClasses>') != -1:
568 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (True, False, False, False, False, False, False)
569 continue
570 if Line.find('<BuildOptions>') != -1:
571 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, True, False, False, False, False, False)
572 continue
573 if Line.find('<PcdsFeatureFlag>') != -1:
574 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, True, False, False, False, False)
575 continue
576 if Line.find('<PcdsPatchableInModule>') != -1:
577 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, True, False, False, False)
578 continue
579 if Line.find('<PcdsFixedAtBuild>') != -1:
580 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, True, False, False)
581 continue
582 if Line.find('<PcdsDynamic>') != -1:
583 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, True, False)
584 continue
585 if Line.find('<PcdsDynamicEx>') != -1:
586 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, True)
587 continue
588 if Line.endswith('}'):
589 #
590 # find '}' at line tail
591 #
592 KeyValues.append([ListItem, LibraryClassItem, BuildOption, Pcd])
593 (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False)
594 LibraryClassItem, BuildOption, Pcd = [], [], []
595 continue
596
597 if findBlock:
598 if findLibraryClass:
599 LibraryClassItem.append(Line)
600 elif findBuildOption:
601 BuildOption.append(Line)
602 elif findPcdsFeatureFlag:
603 Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG, Line))
604 elif findPcdsPatchableInModule:
605 Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE, Line))
606 elif findPcdsFixedAtBuild:
607 Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD, Line))
608 elif findPcdsDynamic:
609 Pcd.append((DataType.TAB_PCDS_DYNAMIC, Line))
610 elif findPcdsDynamicEx:
611 Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX, Line))
612 else:
613 KeyValues.append([ListItem, [], [], []])
614
615 return True
616
617 ## Get Source
618 #
619 # Get Source of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
620 #
621 # @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
622 # @param ContainerFile: The file which describes the library class, used for error report
623 #
624 # @retval (List[0], List[1], List[2], List[3], List[4])
625 #
626 def GetSource(Item, ContainerFile, FileRelativePath, LineNo = -1):
627 ItemNew = Item + DataType.TAB_VALUE_SPLIT * 4
628 List = GetSplitValueList(ItemNew)
629 if len(List) < 5 or len(List) > 9:
630 RaiseParserError(Item, 'Sources', ContainerFile, '<Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]', LineNo)
631 List[0] = NormPath(List[0])
632 CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Sources', Item, LineNo)
633 if List[4] != '':
634 CheckPcdTokenInfo(List[4], 'Sources', ContainerFile, LineNo)
635
636 return (List[0], List[1], List[2], List[3], List[4])
637
638 ## Get Binary
639 #
640 # Get Binary of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
641 #
642 # @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
643 # @param ContainerFile: The file which describes the library class, used for error report
644 #
645 # @retval (List[0], List[1], List[2], List[3])
646 # @retval List
647 #
648 def GetBinary(Item, ContainerFile, FileRelativePath, LineNo = -1):
649 ItemNew = Item + DataType.TAB_VALUE_SPLIT
650 List = GetSplitValueList(ItemNew)
651 if len(List) != 4 and len(List) != 5:
652 RaiseParserError(Item, 'Binaries', ContainerFile, "<FileType>|<Filename>|<Target>[|<TokenSpaceGuidCName>.<PcdCName>]", LineNo)
653 else:
654 if List[3] != '':
655 CheckPcdTokenInfo(List[3], 'Binaries', ContainerFile, LineNo)
656
657 if len(List) == 4:
658 return (List[0], List[1], List[2], List[3])
659 elif len(List) == 3:
660 return (List[0], List[1], List[2], '')
661 elif len(List) == 2:
662 return (List[0], List[1], '', '')
663 elif len(List) == 1:
664 return (List[0], '', '', '')
665
666 ## Get Guids/Protocols/Ppis
667 #
668 # Get Guids/Protocols/Ppis of Inf as <GuidCName>[|<PcdFeatureFlag>]
669 #
670 # @param Item: String as <GuidCName>[|<PcdFeatureFlag>]
671 # @param Type: Type of parsing string
672 # @param ContainerFile: The file which describes the library class, used for error report
673 #
674 # @retval (List[0], List[1])
675 #
676 def GetGuidsProtocolsPpisOfInf(Item, Type, ContainerFile, LineNo = -1):
677 ItemNew = Item + TAB_VALUE_SPLIT
678 List = GetSplitValueList(ItemNew)
679 if List[1] != '':
680 CheckPcdTokenInfo(List[1], Type, ContainerFile, LineNo)
681
682 return (List[0], List[1])
683
684 ## Get Guids/Protocols/Ppis
685 #
686 # Get Guids/Protocols/Ppis of Dec as <GuidCName>=<GuidValue>
687 #
688 # @param Item: String as <GuidCName>=<GuidValue>
689 # @param Type: Type of parsing string
690 # @param ContainerFile: The file which describes the library class, used for error report
691 #
692 # @retval (List[0], List[1])
693 #
694 def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo = -1):
695 List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT)
696 if len(List) != 2:
697 RaiseParserError(Item, Type, ContainerFile, '<CName>=<GuidValue>', LineNo)
698
699 return (List[0], List[1])
700
701 ## GetPackage
702 #
703 # Get Package of Inf as <PackagePath>[|<PcdFeatureFlag>]
704 #
705 # @param Item: String as <PackagePath>[|<PcdFeatureFlag>]
706 # @param Type: Type of parsing string
707 # @param ContainerFile: The file which describes the library class, used for error report
708 #
709 # @retval (List[0], List[1])
710 #
711 def GetPackage(Item, ContainerFile, FileRelativePath, LineNo = -1):
712 ItemNew = Item + TAB_VALUE_SPLIT
713 List = GetSplitValueList(ItemNew)
714 CheckFileType(List[0], '.Dec', ContainerFile, 'package', List[0], LineNo)
715 CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Packages', List[0], LineNo)
716
717 if List[1] != '':
718 CheckPcdTokenInfo(List[1], 'Packages', ContainerFile, LineNo)
719
720 return (List[0], List[1])
721
722 ## Get Pcd Values of Inf
723 #
724 # Get Pcd of Inf as <TokenSpaceGuidCName>.<PcdCName>[|<Value>]
725 #
726 # @param Item: The string describes pcd
727 # @param Type: The type of Pcd
728 # @param File: The file which describes the pcd, used for error report
729 #
730 # @retval (TokenSpcCName, TokenCName, Value, ItemType) Formatted Pcd Item
731 #
732 def GetPcdOfInf(Item, Type, File, LineNo):
733 Format = '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]'
734 TokenGuid, TokenName, Value, InfType = '', '', '', ''
735
736 if Type == TAB_PCDS_FIXED_AT_BUILD:
737 InfType = TAB_INF_FIXED_PCD
738 elif Type == TAB_PCDS_PATCHABLE_IN_MODULE:
739 InfType = TAB_INF_PATCH_PCD
740 elif Type == TAB_PCDS_FEATURE_FLAG:
741 InfType = TAB_INF_FEATURE_PCD
742 elif Type == TAB_PCDS_DYNAMIC_EX:
743 InfType = TAB_INF_PCD_EX
744 elif Type == TAB_PCDS_DYNAMIC:
745 InfType = TAB_INF_PCD
746 List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT)
747 if len(List) < 2 or len(List) > 3:
748 RaiseParserError(Item, InfType, File, Format, LineNo)
749 else:
750 Value = List[1]
751 TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT)
752 if len(TokenInfo) != 2:
753 RaiseParserError(Item, InfType, File, Format, LineNo)
754 else:
755 TokenGuid = TokenInfo[0]
756 TokenName = TokenInfo[1]
757
758 return (TokenGuid, TokenName, Value, Type)
759
760
761 ## Get Pcd Values of Dec
762 #
763 # Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
764 # @retval (TokenSpcCName, TokenCName, Value, DatumType, Token, ItemType) Formatted Pcd Item
765 #
766 def GetPcdOfDec(Item, Type, File, LineNo = -1):
767 Format = '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>'
768 TokenGuid, TokenName, Value, DatumType, Token = '', '', '', '', ''
769 List = GetSplitValueList(Item)
770 if len(List) != 4:
771 RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo)
772 else:
773 Value = List[1]
774 DatumType = List[2]
775 Token = List[3]
776 TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT)
777 if len(TokenInfo) != 2:
778 RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo)
779 else:
780 TokenGuid = TokenInfo[0]
781 TokenName = TokenInfo[1]
782
783 return (TokenGuid, TokenName, Value, DatumType, Token, Type)
784
785 ## Parse DEFINE statement
786 #
787 # Get DEFINE macros
788 #
789 # 1. Insert a record into TblDec
790 # Value1: Macro Name
791 # Value2: Macro Value
792 #
793 def ParseDefine(LineValue, StartLine, Table, FileID, Filename, SectionName, SectionModel, Arch):
794 EdkLogger.debug(EdkLogger.DEBUG_2, "DEFINE statement '%s' found in section %s" % (LineValue, SectionName))
795 Define = GetSplitValueList(CleanString(LineValue[LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') + len(DataType.TAB_DEFINE + ' ') : ]), TAB_EQUAL_SPLIT, 1)
796 Table.Insert(MODEL_META_DATA_DEFINE, Define[0], Define[1], '', '', '', Arch, SectionModel, FileID, StartLine, -1, StartLine, -1, 0)
797
798 ## InsertSectionItems
799 #
800 # Insert item data of a section to a dict
801 #
802 def InsertSectionItems(Model, CurrentSection, SectionItemList, ArchList, ThirdList, RecordSet):
803 # Insert each item data of a section
804 for Index in range(0, len(ArchList)):
805 Arch = ArchList[Index]
806 Third = ThirdList[Index]
807 if Arch == '':
808 Arch = TAB_ARCH_COMMON
809
810 Records = RecordSet[Model]
811 for SectionItem in SectionItemList:
812 BelongsToItem, EndLine, EndColumn = -1, -1, -1
813 LineValue, StartLine, EndLine, Comment = SectionItem[0], SectionItem[1], SectionItem[1], SectionItem[2]
814
815 EdkLogger.debug(4, "Parsing %s ..." %LineValue)
816 # And then parse DEFINE statement
817 if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1:
818 continue
819
820 # At last parse other sections
821 ID = -1
822 Records.append([LineValue, Arch, StartLine, ID, Third, Comment])
823
824 if RecordSet != {}:
825 RecordSet[Model] = Records
826
827 ## Insert records to database
828 #
829 # Insert item data of a section to database
830 # @param Table: The Table to be inserted
831 # @param FileID: The ID of belonging file
832 # @param Filename: The name of belonging file
833 # @param CurrentSection: The name of current section
834 # @param SectionItemList: A list of items of the section
835 # @param ArchList: A list of arches
836 # @param ThirdList: A list of third parameters, ModuleType for LibraryClass and SkuId for Dynamic Pcds
837 # @param IfDefList: A list of all conditional statements
838 # @param RecordSet: A dict of all parsed records
839 #
840 def InsertSectionItemsIntoDatabase(Table, FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, RecordSet):
841 #
842 # Insert each item data of a section
843 #
844 for Index in range(0, len(ArchList)):
845 Arch = ArchList[Index]
846 Third = ThirdList[Index]
847 if Arch == '':
848 Arch = TAB_ARCH_COMMON
849
850 Records = RecordSet[Model]
851 for SectionItem in SectionItemList:
852 BelongsToItem, EndLine, EndColumn = -1, -1, -1
853 LineValue, StartLine, EndLine = SectionItem[0], SectionItem[1], SectionItem[1]
854
855 EdkLogger.debug(4, "Parsing %s ..." %LineValue)
856 #
857 # And then parse DEFINE statement
858 #
859 if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1:
860 ParseDefine(LineValue, StartLine, Table, FileID, Filename, CurrentSection, Model, Arch)
861 continue
862
863 #
864 # At last parse other sections
865 #
866 ID = Table.Insert(Model, LineValue, Third, Third, '', '', Arch, -1, FileID, StartLine, -1, StartLine, -1, 0)
867 Records.append([LineValue, Arch, StartLine, ID, Third])
868
869 if RecordSet != {}:
870 RecordSet[Model] = Records
871
872 ## GenMetaDatSectionItem
873 def GenMetaDatSectionItem(Key, Value, List):
874 if Key not in List:
875 List[Key] = [Value]
876 else:
877 List[Key].append(Value)
878
879 ## IsValidWord
880 #
881 # Check whether the word is valid.
882 # <Word> ::= (a-zA-Z0-9_)(a-zA-Z0-9_-){0,} Alphanumeric characters with
883 # optional
884 # dash "-" and/or underscore "_" characters. No whitespace
885 # characters are permitted.
886 #
887 # @param Word: The word string need to be checked.
888 #
889 def IsValidWord(Word):
890 if not Word:
891 return False
892 #
893 # The first char should be alpha, _ or Digit.
894 #
895 if not Word[0].isalnum() and \
896 not Word[0] == '_' and \
897 not Word[0].isdigit():
898 return False
899
900 LastChar = ''
901 for Char in Word[1:]:
902 if (not Char.isalpha()) and \
903 (not Char.isdigit()) and \
904 Char != '-' and \
905 Char != '_' and \
906 Char != '.':
907 return False
908 if Char == '.' and LastChar == '.':
909 return False
910 LastChar = Char
911
912 return True