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