]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/UPT/Library/Parsing.py
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / Python / UPT / Library / Parsing.py
CommitLineData
4234283c 1## @file\r
f7496d71 2# This file is used to define common parsing related functions used in parsing\r
4234283c
LG
3# INF/DEC/DSC process\r
4#\r
64285f15 5# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
4234283c 6#\r
2e351cbe 7# SPDX-License-Identifier: BSD-2-Clause-Patent\r
4234283c
LG
8#\r
9\r
10'''\r
11Parsing\r
12'''\r
1ccc4d89 13from __future__ import absolute_import\r
4234283c
LG
14\r
15##\r
16# Import Modules\r
17#\r
18import os.path\r
19import re\r
20\r
64285f15
YZ
21from Library.StringUtils import RaiseParserError\r
22from Library.StringUtils import GetSplitValueList\r
23from Library.StringUtils import CheckFileType\r
24from Library.StringUtils import CheckFileExist\r
25from Library.StringUtils import CleanString\r
26from Library.StringUtils import NormPath\r
4234283c
LG
27\r
28from Logger.ToolError import FILE_NOT_FOUND\r
29from Logger.ToolError import FatalError\r
30from Logger.ToolError import FORMAT_INVALID\r
31\r
32from Library import DataType\r
33\r
34from Library.Misc import GuidStructureStringToGuidString\r
35from Library.Misc import CheckGuidRegFormat\r
36from Logger import StringTable as ST\r
37import Logger.Log as Logger\r
38\r
39from Parser.DecParser import Dec\r
ac107416 40from . import GlobalData\r
4234283c
LG
41\r
42gPKG_INFO_DICT = {}\r
43\r
44## GetBuildOption\r
45#\r
46# Parse a string with format "[<Family>:]<ToolFlag>=Flag"\r
47# Return (Family, ToolFlag, Flag)\r
48#\r
49# @param String: String with BuildOption statement\r
50# @param File: The file which defines build option, used in error report\r
51#\r
421ccda3 52def GetBuildOption(String, File, LineNo= -1):\r
4234283c
LG
53 (Family, ToolChain, Flag) = ('', '', '')\r
54 if String.find(DataType.TAB_EQUAL_SPLIT) < 0:\r
55 RaiseParserError(String, 'BuildOptions', File, \\r
56 '[<Family>:]<ToolFlag>=Flag', LineNo)\r
57 else:\r
58 List = GetSplitValueList(String, DataType.TAB_EQUAL_SPLIT, MaxSplit=1)\r
59 if List[0].find(':') > -1:\r
60 Family = List[0][ : List[0].find(':')].strip()\r
61 ToolChain = List[0][List[0].find(':') + 1 : ].strip()\r
62 else:\r
63 ToolChain = List[0].strip()\r
64 Flag = List[1].strip()\r
65 return (Family, ToolChain, Flag)\r
66\r
67## Get Library Class\r
68#\r
69# Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance>\r
70#\r
71# @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>\r
f7496d71 72# @param ContainerFile: The file which describes the library class, used for\r
4234283c
LG
73# error report\r
74#\r
421ccda3 75def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo= -1):\r
4234283c
LG
76 List = GetSplitValueList(Item[0])\r
77 SupMod = DataType.SUP_MODULE_LIST_STRING\r
78 if len(List) != 2:\r
79 RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, \\r
80 '<LibraryClassKeyWord>|<LibraryInstance>')\r
81 else:\r
82 CheckFileType(List[1], '.Inf', ContainerFile, \\r
83 'library class instance', Item[0], LineNo)\r
84 CheckFileExist(WorkspaceDir, List[1], ContainerFile, \\r
85 'LibraryClasses', Item[0], LineNo)\r
86 if Item[1] != '':\r
87 SupMod = Item[1]\r
88\r
89 return (List[0], List[1], SupMod)\r
90\r
91## Get Library Class\r
92#\r
93# Get Library of Dsc as <LibraryClassKeyWord>[|<LibraryInstance>]\r
94# [|<TokenSpaceGuidCName>.<PcdCName>]\r
95#\r
96# @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>\r
f7496d71 97# @param ContainerFile: The file which describes the library class, used for\r
4234283c
LG
98# error report\r
99#\r
421ccda3 100def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo= -1):\r
4234283c
LG
101 ItemList = GetSplitValueList((Item[0] + DataType.TAB_VALUE_SPLIT * 2))\r
102 SupMod = DataType.SUP_MODULE_LIST_STRING\r
103\r
104 if len(ItemList) > 5:\r
105 RaiseParserError\\r
106 (Item[0], 'LibraryClasses', ContainerFile, \\r
107 '<LibraryClassKeyWord>[|<LibraryInstance>]\\r
108 [|<TokenSpaceGuidCName>.<PcdCName>]')\r
109 else:\r
110 CheckFileType(ItemList[1], '.Inf', ContainerFile, 'LibraryClasses', \\r
111 Item[0], LineNo)\r
112 CheckFileExist(WorkspaceDir, ItemList[1], ContainerFile, \\r
113 'LibraryClasses', Item[0], LineNo)\r
114 if ItemList[2] != '':\r
115 CheckPcdTokenInfo(ItemList[2], 'LibraryClasses', \\r
116 ContainerFile, LineNo)\r
117 if Item[1] != '':\r
118 SupMod = Item[1]\r
119\r
120 return (ItemList[0], ItemList[1], ItemList[2], SupMod)\r
121\r
122## CheckPcdTokenInfo\r
123#\r
124# Check if PcdTokenInfo is following <TokenSpaceGuidCName>.<PcdCName>\r
125#\r
126# @param TokenInfoString: String to be checked\r
127# @param Section: Used for error report\r
128# @param File: Used for error report\r
129#\r
421ccda3 130def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo= -1):\r
4234283c 131 Format = '<TokenSpaceGuidCName>.<PcdCName>'\r
4231a819 132 if TokenInfoString != '' and TokenInfoString is not None:\r
4234283c
LG
133 TokenInfoList = GetSplitValueList(TokenInfoString, DataType.TAB_SPLIT)\r
134 if len(TokenInfoList) == 2:\r
135 return True\r
136\r
137 RaiseParserError(TokenInfoString, Section, File, Format, LineNo)\r
138\r
139## Get Pcd\r
140#\r
141# Get Pcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>\r
142# [|<Type>|<MaximumDatumSize>]\r
143#\r
144# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|\r
145# <Value>[|<Type>|<MaximumDatumSize>]\r
f7496d71 146# @param ContainerFile: The file which describes the pcd, used for error\r
4234283c
LG
147# report\r
148\r
149#\r
421ccda3 150def GetPcd(Item, Type, ContainerFile, LineNo= -1):\r
4234283c
LG
151 TokenGuid, TokenName, Value, MaximumDatumSize, Token = '', '', '', '', ''\r
152 List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2)\r
153\r
154 if len(List) < 4 or len(List) > 6:\r
155 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \\r
156 '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>\\r
157 [|<Type>|<MaximumDatumSize>]', LineNo)\r
158 else:\r
159 Value = List[1]\r
160 MaximumDatumSize = List[2]\r
161 Token = List[3]\r
162\r
163 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):\r
164 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
165\r
166 return (TokenName, TokenGuid, Value, MaximumDatumSize, Token, Type)\r
167\r
168## Get FeatureFlagPcd\r
169#\r
170# Get FeatureFlagPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE\r
171#\r
172# @param Item: String as <PcdTokenSpaceGuidCName>\r
173# .<TokenCName>|TRUE/FALSE\r
f7496d71 174# @param ContainerFile: The file which describes the pcd, used for error\r
4234283c
LG
175# report\r
176#\r
421ccda3 177def GetFeatureFlagPcd(Item, Type, ContainerFile, LineNo= -1):\r
4234283c
LG
178 TokenGuid, TokenName, Value = '', '', ''\r
179 List = GetSplitValueList(Item)\r
180 if len(List) != 2:\r
181 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \\r
182 '<PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE', \\r
183 LineNo)\r
184 else:\r
185 Value = List[1]\r
186 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):\r
187 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
188\r
189 return (TokenName, TokenGuid, Value, Type)\r
190\r
191## Get DynamicDefaultPcd\r
192#\r
193# Get DynamicDefaultPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>\r
194# |<Value>[|<DatumTyp>[|<MaxDatumSize>]]\r
195#\r
196# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|\r
197# TRUE/FALSE\r
f7496d71 198# @param ContainerFile: The file which describes the pcd, used for error\r
4234283c
LG
199# report\r
200#\r
421ccda3 201def GetDynamicDefaultPcd(Item, Type, ContainerFile, LineNo= -1):\r
4234283c
LG
202 TokenGuid, TokenName, Value, DatumTyp, MaxDatumSize = '', '', '', '', ''\r
203 List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2)\r
204 if len(List) < 4 or len(List) > 8:\r
205 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \\r
206 '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>\\r
207 [|<DatumTyp>[|<MaxDatumSize>]]', LineNo)\r
208 else:\r
209 Value = List[1]\r
210 DatumTyp = List[2]\r
211 MaxDatumSize = List[3]\r
212 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):\r
213 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
214\r
215 return (TokenName, TokenGuid, Value, DatumTyp, MaxDatumSize, Type)\r
216\r
217## Get DynamicHiiPcd\r
218#\r
219# Get DynamicHiiPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<String>|\r
220# <VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]\r
221#\r
222# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|\r
223# TRUE/FALSE\r
f7496d71 224# @param ContainerFile: The file which describes the pcd, used for error\r
4234283c
LG
225# report\r
226#\r
421ccda3 227def GetDynamicHiiPcd(Item, Type, ContainerFile, LineNo= -1):\r
4234283c
LG
228 TokenGuid, TokenName, List1, List2, List3, List4, List5 = \\r
229 '', '', '', '', '', '', ''\r
230 List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2)\r
231 if len(List) < 6 or len(List) > 8:\r
232 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \\r
233 '<PcdTokenSpaceGuidCName>.<TokenCName>|<String>|\\r
234 <VariableGuidCName>|<VariableOffset>[|<DefaultValue>\\r
235 [|<MaximumDatumSize>]]', LineNo)\r
236 else:\r
237 List1, List2, List3, List4, List5 = \\r
238 List[1], List[2], List[3], List[4], List[5]\r
239 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):\r
240 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
241\r
242 return (TokenName, TokenGuid, List1, List2, List3, List4, List5, Type)\r
243\r
244## Get DynamicVpdPcd\r
245#\r
246# Get DynamicVpdPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|\r
247# <VpdOffset>[|<MaximumDatumSize>]\r
248#\r
249# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>\r
250# |TRUE/FALSE\r
f7496d71 251# @param ContainerFile: The file which describes the pcd, used for error\r
4234283c
LG
252# report\r
253#\r
421ccda3 254def GetDynamicVpdPcd(Item, Type, ContainerFile, LineNo= -1):\r
4234283c
LG
255 TokenGuid, TokenName, List1, List2 = '', '', '', ''\r
256 List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT)\r
257 if len(List) < 3 or len(List) > 4:\r
258 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \\r
259 '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>\\r
260 [|<MaximumDatumSize>]', LineNo)\r
261 else:\r
262 List1, List2 = List[1], List[2]\r
263 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):\r
264 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
265\r
266 return (TokenName, TokenGuid, List1, List2, Type)\r
267\r
268## GetComponent\r
269#\r
270# Parse block of the components defined in dsc file\r
f7496d71 271# Set KeyValues as [ ['component name', [lib1, lib2, lib3],\r
4234283c
LG
272# [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]\r
273#\r
274# @param Lines: The content to be parsed\r
275# @param KeyValues: To store data after parsing\r
276#\r
277def GetComponent(Lines, KeyValues):\r
278 (FindBlock, FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \\r
279 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, FindPcdsDynamic, \\r
280 FindPcdsDynamicEx) = (False, False, False, False, False, False, False, \\r
281 False)\r
282 ListItem = None\r
283 LibraryClassItem = []\r
284 BuildOption = []\r
285 Pcd = []\r
286\r
287 for Line in Lines:\r
288 Line = Line[0]\r
289 #\r
290 # Ignore !include statement\r
291 #\r
292 if Line.upper().find(DataType.TAB_INCLUDE.upper() + ' ') > -1 or \\r
293 Line.upper().find(DataType.TAB_DEFINE + ' ') > -1:\r
294 continue\r
295\r
296 if FindBlock == False:\r
297 ListItem = Line\r
298 #\r
299 # find '{' at line tail\r
300 #\r
301 if Line.endswith('{'):\r
302 FindBlock = True\r
303 ListItem = CleanString(Line.rsplit('{', 1)[0], \\r
304 DataType.TAB_COMMENT_SPLIT)\r
305\r
306 #\r
307 # Parse a block content\r
308 #\r
309 if FindBlock:\r
310 if Line.find('<LibraryClasses>') != -1:\r
311 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \\r
312 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \\r
313 FindPcdsDynamic, FindPcdsDynamicEx) = \\r
314 (True, False, False, False, False, False, False)\r
315 continue\r
316 if Line.find('<BuildOptions>') != -1:\r
317 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \\r
318 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \\r
319 FindPcdsDynamic, FindPcdsDynamicEx) = \\r
320 (False, True, False, False, False, False, False)\r
321 continue\r
322 if Line.find('<PcdsFeatureFlag>') != -1:\r
323 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \\r
324 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \\r
325 FindPcdsDynamic, FindPcdsDynamicEx) = \\r
326 (False, False, True, False, False, False, False)\r
327 continue\r
328 if Line.find('<PcdsPatchableInModule>') != -1:\r
329 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \\r
330 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \\r
331 FindPcdsDynamic, FindPcdsDynamicEx) = \\r
332 (False, False, False, True, False, False, False)\r
333 continue\r
334 if Line.find('<PcdsFixedAtBuild>') != -1:\r
335 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \\r
336 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \\r
337 FindPcdsDynamic, FindPcdsDynamicEx) = \\r
338 (False, False, False, False, True, False, False)\r
339 continue\r
340 if Line.find('<PcdsDynamic>') != -1:\r
341 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \\r
342 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \\r
343 FindPcdsDynamic, FindPcdsDynamicEx) = \\r
344 (False, False, False, False, False, True, False)\r
345 continue\r
346 if Line.find('<PcdsDynamicEx>') != -1:\r
347 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \\r
348 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \\r
349 FindPcdsDynamic, FindPcdsDynamicEx) = \\r
350 (False, False, False, False, False, False, True)\r
351 continue\r
352 if Line.endswith('}'):\r
353 #\r
354 # find '}' at line tail\r
355 #\r
356 KeyValues.append([ListItem, LibraryClassItem, \\r
357 BuildOption, Pcd])\r
358 (FindBlock, FindLibraryClass, FindBuildOption, \\r
359 FindPcdsFeatureFlag, FindPcdsPatchableInModule, \\r
360 FindPcdsFixedAtBuild, FindPcdsDynamic, FindPcdsDynamicEx) = \\r
361 (False, False, False, False, False, False, False, False)\r
362 LibraryClassItem, BuildOption, Pcd = [], [], []\r
363 continue\r
364\r
365 if FindBlock:\r
366 if FindLibraryClass:\r
367 LibraryClassItem.append(Line)\r
368 elif FindBuildOption:\r
369 BuildOption.append(Line)\r
370 elif FindPcdsFeatureFlag:\r
371 Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG_NULL, Line))\r
372 elif FindPcdsPatchableInModule:\r
373 Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE_NULL, Line))\r
374 elif FindPcdsFixedAtBuild:\r
375 Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD_NULL, Line))\r
376 elif FindPcdsDynamic:\r
377 Pcd.append((DataType.TAB_PCDS_DYNAMIC_DEFAULT_NULL, Line))\r
378 elif FindPcdsDynamicEx:\r
379 Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL, Line))\r
380 else:\r
381 KeyValues.append([ListItem, [], [], []])\r
382\r
383 return True\r
384\r
385## GetExec\r
386#\r
387# Parse a string with format "InfFilename [EXEC = ExecFilename]"\r
388# Return (InfFilename, ExecFilename)\r
389#\r
390# @param String: String with EXEC statement\r
391#\r
392def GetExec(String):\r
393 InfFilename = ''\r
394 ExecFilename = ''\r
395 if String.find('EXEC') > -1:\r
396 InfFilename = String[ : String.find('EXEC')].strip()\r
397 ExecFilename = String[String.find('EXEC') + len('EXEC') : ].strip()\r
398 else:\r
399 InfFilename = String.strip()\r
400\r
401 return (InfFilename, ExecFilename)\r
402\r
403## GetComponents\r
404#\r
405# Parse block of the components defined in dsc file\r
f7496d71 406# Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3],\r
4234283c
LG
407# [pcd1, pcd2, pcd3]], ...]\r
408#\r
409# @param Lines: The content to be parsed\r
410# @param Key: Reserved\r
411# @param KeyValues: To store data after parsing\r
412# @param CommentCharacter: Comment char, used to ignore comment content\r
413#\r
414# @retval True Get component successfully\r
415#\r
416def GetComponents(Lines, KeyValues, CommentCharacter):\r
417 if Lines.find(DataType.TAB_SECTION_END) > -1:\r
418 Lines = Lines.split(DataType.TAB_SECTION_END, 1)[1]\r
419 (FindBlock, FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \\r
420 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, FindPcdsDynamic, \\r
421 FindPcdsDynamicEx) = \\r
422 (False, False, False, False, False, False, False, False)\r
423 ListItem = None\r
424 LibraryClassItem = []\r
425 BuildOption = []\r
426 Pcd = []\r
427\r
428 LineList = Lines.split('\n')\r
429 for Line in LineList:\r
430 Line = CleanString(Line, CommentCharacter)\r
4231a819 431 if Line is None or Line == '':\r
4234283c
LG
432 continue\r
433\r
434 if FindBlock == False:\r
435 ListItem = Line\r
436 #\r
437 # find '{' at line tail\r
438 #\r
439 if Line.endswith('{'):\r
440 FindBlock = True\r
441 ListItem = CleanString(Line.rsplit('{', 1)[0], CommentCharacter)\r
442\r
443 #\r
444 # Parse a block content\r
445 #\r
446 if FindBlock:\r
447 if Line.find('<LibraryClasses>') != -1:\r
448 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \\r
449 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \\r
450 FindPcdsDynamic, FindPcdsDynamicEx) = \\r
451 (True, False, False, False, False, False, False)\r
452 continue\r
453 if Line.find('<BuildOptions>') != -1:\r
454 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \\r
455 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \\r
456 FindPcdsDynamic, FindPcdsDynamicEx) = \\r
457 (False, True, False, False, False, False, False)\r
458 continue\r
459 if Line.find('<PcdsFeatureFlag>') != -1:\r
460 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \\r
461 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \\r
462 FindPcdsDynamic, FindPcdsDynamicEx) = \\r
463 (False, False, True, False, False, False, False)\r
464 continue\r
465 if Line.find('<PcdsPatchableInModule>') != -1:\r
466 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \\r
467 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \\r
468 FindPcdsDynamic, FindPcdsDynamicEx) = \\r
469 (False, False, False, True, False, False, False)\r
470 continue\r
471 if Line.find('<PcdsFixedAtBuild>') != -1:\r
472 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \\r
473 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \\r
474 FindPcdsDynamic, FindPcdsDynamicEx) = \\r
475 (False, False, False, False, True, False, False)\r
476 continue\r
477 if Line.find('<PcdsDynamic>') != -1:\r
478 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \\r
479 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \\r
480 FindPcdsDynamic, FindPcdsDynamicEx) = \\r
481 (False, False, False, False, False, True, False)\r
482 continue\r
483 if Line.find('<PcdsDynamicEx>') != -1:\r
484 (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \\r
485 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \\r
486 FindPcdsDynamic, FindPcdsDynamicEx) = \\r
487 (False, False, False, False, False, False, True)\r
488 continue\r
489 if Line.endswith('}'):\r
490 #\r
491 # find '}' at line tail\r
492 #\r
493 KeyValues.append([ListItem, LibraryClassItem, BuildOption, \\r
494 Pcd])\r
495 (FindBlock, FindLibraryClass, FindBuildOption, \\r
496 FindPcdsFeatureFlag, FindPcdsPatchableInModule, \\r
497 FindPcdsFixedAtBuild, FindPcdsDynamic, FindPcdsDynamicEx) = \\r
498 (False, False, False, False, False, False, False, False)\r
499 LibraryClassItem, BuildOption, Pcd = [], [], []\r
500 continue\r
501\r
502 if FindBlock:\r
503 if FindLibraryClass:\r
504 LibraryClassItem.append(Line)\r
505 elif FindBuildOption:\r
506 BuildOption.append(Line)\r
507 elif FindPcdsFeatureFlag:\r
508 Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG, Line))\r
509 elif FindPcdsPatchableInModule:\r
510 Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE, Line))\r
511 elif FindPcdsFixedAtBuild:\r
512 Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD, Line))\r
513 elif FindPcdsDynamic:\r
514 Pcd.append((DataType.TAB_PCDS_DYNAMIC, Line))\r
515 elif FindPcdsDynamicEx:\r
516 Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX, Line))\r
517 else:\r
518 KeyValues.append([ListItem, [], [], []])\r
519\r
520 return True\r
521\r
522## Get Source\r
523#\r
524# Get Source of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>\r
525# [|<PcdFeatureFlag>]]]]\r
526#\r
527# @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>\r
528# [|<PcdFeatureFlag>]]]]\r
f7496d71 529# @param ContainerFile: The file which describes the library class, used\r
4234283c
LG
530# for error report\r
531#\r
421ccda3 532def GetSource(Item, ContainerFile, FileRelativePath, LineNo= -1):\r
4234283c
LG
533 ItemNew = Item + DataType.TAB_VALUE_SPLIT * 4\r
534 List = GetSplitValueList(ItemNew)\r
535 if len(List) < 5 or len(List) > 9:\r
536 RaiseParserError(Item, 'Sources', ContainerFile, \\r
537 '<Filename>[|<Family>[|<TagName>[|<ToolCode>\\r
538 [|<PcdFeatureFlag>]]]]', LineNo)\r
539 List[0] = NormPath(List[0])\r
540 CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Sources', \\r
541 Item, LineNo)\r
542 if List[4] != '':\r
543 CheckPcdTokenInfo(List[4], 'Sources', ContainerFile, LineNo)\r
544\r
545 return (List[0], List[1], List[2], List[3], List[4])\r
546\r
547## Get Binary\r
548#\r
549# Get Binary of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>\r
550# [|<PcdFeatureFlag>]]]]\r
551#\r
552# @param Item: String as <Filename>[|<Family>[|<TagName>\r
553# [|<ToolCode>[|<PcdFeatureFlag>]]]]\r
f7496d71 554# @param ContainerFile: The file which describes the library class,\r
4234283c
LG
555# used for error report\r
556#\r
421ccda3 557def GetBinary(Item, ContainerFile, LineNo= -1):\r
4234283c
LG
558 ItemNew = Item + DataType.TAB_VALUE_SPLIT\r
559 List = GetSplitValueList(ItemNew)\r
560 if len(List) < 3 or len(List) > 5:\r
561 RaiseParserError(Item, 'Binaries', ContainerFile, \\r
562 "<FileType>|<Filename>[|<Target>\\r
563 [|<TokenSpaceGuidCName>.<PcdCName>]]", LineNo)\r
564\r
565 if len(List) >= 4:\r
566 if List[3] != '':\r
567 CheckPcdTokenInfo(List[3], 'Binaries', ContainerFile, LineNo)\r
568 return (List[0], List[1], List[2], List[3])\r
569 elif len(List) == 3:\r
570 return (List[0], List[1], List[2], '')\r
571\r
572## Get Guids/Protocols/Ppis\r
573#\r
574# Get Guids/Protocols/Ppis of Inf as <GuidCName>[|<PcdFeatureFlag>]\r
575#\r
576# @param Item: String as <GuidCName>[|<PcdFeatureFlag>]\r
577# @param Type: Type of parsing string\r
f7496d71 578# @param ContainerFile: The file which describes the library class,\r
4234283c
LG
579# used for error report\r
580#\r
581def GetGuidsProtocolsPpisOfInf(Item):\r
582 ItemNew = Item + DataType.TAB_VALUE_SPLIT\r
583 List = GetSplitValueList(ItemNew)\r
584 return (List[0], List[1])\r
585\r
586## Get Guids/Protocols/Ppis\r
587#\r
588# Get Guids/Protocols/Ppis of Dec as <GuidCName>=<GuidValue>\r
589#\r
590# @param Item: String as <GuidCName>=<GuidValue>\r
591# @param Type: Type of parsing string\r
f7496d71 592# @param ContainerFile: The file which describes the library class,\r
4234283c
LG
593# used for error report\r
594#\r
421ccda3 595def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo= -1):\r
4234283c
LG
596 List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT)\r
597 if len(List) != 2:\r
598 RaiseParserError(Item, Type, ContainerFile, '<CName>=<GuidValue>', \\r
599 LineNo)\r
600 #\r
601 #convert C-Format Guid to Register Format\r
602 #\r
603 if List[1][0] == '{' and List[1][-1] == '}':\r
604 RegisterFormatGuid = GuidStructureStringToGuidString(List[1])\r
605 if RegisterFormatGuid == '':\r
606 RaiseParserError(Item, Type, ContainerFile, \\r
607 'CFormat or RegisterFormat', LineNo)\r
608 else:\r
609 if CheckGuidRegFormat(List[1]):\r
610 RegisterFormatGuid = List[1]\r
611 else:\r
612 RaiseParserError(Item, Type, ContainerFile, \\r
421ccda3 613 'CFormat or RegisterFormat', LineNo)\r
4234283c
LG
614\r
615 return (List[0], RegisterFormatGuid)\r
616\r
617## GetPackage\r
618#\r
619# Get Package of Inf as <PackagePath>[|<PcdFeatureFlag>]\r
620#\r
621# @param Item: String as <PackagePath>[|<PcdFeatureFlag>]\r
622# @param Type: Type of parsing string\r
f7496d71 623# @param ContainerFile: The file which describes the library class,\r
4234283c
LG
624# used for error report\r
625#\r
421ccda3 626def GetPackage(Item, ContainerFile, FileRelativePath, LineNo= -1):\r
4234283c
LG
627 ItemNew = Item + DataType.TAB_VALUE_SPLIT\r
628 List = GetSplitValueList(ItemNew)\r
629 CheckFileType(List[0], '.Dec', ContainerFile, 'package', List[0], LineNo)\r
630 CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Packages', \\r
631 List[0], LineNo)\r
632 if List[1] != '':\r
633 CheckPcdTokenInfo(List[1], 'Packages', ContainerFile, LineNo)\r
634\r
635 return (List[0], List[1])\r
636\r
637## Get Pcd Values of Inf\r
638#\r
639# Get Pcd of Inf as <TokenSpaceGuidCName>.<PcdCName>[|<Value>]\r
640#\r
641# @param Item: The string describes pcd\r
642# @param Type: The type of Pcd\r
643# @param File: The file which describes the pcd, used for error report\r
644#\r
645def GetPcdOfInf(Item, Type, File, LineNo):\r
646 Format = '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]'\r
647 TokenGuid, TokenName, Value, InfType = '', '', '', ''\r
648\r
649 if Type == DataType.TAB_PCDS_FIXED_AT_BUILD:\r
650 InfType = DataType.TAB_INF_FIXED_PCD\r
651 elif Type == DataType.TAB_PCDS_PATCHABLE_IN_MODULE:\r
652 InfType = DataType.TAB_INF_PATCH_PCD\r
653 elif Type == DataType.TAB_PCDS_FEATURE_FLAG:\r
654 InfType = DataType.TAB_INF_FEATURE_PCD\r
655 elif Type == DataType.TAB_PCDS_DYNAMIC_EX:\r
656 InfType = DataType.TAB_INF_PCD_EX\r
657 elif Type == DataType.TAB_PCDS_DYNAMIC:\r
658 InfType = DataType.TAB_INF_PCD\r
659 List = GetSplitValueList(Item, DataType.TAB_VALUE_SPLIT, 1)\r
660 TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
661 if len(TokenInfo) != 2:\r
662 RaiseParserError(Item, InfType, File, Format, LineNo)\r
663 else:\r
664 TokenGuid = TokenInfo[0]\r
665 TokenName = TokenInfo[1]\r
666\r
667 if len(List) > 1:\r
668 Value = List[1]\r
669 else:\r
670 Value = None\r
671 return (TokenGuid, TokenName, Value, InfType)\r
672\r
673\r
674## Get Pcd Values of Dec\r
675#\r
676# Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>\r
677# @param Item: Pcd item\r
678# @param Type: Pcd type\r
679# @param File: Dec file\r
680# @param LineNo: Line number\r
681#\r
421ccda3 682def GetPcdOfDec(Item, Type, File, LineNo= -1):\r
4234283c
LG
683 Format = '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>'\r
684 TokenGuid, TokenName, Value, DatumType, Token = '', '', '', '', ''\r
685 List = GetSplitValueList(Item)\r
686 if len(List) != 4:\r
687 RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo)\r
688 else:\r
689 Value = List[1]\r
690 DatumType = List[2]\r
691 Token = List[3]\r
692 TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
693 if len(TokenInfo) != 2:\r
694 RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo)\r
695 else:\r
696 TokenGuid = TokenInfo[0]\r
697 TokenName = TokenInfo[1]\r
698\r
699 return (TokenGuid, TokenName, Value, DatumType, Token, Type)\r
700\r
701## Parse DEFINE statement\r
702#\r
703# Get DEFINE macros\r
704#\r
705# @param LineValue: A DEFINE line value\r
706# @param StartLine: A DEFINE start line\r
707# @param Table: A table\r
708# @param FileID: File ID\r
709# @param Filename: File name\r
710# @param SectionName: DEFINE section name\r
711# @param SectionModel: DEFINE section model\r
712# @param Arch: DEFINE arch\r
713#\r
714def ParseDefine(LineValue, StartLine, Table, FileID, SectionName, \\r
715 SectionModel, Arch):\r
716 Logger.Debug(Logger.DEBUG_2, ST.MSG_DEFINE_STATEMENT_FOUND % (LineValue, \\r
717 SectionName))\r
718 Define = \\r
719 GetSplitValueList(CleanString\\r
720 (LineValue[LineValue.upper().\\r
721 find(DataType.TAB_DEFINE.upper() + ' ') + \\r
722 len(DataType.TAB_DEFINE + ' ') : ]), \\r
723 DataType.TAB_EQUAL_SPLIT, 1)\r
724 Table.Insert(DataType.MODEL_META_DATA_DEFINE, Define[0], Define[1], '', \\r
725 '', '', Arch, SectionModel, FileID, StartLine, -1, \\r
726 StartLine, -1, 0)\r
727\r
728## InsertSectionItems\r
729#\r
730# Insert item data of a section to a dict\r
731#\r
732# @param Model: A model\r
733# @param CurrentSection: Current section\r
734# @param SectionItemList: Section item list\r
735# @param ArchList: Arch list\r
736# @param ThirdList: Third list\r
737# @param RecordSet: Record set\r
738#\r
739def InsertSectionItems(Model, SectionItemList, ArchList, \\r
740 ThirdList, RecordSet):\r
741 #\r
742 # Insert each item data of a section\r
743 #\r
744 for Index in range(0, len(ArchList)):\r
745 Arch = ArchList[Index]\r
746 Third = ThirdList[Index]\r
747 if Arch == '':\r
748 Arch = DataType.TAB_ARCH_COMMON\r
749\r
750 Records = RecordSet[Model]\r
751 for SectionItem in SectionItemList:\r
752 LineValue, StartLine, Comment = SectionItem[0], \\r
753 SectionItem[1], SectionItem[2]\r
754\r
421ccda3 755 Logger.Debug(4, ST.MSG_PARSING % LineValue)\r
4234283c
LG
756 #\r
757 # And then parse DEFINE statement\r
758 #\r
759 if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1:\r
760 continue\r
761 #\r
762 # At last parse other sections\r
763 #\r
764 IdNum = -1\r
765 Records.append([LineValue, Arch, StartLine, IdNum, Third, Comment])\r
766\r
767 if RecordSet != {}:\r
768 RecordSet[Model] = Records\r
769\r
770## GenMetaDatSectionItem\r
771#\r
772# @param Key: A key\r
773# @param Value: A value\r
774# @param List: A list\r
775#\r
776def GenMetaDatSectionItem(Key, Value, List):\r
777 if Key not in List:\r
778 List[Key] = [Value]\r
779 else:\r
780 List[Key].append(Value)\r
421ccda3 781\r
4234283c
LG
782## GetPkgInfoFromDec\r
783#\r
784# get package name, guid, version info from dec files\r
785#\r
786# @param Path: File path\r
787#\r
788def GetPkgInfoFromDec(Path):\r
789 PkgName = None\r
790 PkgGuid = None\r
791 PkgVersion = None\r
421ccda3 792\r
4234283c 793 Path = Path.replace('\\', '/')\r
421ccda3 794\r
4234283c 795 if not os.path.exists(Path):\r
421ccda3 796 Logger.Error("\nUPT", FILE_NOT_FOUND, File=Path)\r
4234283c
LG
797\r
798 if Path in gPKG_INFO_DICT:\r
799 return gPKG_INFO_DICT[Path]\r
800\r
801 try:\r
421ccda3
HC
802 DecParser = None\r
803 if Path not in GlobalData.gPackageDict:\r
804 DecParser = Dec(Path)\r
805 GlobalData.gPackageDict[Path] = DecParser\r
806 else:\r
807 DecParser = GlobalData.gPackageDict[Path]\r
808\r
4234283c
LG
809 PkgName = DecParser.GetPackageName()\r
810 PkgGuid = DecParser.GetPackageGuid()\r
811 PkgVersion = DecParser.GetPackageVersion()\r
812 gPKG_INFO_DICT[Path] = (PkgName, PkgGuid, PkgVersion)\r
813 return PkgName, PkgGuid, PkgVersion\r
814 except FatalError:\r
815 return None, None, None\r
816\r
817\r
818## GetWorkspacePackage\r
819#\r
820# Get a list of workspace package information.\r
821#\r
822def GetWorkspacePackage():\r
823 DecFileList = []\r
421ccda3 824 WorkspaceDir = GlobalData.gWORKSPACE\r
fb0f8067
HC
825 PackageDir = GlobalData.gPACKAGE_PATH\r
826 for PkgRoot in [WorkspaceDir] + PackageDir:\r
827 for Root, Dirs, Files in os.walk(PkgRoot):\r
828 if 'CVS' in Dirs:\r
829 Dirs.remove('CVS')\r
830 if '.svn' in Dirs:\r
831 Dirs.remove('.svn')\r
832 for Dir in Dirs:\r
833 if Dir.startswith('.'):\r
834 Dirs.remove(Dir)\r
835 for FileSp in Files:\r
836 if FileSp.startswith('.'):\r
837 continue\r
838 Ext = os.path.splitext(FileSp)[1]\r
839 if Ext.lower() in ['.dec']:\r
840 DecFileList.append\\r
841 (os.path.normpath(os.path.join(Root, FileSp)))\r
4234283c
LG
842 #\r
843 # abstract package guid, version info from DecFile List\r
844 #\r
845 PkgList = []\r
846 for DecFile in DecFileList:\r
847 (PkgName, PkgGuid, PkgVersion) = GetPkgInfoFromDec(DecFile)\r
848 if PkgName and PkgGuid and PkgVersion:\r
849 PkgList.append((PkgName, PkgGuid, PkgVersion, DecFile))\r
421ccda3 850\r
4234283c
LG
851 return PkgList\r
852\r
853## GetWorkspaceModule\r
854#\r
855# Get a list of workspace modules.\r
856#\r
857def GetWorkspaceModule():\r
858 InfFileList = []\r
421ccda3 859 WorkspaceDir = GlobalData.gWORKSPACE\r
4234283c
LG
860 for Root, Dirs, Files in os.walk(WorkspaceDir):\r
861 if 'CVS' in Dirs:\r
862 Dirs.remove('CVS')\r
863 if '.svn' in Dirs:\r
864 Dirs.remove('.svn')\r
865 if 'Build' in Dirs:\r
866 Dirs.remove('Build')\r
867 for Dir in Dirs:\r
868 if Dir.startswith('.'):\r
869 Dirs.remove(Dir)\r
870 for FileSp in Files:\r
871 if FileSp.startswith('.'):\r
872 continue\r
873 Ext = os.path.splitext(FileSp)[1]\r
874 if Ext.lower() in ['.inf']:\r
875 InfFileList.append\\r
876 (os.path.normpath(os.path.join(Root, FileSp)))\r
421ccda3 877\r
4234283c
LG
878 return InfFileList\r
879\r
880## MacroParser used to parse macro definition\r
881#\r
882# @param Line: The content contain linestring and line number\r
883# @param FileName: The meta-file file name\r
884# @param SectionType: Section for the Line belong to\r
885# @param FileLocalMacros: A list contain Macro defined in [Defines] section.\r
886#\r
887def MacroParser(Line, FileName, SectionType, FileLocalMacros):\r
888 MacroDefPattern = re.compile("^(DEFINE)[ \t]+")\r
889 LineContent = Line[0]\r
890 LineNo = Line[1]\r
891 Match = MacroDefPattern.match(LineContent)\r
892 if not Match:\r
893 #\r
894 # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method\r
895 #\r
896 return None, None\r
421ccda3 897\r
4234283c
LG
898 TokenList = GetSplitValueList(LineContent[Match.end(1):], \\r
899 DataType.TAB_EQUAL_SPLIT, 1)\r
900 #\r
901 # Syntax check\r
902 #\r
903 if not TokenList[0]:\r
904 Logger.Error('Parser', FORMAT_INVALID, ST.ERR_MACRONAME_NOGIVEN,\r
905 ExtraData=LineContent, File=FileName, Line=LineNo)\r
906 if len(TokenList) < 2:\r
907 Logger.Error('Parser', FORMAT_INVALID, ST.ERR_MACROVALUE_NOGIVEN,\r
908 ExtraData=LineContent, File=FileName, Line=LineNo)\r
909\r
910 Name, Value = TokenList\r
911\r
912 #\r
913 # DEFINE defined macros\r
914 #\r
915 if SectionType == DataType.MODEL_META_DATA_HEADER:\r
916 FileLocalMacros[Name] = Value\r
421ccda3 917\r
4234283c 918 ReIsValidMacroName = re.compile(r"^[A-Z][A-Z0-9_]*$", re.DOTALL)\r
4231a819 919 if ReIsValidMacroName.match(Name) is None:\r
421ccda3
HC
920 Logger.Error('Parser',\r
921 FORMAT_INVALID,\r
922 ST.ERR_MACRONAME_INVALID % (Name),\r
923 ExtraData=LineContent,\r
924 File=FileName,\r
4234283c 925 Line=LineNo)\r
421ccda3 926\r
4234283c
LG
927 # Validate MACRO Value\r
928 #\r
929 # <MacroDefinition> ::= [<Comments>]{0,}\r
930 # "DEFINE" <MACRO> "=" [{<PATH>} {<VALUE>}] <EOL>\r
931 # <Value> ::= {<NumVal>} {<Boolean>} {<AsciiString>} {<GUID>}\r
932 # {<CString>} {<UnicodeString>} {<CArray>}\r
933 #\r
f7496d71 934 # The definition of <NumVal>, <PATH>, <Boolean>, <GUID>, <CString>,\r
4234283c
LG
935 # <UnicodeString>, <CArray> are subset of <AsciiString>.\r
936 #\r
937 ReIsValidMacroValue = re.compile(r"^[\x20-\x7e]*$", re.DOTALL)\r
4231a819 938 if ReIsValidMacroValue.match(Value) is None:\r
421ccda3
HC
939 Logger.Error('Parser',\r
940 FORMAT_INVALID,\r
941 ST.ERR_MACROVALUE_INVALID % (Value),\r
942 ExtraData=LineContent,\r
943 File=FileName,\r
4234283c 944 Line=LineNo)\r
421ccda3 945\r
4234283c
LG
946 return Name, Value\r
947\r
f7496d71 948## GenSection\r
4234283c
LG
949#\r
950# generate section contents\r
951#\r
f7496d71 952# @param SectionName: indicate the name of the section, details refer to\r
4234283c 953# INF, DEC specs\r
f7496d71
LG
954# @param SectionDict: section statement dict, key is SectionAttrs(arch,\r
955# moduletype or platform may exist as needed) list\r
fb0b35e0 956# separated by space,\r
4234283c
LG
957# value is statement\r
958#\r
421ccda3 959def GenSection(SectionName, SectionDict, SplitArch=True, NeedBlankLine=False):\r
4234283c
LG
960 Content = ''\r
961 for SectionAttrs in SectionDict:\r
962 StatementList = SectionDict[SectionAttrs]\r
963 if SectionAttrs and SectionName != 'Defines' and SectionAttrs.strip().upper() != DataType.TAB_ARCH_COMMON:\r
964 if SplitArch:\r
965 ArchList = GetSplitValueList(SectionAttrs, DataType.TAB_SPACE_SPLIT)\r
966 else:\r
967 if SectionName != 'UserExtensions':\r
968 ArchList = GetSplitValueList(SectionAttrs, DataType.TAB_COMMENT_SPLIT)\r
969 else:\r
970 ArchList = [SectionAttrs]\r
174a9d3c 971 for Index in range(0, len(ArchList)):\r
4234283c
LG
972 ArchList[Index] = ConvertArchForInstall(ArchList[Index])\r
973 Section = '[' + SectionName + '.' + (', ' + SectionName + '.').join(ArchList) + ']'\r
974 else:\r
975 Section = '[' + SectionName + ']'\r
421ccda3 976 Content += '\n' + Section + '\n'\r
4231a819 977 if StatementList is not None:\r
4234283c 978 for Statement in StatementList:\r
421ccda3
HC
979 LineList = Statement.split('\n')\r
980 NewStatement = ""\r
981 for Line in LineList:\r
982 # ignore blank comment\r
76d47511 983 if not Line.replace("#", '').strip() and SectionName not in ('Defines', 'Hob', 'Event', 'BootMode'):\r
421ccda3
HC
984 continue\r
985 # add two space before non-comments line except the comments in Defines section\r
986 if Line.strip().startswith('#') and SectionName == 'Defines':\r
987 NewStatement += "%s\n" % Line\r
988 continue\r
989 NewStatement += " %s\n" % Line\r
990 if NeedBlankLine:\r
991 Content += NewStatement + '\n'\r
992 else:\r
993 Content += NewStatement\r
4234283c 994\r
421ccda3
HC
995 if NeedBlankLine:\r
996 Content = Content[:-1]\r
997 if not Content.replace('\\n', '').strip():\r
998 return ''\r
4234283c
LG
999 return Content\r
1000\r
1001## ConvertArchForInstall\r
f7496d71 1002# if Arch.upper() is in "IA32", "X64", "IPF", and "EBC", it must be upper case. "common" must be lower case.\r
4234283c
LG
1003# Anything else, the case must be preserved\r
1004#\r
f7496d71 1005# @param Arch: the arch string that need to be converted, it should be stripped before pass in\r
4234283c
LG
1006# @return: the arch string that get converted\r
1007#\r
1008def ConvertArchForInstall(Arch):\r
421ccda3 1009 if Arch.upper() in [DataType.TAB_ARCH_IA32, DataType.TAB_ARCH_X64,\r
4234283c
LG
1010 DataType.TAB_ARCH_IPF, DataType.TAB_ARCH_EBC]:\r
1011 Arch = Arch.upper()\r
1012 elif Arch.upper() == DataType.TAB_ARCH_COMMON:\r
1013 Arch = Arch.lower()\r
421ccda3 1014\r
4234283c 1015 return Arch\r