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