2 # This file is used to define common parsing related functions used in parsing
5 # Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
7 # This program and the accompanying materials are licensed and made available
8 # under the terms and conditions of the BSD License which accompanies this
9 # distribution. The full text of the license may be found at
10 # http://opensource.org/licenses/bsd-license.php
12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
26 from Library
.String
import RaiseParserError
27 from Library
.String
import GetSplitValueList
28 from Library
.String
import CheckFileType
29 from Library
.String
import CheckFileExist
30 from Library
.String
import CleanString
31 from Library
.String
import NormPath
33 from Logger
.ToolError
import FILE_NOT_FOUND
34 from Logger
.ToolError
import FatalError
35 from Logger
.ToolError
import FORMAT_INVALID
37 from Library
import DataType
39 from Library
.Misc
import GuidStructureStringToGuidString
40 from Library
.Misc
import CheckGuidRegFormat
41 from Logger
import StringTable
as ST
42 import Logger
.Log
as Logger
44 from Parser
.DecParser
import Dec
51 # Parse a string with format "[<Family>:]<ToolFlag>=Flag"
52 # Return (Family, ToolFlag, Flag)
54 # @param String: String with BuildOption statement
55 # @param File: The file which defines build option, used in error report
57 def GetBuildOption(String
, File
, LineNo
= -1):
58 (Family
, ToolChain
, Flag
) = ('', '', '')
59 if String
.find(DataType
.TAB_EQUAL_SPLIT
) < 0:
60 RaiseParserError(String
, 'BuildOptions', File
, \
61 '[<Family>:]<ToolFlag>=Flag', LineNo
)
63 List
= GetSplitValueList(String
, DataType
.TAB_EQUAL_SPLIT
, MaxSplit
=1)
64 if List
[0].find(':') > -1:
65 Family
= List
[0][ : List
[0].find(':')].strip()
66 ToolChain
= List
[0][List
[0].find(':') + 1 : ].strip()
68 ToolChain
= List
[0].strip()
69 Flag
= List
[1].strip()
70 return (Family
, ToolChain
, Flag
)
74 # Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance>
76 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
77 # @param ContainerFile: The file which describes the library class, used for
80 def GetLibraryClass(Item
, ContainerFile
, WorkspaceDir
, LineNo
= -1):
81 List
= GetSplitValueList(Item
[0])
82 SupMod
= DataType
.SUP_MODULE_LIST_STRING
84 RaiseParserError(Item
[0], 'LibraryClasses', ContainerFile
, \
85 '<LibraryClassKeyWord>|<LibraryInstance>')
87 CheckFileType(List
[1], '.Inf', ContainerFile
, \
88 'library class instance', Item
[0], LineNo
)
89 CheckFileExist(WorkspaceDir
, List
[1], ContainerFile
, \
90 'LibraryClasses', Item
[0], LineNo
)
94 return (List
[0], List
[1], SupMod
)
98 # Get Library of Dsc as <LibraryClassKeyWord>[|<LibraryInstance>]
99 # [|<TokenSpaceGuidCName>.<PcdCName>]
101 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
102 # @param ContainerFile: The file which describes the library class, used for
105 def GetLibraryClassOfInf(Item
, ContainerFile
, WorkspaceDir
, LineNo
= -1):
106 ItemList
= GetSplitValueList((Item
[0] + DataType
.TAB_VALUE_SPLIT
* 2))
107 SupMod
= DataType
.SUP_MODULE_LIST_STRING
109 if len(ItemList
) > 5:
111 (Item
[0], 'LibraryClasses', ContainerFile
, \
112 '<LibraryClassKeyWord>[|<LibraryInstance>]\
113 [|<TokenSpaceGuidCName>.<PcdCName>]')
115 CheckFileType(ItemList
[1], '.Inf', ContainerFile
, 'LibraryClasses', \
117 CheckFileExist(WorkspaceDir
, ItemList
[1], ContainerFile
, \
118 'LibraryClasses', Item
[0], LineNo
)
119 if ItemList
[2] != '':
120 CheckPcdTokenInfo(ItemList
[2], 'LibraryClasses', \
121 ContainerFile
, LineNo
)
125 return (ItemList
[0], ItemList
[1], ItemList
[2], SupMod
)
129 # Check if PcdTokenInfo is following <TokenSpaceGuidCName>.<PcdCName>
131 # @param TokenInfoString: String to be checked
132 # @param Section: Used for error report
133 # @param File: Used for error report
135 def CheckPcdTokenInfo(TokenInfoString
, Section
, File
, LineNo
= -1):
136 Format
= '<TokenSpaceGuidCName>.<PcdCName>'
137 if TokenInfoString
!= '' and TokenInfoString
!= None:
138 TokenInfoList
= GetSplitValueList(TokenInfoString
, DataType
.TAB_SPLIT
)
139 if len(TokenInfoList
) == 2:
142 RaiseParserError(TokenInfoString
, Section
, File
, Format
, LineNo
)
146 # Get Pcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>
147 # [|<Type>|<MaximumDatumSize>]
149 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|
150 # <Value>[|<Type>|<MaximumDatumSize>]
151 # @param ContainerFile: The file which describes the pcd, used for error
155 def GetPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
156 TokenGuid
, TokenName
, Value
, MaximumDatumSize
, Token
= '', '', '', '', ''
157 List
= GetSplitValueList(Item
+ DataType
.TAB_VALUE_SPLIT
* 2)
159 if len(List
) < 4 or len(List
) > 6:
160 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, \
161 '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>\
162 [|<Type>|<MaximumDatumSize>]', LineNo
)
165 MaximumDatumSize
= List
[2]
168 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
169 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
171 return (TokenName
, TokenGuid
, Value
, MaximumDatumSize
, Token
, Type
)
173 ## Get FeatureFlagPcd
175 # Get FeatureFlagPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
177 # @param Item: String as <PcdTokenSpaceGuidCName>
178 # .<TokenCName>|TRUE/FALSE
179 # @param ContainerFile: The file which describes the pcd, used for error
182 def GetFeatureFlagPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
183 TokenGuid
, TokenName
, Value
= '', '', ''
184 List
= GetSplitValueList(Item
)
186 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, \
187 '<PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE', \
191 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
192 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
194 return (TokenName
, TokenGuid
, Value
, Type
)
196 ## Get DynamicDefaultPcd
198 # Get DynamicDefaultPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>
199 # |<Value>[|<DatumTyp>[|<MaxDatumSize>]]
201 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|
203 # @param ContainerFile: The file which describes the pcd, used for error
206 def GetDynamicDefaultPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
207 TokenGuid
, TokenName
, Value
, DatumTyp
, MaxDatumSize
= '', '', '', '', ''
208 List
= GetSplitValueList(Item
+ DataType
.TAB_VALUE_SPLIT
* 2)
209 if len(List
) < 4 or len(List
) > 8:
210 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, \
211 '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>\
212 [|<DatumTyp>[|<MaxDatumSize>]]', LineNo
)
216 MaxDatumSize
= List
[3]
217 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
218 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
220 return (TokenName
, TokenGuid
, Value
, DatumTyp
, MaxDatumSize
, Type
)
224 # Get DynamicHiiPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<String>|
225 # <VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]
227 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|
229 # @param ContainerFile: The file which describes the pcd, used for error
232 def GetDynamicHiiPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
233 TokenGuid
, TokenName
, List1
, List2
, List3
, List4
, List5
= \
234 '', '', '', '', '', '', ''
235 List
= GetSplitValueList(Item
+ DataType
.TAB_VALUE_SPLIT
* 2)
236 if len(List
) < 6 or len(List
) > 8:
237 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, \
238 '<PcdTokenSpaceGuidCName>.<TokenCName>|<String>|\
239 <VariableGuidCName>|<VariableOffset>[|<DefaultValue>\
240 [|<MaximumDatumSize>]]', LineNo
)
242 List1
, List2
, List3
, List4
, List5
= \
243 List
[1], List
[2], List
[3], List
[4], List
[5]
244 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
245 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
247 return (TokenName
, TokenGuid
, List1
, List2
, List3
, List4
, List5
, Type
)
251 # Get DynamicVpdPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|
252 # <VpdOffset>[|<MaximumDatumSize>]
254 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>
256 # @param ContainerFile: The file which describes the pcd, used for error
259 def GetDynamicVpdPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
260 TokenGuid
, TokenName
, List1
, List2
= '', '', '', ''
261 List
= GetSplitValueList(Item
+ DataType
.TAB_VALUE_SPLIT
)
262 if len(List
) < 3 or len(List
) > 4:
263 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, \
264 '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>\
265 [|<MaximumDatumSize>]', LineNo
)
267 List1
, List2
= List
[1], List
[2]
268 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
269 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
271 return (TokenName
, TokenGuid
, List1
, List2
, Type
)
275 # Parse block of the components defined in dsc file
276 # Set KeyValues as [ ['component name', [lib1, lib2, lib3],
277 # [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]
279 # @param Lines: The content to be parsed
280 # @param KeyValues: To store data after parsing
282 def GetComponent(Lines
, KeyValues
):
283 (FindBlock
, FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
284 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, FindPcdsDynamic
, \
285 FindPcdsDynamicEx
) = (False, False, False, False, False, False, False, \
288 LibraryClassItem
= []
295 # Ignore !include statement
297 if Line
.upper().find(DataType
.TAB_INCLUDE
.upper() + ' ') > -1 or \
298 Line
.upper().find(DataType
.TAB_DEFINE
+ ' ') > -1:
301 if FindBlock
== False:
304 # find '{' at line tail
306 if Line
.endswith('{'):
308 ListItem
= CleanString(Line
.rsplit('{', 1)[0], \
309 DataType
.TAB_COMMENT_SPLIT
)
312 # Parse a block content
315 if Line
.find('<LibraryClasses>') != -1:
316 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
317 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
318 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
319 (True, False, False, False, False, False, False)
321 if Line
.find('<BuildOptions>') != -1:
322 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
323 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
324 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
325 (False, True, False, False, False, False, False)
327 if Line
.find('<PcdsFeatureFlag>') != -1:
328 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
329 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
330 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
331 (False, False, True, False, False, False, False)
333 if Line
.find('<PcdsPatchableInModule>') != -1:
334 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
335 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
336 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
337 (False, False, False, True, False, False, False)
339 if Line
.find('<PcdsFixedAtBuild>') != -1:
340 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
341 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
342 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
343 (False, False, False, False, True, False, False)
345 if Line
.find('<PcdsDynamic>') != -1:
346 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
347 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
348 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
349 (False, False, False, False, False, True, False)
351 if Line
.find('<PcdsDynamicEx>') != -1:
352 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
353 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
354 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
355 (False, False, False, False, False, False, True)
357 if Line
.endswith('}'):
359 # find '}' at line tail
361 KeyValues
.append([ListItem
, LibraryClassItem
, \
363 (FindBlock
, FindLibraryClass
, FindBuildOption
, \
364 FindPcdsFeatureFlag
, FindPcdsPatchableInModule
, \
365 FindPcdsFixedAtBuild
, FindPcdsDynamic
, FindPcdsDynamicEx
) = \
366 (False, False, False, False, False, False, False, False)
367 LibraryClassItem
, BuildOption
, Pcd
= [], [], []
372 LibraryClassItem
.append(Line
)
373 elif FindBuildOption
:
374 BuildOption
.append(Line
)
375 elif FindPcdsFeatureFlag
:
376 Pcd
.append((DataType
.TAB_PCDS_FEATURE_FLAG_NULL
, Line
))
377 elif FindPcdsPatchableInModule
:
378 Pcd
.append((DataType
.TAB_PCDS_PATCHABLE_IN_MODULE_NULL
, Line
))
379 elif FindPcdsFixedAtBuild
:
380 Pcd
.append((DataType
.TAB_PCDS_FIXED_AT_BUILD_NULL
, Line
))
381 elif FindPcdsDynamic
:
382 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_DEFAULT_NULL
, Line
))
383 elif FindPcdsDynamicEx
:
384 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
, Line
))
386 KeyValues
.append([ListItem
, [], [], []])
392 # Parse a string with format "InfFilename [EXEC = ExecFilename]"
393 # Return (InfFilename, ExecFilename)
395 # @param String: String with EXEC statement
400 if String
.find('EXEC') > -1:
401 InfFilename
= String
[ : String
.find('EXEC')].strip()
402 ExecFilename
= String
[String
.find('EXEC') + len('EXEC') : ].strip()
404 InfFilename
= String
.strip()
406 return (InfFilename
, ExecFilename
)
410 # Parse block of the components defined in dsc file
411 # Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3],
412 # [pcd1, pcd2, pcd3]], ...]
414 # @param Lines: The content to be parsed
415 # @param Key: Reserved
416 # @param KeyValues: To store data after parsing
417 # @param CommentCharacter: Comment char, used to ignore comment content
419 # @retval True Get component successfully
421 def GetComponents(Lines
, KeyValues
, CommentCharacter
):
422 if Lines
.find(DataType
.TAB_SECTION_END
) > -1:
423 Lines
= Lines
.split(DataType
.TAB_SECTION_END
, 1)[1]
424 (FindBlock
, FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
425 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, FindPcdsDynamic
, \
426 FindPcdsDynamicEx
) = \
427 (False, False, False, False, False, False, False, False)
429 LibraryClassItem
= []
433 LineList
= Lines
.split('\n')
434 for Line
in LineList
:
435 Line
= CleanString(Line
, CommentCharacter
)
436 if Line
== None or Line
== '':
439 if FindBlock
== False:
442 # find '{' at line tail
444 if Line
.endswith('{'):
446 ListItem
= CleanString(Line
.rsplit('{', 1)[0], CommentCharacter
)
449 # Parse a block content
452 if Line
.find('<LibraryClasses>') != -1:
453 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
454 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
455 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
456 (True, False, False, False, False, False, False)
458 if Line
.find('<BuildOptions>') != -1:
459 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
460 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
461 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
462 (False, True, False, False, False, False, False)
464 if Line
.find('<PcdsFeatureFlag>') != -1:
465 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
466 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
467 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
468 (False, False, True, False, False, False, False)
470 if Line
.find('<PcdsPatchableInModule>') != -1:
471 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
472 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
473 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
474 (False, False, False, True, False, False, False)
476 if Line
.find('<PcdsFixedAtBuild>') != -1:
477 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
478 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
479 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
480 (False, False, False, False, True, False, False)
482 if Line
.find('<PcdsDynamic>') != -1:
483 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
484 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
485 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
486 (False, False, False, False, False, True, False)
488 if Line
.find('<PcdsDynamicEx>') != -1:
489 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
490 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
491 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
492 (False, False, False, False, False, False, True)
494 if Line
.endswith('}'):
496 # find '}' at line tail
498 KeyValues
.append([ListItem
, LibraryClassItem
, BuildOption
, \
500 (FindBlock
, FindLibraryClass
, FindBuildOption
, \
501 FindPcdsFeatureFlag
, FindPcdsPatchableInModule
, \
502 FindPcdsFixedAtBuild
, FindPcdsDynamic
, FindPcdsDynamicEx
) = \
503 (False, False, False, False, False, False, False, False)
504 LibraryClassItem
, BuildOption
, Pcd
= [], [], []
509 LibraryClassItem
.append(Line
)
510 elif FindBuildOption
:
511 BuildOption
.append(Line
)
512 elif FindPcdsFeatureFlag
:
513 Pcd
.append((DataType
.TAB_PCDS_FEATURE_FLAG
, Line
))
514 elif FindPcdsPatchableInModule
:
515 Pcd
.append((DataType
.TAB_PCDS_PATCHABLE_IN_MODULE
, Line
))
516 elif FindPcdsFixedAtBuild
:
517 Pcd
.append((DataType
.TAB_PCDS_FIXED_AT_BUILD
, Line
))
518 elif FindPcdsDynamic
:
519 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC
, Line
))
520 elif FindPcdsDynamicEx
:
521 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_EX
, Line
))
523 KeyValues
.append([ListItem
, [], [], []])
529 # Get Source of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>
530 # [|<PcdFeatureFlag>]]]]
532 # @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>
533 # [|<PcdFeatureFlag>]]]]
534 # @param ContainerFile: The file which describes the library class, used
537 def GetSource(Item
, ContainerFile
, FileRelativePath
, LineNo
= -1):
538 ItemNew
= Item
+ DataType
.TAB_VALUE_SPLIT
* 4
539 List
= GetSplitValueList(ItemNew
)
540 if len(List
) < 5 or len(List
) > 9:
541 RaiseParserError(Item
, 'Sources', ContainerFile
, \
542 '<Filename>[|<Family>[|<TagName>[|<ToolCode>\
543 [|<PcdFeatureFlag>]]]]', LineNo
)
544 List
[0] = NormPath(List
[0])
545 CheckFileExist(FileRelativePath
, List
[0], ContainerFile
, 'Sources', \
548 CheckPcdTokenInfo(List
[4], 'Sources', ContainerFile
, LineNo
)
550 return (List
[0], List
[1], List
[2], List
[3], List
[4])
554 # Get Binary of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>
555 # [|<PcdFeatureFlag>]]]]
557 # @param Item: String as <Filename>[|<Family>[|<TagName>
558 # [|<ToolCode>[|<PcdFeatureFlag>]]]]
559 # @param ContainerFile: The file which describes the library class,
560 # used for error report
562 def GetBinary(Item
, ContainerFile
, LineNo
= -1):
563 ItemNew
= Item
+ DataType
.TAB_VALUE_SPLIT
564 List
= GetSplitValueList(ItemNew
)
565 if len(List
) < 3 or len(List
) > 5:
566 RaiseParserError(Item
, 'Binaries', ContainerFile
, \
567 "<FileType>|<Filename>[|<Target>\
568 [|<TokenSpaceGuidCName>.<PcdCName>]]", LineNo
)
572 CheckPcdTokenInfo(List
[3], 'Binaries', ContainerFile
, LineNo
)
573 return (List
[0], List
[1], List
[2], List
[3])
575 return (List
[0], List
[1], List
[2], '')
577 ## Get Guids/Protocols/Ppis
579 # Get Guids/Protocols/Ppis of Inf as <GuidCName>[|<PcdFeatureFlag>]
581 # @param Item: String as <GuidCName>[|<PcdFeatureFlag>]
582 # @param Type: Type of parsing string
583 # @param ContainerFile: The file which describes the library class,
584 # used for error report
586 def GetGuidsProtocolsPpisOfInf(Item
):
587 ItemNew
= Item
+ DataType
.TAB_VALUE_SPLIT
588 List
= GetSplitValueList(ItemNew
)
589 return (List
[0], List
[1])
591 ## Get Guids/Protocols/Ppis
593 # Get Guids/Protocols/Ppis of Dec as <GuidCName>=<GuidValue>
595 # @param Item: String as <GuidCName>=<GuidValue>
596 # @param Type: Type of parsing string
597 # @param ContainerFile: The file which describes the library class,
598 # used for error report
600 def GetGuidsProtocolsPpisOfDec(Item
, Type
, ContainerFile
, LineNo
= -1):
601 List
= GetSplitValueList(Item
, DataType
.TAB_EQUAL_SPLIT
)
603 RaiseParserError(Item
, Type
, ContainerFile
, '<CName>=<GuidValue>', \
606 #convert C-Format Guid to Register Format
608 if List
[1][0] == '{' and List
[1][-1] == '}':
609 RegisterFormatGuid
= GuidStructureStringToGuidString(List
[1])
610 if RegisterFormatGuid
== '':
611 RaiseParserError(Item
, Type
, ContainerFile
, \
612 'CFormat or RegisterFormat', LineNo
)
614 if CheckGuidRegFormat(List
[1]):
615 RegisterFormatGuid
= List
[1]
617 RaiseParserError(Item
, Type
, ContainerFile
, \
618 'CFormat or RegisterFormat', LineNo
)
620 return (List
[0], RegisterFormatGuid
)
624 # Get Package of Inf as <PackagePath>[|<PcdFeatureFlag>]
626 # @param Item: String as <PackagePath>[|<PcdFeatureFlag>]
627 # @param Type: Type of parsing string
628 # @param ContainerFile: The file which describes the library class,
629 # used for error report
631 def GetPackage(Item
, ContainerFile
, FileRelativePath
, LineNo
= -1):
632 ItemNew
= Item
+ DataType
.TAB_VALUE_SPLIT
633 List
= GetSplitValueList(ItemNew
)
634 CheckFileType(List
[0], '.Dec', ContainerFile
, 'package', List
[0], LineNo
)
635 CheckFileExist(FileRelativePath
, List
[0], ContainerFile
, 'Packages', \
638 CheckPcdTokenInfo(List
[1], 'Packages', ContainerFile
, LineNo
)
640 return (List
[0], List
[1])
642 ## Get Pcd Values of Inf
644 # Get Pcd of Inf as <TokenSpaceGuidCName>.<PcdCName>[|<Value>]
646 # @param Item: The string describes pcd
647 # @param Type: The type of Pcd
648 # @param File: The file which describes the pcd, used for error report
650 def GetPcdOfInf(Item
, Type
, File
, LineNo
):
651 Format
= '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]'
652 TokenGuid
, TokenName
, Value
, InfType
= '', '', '', ''
654 if Type
== DataType
.TAB_PCDS_FIXED_AT_BUILD
:
655 InfType
= DataType
.TAB_INF_FIXED_PCD
656 elif Type
== DataType
.TAB_PCDS_PATCHABLE_IN_MODULE
:
657 InfType
= DataType
.TAB_INF_PATCH_PCD
658 elif Type
== DataType
.TAB_PCDS_FEATURE_FLAG
:
659 InfType
= DataType
.TAB_INF_FEATURE_PCD
660 elif Type
== DataType
.TAB_PCDS_DYNAMIC_EX
:
661 InfType
= DataType
.TAB_INF_PCD_EX
662 elif Type
== DataType
.TAB_PCDS_DYNAMIC
:
663 InfType
= DataType
.TAB_INF_PCD
664 List
= GetSplitValueList(Item
, DataType
.TAB_VALUE_SPLIT
, 1)
665 TokenInfo
= GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
666 if len(TokenInfo
) != 2:
667 RaiseParserError(Item
, InfType
, File
, Format
, LineNo
)
669 TokenGuid
= TokenInfo
[0]
670 TokenName
= TokenInfo
[1]
676 return (TokenGuid
, TokenName
, Value
, InfType
)
679 ## Get Pcd Values of Dec
681 # Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
682 # @param Item: Pcd item
683 # @param Type: Pcd type
684 # @param File: Dec file
685 # @param LineNo: Line number
687 def GetPcdOfDec(Item
, Type
, File
, LineNo
= -1):
688 Format
= '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>'
689 TokenGuid
, TokenName
, Value
, DatumType
, Token
= '', '', '', '', ''
690 List
= GetSplitValueList(Item
)
692 RaiseParserError(Item
, 'Pcds' + Type
, File
, Format
, LineNo
)
697 TokenInfo
= GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
698 if len(TokenInfo
) != 2:
699 RaiseParserError(Item
, 'Pcds' + Type
, File
, Format
, LineNo
)
701 TokenGuid
= TokenInfo
[0]
702 TokenName
= TokenInfo
[1]
704 return (TokenGuid
, TokenName
, Value
, DatumType
, Token
, Type
)
706 ## Parse DEFINE statement
710 # @param LineValue: A DEFINE line value
711 # @param StartLine: A DEFINE start line
712 # @param Table: A table
713 # @param FileID: File ID
714 # @param Filename: File name
715 # @param SectionName: DEFINE section name
716 # @param SectionModel: DEFINE section model
717 # @param Arch: DEFINE arch
719 def ParseDefine(LineValue
, StartLine
, Table
, FileID
, SectionName
, \
721 Logger
.Debug(Logger
.DEBUG_2
, ST
.MSG_DEFINE_STATEMENT_FOUND
% (LineValue
, \
724 GetSplitValueList(CleanString\
725 (LineValue
[LineValue
.upper().\
726 find(DataType
.TAB_DEFINE
.upper() + ' ') + \
727 len(DataType
.TAB_DEFINE
+ ' ') : ]), \
728 DataType
.TAB_EQUAL_SPLIT
, 1)
729 Table
.Insert(DataType
.MODEL_META_DATA_DEFINE
, Define
[0], Define
[1], '', \
730 '', '', Arch
, SectionModel
, FileID
, StartLine
, -1, \
733 ## InsertSectionItems
735 # Insert item data of a section to a dict
737 # @param Model: A model
738 # @param CurrentSection: Current section
739 # @param SectionItemList: Section item list
740 # @param ArchList: Arch list
741 # @param ThirdList: Third list
742 # @param RecordSet: Record set
744 def InsertSectionItems(Model
, SectionItemList
, ArchList
, \
745 ThirdList
, RecordSet
):
747 # Insert each item data of a section
749 for Index
in range(0, len(ArchList
)):
750 Arch
= ArchList
[Index
]
751 Third
= ThirdList
[Index
]
753 Arch
= DataType
.TAB_ARCH_COMMON
755 Records
= RecordSet
[Model
]
756 for SectionItem
in SectionItemList
:
757 LineValue
, StartLine
, Comment
= SectionItem
[0], \
758 SectionItem
[1], SectionItem
[2]
760 Logger
.Debug(4, ST
.MSG_PARSING
% LineValue
)
762 # And then parse DEFINE statement
764 if LineValue
.upper().find(DataType
.TAB_DEFINE
.upper() + ' ') > -1:
767 # At last parse other sections
770 Records
.append([LineValue
, Arch
, StartLine
, IdNum
, Third
, Comment
])
773 RecordSet
[Model
] = Records
775 ## GenMetaDatSectionItem
778 # @param Value: A value
779 # @param List: A list
781 def GenMetaDatSectionItem(Key
, Value
, List
):
785 List
[Key
].append(Value
)
789 # get package name, guid, version info from dec files
791 # @param Path: File path
793 def GetPkgInfoFromDec(Path
):
798 Path
= Path
.replace('\\', '/')
800 if not os
.path
.exists(Path
):
801 Logger
.Error("\nUPT", FILE_NOT_FOUND
, File
=Path
)
803 if Path
in gPKG_INFO_DICT
:
804 return gPKG_INFO_DICT
[Path
]
808 if Path
not in GlobalData
.gPackageDict
:
809 DecParser
= Dec(Path
)
810 GlobalData
.gPackageDict
[Path
] = DecParser
812 DecParser
= GlobalData
.gPackageDict
[Path
]
814 PkgName
= DecParser
.GetPackageName()
815 PkgGuid
= DecParser
.GetPackageGuid()
816 PkgVersion
= DecParser
.GetPackageVersion()
817 gPKG_INFO_DICT
[Path
] = (PkgName
, PkgGuid
, PkgVersion
)
818 return PkgName
, PkgGuid
, PkgVersion
820 return None, None, None
823 ## GetWorkspacePackage
825 # Get a list of workspace package information.
827 def GetWorkspacePackage():
829 WorkspaceDir
= GlobalData
.gWORKSPACE
830 for Root
, Dirs
, Files
in os
.walk(WorkspaceDir
):
836 if Dir
.startswith('.'):
839 if FileSp
.startswith('.'):
841 Ext
= os
.path
.splitext(FileSp
)[1]
842 if Ext
.lower() in ['.dec']:
844 (os
.path
.normpath(os
.path
.join(Root
, FileSp
)))
846 # abstract package guid, version info from DecFile List
849 for DecFile
in DecFileList
:
850 (PkgName
, PkgGuid
, PkgVersion
) = GetPkgInfoFromDec(DecFile
)
851 if PkgName
and PkgGuid
and PkgVersion
:
852 PkgList
.append((PkgName
, PkgGuid
, PkgVersion
, DecFile
))
856 ## GetWorkspaceModule
858 # Get a list of workspace modules.
860 def GetWorkspaceModule():
862 WorkspaceDir
= GlobalData
.gWORKSPACE
863 for Root
, Dirs
, Files
in os
.walk(WorkspaceDir
):
871 if Dir
.startswith('.'):
874 if FileSp
.startswith('.'):
876 Ext
= os
.path
.splitext(FileSp
)[1]
877 if Ext
.lower() in ['.inf']:
879 (os
.path
.normpath(os
.path
.join(Root
, FileSp
)))
883 ## MacroParser used to parse macro definition
885 # @param Line: The content contain linestring and line number
886 # @param FileName: The meta-file file name
887 # @param SectionType: Section for the Line belong to
888 # @param FileLocalMacros: A list contain Macro defined in [Defines] section.
890 def MacroParser(Line
, FileName
, SectionType
, FileLocalMacros
):
891 MacroDefPattern
= re
.compile("^(DEFINE)[ \t]+")
892 LineContent
= Line
[0]
894 Match
= MacroDefPattern
.match(LineContent
)
897 # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method
901 TokenList
= GetSplitValueList(LineContent
[Match
.end(1):], \
902 DataType
.TAB_EQUAL_SPLIT
, 1)
907 Logger
.Error('Parser', FORMAT_INVALID
, ST
.ERR_MACRONAME_NOGIVEN
,
908 ExtraData
=LineContent
, File
=FileName
, Line
=LineNo
)
909 if len(TokenList
) < 2:
910 Logger
.Error('Parser', FORMAT_INVALID
, ST
.ERR_MACROVALUE_NOGIVEN
,
911 ExtraData
=LineContent
, File
=FileName
, Line
=LineNo
)
913 Name
, Value
= TokenList
916 # DEFINE defined macros
918 if SectionType
== DataType
.MODEL_META_DATA_HEADER
:
919 FileLocalMacros
[Name
] = Value
921 ReIsValidMacroName
= re
.compile(r
"^[A-Z][A-Z0-9_]*$", re
.DOTALL
)
922 if ReIsValidMacroName
.match(Name
) == None:
923 Logger
.Error('Parser',
925 ST
.ERR_MACRONAME_INVALID
% (Name
),
926 ExtraData
=LineContent
,
930 # Validate MACRO Value
932 # <MacroDefinition> ::= [<Comments>]{0,}
933 # "DEFINE" <MACRO> "=" [{<PATH>} {<VALUE>}] <EOL>
934 # <Value> ::= {<NumVal>} {<Boolean>} {<AsciiString>} {<GUID>}
935 # {<CString>} {<UnicodeString>} {<CArray>}
937 # The definition of <NumVal>, <PATH>, <Boolean>, <GUID>, <CString>,
938 # <UnicodeString>, <CArray> are subset of <AsciiString>.
940 ReIsValidMacroValue
= re
.compile(r
"^[\x20-\x7e]*$", re
.DOTALL
)
941 if ReIsValidMacroValue
.match(Value
) == None:
942 Logger
.Error('Parser',
944 ST
.ERR_MACROVALUE_INVALID
% (Value
),
945 ExtraData
=LineContent
,
953 # generate section contents
955 # @param SectionName: indicate the name of the section, details refer to
957 # @param SectionDict: section statement dict, key is SectionAttrs(arch,
958 # moduletype or platform may exist as needed) list
959 # seperated by space,
962 def GenSection(SectionName
, SectionDict
, SplitArch
=True, NeedBlankLine
=False):
964 for SectionAttrs
in SectionDict
:
965 StatementList
= SectionDict
[SectionAttrs
]
966 if SectionAttrs
and SectionName
!= 'Defines' and SectionAttrs
.strip().upper() != DataType
.TAB_ARCH_COMMON
:
968 ArchList
= GetSplitValueList(SectionAttrs
, DataType
.TAB_SPACE_SPLIT
)
970 if SectionName
!= 'UserExtensions':
971 ArchList
= GetSplitValueList(SectionAttrs
, DataType
.TAB_COMMENT_SPLIT
)
973 ArchList
= [SectionAttrs
]
974 for Index
in xrange(0, len(ArchList
)):
975 ArchList
[Index
] = ConvertArchForInstall(ArchList
[Index
])
976 Section
= '[' + SectionName
+ '.' + (', ' + SectionName
+ '.').join(ArchList
) + ']'
978 Section
= '[' + SectionName
+ ']'
979 Content
+= '\n' + Section
+ '\n'
980 if StatementList
!= None:
981 for Statement
in StatementList
:
982 LineList
= Statement
.split('\n')
984 for Line
in LineList
:
985 # ignore blank comment
986 if not Line
.replace("#", '').strip() and SectionName
!= 'Defines':
988 # add two space before non-comments line except the comments in Defines section
989 if Line
.strip().startswith('#') and SectionName
== 'Defines':
990 NewStatement
+= "%s\n" % Line
992 NewStatement
+= " %s\n" % Line
994 Content
+= NewStatement
+ '\n'
996 Content
+= NewStatement
999 Content
= Content
[:-1]
1000 if not Content
.replace('\\n', '').strip():
1004 ## ConvertArchForInstall
1005 # if Arch.upper() is in "IA32", "X64", "IPF", and "EBC", it must be upper case. "common" must be lower case.
1006 # Anything else, the case must be preserved
1008 # @param Arch: the arch string that need to be converted, it should be stripped before pass in
1009 # @return: the arch string that get converted
1011 def ConvertArchForInstall(Arch
):
1012 if Arch
.upper() in [DataType
.TAB_ARCH_IA32
, DataType
.TAB_ARCH_X64
,
1013 DataType
.TAB_ARCH_IPF
, DataType
.TAB_ARCH_EBC
]:
1015 elif Arch
.upper() == DataType
.TAB_ARCH_COMMON
: