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