BaseTools: make static functions when self is not needed
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FdfParser.py
CommitLineData
30fdf114
LG
1## @file\r
2# parse FDF file\r
3#\r
a87e79d9 4# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
118bf096 5# Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>\r
30fdf114 6#\r
40d841f6 7# This program and the accompanying materials\r
30fdf114
LG
8# are licensed and made available under the terms and conditions of the BSD License\r
9# which accompanies this 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
17# Import Modules\r
18#\r
0d2711a6
LG
19import re\r
20\r
30fdf114
LG
21import Fd\r
22import Region\r
23import Fv\r
24import AprioriSection\r
25import FfsInfStatement\r
26import FfsFileStatement\r
27import VerSection\r
28import UiSection\r
29import FvImageSection\r
30import DataSection\r
31import DepexSection\r
32import CompressSection\r
33import GuidSection\r
34import Capsule\r
35import CapsuleData\r
36import Rule\r
37import RuleComplexFile\r
38import RuleSimpleFile\r
39import EfiSection\r
40import Vtf\r
41import ComponentStatement\r
42import OptionRom\r
43import OptRomInfStatement\r
44import OptRomFileStatement\r
cfbe3c35 45import string\r
30fdf114 46\r
52302d4d 47from GenFdsGlobalVariable import GenFdsGlobalVariable\r
30fdf114
LG
48from Common.BuildToolError import *\r
49from Common import EdkLogger\r
14c48571 50from Common.Misc import PathClass\r
51from Common.String import NormPath\r
0d2711a6
LG
52import Common.GlobalData as GlobalData\r
53from Common.Expression import *\r
df692f02 54from Common import GlobalData\r
2bcc713e 55from Common.String import ReplaceMacro\r
91ae2988 56import uuid\r
d0acc87a 57from Common.Misc import tdict\r
94e4bcbb 58from Common.MultipleWorkspace import MultipleWorkspace as mws\r
1be2ed90
HC
59import Common.LongFilePathOs as os\r
60from Common.LongFilePathSupport import OpenLongFilePath as open\r
91ae2988
YZ
61from Capsule import EFI_CERT_TYPE_PKCS7_GUID\r
62from Capsule import EFI_CERT_TYPE_RSA2048_SHA256_GUID\r
2eb370ff 63from Common.RangeExpression import RangeExpression\r
147a656b 64from Common.FdfParserLite import FileExtensionPattern,TokenFindPattern\r
30fdf114
LG
65\r
66##define T_CHAR_SPACE ' '\r
67##define T_CHAR_NULL '\0'\r
68##define T_CHAR_CR '\r'\r
69##define T_CHAR_TAB '\t'\r
70##define T_CHAR_LF '\n'\r
71##define T_CHAR_SLASH '/'\r
72##define T_CHAR_BACKSLASH '\\'\r
73##define T_CHAR_DOUBLE_QUOTE '\"'\r
74##define T_CHAR_SINGLE_QUOTE '\''\r
75##define T_CHAR_STAR '*'\r
76##define T_CHAR_HASH '#'\r
77\r
78(T_CHAR_SPACE, T_CHAR_NULL, T_CHAR_CR, T_CHAR_TAB, T_CHAR_LF, T_CHAR_SLASH, \\r
79T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \\r
80(' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')\r
81\r
82SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')\r
83\r
0d2711a6
LG
84RegionSizePattern = re.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")\r
85RegionSizeGuidPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")\r
2bc3256c 86RegionOffsetPcdPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*$")\r
64b2609f 87ShortcutPcdPattern = re.compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")\r
0d2711a6 88\r
118bf096
CS
89AllIncludeFileList = []\r
90\r
91# Get the closest parent\r
92def GetParentAtLine (Line):\r
93 for Profile in AllIncludeFileList:\r
94 if Profile.IsLineInFile(Line):\r
95 return Profile\r
96 return None\r
97\r
98# Check include loop\r
99def IsValidInclude (File, Line):\r
100 for Profile in AllIncludeFileList:\r
101 if Profile.IsLineInFile(Line) and Profile.FileName == File:\r
102 return False\r
103\r
104 return True\r
30fdf114
LG
105\r
106def GetRealFileLine (File, Line):\r
107\r
108 InsertedLines = 0\r
118bf096
CS
109 for Profile in AllIncludeFileList:\r
110 if Profile.IsLineInFile(Line):\r
111 return Profile.GetLineInFile(Line)\r
112 elif Line >= Profile.InsertStartLineNumber and Profile.Level == 1:\r
df81077f 113 InsertedLines += Profile.GetTotalLines()\r
30fdf114
LG
114\r
115 return (File, Line - InsertedLines)\r
116\r
117## The exception class that used to report error messages when parsing FDF\r
118#\r
119# Currently the "ToolName" is set to be "FDF Parser".\r
120#\r
121class Warning (Exception):\r
122 ## The constructor\r
123 #\r
124 # @param self The object pointer\r
125 # @param Str The message to record\r
126 # @param File The FDF name\r
127 # @param Line The Line number that error occurs\r
128 #\r
129 def __init__(self, Str, File = None, Line = None):\r
130\r
131 FileLineTuple = GetRealFileLine(File, Line)\r
132 self.FileName = FileLineTuple[0]\r
133 self.LineNumber = FileLineTuple[1]\r
118bf096 134 self.OriginalLineNumber = Line\r
30fdf114
LG
135 self.Message = Str\r
136 self.ToolName = 'FdfParser'\r
137\r
138 def __str__(self):\r
139 return self.Message\r
140\r
30fdf114
LG
141## The Include file content class that used to record file data when parsing include file\r
142#\r
143# May raise Exception when opening file.\r
144#\r
145class IncludeFileProfile :\r
146 ## The constructor\r
147 #\r
148 # @param self The object pointer\r
149 # @param FileName The file that to be parsed\r
150 #\r
151 def __init__(self, FileName):\r
152 self.FileName = FileName\r
153 self.FileLinesList = []\r
154 try:\r
155 fsock = open(FileName, "rb", 0)\r
156 try:\r
157 self.FileLinesList = fsock.readlines()\r
47a29bc7
YF
158 for index, line in enumerate(self.FileLinesList):\r
159 if not line.endswith('\n'):\r
160 self.FileLinesList[index] += '\n'\r
161\r
30fdf114
LG
162 finally:\r
163 fsock.close()\r
164\r
165 except:\r
166 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)\r
167\r
168 self.InsertStartLineNumber = None\r
169 self.InsertAdjust = 0\r
118bf096
CS
170 self.IncludeFileList = []\r
171 self.Level = 1 # first level include file\r
172 \r
173 def GetTotalLines(self):\r
174 TotalLines = self.InsertAdjust + len(self.FileLinesList)\r
175\r
176 for Profile in self.IncludeFileList:\r
df81077f 177 TotalLines += Profile.GetTotalLines()\r
118bf096
CS
178\r
179 return TotalLines\r
180\r
181 def IsLineInFile(self, Line):\r
182 if Line >= self.InsertStartLineNumber and Line < self.InsertStartLineNumber + self.GetTotalLines():\r
183 return True\r
184\r
185 return False\r
186\r
187 def GetLineInFile(self, Line):\r
188 if not self.IsLineInFile (Line):\r
189 return (self.FileName, -1)\r
190 \r
191 InsertedLines = self.InsertStartLineNumber\r
192\r
193 for Profile in self.IncludeFileList:\r
194 if Profile.IsLineInFile(Line):\r
195 return Profile.GetLineInFile(Line)\r
196 elif Line >= Profile.InsertStartLineNumber:\r
197 InsertedLines += Profile.GetTotalLines()\r
198\r
199 return (self.FileName, Line - InsertedLines + 1)\r
200\r
201\r
30fdf114
LG
202\r
203## The FDF content class that used to record file data when parsing FDF\r
204#\r
205# May raise Exception when opening file.\r
206#\r
207class FileProfile :\r
208 ## The constructor\r
209 #\r
210 # @param self The object pointer\r
211 # @param FileName The file that to be parsed\r
212 #\r
213 def __init__(self, FileName):\r
214 self.FileLinesList = []\r
215 try:\r
216 fsock = open(FileName, "rb", 0)\r
217 try:\r
218 self.FileLinesList = fsock.readlines()\r
219 finally:\r
220 fsock.close()\r
221\r
222 except:\r
223 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)\r
224\r
225\r
226 self.PcdDict = {}\r
227 self.InfList = []\r
2502b735 228 self.InfDict = {'ArchTBD':[]}\r
d0acc87a
LG
229 # ECC will use this Dict and List information\r
230 self.PcdFileLineDict = {}\r
231 self.InfFileLineList = []\r
232 \r
30fdf114 233 self.FdDict = {}\r
52302d4d 234 self.FdNameNotSet = False\r
30fdf114 235 self.FvDict = {}\r
fd171542 236 self.CapsuleDict = {}\r
30fdf114
LG
237 self.VtfList = []\r
238 self.RuleDict = {}\r
239 self.OptRomDict = {}\r
a3251d84 240 self.FmpPayloadDict = {}\r
30fdf114
LG
241\r
242## The syntax parser for FDF\r
243#\r
244# PreprocessFile method should be called prior to ParseFile\r
245# CycleReferenceCheck method can detect cycles in FDF contents\r
246#\r
247# GetNext*** procedures mean these procedures will get next token first, then make judgement.\r
248# Get*** procedures mean these procedures will make judgement on current token only.\r
249#\r
250class FdfParser:\r
251 ## The constructor\r
252 #\r
253 # @param self The object pointer\r
254 # @param FileName The file that to be parsed\r
255 #\r
256 def __init__(self, FileName):\r
257 self.Profile = FileProfile(FileName)\r
258 self.FileName = FileName\r
259 self.CurrentLineNumber = 1\r
260 self.CurrentOffsetWithinLine = 0\r
261 self.CurrentFdName = None\r
262 self.CurrentFvName = None\r
263 self.__Token = ""\r
264 self.__SkippedChars = ""\r
97fa0ee9 265 GlobalData.gFdfParser = self\r
30fdf114 266\r
d0acc87a
LG
267 # Used to section info\r
268 self.__CurSection = []\r
269 # Key: [section name, UI name, arch]\r
270 # Value: {MACRO_NAME : MACRO_VALUE}\r
271 self.__MacroDict = tdict(True, 3)\r
272 self.__PcdDict = {}\r
273\r
30fdf114 274 self.__WipeOffArea = []\r
14c48571 275 if GenFdsGlobalVariable.WorkSpaceDir == '':\r
276 GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE")\r
30fdf114 277\r
30fdf114
LG
278 ## __SkipWhiteSpace() method\r
279 #\r
280 # Skip white spaces from current char, return number of chars skipped\r
281 #\r
282 # @param self The object pointer\r
283 # @retval Count The number of chars skipped\r
284 #\r
285 def __SkipWhiteSpace(self):\r
286 Count = 0\r
287 while not self.__EndOfFile():\r
288 Count += 1\r
289 if self.__CurrentChar() in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_LF, T_CHAR_SPACE, T_CHAR_TAB):\r
290 self.__SkippedChars += str(self.__CurrentChar())\r
291 self.__GetOneChar()\r
292\r
293 else:\r
294 Count = Count - 1\r
295 return Count\r
296\r
297 ## __EndOfFile() method\r
298 #\r
299 # Judge current buffer pos is at file end\r
300 #\r
301 # @param self The object pointer\r
302 # @retval True Current File buffer position is at file end\r
303 # @retval False Current File buffer position is NOT at file end\r
304 #\r
305 def __EndOfFile(self):\r
306 NumberOfLines = len(self.Profile.FileLinesList)\r
307 SizeOfLastLine = len(self.Profile.FileLinesList[-1])\r
308 if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1:\r
309 return True\r
310 elif self.CurrentLineNumber > NumberOfLines:\r
311 return True\r
312 else:\r
313 return False\r
314\r
315 ## __EndOfLine() method\r
316 #\r
317 # Judge current buffer pos is at line end\r
318 #\r
319 # @param self The object pointer\r
320 # @retval True Current File buffer position is at line end\r
321 # @retval False Current File buffer position is NOT at line end\r
322 #\r
323 def __EndOfLine(self):\r
324 if self.CurrentLineNumber > len(self.Profile.FileLinesList):\r
325 return True\r
326 SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1])\r
327 if self.CurrentOffsetWithinLine >= SizeOfCurrentLine:\r
328 return True\r
329 else:\r
330 return False\r
331\r
332 ## Rewind() method\r
333 #\r
334 # Reset file data buffer to the initial state\r
335 #\r
336 # @param self The object pointer\r
118bf096
CS
337 # @param DestLine Optional new destination line number.\r
338 # @param DestOffset Optional new destination offset. \r
30fdf114 339 #\r
118bf096
CS
340 def Rewind(self, DestLine = 1, DestOffset = 0): \r
341 self.CurrentLineNumber = DestLine \r
342 self.CurrentOffsetWithinLine = DestOffset \r
30fdf114
LG
343\r
344 ## __UndoOneChar() method\r
345 #\r
346 # Go back one char in the file buffer\r
347 #\r
348 # @param self The object pointer\r
349 # @retval True Successfully go back one char\r
350 # @retval False Not able to go back one char as file beginning reached\r
351 #\r
352 def __UndoOneChar(self):\r
353\r
354 if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0:\r
355 return False\r
356 elif self.CurrentOffsetWithinLine == 0:\r
357 self.CurrentLineNumber -= 1\r
358 self.CurrentOffsetWithinLine = len(self.__CurrentLine()) - 1\r
359 else:\r
360 self.CurrentOffsetWithinLine -= 1\r
361 return True\r
362\r
363 ## __GetOneChar() method\r
364 #\r
365 # Move forward one char in the file buffer\r
366 #\r
367 # @param self The object pointer\r
368 #\r
369 def __GetOneChar(self):\r
370 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:\r
0d2711a6
LG
371 self.CurrentLineNumber += 1\r
372 self.CurrentOffsetWithinLine = 0\r
30fdf114 373 else:\r
0d2711a6 374 self.CurrentOffsetWithinLine += 1\r
30fdf114
LG
375\r
376 ## __CurrentChar() method\r
377 #\r
378 # Get the char pointed to by the file buffer pointer\r
379 #\r
380 # @param self The object pointer\r
381 # @retval Char Current char\r
382 #\r
383 def __CurrentChar(self):\r
384 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine]\r
385\r
386 ## __NextChar() method\r
387 #\r
388 # Get the one char pass the char pointed to by the file buffer pointer\r
389 #\r
390 # @param self The object pointer\r
391 # @retval Char Next char\r
392 #\r
393 def __NextChar(self):\r
394 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:\r
395 return self.Profile.FileLinesList[self.CurrentLineNumber][0]\r
396 else:\r
397 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1]\r
398\r
399 ## __SetCurrentCharValue() method\r
400 #\r
401 # Modify the value of current char\r
402 #\r
403 # @param self The object pointer\r
404 # @param Value The new value of current char\r
405 #\r
406 def __SetCurrentCharValue(self, Value):\r
407 self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value\r
408\r
409 ## __CurrentLine() method\r
410 #\r
411 # Get the list that contains current line contents\r
412 #\r
413 # @param self The object pointer\r
414 # @retval List current line contents\r
415 #\r
416 def __CurrentLine(self):\r
417 return self.Profile.FileLinesList[self.CurrentLineNumber - 1]\r
418\r
419 def __StringToList(self):\r
420 self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList]\r
421 self.Profile.FileLinesList[-1].append(' ')\r
422\r
30fdf114
LG
423 def __ReplaceFragment(self, StartPos, EndPos, Value = ' '):\r
424 if StartPos[0] == EndPos[0]:\r
425 Offset = StartPos[1]\r
426 while Offset <= EndPos[1]:\r
427 self.Profile.FileLinesList[StartPos[0]][Offset] = Value\r
428 Offset += 1\r
429 return\r
430\r
431 Offset = StartPos[1]\r
432 while self.Profile.FileLinesList[StartPos[0]][Offset] not in ('\r', '\n'):\r
433 self.Profile.FileLinesList[StartPos[0]][Offset] = Value\r
434 Offset += 1\r
435\r
436 Line = StartPos[0]\r
437 while Line < EndPos[0]:\r
438 Offset = 0\r
439 while self.Profile.FileLinesList[Line][Offset] not in ('\r', '\n'):\r
440 self.Profile.FileLinesList[Line][Offset] = Value\r
441 Offset += 1\r
442 Line += 1\r
443\r
444 Offset = 0\r
445 while Offset <= EndPos[1]:\r
446 self.Profile.FileLinesList[EndPos[0]][Offset] = Value\r
447 Offset += 1\r
448\r
449\r
d5d56f1b
LG
450 def __GetMacroName(self):\r
451 if not self.__GetNextToken():\r
452 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)\r
453 MacroName = self.__Token\r
454 NotFlag = False\r
455 if MacroName.startswith('!'):\r
456 NotFlag = True\r
457 MacroName = MacroName[1:].strip()\r
458 \r
459 if not MacroName.startswith('$(') or not MacroName.endswith(')'):\r
460 raise Warning("Macro name expected(Please use '$(%(Token)s)' if '%(Token)s' is a macro.)" % {"Token" : MacroName},\r
461 self.FileName, self.CurrentLineNumber)\r
462 MacroName = MacroName[2:-1]\r
463 return MacroName, NotFlag\r
d0acc87a
LG
464\r
465 def __SetMacroValue(self, Macro, Value):\r
466 if not self.__CurSection:\r
467 return\r
468\r
469 MacroDict = {}\r
470 if not self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]]:\r
471 self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]] = MacroDict\r
472 else:\r
473 MacroDict = self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]]\r
474 MacroDict[Macro] = Value\r
475\r
476 def __GetMacroValue(self, Macro):\r
477 # Highest priority\r
478 if Macro in GlobalData.gCommandLineDefines:\r
479 return GlobalData.gCommandLineDefines[Macro]\r
480 if Macro in GlobalData.gGlobalDefines:\r
481 return GlobalData.gGlobalDefines[Macro]\r
482\r
483 if self.__CurSection:\r
484 MacroDict = self.__MacroDict[\r
485 self.__CurSection[0],\r
486 self.__CurSection[1],\r
487 self.__CurSection[2]\r
488 ]\r
489 if MacroDict and Macro in MacroDict:\r
490 return MacroDict[Macro]\r
491\r
492 # Lowest priority\r
493 if Macro in GlobalData.gPlatformDefines:\r
494 return GlobalData.gPlatformDefines[Macro]\r
495 return None\r
496\r
497 def __SectionHeaderParser(self, Section):\r
498 # [Defines]\r
499 # [FD.UiName]: use dummy instead if UI name is optional\r
500 # [FV.UiName]\r
501 # [Capsule.UiName]\r
502 # [Rule]: don't take rule section into account, macro is not allowed in this section\r
503 # [VTF.arch.UiName, arch]\r
504 # [OptionRom.DriverName]\r
505 self.__CurSection = []\r
506 Section = Section.strip()[1:-1].upper().replace(' ', '').strip('.')\r
507 ItemList = Section.split('.')\r
508 Item = ItemList[0]\r
509 if Item == '' or Item == 'RULE':\r
510 return\r
511\r
512 if Item == 'DEFINES':\r
513 self.__CurSection = ['COMMON', 'COMMON', 'COMMON']\r
514 elif Item == 'VTF' and len(ItemList) == 3:\r
515 UiName = ItemList[2]\r
516 Pos = UiName.find(',')\r
517 if Pos != -1:\r
518 UiName = UiName[:Pos]\r
519 self.__CurSection = ['VTF', UiName, ItemList[1]]\r
520 elif len(ItemList) > 1:\r
521 self.__CurSection = [ItemList[0], ItemList[1], 'COMMON']\r
522 elif len(ItemList) > 0:\r
523 self.__CurSection = [ItemList[0], 'DUMMY', 'COMMON']\r
524\r
30fdf114
LG
525 ## PreprocessFile() method\r
526 #\r
527 # Preprocess file contents, replace comments with spaces.\r
528 # In the end, rewind the file buffer pointer to the beginning\r
529 # BUGBUG: No !include statement processing contained in this procedure\r
530 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]\r
531 #\r
532 # @param self The object pointer\r
533 #\r
534 def PreprocessFile(self):\r
535\r
536 self.Rewind()\r
537 InComment = False\r
538 DoubleSlashComment = False\r
539 HashComment = False\r
540 # HashComment in quoted string " " is ignored.\r
541 InString = False\r
542\r
543 while not self.__EndOfFile():\r
544\r
545 if self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment:\r
546 InString = not InString\r
547 # meet new line, then no longer in a comment for // and '#'\r
548 if self.__CurrentChar() == T_CHAR_LF:\r
549 self.CurrentLineNumber += 1\r
550 self.CurrentOffsetWithinLine = 0\r
551 if InComment and DoubleSlashComment:\r
552 InComment = False\r
553 DoubleSlashComment = False\r
554 if InComment and HashComment:\r
555 InComment = False\r
556 HashComment = False\r
557 # check for */ comment end\r
558 elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH:\r
559 self.__SetCurrentCharValue(T_CHAR_SPACE)\r
560 self.__GetOneChar()\r
561 self.__SetCurrentCharValue(T_CHAR_SPACE)\r
562 self.__GetOneChar()\r
563 InComment = False\r
564 # set comments to spaces\r
565 elif InComment:\r
566 self.__SetCurrentCharValue(T_CHAR_SPACE)\r
567 self.__GetOneChar()\r
568 # check for // comment\r
569 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH and not self.__EndOfLine():\r
570 InComment = True\r
571 DoubleSlashComment = True\r
572 # check for '#' comment\r
573 elif self.__CurrentChar() == T_CHAR_HASH and not self.__EndOfLine() and not InString:\r
574 InComment = True\r
575 HashComment = True\r
576 # check for /* comment start\r
577 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR:\r
578 self.__SetCurrentCharValue( T_CHAR_SPACE)\r
579 self.__GetOneChar()\r
580 self.__SetCurrentCharValue( T_CHAR_SPACE)\r
581 self.__GetOneChar()\r
582 InComment = True\r
583 else:\r
584 self.__GetOneChar()\r
585\r
586 # restore from ListOfList to ListOfString\r
587 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]\r
588 self.Rewind()\r
589\r
590 ## PreprocessIncludeFile() method\r
591 #\r
592 # Preprocess file contents, replace !include statements with file contents.\r
593 # In the end, rewind the file buffer pointer to the beginning\r
594 #\r
595 # @param self The object pointer\r
596 #\r
597 def PreprocessIncludeFile(self):\r
118bf096
CS
598 # nested include support\r
599 Processed = False\r
0fdfe274 600 MacroDict = {}\r
30fdf114
LG
601 while self.__GetNextToken():\r
602\r
0fdfe274
YZ
603 if self.__Token == 'DEFINE':\r
604 if not self.__GetNextToken():\r
605 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)\r
606 Macro = self.__Token\r
607 if not self.__IsToken( "="):\r
608 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
609 Value = self.__GetExpression()\r
610 MacroDict[Macro] = Value\r
611\r
612 elif self.__Token == '!include':\r
118bf096 613 Processed = True\r
30fdf114
LG
614 IncludeLine = self.CurrentLineNumber\r
615 IncludeOffset = self.CurrentOffsetWithinLine - len('!include')\r
616 if not self.__GetNextToken():\r
617 raise Warning("expected include file name", self.FileName, self.CurrentLineNumber)\r
618 IncFileName = self.__Token\r
0fdfe274
YZ
619 PreIndex = 0\r
620 StartPos = IncFileName.find('$(', PreIndex)\r
621 EndPos = IncFileName.find(')', StartPos+2)\r
622 while StartPos != -1 and EndPos != -1:\r
623 Macro = IncFileName[StartPos+2 : EndPos]\r
d0acc87a 624 MacroVal = self.__GetMacroValue(Macro)\r
0fdfe274
YZ
625 if not MacroVal:\r
626 if Macro in MacroDict:\r
627 MacroVal = MacroDict[Macro]\r
4231a819 628 if MacroVal is not None:\r
0fdfe274
YZ
629 IncFileName = IncFileName.replace('$(' + Macro + ')', MacroVal, 1)\r
630 if MacroVal.find('$(') != -1:\r
631 PreIndex = StartPos\r
632 else:\r
633 PreIndex = StartPos + len(MacroVal)\r
634 else:\r
635 raise Warning("The Macro %s is not defined" %Macro, self.FileName, self.CurrentLineNumber)\r
636 StartPos = IncFileName.find('$(', PreIndex)\r
637 EndPos = IncFileName.find(')', StartPos+2)\r
638\r
639 IncludedFile = NormPath(IncFileName)\r
2bcc713e
LG
640 #\r
641 # First search the include file under the same directory as FDF file\r
642 #\r
643 IncludedFile1 = PathClass(IncludedFile, os.path.dirname(self.FileName))\r
644 ErrorCode = IncludedFile1.Validate()[0]\r
645 if ErrorCode != 0:\r
646 #\r
647 # Then search the include file under the same directory as DSC file\r
648 #\r
d0acc87a
LG
649 PlatformDir = ''\r
650 if GenFdsGlobalVariable.ActivePlatform:\r
651 PlatformDir = GenFdsGlobalVariable.ActivePlatform.Dir\r
652 elif GlobalData.gActivePlatform:\r
653 PlatformDir = GlobalData.gActivePlatform.MetaFile.Dir\r
654 IncludedFile1 = PathClass(IncludedFile, PlatformDir)\r
2bcc713e
LG
655 ErrorCode = IncludedFile1.Validate()[0]\r
656 if ErrorCode != 0:\r
657 #\r
658 # Also search file under the WORKSPACE directory\r
659 #\r
660 IncludedFile1 = PathClass(IncludedFile, GlobalData.gWorkspace)\r
661 ErrorCode = IncludedFile1.Validate()[0]\r
662 if ErrorCode != 0:\r
d0acc87a 663 raise Warning("The include file does not exist under below directories: \n%s\n%s\n%s\n"%(os.path.dirname(self.FileName), PlatformDir, GlobalData.gWorkspace), \r
2bcc713e 664 self.FileName, self.CurrentLineNumber)\r
30fdf114 665\r
118bf096
CS
666 if not IsValidInclude (IncludedFile1.Path, self.CurrentLineNumber):\r
667 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1.Path), self.FileName, self.CurrentLineNumber)\r
668\r
2bcc713e 669 IncFileProfile = IncludeFileProfile(IncludedFile1.Path)\r
30fdf114
LG
670\r
671 CurrentLine = self.CurrentLineNumber\r
672 CurrentOffset = self.CurrentOffsetWithinLine\r
673 # list index of the insertion, note that line number is 'CurrentLine + 1'\r
674 InsertAtLine = CurrentLine\r
118bf096 675 ParentProfile = GetParentAtLine (CurrentLine)\r
4231a819 676 if ParentProfile is not None:\r
118bf096
CS
677 ParentProfile.IncludeFileList.insert(0, IncFileProfile)\r
678 IncFileProfile.Level = ParentProfile.Level + 1\r
30fdf114
LG
679 IncFileProfile.InsertStartLineNumber = InsertAtLine + 1\r
680 # deal with remaining portions after "!include filename", if exists.\r
681 if self.__GetNextToken():\r
682 if self.CurrentLineNumber == CurrentLine:\r
683 RemainingLine = self.__CurrentLine()[CurrentOffset:]\r
684 self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine)\r
685 IncFileProfile.InsertAdjust += 1\r
686 self.CurrentLineNumber += 1\r
687 self.CurrentOffsetWithinLine = 0\r
688\r
689 for Line in IncFileProfile.FileLinesList:\r
690 self.Profile.FileLinesList.insert(InsertAtLine, Line)\r
691 self.CurrentLineNumber += 1\r
692 InsertAtLine += 1\r
693\r
118bf096
CS
694 # reversely sorted to better determine error in file\r
695 AllIncludeFileList.insert(0, IncFileProfile)\r
30fdf114
LG
696\r
697 # comment out the processed include file statement\r
698 TempList = list(self.Profile.FileLinesList[IncludeLine - 1])\r
699 TempList.insert(IncludeOffset, '#')\r
700 self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)\r
118bf096
CS
701 if Processed: # Nested and back-to-back support\r
702 self.Rewind(DestLine = IncFileProfile.InsertStartLineNumber - 1)\r
703 Processed = False\r
704 # Preprocess done.\r
30fdf114 705 self.Rewind()\r
0d2711a6 706 \r
5bcf1d56
CJ
707 @staticmethod\r
708 def __GetIfListCurrentItemStat(IfList):\r
da92f276
LG
709 if len(IfList) == 0:\r
710 return True\r
711 \r
712 for Item in IfList:\r
713 if Item[1] == False:\r
714 return False\r
715 \r
716 return True\r
0d2711a6 717 \r
6780eef1 718 ## PreprocessConditionalStatement() method\r
30fdf114 719 #\r
6780eef1 720 # Preprocess conditional statement.\r
30fdf114
LG
721 # In the end, rewind the file buffer pointer to the beginning\r
722 #\r
723 # @param self The object pointer\r
724 #\r
725 def PreprocessConditionalStatement(self):\r
726 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]\r
727 IfList = []\r
0d2711a6 728 RegionLayoutLine = 0\r
d0acc87a 729 ReplacedLine = -1\r
30fdf114 730 while self.__GetNextToken():\r
d0acc87a
LG
731 # Determine section name and the location dependent macro\r
732 if self.__GetIfListCurrentItemStat(IfList):\r
733 if self.__Token.startswith('['):\r
734 Header = self.__Token\r
735 if not self.__Token.endswith(']'):\r
736 self.__SkipToToken(']')\r
737 Header += self.__SkippedChars\r
738 if Header.find('$(') != -1:\r
739 raise Warning("macro cannot be used in section header", self.FileName, self.CurrentLineNumber)\r
740 self.__SectionHeaderParser(Header)\r
741 continue\r
742 # Replace macros except in RULE section or out of section\r
743 elif self.__CurSection and ReplacedLine != self.CurrentLineNumber:\r
744 ReplacedLine = self.CurrentLineNumber\r
745 self.__UndoToken()\r
746 CurLine = self.Profile.FileLinesList[ReplacedLine - 1]\r
747 PreIndex = 0\r
748 StartPos = CurLine.find('$(', PreIndex)\r
749 EndPos = CurLine.find(')', StartPos+2)\r
64b2609f 750 while StartPos != -1 and EndPos != -1 and self.__Token not in ['!ifdef', '!ifndef', '!if', '!elseif']:\r
d0acc87a
LG
751 MacroName = CurLine[StartPos+2 : EndPos]\r
752 MacorValue = self.__GetMacroValue(MacroName)\r
4231a819 753 if MacorValue is not None:\r
d0acc87a
LG
754 CurLine = CurLine.replace('$(' + MacroName + ')', MacorValue, 1)\r
755 if MacorValue.find('$(') != -1:\r
756 PreIndex = StartPos\r
757 else:\r
758 PreIndex = StartPos + len(MacorValue)\r
759 else:\r
760 PreIndex = EndPos + 1\r
761 StartPos = CurLine.find('$(', PreIndex)\r
762 EndPos = CurLine.find(')', StartPos+2)\r
763 self.Profile.FileLinesList[ReplacedLine - 1] = CurLine\r
764 continue\r
765\r
30fdf114 766 if self.__Token == 'DEFINE':\r
d0acc87a
LG
767 if self.__GetIfListCurrentItemStat(IfList):\r
768 if not self.__CurSection:\r
769 raise Warning("macro cannot be defined in Rule section or out of section", self.FileName, self.CurrentLineNumber)\r
da92f276
LG
770 DefineLine = self.CurrentLineNumber - 1\r
771 DefineOffset = self.CurrentOffsetWithinLine - len('DEFINE')\r
772 if not self.__GetNextToken():\r
773 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)\r
774 Macro = self.__Token\r
775 if not self.__IsToken( "="):\r
776 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
777 \r
d0acc87a
LG
778 Value = self.__GetExpression()\r
779 self.__SetMacroValue(Macro, Value)\r
da92f276 780 self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
0d2711a6 781 elif self.__Token == 'SET':\r
2f04e527
YL
782 if not self.__GetIfListCurrentItemStat(IfList):\r
783 continue\r
64b2609f
LG
784 SetLine = self.CurrentLineNumber - 1\r
785 SetOffset = self.CurrentOffsetWithinLine - len('SET')\r
0d2711a6
LG
786 PcdPair = self.__GetNextPcdName()\r
787 PcdName = "%s.%s" % (PcdPair[1], PcdPair[0])\r
788 if not self.__IsToken( "="):\r
789 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
790\r
d0acc87a
LG
791 Value = self.__GetExpression()\r
792 Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)\r
30fdf114 793\r
d0acc87a 794 self.__PcdDict[PcdName] = Value\r
64b2609f
LG
795\r
796 self.Profile.PcdDict[PcdPair] = Value\r
797 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
798 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple\r
799\r
800 self.__WipeOffArea.append(((SetLine, SetOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
30fdf114
LG
801 elif self.__Token in ('!ifdef', '!ifndef', '!if'):\r
802 IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))\r
803 IfList.append([IfStartPos, None, None])\r
0d2711a6 804\r
30fdf114 805 CondLabel = self.__Token\r
0d2711a6 806 Expression = self.__GetExpression()\r
d5d56f1b 807 \r
30fdf114 808 if CondLabel == '!if':\r
0d2711a6 809 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')\r
30fdf114 810 else:\r
0d2711a6
LG
811 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'in')\r
812 if CondLabel == '!ifndef':\r
30fdf114 813 ConditionSatisfied = not ConditionSatisfied\r
30fdf114 814\r
0d2711a6
LG
815 BranchDetermined = ConditionSatisfied\r
816 IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]\r
817 if ConditionSatisfied:\r
818 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) \r
30fdf114
LG
819 elif self.__Token in ('!elseif', '!else'):\r
820 ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))\r
821 if len(IfList) <= 0:\r
822 raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)\r
0d2711a6 823\r
30fdf114
LG
824 if IfList[-1][1]:\r
825 IfList[-1] = [ElseStartPos, False, True]\r
826 self.__WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
827 else:\r
828 self.__WipeOffArea.append((IfList[-1][0], ElseStartPos))\r
829 IfList[-1] = [ElseStartPos, True, IfList[-1][2]]\r
830 if self.__Token == '!elseif':\r
0d2711a6
LG
831 Expression = self.__GetExpression()\r
832 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')\r
30fdf114
LG
833 IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]]\r
834\r
835 if IfList[-1][1]:\r
836 if IfList[-1][2]:\r
837 IfList[-1][1] = False\r
838 else:\r
839 IfList[-1][2] = True\r
840 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
30fdf114 841 elif self.__Token == '!endif':\r
d0acc87a
LG
842 if len(IfList) <= 0:\r
843 raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
844 if IfList[-1][1]:\r
845 self.__WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
846 else:\r
847 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
848\r
849 IfList.pop()\r
0d2711a6
LG
850 elif not IfList: # Don't use PCDs inside conditional directive\r
851 if self.CurrentLineNumber <= RegionLayoutLine:\r
852 # Don't try the same line twice\r
853 continue\r
64b2609f
LG
854 SetPcd = ShortcutPcdPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])\r
855 if SetPcd:\r
856 self.__PcdDict[SetPcd.group('name')] = SetPcd.group('value')\r
857 RegionLayoutLine = self.CurrentLineNumber\r
858 continue\r
0d2711a6
LG
859 RegionSize = RegionSizePattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])\r
860 if not RegionSize:\r
861 RegionLayoutLine = self.CurrentLineNumber\r
862 continue\r
863 RegionSizeGuid = RegionSizeGuidPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber])\r
864 if not RegionSizeGuid:\r
865 RegionLayoutLine = self.CurrentLineNumber + 1\r
866 continue\r
d0acc87a
LG
867 self.__PcdDict[RegionSizeGuid.group('base')] = RegionSize.group('base')\r
868 self.__PcdDict[RegionSizeGuid.group('size')] = RegionSize.group('size')\r
0d2711a6
LG
869 RegionLayoutLine = self.CurrentLineNumber + 1\r
870\r
871 if IfList:\r
30fdf114
LG
872 raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber)\r
873 self.Rewind()\r
874\r
d0acc87a
LG
875 def __CollectMacroPcd(self):\r
876 MacroDict = {}\r
877\r
878 # PCD macro\r
64b2609f 879 MacroDict.update(GlobalData.gPlatformPcds)\r
d0acc87a
LG
880 MacroDict.update(self.__PcdDict)\r
881\r
882 # Lowest priority\r
883 MacroDict.update(GlobalData.gPlatformDefines)\r
884\r
885 if self.__CurSection:\r
886 # Defines macro\r
887 ScopeMacro = self.__MacroDict['COMMON', 'COMMON', 'COMMON']\r
888 if ScopeMacro:\r
889 MacroDict.update(ScopeMacro)\r
890 \r
891 # Section macro\r
892 ScopeMacro = self.__MacroDict[\r
893 self.__CurSection[0],\r
894 self.__CurSection[1],\r
895 self.__CurSection[2]\r
896 ]\r
897 if ScopeMacro:\r
898 MacroDict.update(ScopeMacro)\r
899\r
900 MacroDict.update(GlobalData.gGlobalDefines)\r
901 MacroDict.update(GlobalData.gCommandLineDefines)\r
1fa7fdf6
FY
902 if GlobalData.BuildOptionPcd:\r
903 for Item in GlobalData.BuildOptionPcd:\r
705ed563
YZ
904 if type(Item) is tuple:\r
905 continue\r
1fa7fdf6 906 PcdName, TmpValue = Item.split("=")\r
8565b582 907 TmpValue = BuildOptionValue(TmpValue, {})\r
1fa7fdf6 908 MacroDict[PcdName.strip()] = TmpValue\r
d0acc87a
LG
909 # Highest priority\r
910\r
911 return MacroDict\r
912\r
0d2711a6 913 def __EvaluateConditional(self, Expression, Line, Op = None, Value = None):\r
30fdf114 914 FileLineTuple = GetRealFileLine(self.FileName, Line)\r
d0acc87a 915 MacroPcdDict = self.__CollectMacroPcd()\r
0d2711a6
LG
916 if Op == 'eval':\r
917 try:\r
d0acc87a
LG
918 if Value:\r
919 return ValueExpression(Expression, MacroPcdDict)(True)\r
920 else:\r
921 return ValueExpression(Expression, MacroPcdDict)()\r
0d2711a6
LG
922 except WrnExpression, Excpt:\r
923 # \r
924 # Catch expression evaluation warning here. We need to report\r
925 # the precise number of line and return the evaluation result\r
926 #\r
927 EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),\r
928 File=self.FileName, ExtraData=self.__CurrentLine(), \r
929 Line=Line)\r
930 return Excpt.result\r
931 except Exception, Excpt:\r
64b2609f
LG
932 if hasattr(Excpt, 'Pcd'):\r
933 if Excpt.Pcd in GlobalData.gPlatformOtherPcds:\r
934 Info = GlobalData.gPlatformOtherPcds[Excpt.Pcd]\r
935 raise Warning("Cannot use this PCD (%s) in an expression as"\r
936 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"\r
937 " of the DSC file (%s), and it is currently defined in this section:"\r
938 " %s, line #: %d." % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE'], Info[0], Info[1]),\r
939 *FileLineTuple)\r
940 else:\r
941 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE']),\r
942 *FileLineTuple)\r
943 else:\r
944 raise Warning(str(Excpt), *FileLineTuple)\r
0d2711a6
LG
945 else:\r
946 if Expression.startswith('$(') and Expression[-1] == ')':\r
947 Expression = Expression[2:-1] \r
d0acc87a 948 return Expression in MacroPcdDict\r
30fdf114
LG
949\r
950 ## __IsToken() method\r
951 #\r
952 # Check whether input string is found from current char position along\r
953 # If found, the string value is put into self.__Token\r
954 #\r
955 # @param self The object pointer\r
956 # @param String The string to search\r
957 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive\r
958 # @retval True Successfully find string, file buffer pointer moved forward\r
959 # @retval False Not able to find string, file buffer pointer not changed\r
960 #\r
961 def __IsToken(self, String, IgnoreCase = False):\r
962 self.__SkipWhiteSpace()\r
963\r
964 # Only consider the same line, no multi-line token allowed\r
965 StartPos = self.CurrentOffsetWithinLine\r
966 index = -1\r
967 if IgnoreCase:\r
968 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())\r
969 else:\r
970 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)\r
971 if index == 0:\r
972 self.CurrentOffsetWithinLine += len(String)\r
973 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]\r
974 return True\r
975 return False\r
976\r
977 ## __IsKeyword() method\r
978 #\r
979 # Check whether input keyword is found from current char position along, whole word only!\r
980 # If found, the string value is put into self.__Token\r
981 #\r
982 # @param self The object pointer\r
983 # @param Keyword The string to search\r
984 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive\r
985 # @retval True Successfully find string, file buffer pointer moved forward\r
986 # @retval False Not able to find string, file buffer pointer not changed\r
987 #\r
988 def __IsKeyword(self, KeyWord, IgnoreCase = False):\r
989 self.__SkipWhiteSpace()\r
990\r
991 # Only consider the same line, no multi-line token allowed\r
992 StartPos = self.CurrentOffsetWithinLine\r
993 index = -1\r
994 if IgnoreCase:\r
995 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(KeyWord.upper())\r
996 else:\r
997 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(KeyWord)\r
998 if index == 0:\r
999 followingChar = self.__CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)]\r
1000 if not str(followingChar).isspace() and followingChar not in SEPERATOR_TUPLE:\r
1001 return False\r
1002 self.CurrentOffsetWithinLine += len(KeyWord)\r
1003 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]\r
1004 return True\r
1005 return False\r
1006\r
0d2711a6
LG
1007 def __GetExpression(self):\r
1008 Line = self.Profile.FileLinesList[self.CurrentLineNumber - 1]\r
1009 Index = len(Line) - 1\r
1010 while Line[Index] in ['\r', '\n']:\r
1011 Index -= 1\r
1012 ExpressionString = self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:Index+1]\r
1013 self.CurrentOffsetWithinLine += len(ExpressionString)\r
1014 ExpressionString = ExpressionString.strip()\r
1015 return ExpressionString\r
1016\r
30fdf114
LG
1017 ## __GetNextWord() method\r
1018 #\r
1019 # Get next C name from file lines\r
1020 # If found, the string value is put into self.__Token\r
1021 #\r
1022 # @param self The object pointer\r
1023 # @retval True Successfully find a C name string, file buffer pointer moved forward\r
1024 # @retval False Not able to find a C name string, file buffer pointer not changed\r
1025 #\r
1026 def __GetNextWord(self):\r
1027 self.__SkipWhiteSpace()\r
1028 if self.__EndOfFile():\r
1029 return False\r
1030\r
1031 TempChar = self.__CurrentChar()\r
1032 StartPos = self.CurrentOffsetWithinLine\r
1033 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_':\r
1034 self.__GetOneChar()\r
1035 while not self.__EndOfLine():\r
1036 TempChar = self.__CurrentChar()\r
1037 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \\r
1038 or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-':\r
1039 self.__GetOneChar()\r
1040\r
1041 else:\r
1042 break\r
1043\r
1044 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]\r
1045 return True\r
1046\r
1047 return False\r
1048\r
1049 ## __GetNextToken() method\r
1050 #\r
1051 # Get next token unit before a seperator\r
1052 # If found, the string value is put into self.__Token\r
1053 #\r
1054 # @param self The object pointer\r
1055 # @retval True Successfully find a token unit, file buffer pointer moved forward\r
1056 # @retval False Not able to find a token unit, file buffer pointer not changed\r
1057 #\r
1058 def __GetNextToken(self):\r
1059 # Skip leading spaces, if exist.\r
1060 self.__SkipWhiteSpace()\r
1061 if self.__EndOfFile():\r
1062 return False\r
1063 # Record the token start position, the position of the first non-space char.\r
1064 StartPos = self.CurrentOffsetWithinLine\r
1065 StartLine = self.CurrentLineNumber\r
d0acc87a 1066 while StartLine == self.CurrentLineNumber:\r
30fdf114
LG
1067 TempChar = self.__CurrentChar()\r
1068 # Try to find the end char that is not a space and not in seperator tuple.\r
1069 # That is, when we got a space or any char in the tuple, we got the end of token.\r
1070 if not str(TempChar).isspace() and TempChar not in SEPERATOR_TUPLE:\r
1071 self.__GetOneChar()\r
1072 # if we happen to meet a seperator as the first char, we must proceed to get it.\r
1073 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.\r
1074 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:\r
1075 self.__GetOneChar()\r
1076 break\r
1077 else:\r
1078 break\r
1079# else:\r
1080# return False\r
1081\r
1082 EndPos = self.CurrentOffsetWithinLine\r
1083 if self.CurrentLineNumber != StartLine:\r
1084 EndPos = len(self.Profile.FileLinesList[StartLine-1])\r
1085 self.__Token = self.Profile.FileLinesList[StartLine-1][StartPos : EndPos]\r
1086 if StartPos != self.CurrentOffsetWithinLine:\r
1087 return True\r
1088 else:\r
1089 return False\r
1090\r
1091 def __GetNextOp(self):\r
1092 # Skip leading spaces, if exist.\r
1093 self.__SkipWhiteSpace()\r
1094 if self.__EndOfFile():\r
1095 return False\r
1096 # Record the token start position, the position of the first non-space char.\r
1097 StartPos = self.CurrentOffsetWithinLine\r
1098 while not self.__EndOfLine():\r
1099 TempChar = self.__CurrentChar()\r
1100 # Try to find the end char that is not a space\r
1101 if not str(TempChar).isspace():\r
1102 self.__GetOneChar()\r
1103 else:\r
1104 break\r
1105 else:\r
1106 return False\r
1107\r
1108 if StartPos != self.CurrentOffsetWithinLine:\r
1109 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]\r
1110 return True\r
1111 else:\r
1112 return False\r
1113 ## __GetNextGuid() method\r
1114 #\r
1115 # Get next token unit before a seperator\r
1116 # If found, the GUID string is put into self.__Token\r
1117 #\r
1118 # @param self The object pointer\r
1119 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward\r
1120 # @retval False Not able to find a registry format GUID, file buffer pointer not changed\r
1121 #\r
1122 def __GetNextGuid(self):\r
1123\r
1124 if not self.__GetNextToken():\r
1125 return False\r
4231a819 1126 if gGuidPattern.match(self.__Token) is not None:\r
30fdf114
LG
1127 return True\r
1128 else:\r
1129 self.__UndoToken()\r
1130 return False\r
1131\r
91ae2988
YZ
1132 def __Verify(self, Name, Value, Scope):\r
1133 if Scope in ['UINT64', 'UINT8']:\r
1134 ValueNumber = 0\r
1135 try:\r
0944818a 1136 ValueNumber = int (Value, 0)\r
91ae2988
YZ
1137 except:\r
1138 EdkLogger.error("FdfParser", FORMAT_INVALID, "The value is not valid dec or hex number for %s." % Name)\r
1139 if ValueNumber < 0:\r
1140 EdkLogger.error("FdfParser", FORMAT_INVALID, "The value can't be set to negative value for %s." % Name)\r
1141 if Scope == 'UINT64':\r
1142 if ValueNumber >= 0x10000000000000000:\r
1143 EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name)\r
1144 if Scope == 'UINT8':\r
1145 if ValueNumber >= 0x100:\r
1146 EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name)\r
1147 return True\r
1148\r
30fdf114
LG
1149 ## __UndoToken() method\r
1150 #\r
1151 # Go back one token unit in file buffer\r
1152 #\r
1153 # @param self The object pointer\r
1154 #\r
1155 def __UndoToken(self):\r
1156 self.__UndoOneChar()\r
1157 while self.__CurrentChar().isspace():\r
1158 if not self.__UndoOneChar():\r
1159 self.__GetOneChar()\r
1160 return\r
1161\r
1162\r
1163 StartPos = self.CurrentOffsetWithinLine\r
1164 CurrentLine = self.CurrentLineNumber\r
1165 while CurrentLine == self.CurrentLineNumber:\r
1166\r
1167 TempChar = self.__CurrentChar()\r
1168 # Try to find the end char that is not a space and not in seperator tuple.\r
1169 # That is, when we got a space or any char in the tuple, we got the end of token.\r
1170 if not str(TempChar).isspace() and not TempChar in SEPERATOR_TUPLE:\r
1171 if not self.__UndoOneChar():\r
d0acc87a 1172 return\r
30fdf114
LG
1173 # if we happen to meet a seperator as the first char, we must proceed to get it.\r
1174 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.\r
1175 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:\r
1176 return\r
1177 else:\r
1178 break\r
1179\r
1180 self.__GetOneChar()\r
1181\r
30fdf114
LG
1182 def __IsHex(self, HexStr):\r
1183 if not HexStr.upper().startswith("0X"):\r
1184 return False\r
1185 if len(self.__Token) <= 2:\r
1186 return False\r
cfbe3c35
CJ
1187 return True if all(x in string.hexdigits for x in HexStr[2:]) else False\r
1188\r
30fdf114
LG
1189 ## __GetNextHexNumber() method\r
1190 #\r
1191 # Get next HEX data before a seperator\r
1192 # If found, the HEX data is put into self.__Token\r
1193 #\r
1194 # @param self The object pointer\r
1195 # @retval True Successfully find a HEX data, file buffer pointer moved forward\r
1196 # @retval False Not able to find a HEX data, file buffer pointer not changed\r
1197 #\r
1198 def __GetNextHexNumber(self):\r
1199 if not self.__GetNextToken():\r
1200 return False\r
1201 if self.__IsHex(self.__Token):\r
1202 return True\r
1203 else:\r
1204 self.__UndoToken()\r
1205 return False\r
1206\r
1207 ## __GetNextDecimalNumber() method\r
1208 #\r
1209 # Get next decimal data before a seperator\r
1210 # If found, the decimal data is put into self.__Token\r
1211 #\r
1212 # @param self The object pointer\r
1213 # @retval True Successfully find a decimal data, file buffer pointer moved forward\r
1214 # @retval False Not able to find a decimal data, file buffer pointer not changed\r
1215 #\r
1216 def __GetNextDecimalNumber(self):\r
1217 if not self.__GetNextToken():\r
1218 return False\r
1219 if self.__Token.isdigit():\r
1220 return True\r
1221 else:\r
1222 self.__UndoToken()\r
1223 return False\r
1224\r
1225 ## __GetNextPcdName() method\r
1226 #\r
1227 # Get next PCD token space C name and PCD C name pair before a seperator\r
1228 # If found, the decimal data is put into self.__Token\r
1229 #\r
1230 # @param self The object pointer\r
1231 # @retval Tuple PCD C name and PCD token space C name pair\r
1232 #\r
1233 def __GetNextPcdName(self):\r
1234 if not self.__GetNextWord():\r
1235 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)\r
1236 pcdTokenSpaceCName = self.__Token\r
1237\r
1238 if not self.__IsToken( "."):\r
1239 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)\r
1240\r
1241 if not self.__GetNextWord():\r
1242 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)\r
1243 pcdCName = self.__Token\r
1244\r
1245 return (pcdCName, pcdTokenSpaceCName)\r
1246\r
1247 ## __GetStringData() method\r
1248 #\r
1249 # Get string contents quoted in ""\r
1250 # If found, the decimal data is put into self.__Token\r
1251 #\r
1252 # @param self The object pointer\r
1253 # @retval True Successfully find a string data, file buffer pointer moved forward\r
1254 # @retval False Not able to find a string data, file buffer pointer not changed\r
1255 #\r
1256 def __GetStringData(self):\r
1257 if self.__Token.startswith("\"") or self.__Token.startswith("L\""):\r
1258 self.__UndoToken()\r
1259 self.__SkipToToken("\"")\r
1260 currentLineNumber = self.CurrentLineNumber\r
1261\r
1262 if not self.__SkipToToken("\""):\r
1263 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber)\r
1264 if currentLineNumber != self.CurrentLineNumber:\r
1265 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber)\r
1266 self.__Token = self.__SkippedChars.rstrip('\"')\r
1267 return True\r
1268\r
1269 elif self.__Token.startswith("\'") or self.__Token.startswith("L\'"):\r
1270 self.__UndoToken()\r
1271 self.__SkipToToken("\'")\r
1272 currentLineNumber = self.CurrentLineNumber\r
1273\r
1274 if not self.__SkipToToken("\'"):\r
1275 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber)\r
1276 if currentLineNumber != self.CurrentLineNumber:\r
1277 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber)\r
1278 self.__Token = self.__SkippedChars.rstrip('\'')\r
1279 return True\r
1280\r
1281 else:\r
1282 return False\r
1283\r
1284 ## __SkipToToken() method\r
1285 #\r
1286 # Search forward in file buffer for the string\r
1287 # The skipped chars are put into self.__SkippedChars\r
1288 #\r
1289 # @param self The object pointer\r
1290 # @param String The string to search\r
1291 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive\r
1292 # @retval True Successfully find the string, file buffer pointer moved forward\r
1293 # @retval False Not able to find the string, file buffer pointer not changed\r
1294 #\r
1295 def __SkipToToken(self, String, IgnoreCase = False):\r
1296 StartPos = self.GetFileBufferPos()\r
1297\r
1298 self.__SkippedChars = ""\r
1299 while not self.__EndOfFile():\r
1300 index = -1\r
1301 if IgnoreCase:\r
1302 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())\r
1303 else:\r
1304 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)\r
1305 if index == 0:\r
1306 self.CurrentOffsetWithinLine += len(String)\r
1307 self.__SkippedChars += String\r
1308 return True\r
1309 self.__SkippedChars += str(self.__CurrentChar())\r
1310 self.__GetOneChar()\r
1311\r
1312 self.SetFileBufferPos( StartPos)\r
1313 self.__SkippedChars = ""\r
1314 return False\r
1315\r
1316 ## GetFileBufferPos() method\r
1317 #\r
1318 # Return the tuple of current line and offset within the line\r
1319 #\r
1320 # @param self The object pointer\r
1321 # @retval Tuple Line number and offset pair\r
1322 #\r
1323 def GetFileBufferPos(self):\r
1324 return (self.CurrentLineNumber, self.CurrentOffsetWithinLine)\r
1325\r
1326 ## SetFileBufferPos() method\r
1327 #\r
1328 # Restore the file buffer position\r
1329 #\r
1330 # @param self The object pointer\r
1331 # @param Pos The new file buffer position\r
1332 #\r
1333 def SetFileBufferPos(self, Pos):\r
1334 (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos\r
1335\r
d40b2ee6
LG
1336 ## Preprocess() method\r
1337 #\r
1338 # Preprocess comment, conditional directive, include directive, replace macro.\r
1339 # Exception will be raised if syntax error found\r
1340 #\r
1341 # @param self The object pointer\r
1342 #\r
1343 def Preprocess(self):\r
1344 self.__StringToList()\r
1345 self.PreprocessFile()\r
1346 self.PreprocessIncludeFile()\r
1347 self.__StringToList()\r
1348 self.PreprocessFile()\r
1349 self.PreprocessConditionalStatement()\r
1350 self.__StringToList()\r
1351 for Pos in self.__WipeOffArea:\r
1352 self.__ReplaceFragment(Pos[0], Pos[1])\r
1353 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]\r
1354\r
1355 while self.__GetDefines():\r
1356 pass\r
d40b2ee6 1357\r
30fdf114
LG
1358 ## ParseFile() method\r
1359 #\r
1360 # Parse the file profile buffer to extract fd, fv ... information\r
1361 # Exception will be raised if syntax error found\r
1362 #\r
1363 # @param self The object pointer\r
1364 #\r
1365 def ParseFile(self):\r
1366\r
1367 try:\r
d40b2ee6 1368 self.Preprocess()\r
dd170333
MK
1369 #\r
1370 # Keep processing sections of the FDF until no new sections or a syntax error is found\r
1371 #\r
1372 while self.__GetFd() or self.__GetFv() or self.__GetFmp() or self.__GetCapsule() or self.__GetVtf() or self.__GetRule() or self.__GetOptionRom():\r
30fdf114
LG
1373 pass\r
1374\r
1375 except Warning, X:\r
1376 self.__UndoToken()\r
30fdf114 1377 #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \\r
118bf096
CS
1378 # At this point, the closest parent would be the included file itself\r
1379 Profile = GetParentAtLine(X.OriginalLineNumber)\r
4231a819 1380 if Profile is not None:\r
118bf096
CS
1381 X.Message += ' near line %d, column %d: %s' \\r
1382 % (X.LineNumber, 0, Profile.FileLinesList[X.LineNumber-1])\r
1383 else:\r
1384 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1385 X.Message += ' near line %d, column %d: %s' \\r
30fdf114
LG
1386 % (FileLineTuple[1], self.CurrentOffsetWithinLine + 1, self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :].rstrip('\n').rstrip('\r'))\r
1387 raise\r
1388\r
df81077f
YZ
1389 ## SectionParser() method\r
1390 #\r
1391 # Parse the file section info\r
1392 # Exception will be raised if syntax error found\r
1393 #\r
1394 # @param self The object pointer\r
1395 # @param section The section string\r
1396\r
1397 def SectionParser(self, section):\r
1398 S = section.upper()\r
1399 if not S.startswith("[DEFINES") and not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \\r
1400 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM.") and not S.startswith('[FMPPAYLOAD.'):\r
1401 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.], [FMPPAYLOAD.])", self.FileName, self.CurrentLineNumber)\r
1402\r
30fdf114
LG
1403 ## __GetDefines() method\r
1404 #\r
1405 # Get Defines section contents and store its data into AllMacrosList\r
1406 #\r
1407 # @param self The object pointer\r
1408 # @retval True Successfully find a Defines\r
1409 # @retval False Not able to find a Defines\r
1410 #\r
1411 def __GetDefines(self):\r
1412\r
1413 if not self.__GetNextToken():\r
1414 return False\r
1415\r
1416 S = self.__Token.upper()\r
1417 if S.startswith("[") and not S.startswith("[DEFINES"):\r
df81077f 1418 self.SectionParser(S)\r
30fdf114
LG
1419 self.__UndoToken()\r
1420 return False\r
1421\r
1422 self.__UndoToken()\r
1423 if not self.__IsToken("[DEFINES", True):\r
1424 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1425 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
1426 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
1427 raise Warning("expected [DEFINES", self.FileName, self.CurrentLineNumber)\r
1428\r
1429 if not self.__IsToken( "]"):\r
1430 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
1431\r
1432 while self.__GetNextWord():\r
6780eef1
LG
1433 # handle the SET statement\r
1434 if self.__Token == 'SET':\r
1435 self.__UndoToken()\r
1436 self.__GetSetStatement(None)\r
1437 continue\r
1438 \r
30fdf114
LG
1439 Macro = self.__Token\r
1440 \r
1441 if not self.__IsToken("="):\r
1442 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1443 if not self.__GetNextToken() or self.__Token.startswith('['):\r
1444 raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber)\r
1445 Value = self.__Token\r
30fdf114
LG
1446\r
1447 return False\r
1448\r
1449 ## __GetFd() method\r
1450 #\r
1451 # Get FD section contents and store its data into FD dictionary of self.Profile\r
1452 #\r
1453 # @param self The object pointer\r
1454 # @retval True Successfully find a FD\r
1455 # @retval False Not able to find a FD\r
1456 #\r
1457 def __GetFd(self):\r
1458\r
1459 if not self.__GetNextToken():\r
1460 return False\r
1461\r
1462 S = self.__Token.upper()\r
1463 if S.startswith("[") and not S.startswith("[FD."):\r
a3251d84 1464 if not S.startswith("[FV.") and not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \\r
30fdf114
LG
1465 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
1466 raise Warning("Unknown section", self.FileName, self.CurrentLineNumber)\r
1467 self.__UndoToken()\r
1468 return False\r
1469\r
1470 self.__UndoToken()\r
1471 if not self.__IsToken("[FD.", True):\r
1472 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1473 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
1474 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
1475 raise Warning("expected [FD.]", self.FileName, self.CurrentLineNumber)\r
1476\r
1477 FdName = self.__GetUiName()\r
52302d4d
LG
1478 if FdName == "":\r
1479 if len (self.Profile.FdDict) == 0:\r
1480 FdName = GenFdsGlobalVariable.PlatformName\r
d0acc87a
LG
1481 if FdName == "" and GlobalData.gActivePlatform:\r
1482 FdName = GlobalData.gActivePlatform.PlatformName\r
52302d4d
LG
1483 self.Profile.FdNameNotSet = True\r
1484 else:\r
1485 raise Warning("expected FdName in [FD.] section", self.FileName, self.CurrentLineNumber)\r
30fdf114 1486 self.CurrentFdName = FdName.upper()\r
52302d4d
LG
1487 \r
1488 if self.CurrentFdName in self.Profile.FdDict:\r
1489 raise Warning("Unexpected the same FD name", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
1490\r
1491 if not self.__IsToken( "]"):\r
1492 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
1493\r
1494 FdObj = Fd.FD()\r
1495 FdObj.FdUiName = self.CurrentFdName\r
1496 self.Profile.FdDict[self.CurrentFdName] = FdObj\r
52302d4d
LG
1497\r
1498 if len (self.Profile.FdDict) > 1 and self.Profile.FdNameNotSet:\r
1499 raise Warning("expected all FDs have their name", self.FileName, self.CurrentLineNumber)\r
1500\r
30fdf114
LG
1501 Status = self.__GetCreateFile(FdObj)\r
1502 if not Status:\r
1503 raise Warning("FD name error", self.FileName, self.CurrentLineNumber)\r
1504\r
e8a47801
LG
1505 while self.__GetTokenStatements(FdObj):\r
1506 pass\r
1507 for Attr in ("BaseAddress", "Size", "ErasePolarity"):\r
4231a819 1508 if getattr(FdObj, Attr) is None:\r
e8a47801
LG
1509 self.__GetNextToken()\r
1510 raise Warning("Keyword %s missing" % Attr, self.FileName, self.CurrentLineNumber)\r
1511\r
1512 if not FdObj.BlockSizeList:\r
1513 FdObj.BlockSizeList.append((1, FdObj.Size, None))\r
30fdf114
LG
1514\r
1515 self.__GetDefineStatements(FdObj)\r
1516\r
1517 self.__GetSetStatements(FdObj)\r
1518\r
1519 if not self.__GetRegionLayout(FdObj):\r
1520 raise Warning("expected region layout", self.FileName, self.CurrentLineNumber)\r
1521\r
1522 while self.__GetRegionLayout(FdObj):\r
1523 pass\r
1524 return True\r
1525\r
1526 ## __GetUiName() method\r
1527 #\r
1528 # Return the UI name of a section\r
1529 #\r
1530 # @param self The object pointer\r
1531 # @retval FdName UI name\r
1532 #\r
1533 def __GetUiName(self):\r
1534 Name = ""\r
1535 if self.__GetNextWord():\r
1536 Name = self.__Token\r
1537\r
1538 return Name\r
1539\r
1540 ## __GetCreateFile() method\r
1541 #\r
1542 # Return the output file name of object\r
1543 #\r
1544 # @param self The object pointer\r
1545 # @param Obj object whose data will be stored in file\r
1546 # @retval FdName UI name\r
1547 #\r
1548 def __GetCreateFile(self, Obj):\r
1549\r
1550 if self.__IsKeyword( "CREATE_FILE"):\r
1551 if not self.__IsToken( "="):\r
1552 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1553\r
1554 if not self.__GetNextToken():\r
1555 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)\r
1556\r
1557 FileName = self.__Token\r
1558 Obj.CreateFileName = FileName\r
1559\r
1560 return True\r
1561\r
1562 ## __GetTokenStatements() method\r
1563 #\r
1564 # Get token statements\r
1565 #\r
1566 # @param self The object pointer\r
1567 # @param Obj for whom token statement is got\r
30fdf114
LG
1568 #\r
1569 def __GetTokenStatements(self, Obj):\r
e8a47801
LG
1570 if self.__IsKeyword( "BaseAddress"):\r
1571 if not self.__IsToken( "="):\r
1572 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1573 \r
1574 if not self.__GetNextHexNumber():\r
1575 raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber)\r
1576 \r
1577 Obj.BaseAddress = self.__Token\r
1578 \r
1579 if self.__IsToken( "|"):\r
1580 pcdPair = self.__GetNextPcdName()\r
1581 Obj.BaseAddressPcd = pcdPair\r
1582 self.Profile.PcdDict[pcdPair] = Obj.BaseAddress\r
1583 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1584 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple\r
1585 return True\r
30fdf114 1586\r
e8a47801
LG
1587 if self.__IsKeyword( "Size"):\r
1588 if not self.__IsToken( "="):\r
1589 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1590 \r
1591 if not self.__GetNextHexNumber():\r
1592 raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber)\r
30fdf114 1593\r
e8a47801
LG
1594 Size = self.__Token\r
1595 if self.__IsToken( "|"):\r
1596 pcdPair = self.__GetNextPcdName()\r
1597 Obj.SizePcd = pcdPair\r
1598 self.Profile.PcdDict[pcdPair] = Size\r
1599 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1600 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple\r
1601 Obj.Size = long(Size, 0)\r
1602 return True\r
30fdf114 1603\r
e8a47801
LG
1604 if self.__IsKeyword( "ErasePolarity"):\r
1605 if not self.__IsToken( "="):\r
1606 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1607 \r
1608 if not self.__GetNextToken():\r
1609 raise Warning("expected Erase Polarity", self.FileName, self.CurrentLineNumber)\r
1610 \r
1611 if self.__Token != "1" and self.__Token != "0":\r
1612 raise Warning("expected 1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)\r
1613 \r
1614 Obj.ErasePolarity = self.__Token\r
1615 return True\r
30fdf114 1616\r
e8a47801 1617 return self.__GetBlockStatements(Obj)\r
30fdf114
LG
1618\r
1619 ## __GetAddressStatements() method\r
1620 #\r
1621 # Get address statements\r
1622 #\r
1623 # @param self The object pointer\r
1624 # @param Obj for whom address statement is got\r
1625 # @retval True Successfully find\r
1626 # @retval False Not able to find\r
1627 #\r
1628 def __GetAddressStatements(self, Obj):\r
1629\r
1630 if self.__IsKeyword("BsBaseAddress"):\r
1631 if not self.__IsToken( "="):\r
1632 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1633\r
1634 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():\r
1635 raise Warning("expected address", self.FileName, self.CurrentLineNumber)\r
1636\r
1637 BsAddress = long(self.__Token, 0)\r
1638 Obj.BsBaseAddress = BsAddress\r
1639\r
1640 if self.__IsKeyword("RtBaseAddress"):\r
1641 if not self.__IsToken( "="):\r
1642 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1643\r
1644 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():\r
1645 raise Warning("expected address", self.FileName, self.CurrentLineNumber)\r
1646\r
1647 RtAddress = long(self.__Token, 0)\r
1648 Obj.RtBaseAddress = RtAddress\r
1649\r
1650 ## __GetBlockStatements() method\r
1651 #\r
1652 # Get block statements\r
1653 #\r
1654 # @param self The object pointer\r
1655 # @param Obj for whom block statement is got\r
30fdf114
LG
1656 #\r
1657 def __GetBlockStatements(self, Obj):\r
e8a47801 1658 IsBlock = False\r
30fdf114 1659 while self.__GetBlockStatement(Obj):\r
e8a47801 1660 IsBlock = True\r
52302d4d 1661 \r
e8a47801 1662 Item = Obj.BlockSizeList[-1]\r
4231a819 1663 if Item[0] is None or Item[1] is None:\r
6780eef1 1664 raise Warning("expected block statement", self.FileName, self.CurrentLineNumber)\r
e8a47801 1665 return IsBlock\r
30fdf114
LG
1666\r
1667 ## __GetBlockStatement() method\r
1668 #\r
1669 # Get block statement\r
1670 #\r
1671 # @param self The object pointer\r
1672 # @param Obj for whom block statement is got\r
1673 # @retval True Successfully find\r
1674 # @retval False Not able to find\r
1675 #\r
1676 def __GetBlockStatement(self, Obj):\r
1677 if not self.__IsKeyword( "BlockSize"):\r
1678 return False\r
1679\r
1680 if not self.__IsToken( "="):\r
1681 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1682\r
1683 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():\r
6780eef1 1684 raise Warning("expected Hex or Integer block size", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
1685\r
1686 BlockSize = self.__Token\r
1687 BlockSizePcd = None\r
1688 if self.__IsToken( "|"):\r
1689 PcdPair = self.__GetNextPcdName()\r
1690 BlockSizePcd = PcdPair\r
1691 self.Profile.PcdDict[PcdPair] = BlockSize\r
d0acc87a
LG
1692 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1693 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple\r
52302d4d 1694 BlockSize = long(BlockSize, 0)\r
30fdf114
LG
1695\r
1696 BlockNumber = None\r
1697 if self.__IsKeyword( "NumBlocks"):\r
1698 if not self.__IsToken( "="):\r
1699 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1700\r
1701 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():\r
1702 raise Warning("expected block numbers", self.FileName, self.CurrentLineNumber)\r
1703\r
1704 BlockNumber = long(self.__Token, 0)\r
1705\r
1706 Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd))\r
1707 return True\r
1708\r
1709 ## __GetDefineStatements() method\r
1710 #\r
1711 # Get define statements\r
1712 #\r
1713 # @param self The object pointer\r
1714 # @param Obj for whom define statement is got\r
1715 # @retval True Successfully find\r
1716 # @retval False Not able to find\r
1717 #\r
1718 def __GetDefineStatements(self, Obj):\r
1719 while self.__GetDefineStatement( Obj):\r
1720 pass\r
1721\r
1722 ## __GetDefineStatement() method\r
1723 #\r
1724 # Get define statement\r
1725 #\r
1726 # @param self The object pointer\r
1727 # @param Obj for whom define statement is got\r
1728 # @retval True Successfully find\r
1729 # @retval False Not able to find\r
1730 #\r
1731 def __GetDefineStatement(self, Obj):\r
1732 if self.__IsKeyword("DEFINE"):\r
1733 self.__GetNextToken()\r
1734 Macro = self.__Token\r
1735 if not self.__IsToken( "="):\r
1736 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1737\r
1738 if not self.__GetNextToken():\r
1739 raise Warning("expected value", self.FileName, self.CurrentLineNumber)\r
1740\r
1741 Value = self.__Token\r
1742 Macro = '$(' + Macro + ')'\r
1743 Obj.DefineVarDict[Macro] = Value\r
1744 return True\r
1745\r
1746 return False\r
1747\r
1748 ## __GetSetStatements() method\r
1749 #\r
1750 # Get set statements\r
1751 #\r
1752 # @param self The object pointer\r
1753 # @param Obj for whom set statement is got\r
1754 # @retval True Successfully find\r
1755 # @retval False Not able to find\r
1756 #\r
1757 def __GetSetStatements(self, Obj):\r
1758 while self.__GetSetStatement(Obj):\r
1759 pass\r
1760\r
1761 ## __GetSetStatement() method\r
1762 #\r
1763 # Get set statement\r
1764 #\r
1765 # @param self The object pointer\r
1766 # @param Obj for whom set statement is got\r
1767 # @retval True Successfully find\r
1768 # @retval False Not able to find\r
1769 #\r
1770 def __GetSetStatement(self, Obj):\r
1771 if self.__IsKeyword("SET"):\r
1772 PcdPair = self.__GetNextPcdName()\r
1773\r
1774 if not self.__IsToken( "="):\r
1775 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1776\r
d0acc87a
LG
1777 Value = self.__GetExpression()\r
1778 Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)\r
30fdf114 1779\r
6780eef1
LG
1780 if Obj:\r
1781 Obj.SetVarDict[PcdPair] = Value\r
30fdf114 1782 self.Profile.PcdDict[PcdPair] = Value\r
d0acc87a
LG
1783 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1784 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple\r
30fdf114
LG
1785 return True\r
1786\r
1787 return False\r
1788\r
4afd3d04
LG
1789 ## __CalcRegionExpr(self)\r
1790 #\r
1791 # Calculate expression for offset or size of a region\r
1792 #\r
1793 # @return: None if invalid expression\r
1794 # Calculated number if successfully\r
1795 #\r
1796 def __CalcRegionExpr(self):\r
1797 StartPos = self.GetFileBufferPos()\r
1798 Expr = ''\r
1799 PairCount = 0\r
1800 while not self.__EndOfFile():\r
1801 CurCh = self.__CurrentChar()\r
1802 if CurCh == '(':\r
1803 PairCount += 1\r
1804 elif CurCh == ')':\r
1805 PairCount -= 1\r
1806\r
1807 if CurCh in '|\r\n' and PairCount == 0:\r
1808 break\r
1809 Expr += CurCh\r
1810 self.__GetOneChar()\r
1811 try:\r
1812 return long(\r
1813 ValueExpression(Expr,\r
2bc3256c 1814 self.__CollectMacroPcd()\r
4afd3d04
LG
1815 )(True),0)\r
1816 except Exception:\r
1817 self.SetFileBufferPos(StartPos)\r
1818 return None\r
1819\r
30fdf114
LG
1820 ## __GetRegionLayout() method\r
1821 #\r
1822 # Get region layout for FD\r
1823 #\r
1824 # @param self The object pointer\r
1825 # @param Fd for whom region is got\r
1826 # @retval True Successfully find\r
1827 # @retval False Not able to find\r
1828 #\r
1829 def __GetRegionLayout(self, Fd):\r
4afd3d04 1830 Offset = self.__CalcRegionExpr() \r
4231a819 1831 if Offset is None:\r
30fdf114
LG
1832 return False\r
1833\r
1834 RegionObj = Region.Region()\r
4afd3d04 1835 RegionObj.Offset = Offset\r
30fdf114
LG
1836 Fd.RegionList.append(RegionObj)\r
1837\r
1838 if not self.__IsToken( "|"):\r
1839 raise Warning("expected '|'", self.FileName, self.CurrentLineNumber)\r
1840\r
4afd3d04 1841 Size = self.__CalcRegionExpr()\r
4231a819 1842 if Size is None:\r
30fdf114 1843 raise Warning("expected Region Size", self.FileName, self.CurrentLineNumber)\r
4afd3d04 1844 RegionObj.Size = Size\r
30fdf114
LG
1845\r
1846 if not self.__GetNextWord():\r
1847 return True\r
1848\r
b21a13fb 1849 if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE", "INF"):\r
2bc3256c
LG
1850 #\r
1851 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]\r
1852 # Or it might be next region's offset described by an expression which starts with a PCD.\r
1853 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size\r
1854 #\r
30fdf114 1855 self.__UndoToken()\r
2bc3256c
LG
1856 IsRegionPcd = (RegionSizeGuidPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]) or\r
1857 RegionOffsetPcdPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]))\r
1858 if IsRegionPcd:\r
1859 RegionObj.PcdOffset = self.__GetNextPcdName()\r
1860 self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0))\r
1861 self.__PcdDict['%s.%s' % (RegionObj.PcdOffset[1], RegionObj.PcdOffset[0])] = "0x%x" % RegionObj.Offset\r
d0acc87a 1862 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2bc3256c
LG
1863 self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple\r
1864 if self.__IsToken( "|"):\r
1865 RegionObj.PcdSize = self.__GetNextPcdName()\r
1866 self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size\r
1867 self.__PcdDict['%s.%s' % (RegionObj.PcdSize[1], RegionObj.PcdSize[0])] = "0x%x" % RegionObj.Size\r
1868 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1869 self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple\r
30fdf114
LG
1870\r
1871 if not self.__GetNextWord():\r
1872 return True\r
1873\r
1874 if self.__Token == "SET":\r
1875 self.__UndoToken()\r
1876 self.__GetSetStatements( RegionObj)\r
1877 if not self.__GetNextWord():\r
1878 return True\r
1879\r
fd171542 1880 elif self.__Token == "FV":\r
30fdf114
LG
1881 self.__UndoToken()\r
1882 self.__GetRegionFvType( RegionObj)\r
1883\r
fd171542 1884 elif self.__Token == "CAPSULE":\r
1885 self.__UndoToken()\r
1886 self.__GetRegionCapType( RegionObj)\r
1887\r
30fdf114
LG
1888 elif self.__Token == "FILE":\r
1889 self.__UndoToken()\r
b21a13fb
YZ
1890 self.__GetRegionFileType(RegionObj)\r
1891\r
1892 elif self.__Token == "INF":\r
1893 self.__UndoToken()\r
1894 RegionObj.RegionType = "INF"\r
1895 while self.__IsKeyword("INF"):\r
1896 self.__UndoToken()\r
1897 ffsInf = self.__ParseInfStatement()\r
1898 if not ffsInf:\r
1899 break\r
1900 RegionObj.RegionDataList.append(ffsInf)\r
30fdf114 1901\r
79b74a03 1902 elif self.__Token == "DATA":\r
30fdf114 1903 self.__UndoToken()\r
b21a13fb 1904 self.__GetRegionDataType(RegionObj)\r
79b74a03 1905 else:\r
2bc3256c
LG
1906 self.__UndoToken()\r
1907 if self.__GetRegionLayout(Fd):\r
1908 return True\r
79b74a03 1909 raise Warning("A valid region type was not found. "\r
b21a13fb 1910 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",\r
79b74a03 1911 self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
1912\r
1913 return True\r
1914\r
1915 ## __GetRegionFvType() method\r
1916 #\r
1917 # Get region fv data for region\r
1918 #\r
1919 # @param self The object pointer\r
1920 # @param RegionObj for whom region data is got\r
1921 #\r
1922 def __GetRegionFvType(self, RegionObj):\r
1923\r
1924 if not self.__IsKeyword( "FV"):\r
1925 raise Warning("expected Keyword 'FV'", self.FileName, self.CurrentLineNumber)\r
1926\r
1927 if not self.__IsToken( "="):\r
1928 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1929\r
1930 if not self.__GetNextToken():\r
1931 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)\r
1932\r
1933 RegionObj.RegionType = "FV"\r
0199377c 1934 RegionObj.RegionDataList.append((self.__Token).upper())\r
30fdf114
LG
1935\r
1936 while self.__IsKeyword( "FV"):\r
1937\r
1938 if not self.__IsToken( "="):\r
1939 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1940\r
1941 if not self.__GetNextToken():\r
1942 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)\r
1943\r
0199377c 1944 RegionObj.RegionDataList.append((self.__Token).upper())\r
30fdf114 1945\r
fd171542 1946 ## __GetRegionCapType() method\r
1947 #\r
1948 # Get region capsule data for region\r
1949 #\r
1950 # @param self The object pointer\r
1951 # @param RegionObj for whom region data is got\r
1952 #\r
1953 def __GetRegionCapType(self, RegionObj):\r
1954\r
1955 if not self.__IsKeyword("CAPSULE"):\r
1956 raise Warning("expected Keyword 'CAPSULE'", self.FileName, self.CurrentLineNumber)\r
1957\r
1958 if not self.__IsToken("="):\r
1959 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1960\r
1961 if not self.__GetNextToken():\r
1962 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)\r
1963\r
1964 RegionObj.RegionType = "CAPSULE"\r
1965 RegionObj.RegionDataList.append(self.__Token)\r
1966\r
1967 while self.__IsKeyword("CAPSULE"):\r
1968\r
1969 if not self.__IsToken("="):\r
1970 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1971\r
1972 if not self.__GetNextToken():\r
1973 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)\r
1974\r
1975 RegionObj.RegionDataList.append(self.__Token)\r
1976\r
30fdf114
LG
1977 ## __GetRegionFileType() method\r
1978 #\r
1979 # Get region file data for region\r
1980 #\r
1981 # @param self The object pointer\r
1982 # @param RegionObj for whom region data is got\r
1983 #\r
1984 def __GetRegionFileType(self, RegionObj):\r
1985\r
1986 if not self.__IsKeyword( "FILE"):\r
1987 raise Warning("expected Keyword 'FILE'", self.FileName, self.CurrentLineNumber)\r
1988\r
1989 if not self.__IsToken( "="):\r
1990 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1991\r
1992 if not self.__GetNextToken():\r
1993 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)\r
1994\r
1995 RegionObj.RegionType = "FILE"\r
1996 RegionObj.RegionDataList.append( self.__Token)\r
1997\r
1998 while self.__IsKeyword( "FILE"):\r
1999\r
2000 if not self.__IsToken( "="):\r
2001 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2002\r
2003 if not self.__GetNextToken():\r
2004 raise Warning("expected FILE name", self.FileName, self.CurrentLineNumber)\r
2005\r
2006 RegionObj.RegionDataList.append(self.__Token)\r
2007\r
2008 ## __GetRegionDataType() method\r
2009 #\r
2010 # Get region array data for region\r
2011 #\r
2012 # @param self The object pointer\r
2013 # @param RegionObj for whom region data is got\r
2014 #\r
2015 def __GetRegionDataType(self, RegionObj):\r
2016\r
2017 if not self.__IsKeyword( "DATA"):\r
2018 raise Warning("expected Region Data type", self.FileName, self.CurrentLineNumber)\r
2019\r
2020 if not self.__IsToken( "="):\r
2021 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2022\r
2023 if not self.__IsToken( "{"):\r
2024 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2025\r
2026 if not self.__GetNextHexNumber():\r
2027 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)\r
2028\r
636f2be6
LG
2029 if len(self.__Token) > 18:\r
2030 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)\r
2031\r
2032 # convert hex string value to byte hex string array\r
2033 AllString = self.__Token\r
2034 AllStrLen = len (AllString)\r
2035 DataString = ""\r
2036 while AllStrLen > 4:\r
2037 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","\r
2038 AllStrLen = AllStrLen - 2\r
2039 DataString = DataString + AllString[:AllStrLen] + ","\r
2040\r
2041 # byte value array\r
2042 if len (self.__Token) <= 4:\r
2043 while self.__IsToken(","):\r
2044 if not self.__GetNextHexNumber():\r
2045 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
2046 if len(self.__Token) > 4:\r
2047 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
2048 DataString += self.__Token\r
2049 DataString += ","\r
30fdf114
LG
2050\r
2051 if not self.__IsToken( "}"):\r
2052 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2053\r
2054 DataString = DataString.rstrip(",")\r
2055 RegionObj.RegionType = "DATA"\r
2056 RegionObj.RegionDataList.append( DataString)\r
2057\r
2058 while self.__IsKeyword( "DATA"):\r
2059\r
2060 if not self.__IsToken( "="):\r
2061 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2062\r
2063 if not self.__IsToken( "{"):\r
2064 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2065\r
2066 if not self.__GetNextHexNumber():\r
2067 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)\r
2068\r
636f2be6
LG
2069 if len(self.__Token) > 18:\r
2070 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)\r
2071\r
2072 # convert hex string value to byte hex string array\r
2073 AllString = self.__Token\r
2074 AllStrLen = len (AllString)\r
2075 DataString = ""\r
2076 while AllStrLen > 4:\r
2077 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","\r
2078 AllStrLen = AllStrLen - 2\r
2079 DataString = DataString + AllString[:AllStrLen] + ","\r
2080\r
2081 # byte value array\r
2082 if len (self.__Token) <= 4:\r
2083 while self.__IsToken(","):\r
2084 if not self.__GetNextHexNumber():\r
2085 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
2086 if len(self.__Token) > 4:\r
2087 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
2088 DataString += self.__Token\r
2089 DataString += ","\r
30fdf114
LG
2090\r
2091 if not self.__IsToken( "}"):\r
2092 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2093\r
2094 DataString = DataString.rstrip(",")\r
2095 RegionObj.RegionDataList.append( DataString)\r
2096\r
2097 ## __GetFv() method\r
2098 #\r
2099 # Get FV section contents and store its data into FV dictionary of self.Profile\r
2100 #\r
2101 # @param self The object pointer\r
2102 # @retval True Successfully find a FV\r
2103 # @retval False Not able to find a FV\r
2104 #\r
2105 def __GetFv(self):\r
2106 if not self.__GetNextToken():\r
2107 return False\r
2108\r
2109 S = self.__Token.upper()\r
2110 if S.startswith("[") and not S.startswith("[FV."):\r
df81077f 2111 self.SectionParser(S)\r
30fdf114
LG
2112 self.__UndoToken()\r
2113 return False\r
2114\r
2115 self.__UndoToken()\r
2116 if not self.__IsToken("[FV.", True):\r
2117 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2118 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
2119 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
2120 raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
2121\r
2122 FvName = self.__GetUiName()\r
2123 self.CurrentFvName = FvName.upper()\r
2124\r
2125 if not self.__IsToken( "]"):\r
2126 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
2127\r
2128 FvObj = Fv.FV()\r
2129 FvObj.UiFvName = self.CurrentFvName\r
2130 self.Profile.FvDict[self.CurrentFvName] = FvObj\r
2131\r
2132 Status = self.__GetCreateFile(FvObj)\r
2133 if not Status:\r
2134 raise Warning("FV name error", self.FileName, self.CurrentLineNumber)\r
2135\r
2136 self.__GetDefineStatements(FvObj)\r
2137\r
2138 self.__GetAddressStatements(FvObj)\r
2139\r
b303ea72
LG
2140 FvObj.FvExtEntryTypeValue = []\r
2141 FvObj.FvExtEntryType = []\r
2142 FvObj.FvExtEntryData = []\r
2143 while True:\r
e8a47801
LG
2144 self.__GetSetStatements(FvObj)\r
2145\r
2146 if not (self.__GetBlockStatement(FvObj) or self.__GetFvBaseAddress(FvObj) or \r
2147 self.__GetFvForceRebase(FvObj) or self.__GetFvAlignment(FvObj) or \r
2148 self.__GetFvAttributes(FvObj) or self.__GetFvNameGuid(FvObj) or \r
aaf8aa7b 2149 self.__GetFvExtEntryStatement(FvObj) or self.__GetFvNameString(FvObj)):\r
b303ea72
LG
2150 break\r
2151\r
aaf8aa7b
YL
2152 if FvObj.FvNameString == 'TRUE' and not FvObj.FvNameGuid:\r
2153 raise Warning("FvNameString found but FvNameGuid was not found", self.FileName, self.CurrentLineNumber)\r
2154\r
30fdf114
LG
2155 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())\r
2156 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())\r
2157\r
2158 while True:\r
2159 isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())\r
2160 isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())\r
2161 if not isInf and not isFile:\r
2162 break\r
2163\r
2164 return True\r
2165\r
2166 ## __GetFvAlignment() method\r
2167 #\r
2168 # Get alignment for FV\r
2169 #\r
2170 # @param self The object pointer\r
2171 # @param Obj for whom alignment is got\r
2172 # @retval True Successfully find a alignment statement\r
2173 # @retval False Not able to find a alignment statement\r
2174 #\r
2175 def __GetFvAlignment(self, Obj):\r
2176\r
2177 if not self.__IsKeyword( "FvAlignment"):\r
2178 return False\r
2179\r
2180 if not self.__IsToken( "="):\r
2181 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2182\r
2183 if not self.__GetNextToken():\r
2184 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)\r
2185\r
2186 if self.__Token.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \\r
2187 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \\r
2188 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \\r
2189 "1G", "2G"):\r
2190 raise Warning("Unknown alignment value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
2191 Obj.FvAlignment = self.__Token\r
2192 return True\r
4234283c
LG
2193 \r
2194 ## __GetFvBaseAddress() method\r
2195 #\r
2196 # Get BaseAddress for FV\r
2197 #\r
2198 # @param self The object pointer\r
2199 # @param Obj for whom FvBaseAddress is got\r
2200 # @retval True Successfully find a FvBaseAddress statement\r
2201 # @retval False Not able to find a FvBaseAddress statement\r
2202 #\r
2203 def __GetFvBaseAddress(self, Obj):\r
2204\r
2205 if not self.__IsKeyword("FvBaseAddress"):\r
2206 return False\r
2207\r
2208 if not self.__IsToken( "="):\r
2209 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2210\r
2211 if not self.__GetNextToken():\r
2212 raise Warning("expected FV base address value", self.FileName, self.CurrentLineNumber)\r
2213\r
2214 IsValidBaseAddrValue = re.compile('^0[x|X][0-9a-fA-F]+')\r
2215\r
2216 if not IsValidBaseAddrValue.match(self.__Token.upper()):\r
79b74a03 2217 raise Warning("Unknown FV base address value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4234283c 2218 Obj.FvBaseAddress = self.__Token\r
0d2711a6
LG
2219 return True \r
2220 \r
79b74a03
LG
2221 ## __GetFvForceRebase() method\r
2222 #\r
2223 # Get FvForceRebase for FV\r
2224 #\r
2225 # @param self The object pointer\r
2226 # @param Obj for whom FvForceRebase is got\r
2227 # @retval True Successfully find a FvForceRebase statement\r
2228 # @retval False Not able to find a FvForceRebase statement\r
2229 #\r
2230 def __GetFvForceRebase(self, Obj):\r
2231\r
2232 if not self.__IsKeyword("FvForceRebase"):\r
2233 return False\r
2234\r
2235 if not self.__IsToken( "="):\r
2236 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2237\r
2238 if not self.__GetNextToken():\r
2239 raise Warning("expected FvForceRebase value", self.FileName, self.CurrentLineNumber)\r
30fdf114 2240\r
79b74a03
LG
2241 if self.__Token.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]:\r
2242 raise Warning("Unknown FvForceRebase value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
2243 \r
2244 if self.__Token.upper() in ["TRUE", "1", "0X1", "0X01"]:\r
2245 Obj.FvForceRebase = True\r
2246 elif self.__Token.upper() in ["FALSE", "0", "0X0", "0X00"]:\r
2247 Obj.FvForceRebase = False\r
2248 else:\r
2249 Obj.FvForceRebase = None\r
2250 \r
2251 return True\r
0d2711a6
LG
2252\r
2253\r
30fdf114
LG
2254 ## __GetFvAttributes() method\r
2255 #\r
2256 # Get attributes for FV\r
2257 #\r
2258 # @param self The object pointer\r
2259 # @param Obj for whom attribute is got\r
2260 # @retval None\r
2261 #\r
2262 def __GetFvAttributes(self, FvObj):\r
2bc3256c 2263 IsWordToken = False\r
30fdf114 2264 while self.__GetNextWord():\r
2bc3256c 2265 IsWordToken = True\r
30fdf114
LG
2266 name = self.__Token\r
2267 if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \\r
2268 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \\r
2269 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \\r
2270 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \\r
2271 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \\r
9425b349 2272 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"):\r
30fdf114 2273 self.__UndoToken()\r
e8a47801 2274 return False\r
30fdf114
LG
2275\r
2276 if not self.__IsToken( "="):\r
2277 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2278\r
2279 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):\r
2280 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)\r
2281\r
2282 FvObj.FvAttributeDict[name] = self.__Token\r
2283\r
2bc3256c 2284 return IsWordToken\r
30fdf114
LG
2285 \r
2286 ## __GetFvNameGuid() method\r
2287 #\r
2288 # Get FV GUID for FV\r
2289 #\r
2290 # @param self The object pointer\r
2291 # @param Obj for whom GUID is got\r
2292 # @retval None\r
2293 #\r
2294 def __GetFvNameGuid(self, FvObj):\r
2295\r
2296 if not self.__IsKeyword( "FvNameGuid"):\r
e8a47801 2297 return False\r
30fdf114
LG
2298\r
2299 if not self.__IsToken( "="):\r
2300 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2301\r
2302 if not self.__GetNextGuid():\r
2303 raise Warning("expected FV GUID value", self.FileName, self.CurrentLineNumber)\r
2304\r
2305 FvObj.FvNameGuid = self.__Token\r
2306\r
e8a47801 2307 return True\r
30fdf114 2308\r
aaf8aa7b
YL
2309 def __GetFvNameString(self, FvObj):\r
2310\r
2311 if not self.__IsKeyword( "FvNameString"):\r
2312 return False\r
2313\r
2314 if not self.__IsToken( "="):\r
2315 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2316\r
2317 if not self.__GetNextToken() or self.__Token not in ('TRUE', 'FALSE'):\r
2318 raise Warning("expected TRUE or FALSE for FvNameString", self.FileName, self.CurrentLineNumber)\r
2319\r
2320 FvObj.FvNameString = self.__Token\r
2321\r
2322 return True\r
2323\r
b303ea72
LG
2324 def __GetFvExtEntryStatement(self, FvObj):\r
2325\r
92d07e48 2326 if not (self.__IsKeyword( "FV_EXT_ENTRY") or self.__IsKeyword( "FV_EXT_ENTRY_TYPE")):\r
b303ea72
LG
2327 return False\r
2328\r
2329 if not self.__IsKeyword ("TYPE"):\r
2330 raise Warning("expected 'TYPE'", self.FileName, self.CurrentLineNumber)\r
2331 \r
2332 if not self.__IsToken( "="):\r
2333 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2334\r
2335 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():\r
2336 raise Warning("expected Hex FV extension entry type value At Line ", self.FileName, self.CurrentLineNumber)\r
2337\r
2338 FvObj.FvExtEntryTypeValue += [self.__Token]\r
2339\r
2340 if not self.__IsToken( "{"):\r
2341 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2342\r
2343 if not self.__IsKeyword ("FILE") and not self.__IsKeyword ("DATA"):\r
2344 raise Warning("expected 'FILE' or 'DATA'", self.FileName, self.CurrentLineNumber)\r
2345\r
2346 FvObj.FvExtEntryType += [self.__Token]\r
2347\r
2348 if self.__Token == 'DATA':\r
2349\r
2350 if not self.__IsToken( "="):\r
2351 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2352 \r
2353 if not self.__IsToken( "{"):\r
2354 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2355\r
2356 if not self.__GetNextHexNumber():\r
2357 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)\r
2358\r
2359 if len(self.__Token) > 4:\r
2360 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
2361\r
2362 DataString = self.__Token\r
2363 DataString += ","\r
2364\r
2365 while self.__IsToken(","):\r
2366 if not self.__GetNextHexNumber():\r
2367 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
2368 if len(self.__Token) > 4:\r
2369 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
2370 DataString += self.__Token\r
2371 DataString += ","\r
2372\r
2373 if not self.__IsToken( "}"):\r
2374 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2375\r
2376 if not self.__IsToken( "}"):\r
2377 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2378\r
2379 DataString = DataString.rstrip(",")\r
2380 FvObj.FvExtEntryData += [DataString]\r
2381\r
2382 if self.__Token == 'FILE':\r
2383 \r
2384 if not self.__IsToken( "="):\r
2385 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2386 \r
2387 if not self.__GetNextToken():\r
2388 raise Warning("expected FV Extension Entry file path At Line ", self.FileName, self.CurrentLineNumber)\r
2389 \r
2390 FvObj.FvExtEntryData += [self.__Token]\r
2391\r
2392 if not self.__IsToken( "}"):\r
2393 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2394\r
2395 return True\r
2396\r
30fdf114
LG
2397 ## __GetAprioriSection() method\r
2398 #\r
2399 # Get token statements\r
2400 #\r
2401 # @param self The object pointer\r
2402 # @param FvObj for whom apriori is got\r
2403 # @param MacroDict dictionary used to replace macro\r
2404 # @retval True Successfully find apriori statement\r
2405 # @retval False Not able to find apriori statement\r
2406 #\r
2407 def __GetAprioriSection(self, FvObj, MacroDict = {}):\r
2408\r
2409 if not self.__IsKeyword( "APRIORI"):\r
2410 return False\r
2411\r
2412 if not self.__IsKeyword("PEI") and not self.__IsKeyword("DXE"):\r
2413 raise Warning("expected Apriori file type", self.FileName, self.CurrentLineNumber)\r
2414 AprType = self.__Token\r
2415\r
2416 if not self.__IsToken( "{"):\r
2417 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2418\r
2419 AprSectionObj = AprioriSection.AprioriSection()\r
2420 AprSectionObj.AprioriType = AprType\r
2421\r
2422 self.__GetDefineStatements(AprSectionObj)\r
2423 MacroDict.update(AprSectionObj.DefineVarDict)\r
2424\r
2425 while True:\r
2426 IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict)\r
2427 IsFile = self.__GetFileStatement( AprSectionObj)\r
2428 if not IsInf and not IsFile:\r
2429 break\r
2430\r
2431 if not self.__IsToken( "}"):\r
2432 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2433\r
2434 FvObj.AprioriSectionList.append(AprSectionObj)\r
2435 return True\r
2436\r
b21a13fb
YZ
2437 def __ParseInfStatement(self):\r
2438 if not self.__IsKeyword("INF"):\r
2439 return None\r
30fdf114
LG
2440\r
2441 ffsInf = FfsInfStatement.FfsInfStatement()\r
b21a13fb 2442 self.__GetInfOptions(ffsInf)\r
30fdf114
LG
2443\r
2444 if not self.__GetNextToken():\r
2445 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)\r
2446 ffsInf.InfFileName = self.__Token\r
a87e79d9
YZ
2447 if not ffsInf.InfFileName.endswith('.inf'):\r
2448 raise Warning("expected .inf file path", self.FileName, self.CurrentLineNumber)\r
64b2609f
LG
2449\r
2450 ffsInf.CurrentLineNum = self.CurrentLineNumber\r
2451 ffsInf.CurrentLineContent = self.__CurrentLine()\r
2452\r
97fa0ee9
YL
2453 #Replace $(SAPCE) with real space\r
2454 ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ')\r
2455\r
14c48571 2456 if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:\r
2457 #do case sensitive check for file path\r
2458 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
2459 if ErrorCode != 0:\r
2460 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 2461\r
30fdf114
LG
2462 if not ffsInf.InfFileName in self.Profile.InfList:\r
2463 self.Profile.InfList.append(ffsInf.InfFileName)\r
d0acc87a
LG
2464 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2465 self.Profile.InfFileLineList.append(FileLineTuple)\r
2502b735
YZ
2466 if ffsInf.UseArch:\r
2467 if ffsInf.UseArch not in self.Profile.InfDict:\r
2468 self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]\r
2469 else:\r
2470 self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)\r
2471 else:\r
2472 self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)\r
30fdf114
LG
2473\r
2474 if self.__IsToken('|'):\r
2475 if self.__IsKeyword('RELOCS_STRIPPED'):\r
2476 ffsInf.KeepReloc = False\r
2477 elif self.__IsKeyword('RELOCS_RETAINED'):\r
2478 ffsInf.KeepReloc = True\r
2479 else:\r
2480 raise Warning("Unknown reloc strip flag '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
b21a13fb
YZ
2481 return ffsInf\r
2482\r
2483 ## __GetInfStatement() method\r
2484 #\r
2485 # Get INF statements\r
2486 #\r
2487 # @param self The object pointer\r
2488 # @param Obj for whom inf statement is got\r
2489 # @param MacroDict dictionary used to replace macro\r
2490 # @retval True Successfully find inf statement\r
2491 # @retval False Not able to find inf statement\r
2492 #\r
2493 def __GetInfStatement(self, Obj, ForCapsule=False, MacroDict={}):\r
2494 ffsInf = self.__ParseInfStatement()\r
2495 if not ffsInf:\r
2496 return False\r
2497\r
30fdf114
LG
2498 if ForCapsule:\r
2499 capsuleFfs = CapsuleData.CapsuleFfs()\r
2500 capsuleFfs.Ffs = ffsInf\r
2501 Obj.CapsuleDataList.append(capsuleFfs)\r
2502 else:\r
2503 Obj.FfsList.append(ffsInf)\r
2504 return True\r
2505\r
2506 ## __GetInfOptions() method\r
2507 #\r
2508 # Get options for INF\r
2509 #\r
2510 # @param self The object pointer\r
2511 # @param FfsInfObj for whom option is got\r
2512 #\r
2513 def __GetInfOptions(self, FfsInfObj):\r
97fa0ee9
YL
2514 if self.__IsKeyword("FILE_GUID"):\r
2515 if not self.__IsToken("="):\r
2516 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2517 if not self.__GetNextGuid():\r
2518 raise Warning("expected GUID value", self.FileName, self.CurrentLineNumber)\r
2519 FfsInfObj.OverrideGuid = self.__Token\r
30fdf114
LG
2520\r
2521 if self.__IsKeyword( "RuleOverride"):\r
2522 if not self.__IsToken( "="):\r
2523 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2524 if not self.__GetNextToken():\r
2525 raise Warning("expected Rule name", self.FileName, self.CurrentLineNumber)\r
2526 FfsInfObj.Rule = self.__Token\r
2527\r
2528 if self.__IsKeyword( "VERSION"):\r
2529 if not self.__IsToken( "="):\r
2530 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2531 if not self.__GetNextToken():\r
2532 raise Warning("expected Version", self.FileName, self.CurrentLineNumber)\r
2533\r
2534 if self.__GetStringData():\r
2535 FfsInfObj.Version = self.__Token\r
2536\r
2537 if self.__IsKeyword( "UI"):\r
2538 if not self.__IsToken( "="):\r
2539 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2540 if not self.__GetNextToken():\r
2541 raise Warning("expected UI name", self.FileName, self.CurrentLineNumber)\r
2542\r
2543 if self.__GetStringData():\r
2544 FfsInfObj.Ui = self.__Token\r
2545\r
2546 if self.__IsKeyword( "USE"):\r
2547 if not self.__IsToken( "="):\r
2548 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2549 if not self.__GetNextToken():\r
2550 raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber)\r
2551 FfsInfObj.UseArch = self.__Token\r
2552\r
2553 \r
2554 if self.__GetNextToken():\r
97fa0ee9
YL
2555 p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')\r
2556 if p.match(self.__Token) and p.match(self.__Token).span()[1] == len(self.__Token):\r
30fdf114
LG
2557 FfsInfObj.KeyStringList.append(self.__Token)\r
2558 if not self.__IsToken(","):\r
2559 return\r
2560 else:\r
2561 self.__UndoToken()\r
2562 return\r
2563\r
2564 while self.__GetNextToken():\r
2565 if not p.match(self.__Token):\r
2566 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
2567 FfsInfObj.KeyStringList.append(self.__Token)\r
2568\r
2569 if not self.__IsToken(","):\r
2570 break\r
2571\r
2572 ## __GetFileStatement() method\r
2573 #\r
2574 # Get FILE statements\r
2575 #\r
2576 # @param self The object pointer\r
2577 # @param Obj for whom FILE statement is got\r
2578 # @param MacroDict dictionary used to replace macro\r
2579 # @retval True Successfully find FILE statement\r
2580 # @retval False Not able to find FILE statement\r
2581 #\r
2582 def __GetFileStatement(self, Obj, ForCapsule = False, MacroDict = {}):\r
2583\r
2584 if not self.__IsKeyword( "FILE"):\r
2585 return False\r
2586\r
30fdf114
LG
2587 if not self.__GetNextWord():\r
2588 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)\r
b36d134f
LG
2589\r
2590 if ForCapsule and self.__Token == 'DATA':\r
2591 self.__UndoToken()\r
2592 self.__UndoToken()\r
2593 return False\r
2594 \r
2595 FfsFileObj = FfsFileStatement.FileStatement()\r
30fdf114
LG
2596 FfsFileObj.FvFileType = self.__Token\r
2597\r
2598 if not self.__IsToken( "="):\r
2599 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2600\r
2601 if not self.__GetNextGuid():\r
2602 if not self.__GetNextWord():\r
2603 raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber)\r
2604 if self.__Token == 'PCD':\r
2605 if not self.__IsToken( "("):\r
2606 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)\r
2607 PcdPair = self.__GetNextPcdName()\r
2608 if not self.__IsToken( ")"):\r
2609 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)\r
2610 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'\r
2611 \r
2612 FfsFileObj.NameGuid = self.__Token\r
79b74a03 2613 \r
30fdf114
LG
2614 self.__GetFilePart( FfsFileObj, MacroDict.copy())\r
2615\r
2616 if ForCapsule:\r
2617 capsuleFfs = CapsuleData.CapsuleFfs()\r
2618 capsuleFfs.Ffs = FfsFileObj\r
2619 Obj.CapsuleDataList.append(capsuleFfs)\r
2620 else:\r
2621 Obj.FfsList.append(FfsFileObj)\r
2622\r
2623 return True\r
2624\r
2625 ## __FileCouldHaveRelocFlag() method\r
2626 #\r
2627 # Check whether reloc strip flag can be set for a file type.\r
2628 #\r
30fdf114
LG
2629 # @param FileType The file type to check with\r
2630 # @retval True This type could have relocation strip flag\r
2631 # @retval False No way to have it\r
2632 #\r
5bcf1d56
CJ
2633 @staticmethod\r
2634 def __FileCouldHaveRelocFlag (FileType):\r
30fdf114
LG
2635 if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):\r
2636 return True\r
2637 else:\r
2638 return False\r
2639\r
2640 ## __SectionCouldHaveRelocFlag() method\r
2641 #\r
2642 # Check whether reloc strip flag can be set for a section type.\r
2643 #\r
30fdf114
LG
2644 # @param SectionType The section type to check with\r
2645 # @retval True This type could have relocation strip flag\r
2646 # @retval False No way to have it\r
2647 #\r
5bcf1d56
CJ
2648 @staticmethod\r
2649 def __SectionCouldHaveRelocFlag (SectionType):\r
30fdf114
LG
2650 if SectionType in ('TE', 'PE32'):\r
2651 return True\r
2652 else:\r
2653 return False\r
2654\r
2655 ## __GetFilePart() method\r
2656 #\r
2657 # Get components for FILE statement\r
2658 #\r
2659 # @param self The object pointer\r
2660 # @param FfsFileObj for whom component is got\r
2661 # @param MacroDict dictionary used to replace macro\r
2662 #\r
2663 def __GetFilePart(self, FfsFileObj, MacroDict = {}):\r
2664\r
2665 self.__GetFileOpts( FfsFileObj)\r
2666\r
2667 if not self.__IsToken("{"):\r
4afd3d04
LG
2668 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):\r
2669 if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType):\r
2670 if self.__Token == 'RELOCS_STRIPPED':\r
2671 FfsFileObj.KeepReloc = False\r
2672 else:\r
2673 FfsFileObj.KeepReloc = True\r
2674 else:\r
2675 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
2676\r
2677 if not self.__IsToken("{"):\r
30fdf114
LG
2678 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2679\r
2680 if not self.__GetNextToken():\r
2681 raise Warning("expected File name or section data", self.FileName, self.CurrentLineNumber)\r
2682\r
2683 if self.__Token == "FV":\r
2684 if not self.__IsToken( "="):\r
2685 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2686 if not self.__GetNextToken():\r
2687 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)\r
2688 FfsFileObj.FvName = self.__Token\r
2689\r
2690 elif self.__Token == "FD":\r
2691 if not self.__IsToken( "="):\r
2692 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2693 if not self.__GetNextToken():\r
2694 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)\r
2695 FfsFileObj.FdName = self.__Token\r
2696\r
2697 elif self.__Token in ("DEFINE", "APRIORI", "SECTION"):\r
2698 self.__UndoToken()\r
2699 self.__GetSectionData( FfsFileObj, MacroDict)\r
860992ed
YZ
2700\r
2701 elif hasattr(FfsFileObj, 'FvFileType') and FfsFileObj.FvFileType == 'RAW':\r
2702 self.__UndoToken()\r
2703 self.__GetRAWData(FfsFileObj, MacroDict)\r
2704\r
30fdf114 2705 else:\r
64b2609f
LG
2706 FfsFileObj.CurrentLineNum = self.CurrentLineNumber\r
2707 FfsFileObj.CurrentLineContent = self.__CurrentLine()\r
97fa0ee9 2708 FfsFileObj.FileName = self.__Token.replace('$(SPACE)', ' ')\r
2bc3256c 2709 self.__VerifyFile(FfsFileObj.FileName)\r
0d2711a6 2710\r
30fdf114
LG
2711 if not self.__IsToken( "}"):\r
2712 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2713\r
860992ed
YZ
2714 ## __GetRAWData() method\r
2715 #\r
2716 # Get RAW data for FILE statement\r
2717 #\r
2718 # @param self The object pointer\r
2719 # @param FfsFileObj for whom section is got\r
2720 # @param MacroDict dictionary used to replace macro\r
2721 #\r
2722 def __GetRAWData(self, FfsFileObj, MacroDict = {}):\r
2723 FfsFileObj.FileName = []\r
cfaaf99b 2724 FfsFileObj.SubAlignment = []\r
860992ed
YZ
2725 while True:\r
2726 AlignValue = None\r
2727 if self.__GetAlignment():\r
e921f58d
YZ
2728 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",\r
2729 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):\r
860992ed 2730 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
f475f1e2
YZ
2731 #For FFS, Auto is default option same to ""\r
2732 if not self.__Token == "Auto":\r
2733 AlignValue = self.__Token\r
860992ed
YZ
2734 if not self.__GetNextToken():\r
2735 raise Warning("expected Filename value", self.FileName, self.CurrentLineNumber)\r
2736\r
2737 FileName = self.__Token.replace('$(SPACE)', ' ')\r
2738 if FileName == '}':\r
2739 self.__UndoToken()\r
2740 raise Warning("expected Filename value", self.FileName, self.CurrentLineNumber)\r
860992ed
YZ
2741\r
2742 self.__VerifyFile(FileName)\r
2743 File = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir)\r
2744 FfsFileObj.FileName.append(File.Path)\r
cfaaf99b 2745 FfsFileObj.SubAlignment.append(AlignValue)\r
860992ed
YZ
2746\r
2747 if self.__IsToken( "}"):\r
2748 self.__UndoToken()\r
2749 break\r
2750\r
cfaaf99b
YZ
2751 if len(FfsFileObj.SubAlignment) == 1:\r
2752 FfsFileObj.SubAlignment = FfsFileObj.SubAlignment[0]\r
860992ed
YZ
2753 if len(FfsFileObj.FileName) == 1:\r
2754 FfsFileObj.FileName = FfsFileObj.FileName[0]\r
2755\r
30fdf114
LG
2756 ## __GetFileOpts() method\r
2757 #\r
2758 # Get options for FILE statement\r
2759 #\r
2760 # @param self The object pointer\r
2761 # @param FfsFileObj for whom options is got\r
2762 #\r
2763 def __GetFileOpts(self, FfsFileObj):\r
2764\r
2765 if self.__GetNextToken():\r
147a656b 2766 if TokenFindPattern.match(self.__Token):\r
30fdf114
LG
2767 FfsFileObj.KeyStringList.append(self.__Token)\r
2768 if self.__IsToken(","):\r
2769 while self.__GetNextToken():\r
147a656b 2770 if not TokenFindPattern.match(self.__Token):\r
30fdf114
LG
2771 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
2772 FfsFileObj.KeyStringList.append(self.__Token)\r
2773\r
2774 if not self.__IsToken(","):\r
2775 break\r
2776\r
2777 else:\r
2778 self.__UndoToken()\r
2779\r
2780 if self.__IsKeyword( "FIXED", True):\r
2781 FfsFileObj.Fixed = True\r
2782\r
2783 if self.__IsKeyword( "CHECKSUM", True):\r
2784 FfsFileObj.CheckSum = True\r
2785\r
2786 if self.__GetAlignment():\r
e921f58d
YZ
2787 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",\r
2788 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):\r
9053bc51 2789 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
2790 #For FFS, Auto is default option same to ""\r
2791 if not self.__Token == "Auto":\r
2792 FfsFileObj.Alignment = self.__Token\r
30fdf114
LG
2793\r
2794 ## __GetAlignment() method\r
2795 #\r
2796 # Return the alignment value\r
2797 #\r
2798 # @param self The object pointer\r
2799 # @retval True Successfully find alignment\r
2800 # @retval False Not able to find alignment\r
2801 #\r
2802 def __GetAlignment(self):\r
2803 if self.__IsKeyword( "Align", True):\r
2804 if not self.__IsToken( "="):\r
2805 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2806\r
2807 if not self.__GetNextToken():\r
2808 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)\r
2809 return True\r
2810\r
2811 return False\r
2812\r
2813 ## __GetFilePart() method\r
2814 #\r
2815 # Get section data for FILE statement\r
2816 #\r
2817 # @param self The object pointer\r
2818 # @param FfsFileObj for whom section is got\r
2819 # @param MacroDict dictionary used to replace macro\r
2820 #\r
2821 def __GetSectionData(self, FfsFileObj, MacroDict = {}):\r
2822 Dict = {}\r
2823 Dict.update(MacroDict)\r
2824\r
2825 self.__GetDefineStatements(FfsFileObj)\r
2826\r
2827 Dict.update(FfsFileObj.DefineVarDict)\r
2828 self.__GetAprioriSection(FfsFileObj, Dict.copy())\r
2829 self.__GetAprioriSection(FfsFileObj, Dict.copy())\r
2830\r
2831 while True:\r
2832 IsLeafSection = self.__GetLeafSection(FfsFileObj, Dict)\r
2833 IsEncapSection = self.__GetEncapsulationSec(FfsFileObj)\r
2834 if not IsLeafSection and not IsEncapSection:\r
2835 break\r
2836\r
2837 ## __GetLeafSection() method\r
2838 #\r
2839 # Get leaf section for Obj\r
2840 #\r
2841 # @param self The object pointer\r
2842 # @param Obj for whom leaf section is got\r
2843 # @param MacroDict dictionary used to replace macro\r
2844 # @retval True Successfully find section statement\r
2845 # @retval False Not able to find section statement\r
2846 #\r
2847 def __GetLeafSection(self, Obj, MacroDict = {}):\r
2848\r
2849 OldPos = self.GetFileBufferPos()\r
2850\r
2851 if not self.__IsKeyword( "SECTION"):\r
2852 if len(Obj.SectionList) == 0:\r
2853 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)\r
2854 else:\r
2855 return False\r
2856\r
2857 AlignValue = None\r
2858 if self.__GetAlignment():\r
e921f58d
YZ
2859 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",\r
2860 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):\r
52302d4d 2861 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2862 AlignValue = self.__Token\r
2863\r
2864 BuildNum = None\r
2865 if self.__IsKeyword( "BUILD_NUM"):\r
2866 if not self.__IsToken( "="):\r
2867 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2868\r
2869 if not self.__GetNextToken():\r
2870 raise Warning("expected Build number value", self.FileName, self.CurrentLineNumber)\r
2871\r
2872 BuildNum = self.__Token\r
2873\r
2874 if self.__IsKeyword( "VERSION"):\r
52302d4d
LG
2875 if AlignValue == 'Auto':\r
2876 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2877 if not self.__IsToken( "="):\r
2878 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2879 if not self.__GetNextToken():\r
2880 raise Warning("expected version", self.FileName, self.CurrentLineNumber)\r
2881 VerSectionObj = VerSection.VerSection()\r
2882 VerSectionObj.Alignment = AlignValue\r
2883 VerSectionObj.BuildNum = BuildNum\r
2884 if self.__GetStringData():\r
2885 VerSectionObj.StringData = self.__Token\r
2886 else:\r
2887 VerSectionObj.FileName = self.__Token\r
2888 Obj.SectionList.append(VerSectionObj)\r
52302d4d 2889 \r
30fdf114 2890 elif self.__IsKeyword( "UI"):\r
52302d4d
LG
2891 if AlignValue == 'Auto':\r
2892 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2893 if not self.__IsToken( "="):\r
2894 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2895 if not self.__GetNextToken():\r
2896 raise Warning("expected UI", self.FileName, self.CurrentLineNumber)\r
2897 UiSectionObj = UiSection.UiSection()\r
2898 UiSectionObj.Alignment = AlignValue\r
2899 if self.__GetStringData():\r
2900 UiSectionObj.StringData = self.__Token\r
2901 else:\r
2902 UiSectionObj.FileName = self.__Token\r
2903 Obj.SectionList.append(UiSectionObj)\r
2904\r
2905 elif self.__IsKeyword( "FV_IMAGE"):\r
52302d4d
LG
2906 if AlignValue == 'Auto':\r
2907 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2908 if not self.__IsToken( "="):\r
2909 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2910 if not self.__GetNextToken():\r
2911 raise Warning("expected FV name or FV file path", self.FileName, self.CurrentLineNumber)\r
2912\r
2913 FvName = self.__Token\r
2914 FvObj = None\r
2915\r
2916 if self.__IsToken( "{"):\r
2917 FvObj = Fv.FV()\r
2918 FvObj.UiFvName = FvName.upper()\r
2919 self.__GetDefineStatements(FvObj)\r
2920 MacroDict.update(FvObj.DefineVarDict)\r
2921 self.__GetBlockStatement(FvObj)\r
2922 self.__GetSetStatements(FvObj)\r
2923 self.__GetFvAlignment(FvObj)\r
2924 self.__GetFvAttributes(FvObj)\r
2925 self.__GetAprioriSection(FvObj, MacroDict.copy())\r
2926 self.__GetAprioriSection(FvObj, MacroDict.copy())\r
2927\r
2928 while True:\r
2929 IsInf = self.__GetInfStatement(FvObj, MacroDict.copy())\r
2930 IsFile = self.__GetFileStatement(FvObj, MacroDict.copy())\r
2931 if not IsInf and not IsFile:\r
2932 break\r
2933\r
2934 if not self.__IsToken( "}"):\r
2935 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2936\r
2937 FvImageSectionObj = FvImageSection.FvImageSection()\r
2938 FvImageSectionObj.Alignment = AlignValue\r
4231a819 2939 if FvObj is not None:\r
30fdf114
LG
2940 FvImageSectionObj.Fv = FvObj\r
2941 FvImageSectionObj.FvName = None\r
2942 else:\r
2943 FvImageSectionObj.FvName = FvName.upper()\r
2944 FvImageSectionObj.FvFileName = FvName\r
2945\r
2946 Obj.SectionList.append(FvImageSectionObj)\r
2947\r
2948 elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP") or self.__IsKeyword("SMM_DEPEX_EXP"):\r
52302d4d
LG
2949 if AlignValue == 'Auto':\r
2950 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2951 DepexSectionObj = DepexSection.DepexSection()\r
2952 DepexSectionObj.Alignment = AlignValue\r
2953 DepexSectionObj.DepexType = self.__Token\r
2954\r
2955 if not self.__IsToken( "="):\r
2956 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2957 if not self.__IsToken( "{"):\r
2958 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2959 if not self.__SkipToToken( "}"):\r
2960 raise Warning("expected Depex expression ending '}'", self.FileName, self.CurrentLineNumber)\r
2961\r
2962 DepexSectionObj.Expression = self.__SkippedChars.rstrip('}')\r
2963 Obj.SectionList.append(DepexSectionObj)\r
2964\r
2965 else:\r
30fdf114
LG
2966 if not self.__GetNextWord():\r
2967 raise Warning("expected section type", self.FileName, self.CurrentLineNumber)\r
2968\r
2969 # Encapsulation section appear, UndoToken and return\r
2970 if self.__Token == "COMPRESS" or self.__Token == "GUIDED":\r
2971 self.SetFileBufferPos(OldPos)\r
2972 return False\r
2973\r
2974 if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\\r
2975 "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"):\r
2976 raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
52302d4d
LG
2977 if AlignValue == 'Auto'and (not self.__Token == 'PE32') and (not self.__Token == 'TE'):\r
2978 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
2979\r
30fdf114
LG
2980 # DataSection\r
2981 DataSectionObj = DataSection.DataSection()\r
2982 DataSectionObj.Alignment = AlignValue\r
2983 DataSectionObj.SecType = self.__Token\r
2984\r
2985 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):\r
2986 if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType):\r
2987 if self.__Token == 'RELOCS_STRIPPED':\r
2988 DataSectionObj.KeepReloc = False\r
2989 else:\r
2990 DataSectionObj.KeepReloc = True\r
2991 else:\r
2992 raise Warning("File type %s, section type %s, could not have reloc strip flag%d" % (Obj.FvFileType, DataSectionObj.SecType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
2993\r
2994 if self.__IsToken("="):\r
2995 if not self.__GetNextToken():\r
2996 raise Warning("expected section file path", self.FileName, self.CurrentLineNumber)\r
2997 DataSectionObj.SectFileName = self.__Token\r
2bc3256c 2998 self.__VerifyFile(DataSectionObj.SectFileName)\r
30fdf114
LG
2999 else:\r
3000 if not self.__GetCglSection(DataSectionObj):\r
3001 return False\r
3002\r
3003 Obj.SectionList.append(DataSectionObj)\r
3004\r
3005 return True\r
3006\r
2bc3256c
LG
3007 ## __VerifyFile\r
3008 #\r
3009 # Check if file exists or not:\r
3010 # If current phase if Gen