2 # This file is used to define common parsing related functions used in parsing
5 # Copyright (c) 2011, 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
50 # Parse a string with format "[<Family>:]<ToolFlag>=Flag"
51 # Return (Family, ToolFlag, Flag)
53 # @param String: String with BuildOption statement
54 # @param File: The file which defines build option, used in error report
56 def GetBuildOption(String
, File
, LineNo
=-1):
57 (Family
, ToolChain
, Flag
) = ('', '', '')
58 if String
.find(DataType
.TAB_EQUAL_SPLIT
) < 0:
59 RaiseParserError(String
, 'BuildOptions', File
, \
60 '[<Family>:]<ToolFlag>=Flag', LineNo
)
62 List
= GetSplitValueList(String
, DataType
.TAB_EQUAL_SPLIT
, MaxSplit
=1)
63 if List
[0].find(':') > -1:
64 Family
= List
[0][ : List
[0].find(':')].strip()
65 ToolChain
= List
[0][List
[0].find(':') + 1 : ].strip()
67 ToolChain
= List
[0].strip()
68 Flag
= List
[1].strip()
69 return (Family
, ToolChain
, Flag
)
73 # Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance>
75 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
76 # @param ContainerFile: The file which describes the library class, used for
79 def GetLibraryClass(Item
, ContainerFile
, WorkspaceDir
, LineNo
=-1):
80 List
= GetSplitValueList(Item
[0])
81 SupMod
= DataType
.SUP_MODULE_LIST_STRING
83 RaiseParserError(Item
[0], 'LibraryClasses', ContainerFile
, \
84 '<LibraryClassKeyWord>|<LibraryInstance>')
86 CheckFileType(List
[1], '.Inf', ContainerFile
, \
87 'library class instance', Item
[0], LineNo
)
88 CheckFileExist(WorkspaceDir
, List
[1], ContainerFile
, \
89 'LibraryClasses', Item
[0], LineNo
)
93 return (List
[0], List
[1], SupMod
)
97 # Get Library of Dsc as <LibraryClassKeyWord>[|<LibraryInstance>]
98 # [|<TokenSpaceGuidCName>.<PcdCName>]
100 # @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
101 # @param ContainerFile: The file which describes the library class, used for
104 def GetLibraryClassOfInf(Item
, ContainerFile
, WorkspaceDir
, LineNo
= -1):
105 ItemList
= GetSplitValueList((Item
[0] + DataType
.TAB_VALUE_SPLIT
* 2))
106 SupMod
= DataType
.SUP_MODULE_LIST_STRING
108 if len(ItemList
) > 5:
110 (Item
[0], 'LibraryClasses', ContainerFile
, \
111 '<LibraryClassKeyWord>[|<LibraryInstance>]\
112 [|<TokenSpaceGuidCName>.<PcdCName>]')
114 CheckFileType(ItemList
[1], '.Inf', ContainerFile
, 'LibraryClasses', \
116 CheckFileExist(WorkspaceDir
, ItemList
[1], ContainerFile
, \
117 'LibraryClasses', Item
[0], LineNo
)
118 if ItemList
[2] != '':
119 CheckPcdTokenInfo(ItemList
[2], 'LibraryClasses', \
120 ContainerFile
, LineNo
)
124 return (ItemList
[0], ItemList
[1], ItemList
[2], SupMod
)
128 # Check if PcdTokenInfo is following <TokenSpaceGuidCName>.<PcdCName>
130 # @param TokenInfoString: String to be checked
131 # @param Section: Used for error report
132 # @param File: Used for error report
134 def CheckPcdTokenInfo(TokenInfoString
, Section
, File
, LineNo
=-1):
135 Format
= '<TokenSpaceGuidCName>.<PcdCName>'
136 if TokenInfoString
!= '' and TokenInfoString
!= None:
137 TokenInfoList
= GetSplitValueList(TokenInfoString
, DataType
.TAB_SPLIT
)
138 if len(TokenInfoList
) == 2:
141 RaiseParserError(TokenInfoString
, Section
, File
, Format
, LineNo
)
145 # Get Pcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>
146 # [|<Type>|<MaximumDatumSize>]
148 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|
149 # <Value>[|<Type>|<MaximumDatumSize>]
150 # @param ContainerFile: The file which describes the pcd, used for error
154 def GetPcd(Item
, Type
, ContainerFile
, LineNo
=-1):
155 TokenGuid
, TokenName
, Value
, MaximumDatumSize
, Token
= '', '', '', '', ''
156 List
= GetSplitValueList(Item
+ DataType
.TAB_VALUE_SPLIT
* 2)
158 if len(List
) < 4 or len(List
) > 6:
159 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, \
160 '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>\
161 [|<Type>|<MaximumDatumSize>]', LineNo
)
164 MaximumDatumSize
= List
[2]
167 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
168 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
170 return (TokenName
, TokenGuid
, Value
, MaximumDatumSize
, Token
, Type
)
172 ## Get FeatureFlagPcd
174 # Get FeatureFlagPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
176 # @param Item: String as <PcdTokenSpaceGuidCName>
177 # .<TokenCName>|TRUE/FALSE
178 # @param ContainerFile: The file which describes the pcd, used for error
181 def GetFeatureFlagPcd(Item
, Type
, ContainerFile
, LineNo
=-1):
182 TokenGuid
, TokenName
, Value
= '', '', ''
183 List
= GetSplitValueList(Item
)
185 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, \
186 '<PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE', \
190 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
191 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
193 return (TokenName
, TokenGuid
, Value
, Type
)
195 ## Get DynamicDefaultPcd
197 # Get DynamicDefaultPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>
198 # |<Value>[|<DatumTyp>[|<MaxDatumSize>]]
200 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|
202 # @param ContainerFile: The file which describes the pcd, used for error
205 def GetDynamicDefaultPcd(Item
, Type
, ContainerFile
, LineNo
=-1):
206 TokenGuid
, TokenName
, Value
, DatumTyp
, MaxDatumSize
= '', '', '', '', ''
207 List
= GetSplitValueList(Item
+ DataType
.TAB_VALUE_SPLIT
* 2)
208 if len(List
) < 4 or len(List
) > 8:
209 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, \
210 '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>\
211 [|<DatumTyp>[|<MaxDatumSize>]]', LineNo
)
215 MaxDatumSize
= List
[3]
216 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
217 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
219 return (TokenName
, TokenGuid
, Value
, DatumTyp
, MaxDatumSize
, Type
)
223 # Get DynamicHiiPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<String>|
224 # <VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]
226 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|
228 # @param ContainerFile: The file which describes the pcd, used for error
231 def GetDynamicHiiPcd(Item
, Type
, ContainerFile
, LineNo
= -1):
232 TokenGuid
, TokenName
, List1
, List2
, List3
, List4
, List5
= \
233 '', '', '', '', '', '', ''
234 List
= GetSplitValueList(Item
+ DataType
.TAB_VALUE_SPLIT
* 2)
235 if len(List
) < 6 or len(List
) > 8:
236 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, \
237 '<PcdTokenSpaceGuidCName>.<TokenCName>|<String>|\
238 <VariableGuidCName>|<VariableOffset>[|<DefaultValue>\
239 [|<MaximumDatumSize>]]', LineNo
)
241 List1
, List2
, List3
, List4
, List5
= \
242 List
[1], List
[2], List
[3], List
[4], List
[5]
243 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
244 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
246 return (TokenName
, TokenGuid
, List1
, List2
, List3
, List4
, List5
, Type
)
250 # Get DynamicVpdPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|
251 # <VpdOffset>[|<MaximumDatumSize>]
253 # @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>
255 # @param ContainerFile: The file which describes the pcd, used for error
258 def GetDynamicVpdPcd(Item
, Type
, ContainerFile
, LineNo
=-1):
259 TokenGuid
, TokenName
, List1
, List2
= '', '', '', ''
260 List
= GetSplitValueList(Item
+ DataType
.TAB_VALUE_SPLIT
)
261 if len(List
) < 3 or len(List
) > 4:
262 RaiseParserError(Item
, 'Pcds' + Type
, ContainerFile
, \
263 '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>\
264 [|<MaximumDatumSize>]', LineNo
)
266 List1
, List2
= List
[1], List
[2]
267 if CheckPcdTokenInfo(List
[0], 'Pcds' + Type
, ContainerFile
, LineNo
):
268 (TokenGuid
, TokenName
) = GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
270 return (TokenName
, TokenGuid
, List1
, List2
, Type
)
274 # Parse block of the components defined in dsc file
275 # Set KeyValues as [ ['component name', [lib1, lib2, lib3],
276 # [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]
278 # @param Lines: The content to be parsed
279 # @param KeyValues: To store data after parsing
281 def GetComponent(Lines
, KeyValues
):
282 (FindBlock
, FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
283 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, FindPcdsDynamic
, \
284 FindPcdsDynamicEx
) = (False, False, False, False, False, False, False, \
287 LibraryClassItem
= []
294 # Ignore !include statement
296 if Line
.upper().find(DataType
.TAB_INCLUDE
.upper() + ' ') > -1 or \
297 Line
.upper().find(DataType
.TAB_DEFINE
+ ' ') > -1:
300 if FindBlock
== False:
303 # find '{' at line tail
305 if Line
.endswith('{'):
307 ListItem
= CleanString(Line
.rsplit('{', 1)[0], \
308 DataType
.TAB_COMMENT_SPLIT
)
311 # Parse a block content
314 if Line
.find('<LibraryClasses>') != -1:
315 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
316 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
317 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
318 (True, False, False, False, False, False, False)
320 if Line
.find('<BuildOptions>') != -1:
321 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
322 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
323 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
324 (False, True, False, False, False, False, False)
326 if Line
.find('<PcdsFeatureFlag>') != -1:
327 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
328 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
329 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
330 (False, False, True, False, False, False, False)
332 if Line
.find('<PcdsPatchableInModule>') != -1:
333 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
334 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
335 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
336 (False, False, False, True, False, False, False)
338 if Line
.find('<PcdsFixedAtBuild>') != -1:
339 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
340 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
341 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
342 (False, False, False, False, True, False, False)
344 if Line
.find('<PcdsDynamic>') != -1:
345 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
346 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
347 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
348 (False, False, False, False, False, True, False)
350 if Line
.find('<PcdsDynamicEx>') != -1:
351 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
352 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
353 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
354 (False, False, False, False, False, False, True)
356 if Line
.endswith('}'):
358 # find '}' at line tail
360 KeyValues
.append([ListItem
, LibraryClassItem
, \
362 (FindBlock
, FindLibraryClass
, FindBuildOption
, \
363 FindPcdsFeatureFlag
, FindPcdsPatchableInModule
, \
364 FindPcdsFixedAtBuild
, FindPcdsDynamic
, FindPcdsDynamicEx
) = \
365 (False, False, False, False, False, False, False, False)
366 LibraryClassItem
, BuildOption
, Pcd
= [], [], []
371 LibraryClassItem
.append(Line
)
372 elif FindBuildOption
:
373 BuildOption
.append(Line
)
374 elif FindPcdsFeatureFlag
:
375 Pcd
.append((DataType
.TAB_PCDS_FEATURE_FLAG_NULL
, Line
))
376 elif FindPcdsPatchableInModule
:
377 Pcd
.append((DataType
.TAB_PCDS_PATCHABLE_IN_MODULE_NULL
, Line
))
378 elif FindPcdsFixedAtBuild
:
379 Pcd
.append((DataType
.TAB_PCDS_FIXED_AT_BUILD_NULL
, Line
))
380 elif FindPcdsDynamic
:
381 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_DEFAULT_NULL
, Line
))
382 elif FindPcdsDynamicEx
:
383 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
, Line
))
385 KeyValues
.append([ListItem
, [], [], []])
391 # Parse a string with format "InfFilename [EXEC = ExecFilename]"
392 # Return (InfFilename, ExecFilename)
394 # @param String: String with EXEC statement
399 if String
.find('EXEC') > -1:
400 InfFilename
= String
[ : String
.find('EXEC')].strip()
401 ExecFilename
= String
[String
.find('EXEC') + len('EXEC') : ].strip()
403 InfFilename
= String
.strip()
405 return (InfFilename
, ExecFilename
)
409 # Parse block of the components defined in dsc file
410 # Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3],
411 # [pcd1, pcd2, pcd3]], ...]
413 # @param Lines: The content to be parsed
414 # @param Key: Reserved
415 # @param KeyValues: To store data after parsing
416 # @param CommentCharacter: Comment char, used to ignore comment content
418 # @retval True Get component successfully
420 def GetComponents(Lines
, KeyValues
, CommentCharacter
):
421 if Lines
.find(DataType
.TAB_SECTION_END
) > -1:
422 Lines
= Lines
.split(DataType
.TAB_SECTION_END
, 1)[1]
423 (FindBlock
, FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
424 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, FindPcdsDynamic
, \
425 FindPcdsDynamicEx
) = \
426 (False, False, False, False, False, False, False, False)
428 LibraryClassItem
= []
432 LineList
= Lines
.split('\n')
433 for Line
in LineList
:
434 Line
= CleanString(Line
, CommentCharacter
)
435 if Line
== None or Line
== '':
438 if FindBlock
== False:
441 # find '{' at line tail
443 if Line
.endswith('{'):
445 ListItem
= CleanString(Line
.rsplit('{', 1)[0], CommentCharacter
)
448 # Parse a block content
451 if Line
.find('<LibraryClasses>') != -1:
452 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
453 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
454 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
455 (True, False, False, False, False, False, False)
457 if Line
.find('<BuildOptions>') != -1:
458 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
459 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
460 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
461 (False, True, False, False, False, False, False)
463 if Line
.find('<PcdsFeatureFlag>') != -1:
464 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
465 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
466 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
467 (False, False, True, False, False, False, False)
469 if Line
.find('<PcdsPatchableInModule>') != -1:
470 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
471 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
472 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
473 (False, False, False, True, False, False, False)
475 if Line
.find('<PcdsFixedAtBuild>') != -1:
476 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
477 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
478 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
479 (False, False, False, False, True, False, False)
481 if Line
.find('<PcdsDynamic>') != -1:
482 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
483 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
484 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
485 (False, False, False, False, False, True, False)
487 if Line
.find('<PcdsDynamicEx>') != -1:
488 (FindLibraryClass
, FindBuildOption
, FindPcdsFeatureFlag
, \
489 FindPcdsPatchableInModule
, FindPcdsFixedAtBuild
, \
490 FindPcdsDynamic
, FindPcdsDynamicEx
) = \
491 (False, False, False, False, False, False, True)
493 if Line
.endswith('}'):
495 # find '}' at line tail
497 KeyValues
.append([ListItem
, LibraryClassItem
, BuildOption
, \
499 (FindBlock
, FindLibraryClass
, FindBuildOption
, \
500 FindPcdsFeatureFlag
, FindPcdsPatchableInModule
, \
501 FindPcdsFixedAtBuild
, FindPcdsDynamic
, FindPcdsDynamicEx
) = \
502 (False, False, False, False, False, False, False, False)
503 LibraryClassItem
, BuildOption
, Pcd
= [], [], []
508 LibraryClassItem
.append(Line
)
509 elif FindBuildOption
:
510 BuildOption
.append(Line
)
511 elif FindPcdsFeatureFlag
:
512 Pcd
.append((DataType
.TAB_PCDS_FEATURE_FLAG
, Line
))
513 elif FindPcdsPatchableInModule
:
514 Pcd
.append((DataType
.TAB_PCDS_PATCHABLE_IN_MODULE
, Line
))
515 elif FindPcdsFixedAtBuild
:
516 Pcd
.append((DataType
.TAB_PCDS_FIXED_AT_BUILD
, Line
))
517 elif FindPcdsDynamic
:
518 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC
, Line
))
519 elif FindPcdsDynamicEx
:
520 Pcd
.append((DataType
.TAB_PCDS_DYNAMIC_EX
, Line
))
522 KeyValues
.append([ListItem
, [], [], []])
528 # Get Source of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>
529 # [|<PcdFeatureFlag>]]]]
531 # @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>
532 # [|<PcdFeatureFlag>]]]]
533 # @param ContainerFile: The file which describes the library class, used
536 def GetSource(Item
, ContainerFile
, FileRelativePath
, LineNo
=-1):
537 ItemNew
= Item
+ DataType
.TAB_VALUE_SPLIT
* 4
538 List
= GetSplitValueList(ItemNew
)
539 if len(List
) < 5 or len(List
) > 9:
540 RaiseParserError(Item
, 'Sources', ContainerFile
, \
541 '<Filename>[|<Family>[|<TagName>[|<ToolCode>\
542 [|<PcdFeatureFlag>]]]]', LineNo
)
543 List
[0] = NormPath(List
[0])
544 CheckFileExist(FileRelativePath
, List
[0], ContainerFile
, 'Sources', \
547 CheckPcdTokenInfo(List
[4], 'Sources', ContainerFile
, LineNo
)
549 return (List
[0], List
[1], List
[2], List
[3], List
[4])
553 # Get Binary of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>
554 # [|<PcdFeatureFlag>]]]]
556 # @param Item: String as <Filename>[|<Family>[|<TagName>
557 # [|<ToolCode>[|<PcdFeatureFlag>]]]]
558 # @param ContainerFile: The file which describes the library class,
559 # used for error report
561 def GetBinary(Item
, ContainerFile
, LineNo
=-1):
562 ItemNew
= Item
+ DataType
.TAB_VALUE_SPLIT
563 List
= GetSplitValueList(ItemNew
)
564 if len(List
) < 3 or len(List
) > 5:
565 RaiseParserError(Item
, 'Binaries', ContainerFile
, \
566 "<FileType>|<Filename>[|<Target>\
567 [|<TokenSpaceGuidCName>.<PcdCName>]]", LineNo
)
571 CheckPcdTokenInfo(List
[3], 'Binaries', ContainerFile
, LineNo
)
572 return (List
[0], List
[1], List
[2], List
[3])
574 return (List
[0], List
[1], List
[2], '')
576 ## Get Guids/Protocols/Ppis
578 # Get Guids/Protocols/Ppis of Inf as <GuidCName>[|<PcdFeatureFlag>]
580 # @param Item: String as <GuidCName>[|<PcdFeatureFlag>]
581 # @param Type: Type of parsing string
582 # @param ContainerFile: The file which describes the library class,
583 # used for error report
585 def GetGuidsProtocolsPpisOfInf(Item
):
586 ItemNew
= Item
+ DataType
.TAB_VALUE_SPLIT
587 List
= GetSplitValueList(ItemNew
)
588 return (List
[0], List
[1])
590 ## Get Guids/Protocols/Ppis
592 # Get Guids/Protocols/Ppis of Dec as <GuidCName>=<GuidValue>
594 # @param Item: String as <GuidCName>=<GuidValue>
595 # @param Type: Type of parsing string
596 # @param ContainerFile: The file which describes the library class,
597 # used for error report
599 def GetGuidsProtocolsPpisOfDec(Item
, Type
, ContainerFile
, LineNo
=-1):
600 List
= GetSplitValueList(Item
, DataType
.TAB_EQUAL_SPLIT
)
602 RaiseParserError(Item
, Type
, ContainerFile
, '<CName>=<GuidValue>', \
605 #convert C-Format Guid to Register Format
607 if List
[1][0] == '{' and List
[1][-1] == '}':
608 RegisterFormatGuid
= GuidStructureStringToGuidString(List
[1])
609 if RegisterFormatGuid
== '':
610 RaiseParserError(Item
, Type
, ContainerFile
, \
611 'CFormat or RegisterFormat', LineNo
)
613 if CheckGuidRegFormat(List
[1]):
614 RegisterFormatGuid
= List
[1]
616 RaiseParserError(Item
, Type
, ContainerFile
, \
617 'CFormat or RegisterFormat', LineNo
)
619 return (List
[0], RegisterFormatGuid
)
623 # Get Package of Inf as <PackagePath>[|<PcdFeatureFlag>]
625 # @param Item: String as <PackagePath>[|<PcdFeatureFlag>]
626 # @param Type: Type of parsing string
627 # @param ContainerFile: The file which describes the library class,
628 # used for error report
630 def GetPackage(Item
, ContainerFile
, FileRelativePath
, LineNo
=-1):
631 ItemNew
= Item
+ DataType
.TAB_VALUE_SPLIT
632 List
= GetSplitValueList(ItemNew
)
633 CheckFileType(List
[0], '.Dec', ContainerFile
, 'package', List
[0], LineNo
)
634 CheckFileExist(FileRelativePath
, List
[0], ContainerFile
, 'Packages', \
637 CheckPcdTokenInfo(List
[1], 'Packages', ContainerFile
, LineNo
)
639 return (List
[0], List
[1])
641 ## Get Pcd Values of Inf
643 # Get Pcd of Inf as <TokenSpaceGuidCName>.<PcdCName>[|<Value>]
645 # @param Item: The string describes pcd
646 # @param Type: The type of Pcd
647 # @param File: The file which describes the pcd, used for error report
649 def GetPcdOfInf(Item
, Type
, File
, LineNo
):
650 Format
= '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]'
651 TokenGuid
, TokenName
, Value
, InfType
= '', '', '', ''
653 if Type
== DataType
.TAB_PCDS_FIXED_AT_BUILD
:
654 InfType
= DataType
.TAB_INF_FIXED_PCD
655 elif Type
== DataType
.TAB_PCDS_PATCHABLE_IN_MODULE
:
656 InfType
= DataType
.TAB_INF_PATCH_PCD
657 elif Type
== DataType
.TAB_PCDS_FEATURE_FLAG
:
658 InfType
= DataType
.TAB_INF_FEATURE_PCD
659 elif Type
== DataType
.TAB_PCDS_DYNAMIC_EX
:
660 InfType
= DataType
.TAB_INF_PCD_EX
661 elif Type
== DataType
.TAB_PCDS_DYNAMIC
:
662 InfType
= DataType
.TAB_INF_PCD
663 List
= GetSplitValueList(Item
, DataType
.TAB_VALUE_SPLIT
, 1)
664 TokenInfo
= GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
665 if len(TokenInfo
) != 2:
666 RaiseParserError(Item
, InfType
, File
, Format
, LineNo
)
668 TokenGuid
= TokenInfo
[0]
669 TokenName
= TokenInfo
[1]
675 return (TokenGuid
, TokenName
, Value
, InfType
)
678 ## Get Pcd Values of Dec
680 # Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
681 # @param Item: Pcd item
682 # @param Type: Pcd type
683 # @param File: Dec file
684 # @param LineNo: Line number
686 def GetPcdOfDec(Item
, Type
, File
, LineNo
=-1):
687 Format
= '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>'
688 TokenGuid
, TokenName
, Value
, DatumType
, Token
= '', '', '', '', ''
689 List
= GetSplitValueList(Item
)
691 RaiseParserError(Item
, 'Pcds' + Type
, File
, Format
, LineNo
)
696 TokenInfo
= GetSplitValueList(List
[0], DataType
.TAB_SPLIT
)
697 if len(TokenInfo
) != 2:
698 RaiseParserError(Item
, 'Pcds' + Type
, File
, Format
, LineNo
)
700 TokenGuid
= TokenInfo
[0]
701 TokenName
= TokenInfo
[1]
703 return (TokenGuid
, TokenName
, Value
, DatumType
, Token
, Type
)
705 ## Parse DEFINE statement
709 # @param LineValue: A DEFINE line value
710 # @param StartLine: A DEFINE start line
711 # @param Table: A table
712 # @param FileID: File ID
713 # @param Filename: File name
714 # @param SectionName: DEFINE section name
715 # @param SectionModel: DEFINE section model
716 # @param Arch: DEFINE arch
718 def ParseDefine(LineValue
, StartLine
, Table
, FileID
, SectionName
, \
720 Logger
.Debug(Logger
.DEBUG_2
, ST
.MSG_DEFINE_STATEMENT_FOUND
% (LineValue
, \
723 GetSplitValueList(CleanString\
724 (LineValue
[LineValue
.upper().\
725 find(DataType
.TAB_DEFINE
.upper() + ' ') + \
726 len(DataType
.TAB_DEFINE
+ ' ') : ]), \
727 DataType
.TAB_EQUAL_SPLIT
, 1)
728 Table
.Insert(DataType
.MODEL_META_DATA_DEFINE
, Define
[0], Define
[1], '', \
729 '', '', Arch
, SectionModel
, FileID
, StartLine
, -1, \
732 ## InsertSectionItems
734 # Insert item data of a section to a dict
736 # @param Model: A model
737 # @param CurrentSection: Current section
738 # @param SectionItemList: Section item list
739 # @param ArchList: Arch list
740 # @param ThirdList: Third list
741 # @param RecordSet: Record set
743 def InsertSectionItems(Model
, SectionItemList
, ArchList
, \
744 ThirdList
, RecordSet
):
746 # Insert each item data of a section
748 for Index
in range(0, len(ArchList
)):
749 Arch
= ArchList
[Index
]
750 Third
= ThirdList
[Index
]
752 Arch
= DataType
.TAB_ARCH_COMMON
754 Records
= RecordSet
[Model
]
755 for SectionItem
in SectionItemList
:
756 LineValue
, StartLine
, Comment
= SectionItem
[0], \
757 SectionItem
[1], SectionItem
[2]
759 Logger
.Debug(4, ST
.MSG_PARSING
%LineValue
)
761 # And then parse DEFINE statement
763 if LineValue
.upper().find(DataType
.TAB_DEFINE
.upper() + ' ') > -1:
766 # At last parse other sections
769 Records
.append([LineValue
, Arch
, StartLine
, IdNum
, Third
, Comment
])
772 RecordSet
[Model
] = Records
774 ## GenMetaDatSectionItem
777 # @param Value: A value
778 # @param List: A list
780 def GenMetaDatSectionItem(Key
, Value
, List
):
784 List
[Key
].append(Value
)
788 # get package name, guid, version info from dec files
790 # @param Path: File path
792 def GetPkgInfoFromDec(Path
):
797 Path
= Path
.replace('\\', '/')
799 if not os
.path
.exists(Path
):
800 Logger
.Error("\nUPT", FILE_NOT_FOUND
, File
= Path
)
802 if Path
in gPKG_INFO_DICT
:
803 return gPKG_INFO_DICT
[Path
]
806 DecParser
= Dec(Path
)
807 PkgName
= DecParser
.GetPackageName()
808 PkgGuid
= DecParser
.GetPackageGuid()
809 PkgVersion
= DecParser
.GetPackageVersion()
810 gPKG_INFO_DICT
[Path
] = (PkgName
, PkgGuid
, PkgVersion
)
811 return PkgName
, PkgGuid
, PkgVersion
813 return None, None, None
816 ## GetWorkspacePackage
818 # Get a list of workspace package information.
820 def GetWorkspacePackage():
822 WorkspaceDir
= os
.environ
["WORKSPACE"]
823 for Root
, Dirs
, Files
in os
.walk(WorkspaceDir
):
829 if Dir
.startswith('.'):
832 if FileSp
.startswith('.'):
834 Ext
= os
.path
.splitext(FileSp
)[1]
835 if Ext
.lower() in ['.dec']:
837 (os
.path
.normpath(os
.path
.join(Root
, FileSp
)))
839 # abstract package guid, version info from DecFile List
842 for DecFile
in DecFileList
:
843 (PkgName
, PkgGuid
, PkgVersion
) = GetPkgInfoFromDec(DecFile
)
844 if PkgName
and PkgGuid
and PkgVersion
:
845 PkgList
.append((PkgName
, PkgGuid
, PkgVersion
, DecFile
))
849 ## GetWorkspaceModule
851 # Get a list of workspace modules.
853 def GetWorkspaceModule():
855 WorkspaceDir
= os
.environ
["WORKSPACE"]
856 for Root
, Dirs
, Files
in os
.walk(WorkspaceDir
):
864 if Dir
.startswith('.'):
867 if FileSp
.startswith('.'):
869 Ext
= os
.path
.splitext(FileSp
)[1]
870 if Ext
.lower() in ['.inf']:
872 (os
.path
.normpath(os
.path
.join(Root
, FileSp
)))
876 ## MacroParser used to parse macro definition
878 # @param Line: The content contain linestring and line number
879 # @param FileName: The meta-file file name
880 # @param SectionType: Section for the Line belong to
881 # @param FileLocalMacros: A list contain Macro defined in [Defines] section.
883 def MacroParser(Line
, FileName
, SectionType
, FileLocalMacros
):
884 MacroDefPattern
= re
.compile("^(DEFINE)[ \t]+")
885 LineContent
= Line
[0]
887 Match
= MacroDefPattern
.match(LineContent
)
890 # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method
894 TokenList
= GetSplitValueList(LineContent
[Match
.end(1):], \
895 DataType
.TAB_EQUAL_SPLIT
, 1)
900 Logger
.Error('Parser', FORMAT_INVALID
, ST
.ERR_MACRONAME_NOGIVEN
,
901 ExtraData
=LineContent
, File
=FileName
, Line
=LineNo
)
902 if len(TokenList
) < 2:
903 Logger
.Error('Parser', FORMAT_INVALID
, ST
.ERR_MACROVALUE_NOGIVEN
,
904 ExtraData
=LineContent
, File
=FileName
, Line
=LineNo
)
906 Name
, Value
= TokenList
909 # DEFINE defined macros
911 if SectionType
== DataType
.MODEL_META_DATA_HEADER
:
912 FileLocalMacros
[Name
] = Value
914 ReIsValidMacroName
= re
.compile(r
"^[A-Z][A-Z0-9_]*$", re
.DOTALL
)
915 if ReIsValidMacroName
.match(Name
) == None:
916 Logger
.Error('Parser',
918 ST
.ERR_MACRONAME_INVALID
%(Name),
919 ExtraData
=LineContent
,
923 # Validate MACRO Value
925 # <MacroDefinition> ::= [<Comments>]{0,}
926 # "DEFINE" <MACRO> "=" [{<PATH>} {<VALUE>}] <EOL>
927 # <Value> ::= {<NumVal>} {<Boolean>} {<AsciiString>} {<GUID>}
928 # {<CString>} {<UnicodeString>} {<CArray>}
930 # The definition of <NumVal>, <PATH>, <Boolean>, <GUID>, <CString>,
931 # <UnicodeString>, <CArray> are subset of <AsciiString>.
933 ReIsValidMacroValue
= re
.compile(r
"^[\x20-\x7e]*$", re
.DOTALL
)
934 if ReIsValidMacroValue
.match(Value
) == None:
935 Logger
.Error('Parser',
937 ST
.ERR_MACROVALUE_INVALID
%(Value),
938 ExtraData
=LineContent
,
946 # generate section contents
948 # @param SectionName: indicate the name of the section, details refer to
950 # @param SectionDict: section statement dict, key is SectionAttrs(arch,
951 # moduletype or platform may exist as needed) list
952 # seperated by space,
955 def GenSection(SectionName
, SectionDict
, SplitArch
=True):
957 for SectionAttrs
in SectionDict
:
958 StatementList
= SectionDict
[SectionAttrs
]
959 if SectionAttrs
and SectionName
!= 'Defines' and SectionAttrs
.strip().upper() != DataType
.TAB_ARCH_COMMON
:
961 ArchList
= GetSplitValueList(SectionAttrs
, DataType
.TAB_SPACE_SPLIT
)
963 if SectionName
!= 'UserExtensions':
964 ArchList
= GetSplitValueList(SectionAttrs
, DataType
.TAB_COMMENT_SPLIT
)
966 ArchList
= [SectionAttrs
]
967 for Index
in xrange(0, len(ArchList
)):
968 ArchList
[Index
] = ConvertArchForInstall(ArchList
[Index
])
969 Section
= '[' + SectionName
+ '.' + (', ' + SectionName
+ '.').join(ArchList
) + ']'
971 Section
= '[' + SectionName
+ ']'
972 Content
+= '\n\n' + Section
+ '\n'
973 if StatementList
!= None:
974 for Statement
in StatementList
:
975 Content
+= Statement
+ '\n'
979 ## ConvertArchForInstall
980 # if Arch.upper() is in "IA32", "X64", "IPF", and "EBC", it must be upper case. "common" must be lower case.
981 # Anything else, the case must be preserved
983 # @param Arch: the arch string that need to be converted, it should be stripped before pass in
984 # @return: the arch string that get converted
986 def ConvertArchForInstall(Arch
):
987 if Arch
.upper() in [DataType
.TAB_ARCH_IA32
, DataType
.TAB_ARCH_X64
,
988 DataType
.TAB_ARCH_IPF
, DataType
.TAB_ARCH_EBC
]:
990 elif Arch
.upper() == DataType
.TAB_ARCH_COMMON
: