]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/FdfParser.py
BaseTools: StrGather remove functions no one calls
[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
45\r
52302d4d 46from GenFdsGlobalVariable import GenFdsGlobalVariable\r
30fdf114
LG
47from Common.BuildToolError import *\r
48from Common import EdkLogger\r
14c48571 49from Common.Misc import PathClass\r
50from Common.String import NormPath\r
0d2711a6
LG
51import Common.GlobalData as GlobalData\r
52from Common.Expression import *\r
df692f02 53from Common import GlobalData\r
2bcc713e 54from Common.String import ReplaceMacro\r
91ae2988 55import uuid\r
d0acc87a 56from Common.Misc import tdict\r
94e4bcbb 57from Common.MultipleWorkspace import MultipleWorkspace as mws\r
1be2ed90
HC
58import Common.LongFilePathOs as os\r
59from Common.LongFilePathSupport import OpenLongFilePath as open\r
91ae2988
YZ
60from Capsule import EFI_CERT_TYPE_PKCS7_GUID\r
61from Capsule import EFI_CERT_TYPE_RSA2048_SHA256_GUID\r
30fdf114
LG
62\r
63##define T_CHAR_SPACE ' '\r
64##define T_CHAR_NULL '\0'\r
65##define T_CHAR_CR '\r'\r
66##define T_CHAR_TAB '\t'\r
67##define T_CHAR_LF '\n'\r
68##define T_CHAR_SLASH '/'\r
69##define T_CHAR_BACKSLASH '\\'\r
70##define T_CHAR_DOUBLE_QUOTE '\"'\r
71##define T_CHAR_SINGLE_QUOTE '\''\r
72##define T_CHAR_STAR '*'\r
73##define T_CHAR_HASH '#'\r
74\r
75(T_CHAR_SPACE, T_CHAR_NULL, T_CHAR_CR, T_CHAR_TAB, T_CHAR_LF, T_CHAR_SLASH, \\r
76T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \\r
77(' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')\r
78\r
79SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')\r
80\r
0d2711a6
LG
81RegionSizePattern = re.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")\r
82RegionSizeGuidPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")\r
2bc3256c 83RegionOffsetPcdPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*$")\r
64b2609f 84ShortcutPcdPattern = re.compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")\r
0d2711a6 85\r
118bf096
CS
86AllIncludeFileList = []\r
87\r
88# Get the closest parent\r
89def GetParentAtLine (Line):\r
90 for Profile in AllIncludeFileList:\r
91 if Profile.IsLineInFile(Line):\r
92 return Profile\r
93 return None\r
94\r
95# Check include loop\r
96def IsValidInclude (File, Line):\r
97 for Profile in AllIncludeFileList:\r
98 if Profile.IsLineInFile(Line) and Profile.FileName == File:\r
99 return False\r
100\r
101 return True\r
30fdf114
LG
102\r
103def GetRealFileLine (File, Line):\r
104\r
105 InsertedLines = 0\r
118bf096
CS
106 for Profile in AllIncludeFileList:\r
107 if Profile.IsLineInFile(Line):\r
108 return Profile.GetLineInFile(Line)\r
109 elif Line >= Profile.InsertStartLineNumber and Profile.Level == 1:\r
df81077f 110 InsertedLines += Profile.GetTotalLines()\r
30fdf114
LG
111\r
112 return (File, Line - InsertedLines)\r
113\r
114## The exception class that used to report error messages when parsing FDF\r
115#\r
116# Currently the "ToolName" is set to be "FDF Parser".\r
117#\r
118class Warning (Exception):\r
119 ## The constructor\r
120 #\r
121 # @param self The object pointer\r
122 # @param Str The message to record\r
123 # @param File The FDF name\r
124 # @param Line The Line number that error occurs\r
125 #\r
126 def __init__(self, Str, File = None, Line = None):\r
127\r
128 FileLineTuple = GetRealFileLine(File, Line)\r
129 self.FileName = FileLineTuple[0]\r
130 self.LineNumber = FileLineTuple[1]\r
118bf096 131 self.OriginalLineNumber = Line\r
30fdf114
LG
132 self.Message = Str\r
133 self.ToolName = 'FdfParser'\r
134\r
135 def __str__(self):\r
136 return self.Message\r
137\r
138## The MACRO class that used to record macro value data when parsing include file\r
139#\r
140#\r
141class MacroProfile :\r
142 ## The constructor\r
143 #\r
144 # @param self The object pointer\r
145 # @param FileName The file that to be parsed\r
146 #\r
147 def __init__(self, FileName, Line):\r
148 self.FileName = FileName\r
149 self.DefinedAtLine = Line\r
150 self.MacroName = None\r
151 self.MacroValue = None\r
152\r
153## The Include file content class that used to record file data when parsing include file\r
154#\r
155# May raise Exception when opening file.\r
156#\r
157class IncludeFileProfile :\r
158 ## The constructor\r
159 #\r
160 # @param self The object pointer\r
161 # @param FileName The file that to be parsed\r
162 #\r
163 def __init__(self, FileName):\r
164 self.FileName = FileName\r
165 self.FileLinesList = []\r
166 try:\r
167 fsock = open(FileName, "rb", 0)\r
168 try:\r
169 self.FileLinesList = fsock.readlines()\r
47a29bc7
YF
170 for index, line in enumerate(self.FileLinesList):\r
171 if not line.endswith('\n'):\r
172 self.FileLinesList[index] += '\n'\r
173\r
30fdf114
LG
174 finally:\r
175 fsock.close()\r
176\r
177 except:\r
178 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)\r
179\r
180 self.InsertStartLineNumber = None\r
181 self.InsertAdjust = 0\r
118bf096
CS
182 self.IncludeFileList = []\r
183 self.Level = 1 # first level include file\r
184 \r
185 def GetTotalLines(self):\r
186 TotalLines = self.InsertAdjust + len(self.FileLinesList)\r
187\r
188 for Profile in self.IncludeFileList:\r
df81077f 189 TotalLines += Profile.GetTotalLines()\r
118bf096
CS
190\r
191 return TotalLines\r
192\r
193 def IsLineInFile(self, Line):\r
194 if Line >= self.InsertStartLineNumber and Line < self.InsertStartLineNumber + self.GetTotalLines():\r
195 return True\r
196\r
197 return False\r
198\r
199 def GetLineInFile(self, Line):\r
200 if not self.IsLineInFile (Line):\r
201 return (self.FileName, -1)\r
202 \r
203 InsertedLines = self.InsertStartLineNumber\r
204\r
205 for Profile in self.IncludeFileList:\r
206 if Profile.IsLineInFile(Line):\r
207 return Profile.GetLineInFile(Line)\r
208 elif Line >= Profile.InsertStartLineNumber:\r
209 InsertedLines += Profile.GetTotalLines()\r
210\r
211 return (self.FileName, Line - InsertedLines + 1)\r
212\r
213\r
30fdf114
LG
214\r
215## The FDF content class that used to record file data when parsing FDF\r
216#\r
217# May raise Exception when opening file.\r
218#\r
219class FileProfile :\r
220 ## The constructor\r
221 #\r
222 # @param self The object pointer\r
223 # @param FileName The file that to be parsed\r
224 #\r
225 def __init__(self, FileName):\r
226 self.FileLinesList = []\r
227 try:\r
228 fsock = open(FileName, "rb", 0)\r
229 try:\r
230 self.FileLinesList = fsock.readlines()\r
231 finally:\r
232 fsock.close()\r
233\r
234 except:\r
235 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)\r
236\r
237\r
238 self.PcdDict = {}\r
239 self.InfList = []\r
2502b735 240 self.InfDict = {'ArchTBD':[]}\r
d0acc87a
LG
241 # ECC will use this Dict and List information\r
242 self.PcdFileLineDict = {}\r
243 self.InfFileLineList = []\r
244 \r
30fdf114 245 self.FdDict = {}\r
52302d4d 246 self.FdNameNotSet = False\r
30fdf114 247 self.FvDict = {}\r
fd171542 248 self.CapsuleDict = {}\r
30fdf114
LG
249 self.VtfList = []\r
250 self.RuleDict = {}\r
251 self.OptRomDict = {}\r
a3251d84 252 self.FmpPayloadDict = {}\r
30fdf114
LG
253\r
254## The syntax parser for FDF\r
255#\r
256# PreprocessFile method should be called prior to ParseFile\r
257# CycleReferenceCheck method can detect cycles in FDF contents\r
258#\r
259# GetNext*** procedures mean these procedures will get next token first, then make judgement.\r
260# Get*** procedures mean these procedures will make judgement on current token only.\r
261#\r
262class FdfParser:\r
263 ## The constructor\r
264 #\r
265 # @param self The object pointer\r
266 # @param FileName The file that to be parsed\r
267 #\r
268 def __init__(self, FileName):\r
269 self.Profile = FileProfile(FileName)\r
270 self.FileName = FileName\r
271 self.CurrentLineNumber = 1\r
272 self.CurrentOffsetWithinLine = 0\r
273 self.CurrentFdName = None\r
274 self.CurrentFvName = None\r
275 self.__Token = ""\r
276 self.__SkippedChars = ""\r
97fa0ee9 277 GlobalData.gFdfParser = self\r
30fdf114 278\r
d0acc87a
LG
279 # Used to section info\r
280 self.__CurSection = []\r
281 # Key: [section name, UI name, arch]\r
282 # Value: {MACRO_NAME : MACRO_VALUE}\r
283 self.__MacroDict = tdict(True, 3)\r
284 self.__PcdDict = {}\r
285\r
30fdf114 286 self.__WipeOffArea = []\r
14c48571 287 if GenFdsGlobalVariable.WorkSpaceDir == '':\r
288 GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE")\r
30fdf114
LG
289\r
290 ## __IsWhiteSpace() method\r
291 #\r
292 # Whether char at current FileBufferPos is whitespace\r
293 #\r
294 # @param self The object pointer\r
295 # @param Char The char to test\r
296 # @retval True The char is a kind of white space\r
297 # @retval False The char is NOT a kind of white space\r
298 #\r
299 def __IsWhiteSpace(self, Char):\r
300 if Char in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_SPACE, T_CHAR_TAB, T_CHAR_LF):\r
301 return True\r
302 else:\r
303 return False\r
304\r
305 ## __SkipWhiteSpace() method\r
306 #\r
307 # Skip white spaces from current char, return number of chars skipped\r
308 #\r
309 # @param self The object pointer\r
310 # @retval Count The number of chars skipped\r
311 #\r
312 def __SkipWhiteSpace(self):\r
313 Count = 0\r
314 while not self.__EndOfFile():\r
315 Count += 1\r
316 if self.__CurrentChar() in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_LF, T_CHAR_SPACE, T_CHAR_TAB):\r
317 self.__SkippedChars += str(self.__CurrentChar())\r
318 self.__GetOneChar()\r
319\r
320 else:\r
321 Count = Count - 1\r
322 return Count\r
323\r
324 ## __EndOfFile() method\r
325 #\r
326 # Judge current buffer pos is at file end\r
327 #\r
328 # @param self The object pointer\r
329 # @retval True Current File buffer position is at file end\r
330 # @retval False Current File buffer position is NOT at file end\r
331 #\r
332 def __EndOfFile(self):\r
333 NumberOfLines = len(self.Profile.FileLinesList)\r
334 SizeOfLastLine = len(self.Profile.FileLinesList[-1])\r
335 if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1:\r
336 return True\r
337 elif self.CurrentLineNumber > NumberOfLines:\r
338 return True\r
339 else:\r
340 return False\r
341\r
342 ## __EndOfLine() method\r
343 #\r
344 # Judge current buffer pos is at line end\r
345 #\r
346 # @param self The object pointer\r
347 # @retval True Current File buffer position is at line end\r
348 # @retval False Current File buffer position is NOT at line end\r
349 #\r
350 def __EndOfLine(self):\r
351 if self.CurrentLineNumber > len(self.Profile.FileLinesList):\r
352 return True\r
353 SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1])\r
354 if self.CurrentOffsetWithinLine >= SizeOfCurrentLine:\r
355 return True\r
356 else:\r
357 return False\r
358\r
359 ## Rewind() method\r
360 #\r
361 # Reset file data buffer to the initial state\r
362 #\r
363 # @param self The object pointer\r
118bf096
CS
364 # @param DestLine Optional new destination line number.\r
365 # @param DestOffset Optional new destination offset. \r
30fdf114 366 #\r
118bf096
CS
367 def Rewind(self, DestLine = 1, DestOffset = 0): \r
368 self.CurrentLineNumber = DestLine \r
369 self.CurrentOffsetWithinLine = DestOffset \r
30fdf114
LG
370\r
371 ## __UndoOneChar() method\r
372 #\r
373 # Go back one char in the file buffer\r
374 #\r
375 # @param self The object pointer\r
376 # @retval True Successfully go back one char\r
377 # @retval False Not able to go back one char as file beginning reached\r
378 #\r
379 def __UndoOneChar(self):\r
380\r
381 if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0:\r
382 return False\r
383 elif self.CurrentOffsetWithinLine == 0:\r
384 self.CurrentLineNumber -= 1\r
385 self.CurrentOffsetWithinLine = len(self.__CurrentLine()) - 1\r
386 else:\r
387 self.CurrentOffsetWithinLine -= 1\r
388 return True\r
389\r
390 ## __GetOneChar() method\r
391 #\r
392 # Move forward one char in the file buffer\r
393 #\r
394 # @param self The object pointer\r
395 #\r
396 def __GetOneChar(self):\r
397 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:\r
0d2711a6
LG
398 self.CurrentLineNumber += 1\r
399 self.CurrentOffsetWithinLine = 0\r
30fdf114 400 else:\r
0d2711a6 401 self.CurrentOffsetWithinLine += 1\r
30fdf114
LG
402\r
403 ## __CurrentChar() method\r
404 #\r
405 # Get the char pointed to by the file buffer pointer\r
406 #\r
407 # @param self The object pointer\r
408 # @retval Char Current char\r
409 #\r
410 def __CurrentChar(self):\r
411 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine]\r
412\r
413 ## __NextChar() method\r
414 #\r
415 # Get the one char pass the char pointed to by the file buffer pointer\r
416 #\r
417 # @param self The object pointer\r
418 # @retval Char Next char\r
419 #\r
420 def __NextChar(self):\r
421 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:\r
422 return self.Profile.FileLinesList[self.CurrentLineNumber][0]\r
423 else:\r
424 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1]\r
425\r
426 ## __SetCurrentCharValue() method\r
427 #\r
428 # Modify the value of current char\r
429 #\r
430 # @param self The object pointer\r
431 # @param Value The new value of current char\r
432 #\r
433 def __SetCurrentCharValue(self, Value):\r
434 self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value\r
435\r
436 ## __CurrentLine() method\r
437 #\r
438 # Get the list that contains current line contents\r
439 #\r
440 # @param self The object pointer\r
441 # @retval List current line contents\r
442 #\r
443 def __CurrentLine(self):\r
444 return self.Profile.FileLinesList[self.CurrentLineNumber - 1]\r
445\r
446 def __StringToList(self):\r
447 self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList]\r
448 self.Profile.FileLinesList[-1].append(' ')\r
449\r
30fdf114
LG
450 def __ReplaceFragment(self, StartPos, EndPos, Value = ' '):\r
451 if StartPos[0] == EndPos[0]:\r
452 Offset = StartPos[1]\r
453 while Offset <= EndPos[1]:\r
454 self.Profile.FileLinesList[StartPos[0]][Offset] = Value\r
455 Offset += 1\r
456 return\r
457\r
458 Offset = StartPos[1]\r
459 while self.Profile.FileLinesList[StartPos[0]][Offset] not in ('\r', '\n'):\r
460 self.Profile.FileLinesList[StartPos[0]][Offset] = Value\r
461 Offset += 1\r
462\r
463 Line = StartPos[0]\r
464 while Line < EndPos[0]:\r
465 Offset = 0\r
466 while self.Profile.FileLinesList[Line][Offset] not in ('\r', '\n'):\r
467 self.Profile.FileLinesList[Line][Offset] = Value\r
468 Offset += 1\r
469 Line += 1\r
470\r
471 Offset = 0\r
472 while Offset <= EndPos[1]:\r
473 self.Profile.FileLinesList[EndPos[0]][Offset] = Value\r
474 Offset += 1\r
475\r
476\r
d5d56f1b
LG
477 def __GetMacroName(self):\r
478 if not self.__GetNextToken():\r
479 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)\r
480 MacroName = self.__Token\r
481 NotFlag = False\r
482 if MacroName.startswith('!'):\r
483 NotFlag = True\r
484 MacroName = MacroName[1:].strip()\r
485 \r
486 if not MacroName.startswith('$(') or not MacroName.endswith(')'):\r
487 raise Warning("Macro name expected(Please use '$(%(Token)s)' if '%(Token)s' is a macro.)" % {"Token" : MacroName},\r
488 self.FileName, self.CurrentLineNumber)\r
489 MacroName = MacroName[2:-1]\r
490 return MacroName, NotFlag\r
d0acc87a
LG
491\r
492 def __SetMacroValue(self, Macro, Value):\r
493 if not self.__CurSection:\r
494 return\r
495\r
496 MacroDict = {}\r
497 if not self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]]:\r
498 self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]] = MacroDict\r
499 else:\r
500 MacroDict = self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]]\r
501 MacroDict[Macro] = Value\r
502\r
503 def __GetMacroValue(self, Macro):\r
504 # Highest priority\r
505 if Macro in GlobalData.gCommandLineDefines:\r
506 return GlobalData.gCommandLineDefines[Macro]\r
507 if Macro in GlobalData.gGlobalDefines:\r
508 return GlobalData.gGlobalDefines[Macro]\r
509\r
510 if self.__CurSection:\r
511 MacroDict = self.__MacroDict[\r
512 self.__CurSection[0],\r
513 self.__CurSection[1],\r
514 self.__CurSection[2]\r
515 ]\r
516 if MacroDict and Macro in MacroDict:\r
517 return MacroDict[Macro]\r
518\r
519 # Lowest priority\r
520 if Macro in GlobalData.gPlatformDefines:\r
521 return GlobalData.gPlatformDefines[Macro]\r
522 return None\r
523\r
524 def __SectionHeaderParser(self, Section):\r
525 # [Defines]\r
526 # [FD.UiName]: use dummy instead if UI name is optional\r
527 # [FV.UiName]\r
528 # [Capsule.UiName]\r
529 # [Rule]: don't take rule section into account, macro is not allowed in this section\r
530 # [VTF.arch.UiName, arch]\r
531 # [OptionRom.DriverName]\r
532 self.__CurSection = []\r
533 Section = Section.strip()[1:-1].upper().replace(' ', '').strip('.')\r
534 ItemList = Section.split('.')\r
535 Item = ItemList[0]\r
536 if Item == '' or Item == 'RULE':\r
537 return\r
538\r
539 if Item == 'DEFINES':\r
540 self.__CurSection = ['COMMON', 'COMMON', 'COMMON']\r
541 elif Item == 'VTF' and len(ItemList) == 3:\r
542 UiName = ItemList[2]\r
543 Pos = UiName.find(',')\r
544 if Pos != -1:\r
545 UiName = UiName[:Pos]\r
546 self.__CurSection = ['VTF', UiName, ItemList[1]]\r
547 elif len(ItemList) > 1:\r
548 self.__CurSection = [ItemList[0], ItemList[1], 'COMMON']\r
549 elif len(ItemList) > 0:\r
550 self.__CurSection = [ItemList[0], 'DUMMY', 'COMMON']\r
551\r
30fdf114
LG
552 ## PreprocessFile() method\r
553 #\r
554 # Preprocess file contents, replace comments with spaces.\r
555 # In the end, rewind the file buffer pointer to the beginning\r
556 # BUGBUG: No !include statement processing contained in this procedure\r
557 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]\r
558 #\r
559 # @param self The object pointer\r
560 #\r
561 def PreprocessFile(self):\r
562\r
563 self.Rewind()\r
564 InComment = False\r
565 DoubleSlashComment = False\r
566 HashComment = False\r
567 # HashComment in quoted string " " is ignored.\r
568 InString = False\r
569\r
570 while not self.__EndOfFile():\r
571\r
572 if self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment:\r
573 InString = not InString\r
574 # meet new line, then no longer in a comment for // and '#'\r
575 if self.__CurrentChar() == T_CHAR_LF:\r
576 self.CurrentLineNumber += 1\r
577 self.CurrentOffsetWithinLine = 0\r
578 if InComment and DoubleSlashComment:\r
579 InComment = False\r
580 DoubleSlashComment = False\r
581 if InComment and HashComment:\r
582 InComment = False\r
583 HashComment = False\r
584 # check for */ comment end\r
585 elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH:\r
586 self.__SetCurrentCharValue(T_CHAR_SPACE)\r
587 self.__GetOneChar()\r
588 self.__SetCurrentCharValue(T_CHAR_SPACE)\r
589 self.__GetOneChar()\r
590 InComment = False\r
591 # set comments to spaces\r
592 elif InComment:\r
593 self.__SetCurrentCharValue(T_CHAR_SPACE)\r
594 self.__GetOneChar()\r
595 # check for // comment\r
596 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH and not self.__EndOfLine():\r
597 InComment = True\r
598 DoubleSlashComment = True\r
599 # check for '#' comment\r
600 elif self.__CurrentChar() == T_CHAR_HASH and not self.__EndOfLine() and not InString:\r
601 InComment = True\r
602 HashComment = True\r
603 # check for /* comment start\r
604 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR:\r
605 self.__SetCurrentCharValue( T_CHAR_SPACE)\r
606 self.__GetOneChar()\r
607 self.__SetCurrentCharValue( T_CHAR_SPACE)\r
608 self.__GetOneChar()\r
609 InComment = True\r
610 else:\r
611 self.__GetOneChar()\r
612\r
613 # restore from ListOfList to ListOfString\r
614 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]\r
615 self.Rewind()\r
616\r
617 ## PreprocessIncludeFile() method\r
618 #\r
619 # Preprocess file contents, replace !include statements with file contents.\r
620 # In the end, rewind the file buffer pointer to the beginning\r
621 #\r
622 # @param self The object pointer\r
623 #\r
624 def PreprocessIncludeFile(self):\r
118bf096
CS
625 # nested include support\r
626 Processed = False\r
0fdfe274 627 MacroDict = {}\r
30fdf114
LG
628 while self.__GetNextToken():\r
629\r
0fdfe274
YZ
630 if self.__Token == 'DEFINE':\r
631 if not self.__GetNextToken():\r
632 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)\r
633 Macro = self.__Token\r
634 if not self.__IsToken( "="):\r
635 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
636 Value = self.__GetExpression()\r
637 MacroDict[Macro] = Value\r
638\r
639 elif self.__Token == '!include':\r
118bf096 640 Processed = True\r
30fdf114
LG
641 IncludeLine = self.CurrentLineNumber\r
642 IncludeOffset = self.CurrentOffsetWithinLine - len('!include')\r
643 if not self.__GetNextToken():\r
644 raise Warning("expected include file name", self.FileName, self.CurrentLineNumber)\r
645 IncFileName = self.__Token\r
0fdfe274
YZ
646 PreIndex = 0\r
647 StartPos = IncFileName.find('$(', PreIndex)\r
648 EndPos = IncFileName.find(')', StartPos+2)\r
649 while StartPos != -1 and EndPos != -1:\r
650 Macro = IncFileName[StartPos+2 : EndPos]\r
d0acc87a 651 MacroVal = self.__GetMacroValue(Macro)\r
0fdfe274
YZ
652 if not MacroVal:\r
653 if Macro in MacroDict:\r
654 MacroVal = MacroDict[Macro]\r
655 if MacroVal != None:\r
656 IncFileName = IncFileName.replace('$(' + Macro + ')', MacroVal, 1)\r
657 if MacroVal.find('$(') != -1:\r
658 PreIndex = StartPos\r
659 else:\r
660 PreIndex = StartPos + len(MacroVal)\r
661 else:\r
662 raise Warning("The Macro %s is not defined" %Macro, self.FileName, self.CurrentLineNumber)\r
663 StartPos = IncFileName.find('$(', PreIndex)\r
664 EndPos = IncFileName.find(')', StartPos+2)\r
665\r
666 IncludedFile = NormPath(IncFileName)\r
2bcc713e
LG
667 #\r
668 # First search the include file under the same directory as FDF file\r
669 #\r
670 IncludedFile1 = PathClass(IncludedFile, os.path.dirname(self.FileName))\r
671 ErrorCode = IncludedFile1.Validate()[0]\r
672 if ErrorCode != 0:\r
673 #\r
674 # Then search the include file under the same directory as DSC file\r
675 #\r
d0acc87a
LG
676 PlatformDir = ''\r
677 if GenFdsGlobalVariable.ActivePlatform:\r
678 PlatformDir = GenFdsGlobalVariable.ActivePlatform.Dir\r
679 elif GlobalData.gActivePlatform:\r
680 PlatformDir = GlobalData.gActivePlatform.MetaFile.Dir\r
681 IncludedFile1 = PathClass(IncludedFile, PlatformDir)\r
2bcc713e
LG
682 ErrorCode = IncludedFile1.Validate()[0]\r
683 if ErrorCode != 0:\r
684 #\r
685 # Also search file under the WORKSPACE directory\r
686 #\r
687 IncludedFile1 = PathClass(IncludedFile, GlobalData.gWorkspace)\r
688 ErrorCode = IncludedFile1.Validate()[0]\r
689 if ErrorCode != 0:\r
d0acc87a 690 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 691 self.FileName, self.CurrentLineNumber)\r
30fdf114 692\r
118bf096
CS
693 if not IsValidInclude (IncludedFile1.Path, self.CurrentLineNumber):\r
694 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1.Path), self.FileName, self.CurrentLineNumber)\r
695\r
2bcc713e 696 IncFileProfile = IncludeFileProfile(IncludedFile1.Path)\r
30fdf114
LG
697\r
698 CurrentLine = self.CurrentLineNumber\r
699 CurrentOffset = self.CurrentOffsetWithinLine\r
700 # list index of the insertion, note that line number is 'CurrentLine + 1'\r
701 InsertAtLine = CurrentLine\r
118bf096
CS
702 ParentProfile = GetParentAtLine (CurrentLine)\r
703 if ParentProfile != None:\r
704 ParentProfile.IncludeFileList.insert(0, IncFileProfile)\r
705 IncFileProfile.Level = ParentProfile.Level + 1\r
30fdf114
LG
706 IncFileProfile.InsertStartLineNumber = InsertAtLine + 1\r
707 # deal with remaining portions after "!include filename", if exists.\r
708 if self.__GetNextToken():\r
709 if self.CurrentLineNumber == CurrentLine:\r
710 RemainingLine = self.__CurrentLine()[CurrentOffset:]\r
711 self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine)\r
712 IncFileProfile.InsertAdjust += 1\r
713 self.CurrentLineNumber += 1\r
714 self.CurrentOffsetWithinLine = 0\r
715\r
716 for Line in IncFileProfile.FileLinesList:\r
717 self.Profile.FileLinesList.insert(InsertAtLine, Line)\r
718 self.CurrentLineNumber += 1\r
719 InsertAtLine += 1\r
720\r
118bf096
CS
721 # reversely sorted to better determine error in file\r
722 AllIncludeFileList.insert(0, IncFileProfile)\r
30fdf114
LG
723\r
724 # comment out the processed include file statement\r
725 TempList = list(self.Profile.FileLinesList[IncludeLine - 1])\r
726 TempList.insert(IncludeOffset, '#')\r
727 self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)\r
118bf096
CS
728 if Processed: # Nested and back-to-back support\r
729 self.Rewind(DestLine = IncFileProfile.InsertStartLineNumber - 1)\r
730 Processed = False\r
731 # Preprocess done.\r
30fdf114 732 self.Rewind()\r
0d2711a6 733 \r
da92f276
LG
734 def __GetIfListCurrentItemStat(self, IfList):\r
735 if len(IfList) == 0:\r
736 return True\r
737 \r
738 for Item in IfList:\r
739 if Item[1] == False:\r
740 return False\r
741 \r
742 return True\r
0d2711a6 743 \r
6780eef1 744 ## PreprocessConditionalStatement() method\r
30fdf114 745 #\r
6780eef1 746 # Preprocess conditional statement.\r
30fdf114
LG
747 # In the end, rewind the file buffer pointer to the beginning\r
748 #\r
749 # @param self The object pointer\r
750 #\r
751 def PreprocessConditionalStatement(self):\r
752 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]\r
753 IfList = []\r
0d2711a6 754 RegionLayoutLine = 0\r
d0acc87a 755 ReplacedLine = -1\r
30fdf114 756 while self.__GetNextToken():\r
d0acc87a
LG
757 # Determine section name and the location dependent macro\r
758 if self.__GetIfListCurrentItemStat(IfList):\r
759 if self.__Token.startswith('['):\r
760 Header = self.__Token\r
761 if not self.__Token.endswith(']'):\r
762 self.__SkipToToken(']')\r
763 Header += self.__SkippedChars\r
764 if Header.find('$(') != -1:\r
765 raise Warning("macro cannot be used in section header", self.FileName, self.CurrentLineNumber)\r
766 self.__SectionHeaderParser(Header)\r
767 continue\r
768 # Replace macros except in RULE section or out of section\r
769 elif self.__CurSection and ReplacedLine != self.CurrentLineNumber:\r
770 ReplacedLine = self.CurrentLineNumber\r
771 self.__UndoToken()\r
772 CurLine = self.Profile.FileLinesList[ReplacedLine - 1]\r
773 PreIndex = 0\r
774 StartPos = CurLine.find('$(', PreIndex)\r
775 EndPos = CurLine.find(')', StartPos+2)\r
64b2609f 776 while StartPos != -1 and EndPos != -1 and self.__Token not in ['!ifdef', '!ifndef', '!if', '!elseif']:\r
d0acc87a
LG
777 MacroName = CurLine[StartPos+2 : EndPos]\r
778 MacorValue = self.__GetMacroValue(MacroName)\r
779 if MacorValue != None:\r
780 CurLine = CurLine.replace('$(' + MacroName + ')', MacorValue, 1)\r
781 if MacorValue.find('$(') != -1:\r
782 PreIndex = StartPos\r
783 else:\r
784 PreIndex = StartPos + len(MacorValue)\r
785 else:\r
786 PreIndex = EndPos + 1\r
787 StartPos = CurLine.find('$(', PreIndex)\r
788 EndPos = CurLine.find(')', StartPos+2)\r
789 self.Profile.FileLinesList[ReplacedLine - 1] = CurLine\r
790 continue\r
791\r
30fdf114 792 if self.__Token == 'DEFINE':\r
d0acc87a
LG
793 if self.__GetIfListCurrentItemStat(IfList):\r
794 if not self.__CurSection:\r
795 raise Warning("macro cannot be defined in Rule section or out of section", self.FileName, self.CurrentLineNumber)\r
da92f276
LG
796 DefineLine = self.CurrentLineNumber - 1\r
797 DefineOffset = self.CurrentOffsetWithinLine - len('DEFINE')\r
798 if not self.__GetNextToken():\r
799 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)\r
800 Macro = self.__Token\r
801 if not self.__IsToken( "="):\r
802 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
803 \r
d0acc87a
LG
804 Value = self.__GetExpression()\r
805 self.__SetMacroValue(Macro, Value)\r
da92f276 806 self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
0d2711a6 807 elif self.__Token == 'SET':\r
2f04e527
YL
808 if not self.__GetIfListCurrentItemStat(IfList):\r
809 continue\r
64b2609f
LG
810 SetLine = self.CurrentLineNumber - 1\r
811 SetOffset = self.CurrentOffsetWithinLine - len('SET')\r
0d2711a6
LG
812 PcdPair = self.__GetNextPcdName()\r
813 PcdName = "%s.%s" % (PcdPair[1], PcdPair[0])\r
814 if not self.__IsToken( "="):\r
815 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
816\r
d0acc87a
LG
817 Value = self.__GetExpression()\r
818 Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)\r
30fdf114 819\r
d0acc87a 820 self.__PcdDict[PcdName] = Value\r
64b2609f
LG
821\r
822 self.Profile.PcdDict[PcdPair] = Value\r
823 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
824 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple\r
825\r
826 self.__WipeOffArea.append(((SetLine, SetOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
30fdf114
LG
827 elif self.__Token in ('!ifdef', '!ifndef', '!if'):\r
828 IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))\r
829 IfList.append([IfStartPos, None, None])\r
0d2711a6 830\r
30fdf114 831 CondLabel = self.__Token\r
0d2711a6 832 Expression = self.__GetExpression()\r
d5d56f1b 833 \r
30fdf114 834 if CondLabel == '!if':\r
0d2711a6 835 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')\r
30fdf114 836 else:\r
0d2711a6
LG
837 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'in')\r
838 if CondLabel == '!ifndef':\r
30fdf114 839 ConditionSatisfied = not ConditionSatisfied\r
30fdf114 840\r
0d2711a6
LG
841 BranchDetermined = ConditionSatisfied\r
842 IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]\r
843 if ConditionSatisfied:\r
844 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) \r
30fdf114
LG
845 elif self.__Token in ('!elseif', '!else'):\r
846 ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))\r
847 if len(IfList) <= 0:\r
848 raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)\r
0d2711a6 849\r
30fdf114
LG
850 if IfList[-1][1]:\r
851 IfList[-1] = [ElseStartPos, False, True]\r
852 self.__WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
853 else:\r
854 self.__WipeOffArea.append((IfList[-1][0], ElseStartPos))\r
855 IfList[-1] = [ElseStartPos, True, IfList[-1][2]]\r
856 if self.__Token == '!elseif':\r
0d2711a6
LG
857 Expression = self.__GetExpression()\r
858 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')\r
30fdf114
LG
859 IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]]\r
860\r
861 if IfList[-1][1]:\r
862 if IfList[-1][2]:\r
863 IfList[-1][1] = False\r
864 else:\r
865 IfList[-1][2] = True\r
866 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
30fdf114 867 elif self.__Token == '!endif':\r
d0acc87a
LG
868 if len(IfList) <= 0:\r
869 raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
870 if IfList[-1][1]:\r
871 self.__WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
872 else:\r
873 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
874\r
875 IfList.pop()\r
0d2711a6
LG
876 elif not IfList: # Don't use PCDs inside conditional directive\r
877 if self.CurrentLineNumber <= RegionLayoutLine:\r
878 # Don't try the same line twice\r
879 continue\r
64b2609f
LG
880 SetPcd = ShortcutPcdPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])\r
881 if SetPcd:\r
882 self.__PcdDict[SetPcd.group('name')] = SetPcd.group('value')\r
883 RegionLayoutLine = self.CurrentLineNumber\r
884 continue\r
0d2711a6
LG
885 RegionSize = RegionSizePattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])\r
886 if not RegionSize:\r
887 RegionLayoutLine = self.CurrentLineNumber\r
888 continue\r
889 RegionSizeGuid = RegionSizeGuidPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber])\r
890 if not RegionSizeGuid:\r
891 RegionLayoutLine = self.CurrentLineNumber + 1\r
892 continue\r
d0acc87a
LG
893 self.__PcdDict[RegionSizeGuid.group('base')] = RegionSize.group('base')\r
894 self.__PcdDict[RegionSizeGuid.group('size')] = RegionSize.group('size')\r
0d2711a6
LG
895 RegionLayoutLine = self.CurrentLineNumber + 1\r
896\r
897 if IfList:\r
30fdf114
LG
898 raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber)\r
899 self.Rewind()\r
900\r
d0acc87a
LG
901 def __CollectMacroPcd(self):\r
902 MacroDict = {}\r
903\r
904 # PCD macro\r
64b2609f 905 MacroDict.update(GlobalData.gPlatformPcds)\r
d0acc87a
LG
906 MacroDict.update(self.__PcdDict)\r
907\r
908 # Lowest priority\r
909 MacroDict.update(GlobalData.gPlatformDefines)\r
910\r
911 if self.__CurSection:\r
912 # Defines macro\r
913 ScopeMacro = self.__MacroDict['COMMON', 'COMMON', 'COMMON']\r
914 if ScopeMacro:\r
915 MacroDict.update(ScopeMacro)\r
916 \r
917 # Section macro\r
918 ScopeMacro = self.__MacroDict[\r
919 self.__CurSection[0],\r
920 self.__CurSection[1],\r
921 self.__CurSection[2]\r
922 ]\r
923 if ScopeMacro:\r
924 MacroDict.update(ScopeMacro)\r
925\r
926 MacroDict.update(GlobalData.gGlobalDefines)\r
927 MacroDict.update(GlobalData.gCommandLineDefines)\r
1fa7fdf6
FY
928 if GlobalData.BuildOptionPcd:\r
929 for Item in GlobalData.BuildOptionPcd:\r
705ed563
YZ
930 if type(Item) is tuple:\r
931 continue\r
1fa7fdf6 932 PcdName, TmpValue = Item.split("=")\r
8565b582 933 TmpValue = BuildOptionValue(TmpValue, {})\r
1fa7fdf6 934 MacroDict[PcdName.strip()] = TmpValue\r
d0acc87a
LG
935 # Highest priority\r
936\r
937 return MacroDict\r
938\r
0d2711a6 939 def __EvaluateConditional(self, Expression, Line, Op = None, Value = None):\r
30fdf114 940 FileLineTuple = GetRealFileLine(self.FileName, Line)\r
d0acc87a 941 MacroPcdDict = self.__CollectMacroPcd()\r
0d2711a6
LG
942 if Op == 'eval':\r
943 try:\r
d0acc87a
LG
944 if Value:\r
945 return ValueExpression(Expression, MacroPcdDict)(True)\r
946 else:\r
947 return ValueExpression(Expression, MacroPcdDict)()\r
0d2711a6
LG
948 except WrnExpression, Excpt:\r
949 # \r
950 # Catch expression evaluation warning here. We need to report\r
951 # the precise number of line and return the evaluation result\r
952 #\r
953 EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),\r
954 File=self.FileName, ExtraData=self.__CurrentLine(), \r
955 Line=Line)\r
956 return Excpt.result\r
957 except Exception, Excpt:\r
64b2609f
LG
958 if hasattr(Excpt, 'Pcd'):\r
959 if Excpt.Pcd in GlobalData.gPlatformOtherPcds:\r
960 Info = GlobalData.gPlatformOtherPcds[Excpt.Pcd]\r
961 raise Warning("Cannot use this PCD (%s) in an expression as"\r
962 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"\r
963 " of the DSC file (%s), and it is currently defined in this section:"\r
964 " %s, line #: %d." % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE'], Info[0], Info[1]),\r
965 *FileLineTuple)\r
966 else:\r
967 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE']),\r
968 *FileLineTuple)\r
969 else:\r
970 raise Warning(str(Excpt), *FileLineTuple)\r
0d2711a6
LG
971 else:\r
972 if Expression.startswith('$(') and Expression[-1] == ')':\r
973 Expression = Expression[2:-1] \r
d0acc87a 974 return Expression in MacroPcdDict\r
30fdf114
LG
975\r
976 ## __IsToken() method\r
977 #\r
978 # Check whether input string is found from current char position along\r
979 # If found, the string value is put into self.__Token\r
980 #\r
981 # @param self The object pointer\r
982 # @param String The string to search\r
983 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive\r
984 # @retval True Successfully find string, file buffer pointer moved forward\r
985 # @retval False Not able to find string, file buffer pointer not changed\r
986 #\r
987 def __IsToken(self, String, IgnoreCase = False):\r
988 self.__SkipWhiteSpace()\r
989\r
990 # Only consider the same line, no multi-line token allowed\r
991 StartPos = self.CurrentOffsetWithinLine\r
992 index = -1\r
993 if IgnoreCase:\r
994 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())\r
995 else:\r
996 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)\r
997 if index == 0:\r
998 self.CurrentOffsetWithinLine += len(String)\r
999 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]\r
1000 return True\r
1001 return False\r
1002\r
1003 ## __IsKeyword() method\r
1004 #\r
1005 # Check whether input keyword is found from current char position along, whole word only!\r
1006 # If found, the string value is put into self.__Token\r
1007 #\r
1008 # @param self The object pointer\r
1009 # @param Keyword The string to search\r
1010 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive\r
1011 # @retval True Successfully find string, file buffer pointer moved forward\r
1012 # @retval False Not able to find string, file buffer pointer not changed\r
1013 #\r
1014 def __IsKeyword(self, KeyWord, IgnoreCase = False):\r
1015 self.__SkipWhiteSpace()\r
1016\r
1017 # Only consider the same line, no multi-line token allowed\r
1018 StartPos = self.CurrentOffsetWithinLine\r
1019 index = -1\r
1020 if IgnoreCase:\r
1021 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(KeyWord.upper())\r
1022 else:\r
1023 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(KeyWord)\r
1024 if index == 0:\r
1025 followingChar = self.__CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)]\r
1026 if not str(followingChar).isspace() and followingChar not in SEPERATOR_TUPLE:\r
1027 return False\r
1028 self.CurrentOffsetWithinLine += len(KeyWord)\r
1029 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]\r
1030 return True\r
1031 return False\r
1032\r
0d2711a6
LG
1033 def __GetExpression(self):\r
1034 Line = self.Profile.FileLinesList[self.CurrentLineNumber - 1]\r
1035 Index = len(Line) - 1\r
1036 while Line[Index] in ['\r', '\n']:\r
1037 Index -= 1\r
1038 ExpressionString = self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:Index+1]\r
1039 self.CurrentOffsetWithinLine += len(ExpressionString)\r
1040 ExpressionString = ExpressionString.strip()\r
1041 return ExpressionString\r
1042\r
30fdf114
LG
1043 ## __GetNextWord() method\r
1044 #\r
1045 # Get next C name from file lines\r
1046 # If found, the string value is put into self.__Token\r
1047 #\r
1048 # @param self The object pointer\r
1049 # @retval True Successfully find a C name string, file buffer pointer moved forward\r
1050 # @retval False Not able to find a C name string, file buffer pointer not changed\r
1051 #\r
1052 def __GetNextWord(self):\r
1053 self.__SkipWhiteSpace()\r
1054 if self.__EndOfFile():\r
1055 return False\r
1056\r
1057 TempChar = self.__CurrentChar()\r
1058 StartPos = self.CurrentOffsetWithinLine\r
1059 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_':\r
1060 self.__GetOneChar()\r
1061 while not self.__EndOfLine():\r
1062 TempChar = self.__CurrentChar()\r
1063 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \\r
1064 or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-':\r
1065 self.__GetOneChar()\r
1066\r
1067 else:\r
1068 break\r
1069\r
1070 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]\r
1071 return True\r
1072\r
1073 return False\r
1074\r
1075 ## __GetNextToken() method\r
1076 #\r
1077 # Get next token unit before a seperator\r
1078 # If found, the string value is put into self.__Token\r
1079 #\r
1080 # @param self The object pointer\r
1081 # @retval True Successfully find a token unit, file buffer pointer moved forward\r
1082 # @retval False Not able to find a token unit, file buffer pointer not changed\r
1083 #\r
1084 def __GetNextToken(self):\r
1085 # Skip leading spaces, if exist.\r
1086 self.__SkipWhiteSpace()\r
1087 if self.__EndOfFile():\r
1088 return False\r
1089 # Record the token start position, the position of the first non-space char.\r
1090 StartPos = self.CurrentOffsetWithinLine\r
1091 StartLine = self.CurrentLineNumber\r
d0acc87a 1092 while StartLine == self.CurrentLineNumber:\r
30fdf114
LG
1093 TempChar = self.__CurrentChar()\r
1094 # Try to find the end char that is not a space and not in seperator tuple.\r
1095 # That is, when we got a space or any char in the tuple, we got the end of token.\r
1096 if not str(TempChar).isspace() and TempChar not in SEPERATOR_TUPLE:\r
1097 self.__GetOneChar()\r
1098 # if we happen to meet a seperator as the first char, we must proceed to get it.\r
1099 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.\r
1100 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:\r
1101 self.__GetOneChar()\r
1102 break\r
1103 else:\r
1104 break\r
1105# else:\r
1106# return False\r
1107\r
1108 EndPos = self.CurrentOffsetWithinLine\r
1109 if self.CurrentLineNumber != StartLine:\r
1110 EndPos = len(self.Profile.FileLinesList[StartLine-1])\r
1111 self.__Token = self.Profile.FileLinesList[StartLine-1][StartPos : EndPos]\r
1112 if StartPos != self.CurrentOffsetWithinLine:\r
1113 return True\r
1114 else:\r
1115 return False\r
1116\r
1117 def __GetNextOp(self):\r
1118 # Skip leading spaces, if exist.\r
1119 self.__SkipWhiteSpace()\r
1120 if self.__EndOfFile():\r
1121 return False\r
1122 # Record the token start position, the position of the first non-space char.\r
1123 StartPos = self.CurrentOffsetWithinLine\r
1124 while not self.__EndOfLine():\r
1125 TempChar = self.__CurrentChar()\r
1126 # Try to find the end char that is not a space\r
1127 if not str(TempChar).isspace():\r
1128 self.__GetOneChar()\r
1129 else:\r
1130 break\r
1131 else:\r
1132 return False\r
1133\r
1134 if StartPos != self.CurrentOffsetWithinLine:\r
1135 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]\r
1136 return True\r
1137 else:\r
1138 return False\r
1139 ## __GetNextGuid() method\r
1140 #\r
1141 # Get next token unit before a seperator\r
1142 # If found, the GUID string is put into self.__Token\r
1143 #\r
1144 # @param self The object pointer\r
1145 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward\r
1146 # @retval False Not able to find a registry format GUID, file buffer pointer not changed\r
1147 #\r
1148 def __GetNextGuid(self):\r
1149\r
1150 if not self.__GetNextToken():\r
1151 return False\r
1152 p = re.compile('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}')\r
1153 if p.match(self.__Token) != None:\r
1154 return True\r
1155 else:\r
1156 self.__UndoToken()\r
1157 return False\r
1158\r
91ae2988
YZ
1159 def __Verify(self, Name, Value, Scope):\r
1160 if Scope in ['UINT64', 'UINT8']:\r
1161 ValueNumber = 0\r
1162 try:\r
1163 if Value.upper().startswith('0X'):\r
1164 ValueNumber = int (Value, 16)\r
1165 else:\r
1166 ValueNumber = int (Value)\r
1167 except:\r
1168 EdkLogger.error("FdfParser", FORMAT_INVALID, "The value is not valid dec or hex number for %s." % Name)\r
1169 if ValueNumber < 0:\r
1170 EdkLogger.error("FdfParser", FORMAT_INVALID, "The value can't be set to negative value for %s." % Name)\r
1171 if Scope == 'UINT64':\r
1172 if ValueNumber >= 0x10000000000000000:\r
1173 EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name)\r
1174 if Scope == 'UINT8':\r
1175 if ValueNumber >= 0x100:\r
1176 EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name)\r
1177 return True\r
1178\r
30fdf114
LG
1179 ## __UndoToken() method\r
1180 #\r
1181 # Go back one token unit in file buffer\r
1182 #\r
1183 # @param self The object pointer\r
1184 #\r
1185 def __UndoToken(self):\r
1186 self.__UndoOneChar()\r
1187 while self.__CurrentChar().isspace():\r
1188 if not self.__UndoOneChar():\r
1189 self.__GetOneChar()\r
1190 return\r
1191\r
1192\r
1193 StartPos = self.CurrentOffsetWithinLine\r
1194 CurrentLine = self.CurrentLineNumber\r
1195 while CurrentLine == self.CurrentLineNumber:\r
1196\r
1197 TempChar = self.__CurrentChar()\r
1198 # Try to find the end char that is not a space and not in seperator tuple.\r
1199 # That is, when we got a space or any char in the tuple, we got the end of token.\r
1200 if not str(TempChar).isspace() and not TempChar in SEPERATOR_TUPLE:\r
1201 if not self.__UndoOneChar():\r
d0acc87a 1202 return\r
30fdf114
LG
1203 # if we happen to meet a seperator as the first char, we must proceed to get it.\r
1204 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.\r
1205 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:\r
1206 return\r
1207 else:\r
1208 break\r
1209\r
1210 self.__GetOneChar()\r
1211\r
1212 ## __HexDigit() method\r
1213 #\r
1214 # Whether char input is a Hex data bit\r
1215 #\r
1216 # @param self The object pointer\r
1217 # @param TempChar The char to test\r
1218 # @retval True The char is a Hex data bit\r
1219 # @retval False The char is NOT a Hex data bit\r
1220 #\r
1221 def __HexDigit(self, TempChar):\r
1222 if (TempChar >= 'a' and TempChar <= 'f') or (TempChar >= 'A' and TempChar <= 'F') \\r
1223 or (TempChar >= '0' and TempChar <= '9'):\r
1224 return True\r
1225 else:\r
1226 return False\r
1227\r
1228 def __IsHex(self, HexStr):\r
1229 if not HexStr.upper().startswith("0X"):\r
1230 return False\r
1231 if len(self.__Token) <= 2:\r
1232 return False\r
1233 charList = [c for c in HexStr[2 : ] if not self.__HexDigit( c)]\r
1234 if len(charList) == 0:\r
1235 return True\r
1236 else:\r
1237 return False\r
1238 ## __GetNextHexNumber() method\r
1239 #\r
1240 # Get next HEX data before a seperator\r
1241 # If found, the HEX data is put into self.__Token\r
1242 #\r
1243 # @param self The object pointer\r
1244 # @retval True Successfully find a HEX data, file buffer pointer moved forward\r
1245 # @retval False Not able to find a HEX data, file buffer pointer not changed\r
1246 #\r
1247 def __GetNextHexNumber(self):\r
1248 if not self.__GetNextToken():\r
1249 return False\r
1250 if self.__IsHex(self.__Token):\r
1251 return True\r
1252 else:\r
1253 self.__UndoToken()\r
1254 return False\r
1255\r
1256 ## __GetNextDecimalNumber() method\r
1257 #\r
1258 # Get next decimal data before a seperator\r
1259 # If found, the decimal data is put into self.__Token\r
1260 #\r
1261 # @param self The object pointer\r
1262 # @retval True Successfully find a decimal data, file buffer pointer moved forward\r
1263 # @retval False Not able to find a decimal data, file buffer pointer not changed\r
1264 #\r
1265 def __GetNextDecimalNumber(self):\r
1266 if not self.__GetNextToken():\r
1267 return False\r
1268 if self.__Token.isdigit():\r
1269 return True\r
1270 else:\r
1271 self.__UndoToken()\r
1272 return False\r
1273\r
1274 ## __GetNextPcdName() method\r
1275 #\r
1276 # Get next PCD token space C name and PCD C name pair before a seperator\r
1277 # If found, the decimal data is put into self.__Token\r
1278 #\r
1279 # @param self The object pointer\r
1280 # @retval Tuple PCD C name and PCD token space C name pair\r
1281 #\r
1282 def __GetNextPcdName(self):\r
1283 if not self.__GetNextWord():\r
1284 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)\r
1285 pcdTokenSpaceCName = self.__Token\r
1286\r
1287 if not self.__IsToken( "."):\r
1288 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)\r
1289\r
1290 if not self.__GetNextWord():\r
1291 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)\r
1292 pcdCName = self.__Token\r
1293\r
1294 return (pcdCName, pcdTokenSpaceCName)\r
1295\r
1296 ## __GetStringData() method\r
1297 #\r
1298 # Get string contents quoted in ""\r
1299 # If found, the decimal data is put into self.__Token\r
1300 #\r
1301 # @param self The object pointer\r
1302 # @retval True Successfully find a string data, file buffer pointer moved forward\r
1303 # @retval False Not able to find a string data, file buffer pointer not changed\r
1304 #\r
1305 def __GetStringData(self):\r
1306 if self.__Token.startswith("\"") or self.__Token.startswith("L\""):\r
1307 self.__UndoToken()\r
1308 self.__SkipToToken("\"")\r
1309 currentLineNumber = self.CurrentLineNumber\r
1310\r
1311 if not self.__SkipToToken("\""):\r
1312 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber)\r
1313 if currentLineNumber != self.CurrentLineNumber:\r
1314 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber)\r
1315 self.__Token = self.__SkippedChars.rstrip('\"')\r
1316 return True\r
1317\r
1318 elif self.__Token.startswith("\'") or self.__Token.startswith("L\'"):\r
1319 self.__UndoToken()\r
1320 self.__SkipToToken("\'")\r
1321 currentLineNumber = self.CurrentLineNumber\r
1322\r
1323 if not self.__SkipToToken("\'"):\r
1324 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber)\r
1325 if currentLineNumber != self.CurrentLineNumber:\r
1326 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber)\r
1327 self.__Token = self.__SkippedChars.rstrip('\'')\r
1328 return True\r
1329\r
1330 else:\r
1331 return False\r
1332\r
1333 ## __SkipToToken() method\r
1334 #\r
1335 # Search forward in file buffer for the string\r
1336 # The skipped chars are put into self.__SkippedChars\r
1337 #\r
1338 # @param self The object pointer\r
1339 # @param String The string to search\r
1340 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive\r
1341 # @retval True Successfully find the string, file buffer pointer moved forward\r
1342 # @retval False Not able to find the string, file buffer pointer not changed\r
1343 #\r
1344 def __SkipToToken(self, String, IgnoreCase = False):\r
1345 StartPos = self.GetFileBufferPos()\r
1346\r
1347 self.__SkippedChars = ""\r
1348 while not self.__EndOfFile():\r
1349 index = -1\r
1350 if IgnoreCase:\r
1351 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())\r
1352 else:\r
1353 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)\r
1354 if index == 0:\r
1355 self.CurrentOffsetWithinLine += len(String)\r
1356 self.__SkippedChars += String\r
1357 return True\r
1358 self.__SkippedChars += str(self.__CurrentChar())\r
1359 self.__GetOneChar()\r
1360\r
1361 self.SetFileBufferPos( StartPos)\r
1362 self.__SkippedChars = ""\r
1363 return False\r
1364\r
1365 ## GetFileBufferPos() method\r
1366 #\r
1367 # Return the tuple of current line and offset within the line\r
1368 #\r
1369 # @param self The object pointer\r
1370 # @retval Tuple Line number and offset pair\r
1371 #\r
1372 def GetFileBufferPos(self):\r
1373 return (self.CurrentLineNumber, self.CurrentOffsetWithinLine)\r
1374\r
1375 ## SetFileBufferPos() method\r
1376 #\r
1377 # Restore the file buffer position\r
1378 #\r
1379 # @param self The object pointer\r
1380 # @param Pos The new file buffer position\r
1381 #\r
1382 def SetFileBufferPos(self, Pos):\r
1383 (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos\r
1384\r
d40b2ee6
LG
1385 ## Preprocess() method\r
1386 #\r
1387 # Preprocess comment, conditional directive, include directive, replace macro.\r
1388 # Exception will be raised if syntax error found\r
1389 #\r
1390 # @param self The object pointer\r
1391 #\r
1392 def Preprocess(self):\r
1393 self.__StringToList()\r
1394 self.PreprocessFile()\r
1395 self.PreprocessIncludeFile()\r
1396 self.__StringToList()\r
1397 self.PreprocessFile()\r
1398 self.PreprocessConditionalStatement()\r
1399 self.__StringToList()\r
1400 for Pos in self.__WipeOffArea:\r
1401 self.__ReplaceFragment(Pos[0], Pos[1])\r
1402 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]\r
1403\r
1404 while self.__GetDefines():\r
1405 pass\r
d40b2ee6 1406\r
30fdf114
LG
1407 ## ParseFile() method\r
1408 #\r
1409 # Parse the file profile buffer to extract fd, fv ... information\r
1410 # Exception will be raised if syntax error found\r
1411 #\r
1412 # @param self The object pointer\r
1413 #\r
1414 def ParseFile(self):\r
1415\r
1416 try:\r
d40b2ee6 1417 self.Preprocess()\r
dd170333
MK
1418 #\r
1419 # Keep processing sections of the FDF until no new sections or a syntax error is found\r
1420 #\r
1421 while self.__GetFd() or self.__GetFv() or self.__GetFmp() or self.__GetCapsule() or self.__GetVtf() or self.__GetRule() or self.__GetOptionRom():\r
30fdf114
LG
1422 pass\r
1423\r
1424 except Warning, X:\r
1425 self.__UndoToken()\r
30fdf114 1426 #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \\r
118bf096
CS
1427 # At this point, the closest parent would be the included file itself\r
1428 Profile = GetParentAtLine(X.OriginalLineNumber)\r
1429 if Profile != None:\r
1430 X.Message += ' near line %d, column %d: %s' \\r
1431 % (X.LineNumber, 0, Profile.FileLinesList[X.LineNumber-1])\r
1432 else:\r
1433 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1434 X.Message += ' near line %d, column %d: %s' \\r
30fdf114
LG
1435 % (FileLineTuple[1], self.CurrentOffsetWithinLine + 1, self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :].rstrip('\n').rstrip('\r'))\r
1436 raise\r
1437\r
df81077f
YZ
1438 ## SectionParser() method\r
1439 #\r
1440 # Parse the file section info\r
1441 # Exception will be raised if syntax error found\r
1442 #\r
1443 # @param self The object pointer\r
1444 # @param section The section string\r
1445\r
1446 def SectionParser(self, section):\r
1447 S = section.upper()\r
1448 if not S.startswith("[DEFINES") and not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \\r
1449 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM.") and not S.startswith('[FMPPAYLOAD.'):\r
1450 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
1451\r
30fdf114
LG
1452 ## __GetDefines() method\r
1453 #\r
1454 # Get Defines section contents and store its data into AllMacrosList\r
1455 #\r
1456 # @param self The object pointer\r
1457 # @retval True Successfully find a Defines\r
1458 # @retval False Not able to find a Defines\r
1459 #\r
1460 def __GetDefines(self):\r
1461\r
1462 if not self.__GetNextToken():\r
1463 return False\r
1464\r
1465 S = self.__Token.upper()\r
1466 if S.startswith("[") and not S.startswith("[DEFINES"):\r
df81077f 1467 self.SectionParser(S)\r
30fdf114
LG
1468 self.__UndoToken()\r
1469 return False\r
1470\r
1471 self.__UndoToken()\r
1472 if not self.__IsToken("[DEFINES", True):\r
1473 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1474 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
1475 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
1476 raise Warning("expected [DEFINES", self.FileName, self.CurrentLineNumber)\r
1477\r
1478 if not self.__IsToken( "]"):\r
1479 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
1480\r
1481 while self.__GetNextWord():\r
6780eef1
LG
1482 # handle the SET statement\r
1483 if self.__Token == 'SET':\r
1484 self.__UndoToken()\r
1485 self.__GetSetStatement(None)\r
1486 continue\r
1487 \r
30fdf114
LG
1488 Macro = self.__Token\r
1489 \r
1490 if not self.__IsToken("="):\r
1491 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1492 if not self.__GetNextToken() or self.__Token.startswith('['):\r
1493 raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber)\r
1494 Value = self.__Token\r
30fdf114
LG
1495\r
1496 return False\r
1497\r
1498 ## __GetFd() method\r
1499 #\r
1500 # Get FD section contents and store its data into FD dictionary of self.Profile\r
1501 #\r
1502 # @param self The object pointer\r
1503 # @retval True Successfully find a FD\r
1504 # @retval False Not able to find a FD\r
1505 #\r
1506 def __GetFd(self):\r
1507\r
1508 if not self.__GetNextToken():\r
1509 return False\r
1510\r
1511 S = self.__Token.upper()\r
1512 if S.startswith("[") and not S.startswith("[FD."):\r
a3251d84 1513 if not S.startswith("[FV.") and not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \\r
30fdf114
LG
1514 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
1515 raise Warning("Unknown section", self.FileName, self.CurrentLineNumber)\r
1516 self.__UndoToken()\r
1517 return False\r
1518\r
1519 self.__UndoToken()\r
1520 if not self.__IsToken("[FD.", True):\r
1521 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1522 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
1523 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
1524 raise Warning("expected [FD.]", self.FileName, self.CurrentLineNumber)\r
1525\r
1526 FdName = self.__GetUiName()\r
52302d4d
LG
1527 if FdName == "":\r
1528 if len (self.Profile.FdDict) == 0:\r
1529 FdName = GenFdsGlobalVariable.PlatformName\r
d0acc87a
LG
1530 if FdName == "" and GlobalData.gActivePlatform:\r
1531 FdName = GlobalData.gActivePlatform.PlatformName\r
52302d4d
LG
1532 self.Profile.FdNameNotSet = True\r
1533 else:\r
1534 raise Warning("expected FdName in [FD.] section", self.FileName, self.CurrentLineNumber)\r
30fdf114 1535 self.CurrentFdName = FdName.upper()\r
52302d4d
LG
1536 \r
1537 if self.CurrentFdName in self.Profile.FdDict:\r
1538 raise Warning("Unexpected the same FD name", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
1539\r
1540 if not self.__IsToken( "]"):\r
1541 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
1542\r
1543 FdObj = Fd.FD()\r
1544 FdObj.FdUiName = self.CurrentFdName\r
1545 self.Profile.FdDict[self.CurrentFdName] = FdObj\r
52302d4d
LG
1546\r
1547 if len (self.Profile.FdDict) > 1 and self.Profile.FdNameNotSet:\r
1548 raise Warning("expected all FDs have their name", self.FileName, self.CurrentLineNumber)\r
1549\r
30fdf114
LG
1550 Status = self.__GetCreateFile(FdObj)\r
1551 if not Status:\r
1552 raise Warning("FD name error", self.FileName, self.CurrentLineNumber)\r
1553\r
e8a47801
LG
1554 while self.__GetTokenStatements(FdObj):\r
1555 pass\r
1556 for Attr in ("BaseAddress", "Size", "ErasePolarity"):\r
1557 if getattr(FdObj, Attr) == None:\r
1558 self.__GetNextToken()\r
1559 raise Warning("Keyword %s missing" % Attr, self.FileName, self.CurrentLineNumber)\r
1560\r
1561 if not FdObj.BlockSizeList:\r
1562 FdObj.BlockSizeList.append((1, FdObj.Size, None))\r
30fdf114
LG
1563\r
1564 self.__GetDefineStatements(FdObj)\r
1565\r
1566 self.__GetSetStatements(FdObj)\r
1567\r
1568 if not self.__GetRegionLayout(FdObj):\r
1569 raise Warning("expected region layout", self.FileName, self.CurrentLineNumber)\r
1570\r
1571 while self.__GetRegionLayout(FdObj):\r
1572 pass\r
1573 return True\r
1574\r
1575 ## __GetUiName() method\r
1576 #\r
1577 # Return the UI name of a section\r
1578 #\r
1579 # @param self The object pointer\r
1580 # @retval FdName UI name\r
1581 #\r
1582 def __GetUiName(self):\r
1583 Name = ""\r
1584 if self.__GetNextWord():\r
1585 Name = self.__Token\r
1586\r
1587 return Name\r
1588\r
1589 ## __GetCreateFile() method\r
1590 #\r
1591 # Return the output file name of object\r
1592 #\r
1593 # @param self The object pointer\r
1594 # @param Obj object whose data will be stored in file\r
1595 # @retval FdName UI name\r
1596 #\r
1597 def __GetCreateFile(self, Obj):\r
1598\r
1599 if self.__IsKeyword( "CREATE_FILE"):\r
1600 if not self.__IsToken( "="):\r
1601 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1602\r
1603 if not self.__GetNextToken():\r
1604 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)\r
1605\r
1606 FileName = self.__Token\r
1607 Obj.CreateFileName = FileName\r
1608\r
1609 return True\r
1610\r
1611 ## __GetTokenStatements() method\r
1612 #\r
1613 # Get token statements\r
1614 #\r
1615 # @param self The object pointer\r
1616 # @param Obj for whom token statement is got\r
30fdf114
LG
1617 #\r
1618 def __GetTokenStatements(self, Obj):\r
e8a47801
LG
1619 if self.__IsKeyword( "BaseAddress"):\r
1620 if not self.__IsToken( "="):\r
1621 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1622 \r
1623 if not self.__GetNextHexNumber():\r
1624 raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber)\r
1625 \r
1626 Obj.BaseAddress = self.__Token\r
1627 \r
1628 if self.__IsToken( "|"):\r
1629 pcdPair = self.__GetNextPcdName()\r
1630 Obj.BaseAddressPcd = pcdPair\r
1631 self.Profile.PcdDict[pcdPair] = Obj.BaseAddress\r
1632 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1633 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple\r
1634 return True\r
30fdf114 1635\r
e8a47801
LG
1636 if self.__IsKeyword( "Size"):\r
1637 if not self.__IsToken( "="):\r
1638 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1639 \r
1640 if not self.__GetNextHexNumber():\r
1641 raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber)\r
30fdf114 1642\r
e8a47801
LG
1643 Size = self.__Token\r
1644 if self.__IsToken( "|"):\r
1645 pcdPair = self.__GetNextPcdName()\r
1646 Obj.SizePcd = pcdPair\r
1647 self.Profile.PcdDict[pcdPair] = Size\r
1648 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1649 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple\r
1650 Obj.Size = long(Size, 0)\r
1651 return True\r
30fdf114 1652\r
e8a47801
LG
1653 if self.__IsKeyword( "ErasePolarity"):\r
1654 if not self.__IsToken( "="):\r
1655 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1656 \r
1657 if not self.__GetNextToken():\r
1658 raise Warning("expected Erase Polarity", self.FileName, self.CurrentLineNumber)\r
1659 \r
1660 if self.__Token != "1" and self.__Token != "0":\r
1661 raise Warning("expected 1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)\r
1662 \r
1663 Obj.ErasePolarity = self.__Token\r
1664 return True\r
30fdf114 1665\r
e8a47801 1666 return self.__GetBlockStatements(Obj)\r
30fdf114
LG
1667\r
1668 ## __GetAddressStatements() method\r
1669 #\r
1670 # Get address statements\r
1671 #\r
1672 # @param self The object pointer\r
1673 # @param Obj for whom address statement is got\r
1674 # @retval True Successfully find\r
1675 # @retval False Not able to find\r
1676 #\r
1677 def __GetAddressStatements(self, Obj):\r
1678\r
1679 if self.__IsKeyword("BsBaseAddress"):\r
1680 if not self.__IsToken( "="):\r
1681 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1682\r
1683 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():\r
1684 raise Warning("expected address", self.FileName, self.CurrentLineNumber)\r
1685\r
1686 BsAddress = long(self.__Token, 0)\r
1687 Obj.BsBaseAddress = BsAddress\r
1688\r
1689 if self.__IsKeyword("RtBaseAddress"):\r
1690 if not self.__IsToken( "="):\r
1691 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1692\r
1693 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():\r
1694 raise Warning("expected address", self.FileName, self.CurrentLineNumber)\r
1695\r
1696 RtAddress = long(self.__Token, 0)\r
1697 Obj.RtBaseAddress = RtAddress\r
1698\r
1699 ## __GetBlockStatements() method\r
1700 #\r
1701 # Get block statements\r
1702 #\r
1703 # @param self The object pointer\r
1704 # @param Obj for whom block statement is got\r
30fdf114
LG
1705 #\r
1706 def __GetBlockStatements(self, Obj):\r
e8a47801 1707 IsBlock = False\r
30fdf114 1708 while self.__GetBlockStatement(Obj):\r
e8a47801 1709 IsBlock = True\r
52302d4d 1710 \r
e8a47801 1711 Item = Obj.BlockSizeList[-1]\r
52302d4d 1712 if Item[0] == None or Item[1] == None:\r
6780eef1 1713 raise Warning("expected block statement", self.FileName, self.CurrentLineNumber)\r
e8a47801 1714 return IsBlock\r
30fdf114
LG
1715\r
1716 ## __GetBlockStatement() method\r
1717 #\r
1718 # Get block statement\r
1719 #\r
1720 # @param self The object pointer\r
1721 # @param Obj for whom block statement is got\r
1722 # @retval True Successfully find\r
1723 # @retval False Not able to find\r
1724 #\r
1725 def __GetBlockStatement(self, Obj):\r
1726 if not self.__IsKeyword( "BlockSize"):\r
1727 return False\r
1728\r
1729 if not self.__IsToken( "="):\r
1730 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1731\r
1732 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():\r
6780eef1 1733 raise Warning("expected Hex or Integer block size", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
1734\r
1735 BlockSize = self.__Token\r
1736 BlockSizePcd = None\r
1737 if self.__IsToken( "|"):\r
1738 PcdPair = self.__GetNextPcdName()\r
1739 BlockSizePcd = PcdPair\r
1740 self.Profile.PcdDict[PcdPair] = BlockSize\r
d0acc87a
LG
1741 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1742 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple\r
52302d4d 1743 BlockSize = long(BlockSize, 0)\r
30fdf114
LG
1744\r
1745 BlockNumber = None\r
1746 if self.__IsKeyword( "NumBlocks"):\r
1747 if not self.__IsToken( "="):\r
1748 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1749\r
1750 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():\r
1751 raise Warning("expected block numbers", self.FileName, self.CurrentLineNumber)\r
1752\r
1753 BlockNumber = long(self.__Token, 0)\r
1754\r
1755 Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd))\r
1756 return True\r
1757\r
1758 ## __GetDefineStatements() method\r
1759 #\r
1760 # Get define statements\r
1761 #\r
1762 # @param self The object pointer\r
1763 # @param Obj for whom define statement is got\r
1764 # @retval True Successfully find\r
1765 # @retval False Not able to find\r
1766 #\r
1767 def __GetDefineStatements(self, Obj):\r
1768 while self.__GetDefineStatement( Obj):\r
1769 pass\r
1770\r
1771 ## __GetDefineStatement() method\r
1772 #\r
1773 # Get define statement\r
1774 #\r
1775 # @param self The object pointer\r
1776 # @param Obj for whom define statement is got\r
1777 # @retval True Successfully find\r
1778 # @retval False Not able to find\r
1779 #\r
1780 def __GetDefineStatement(self, Obj):\r
1781 if self.__IsKeyword("DEFINE"):\r
1782 self.__GetNextToken()\r
1783 Macro = self.__Token\r
1784 if not self.__IsToken( "="):\r
1785 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1786\r
1787 if not self.__GetNextToken():\r
1788 raise Warning("expected value", self.FileName, self.CurrentLineNumber)\r
1789\r
1790 Value = self.__Token\r
1791 Macro = '$(' + Macro + ')'\r
1792 Obj.DefineVarDict[Macro] = Value\r
1793 return True\r
1794\r
1795 return False\r
1796\r
1797 ## __GetSetStatements() method\r
1798 #\r
1799 # Get set statements\r
1800 #\r
1801 # @param self The object pointer\r
1802 # @param Obj for whom set statement is got\r
1803 # @retval True Successfully find\r
1804 # @retval False Not able to find\r
1805 #\r
1806 def __GetSetStatements(self, Obj):\r
1807 while self.__GetSetStatement(Obj):\r
1808 pass\r
1809\r
1810 ## __GetSetStatement() method\r
1811 #\r
1812 # Get set statement\r
1813 #\r
1814 # @param self The object pointer\r
1815 # @param Obj for whom set statement is got\r
1816 # @retval True Successfully find\r
1817 # @retval False Not able to find\r
1818 #\r
1819 def __GetSetStatement(self, Obj):\r
1820 if self.__IsKeyword("SET"):\r
1821 PcdPair = self.__GetNextPcdName()\r
1822\r
1823 if not self.__IsToken( "="):\r
1824 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1825\r
d0acc87a
LG
1826 Value = self.__GetExpression()\r
1827 Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)\r
30fdf114 1828\r
6780eef1
LG
1829 if Obj:\r
1830 Obj.SetVarDict[PcdPair] = Value\r
30fdf114 1831 self.Profile.PcdDict[PcdPair] = Value\r
d0acc87a
LG
1832 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1833 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple\r
30fdf114
LG
1834 return True\r
1835\r
1836 return False\r
1837\r
4afd3d04
LG
1838 ## __CalcRegionExpr(self)\r
1839 #\r
1840 # Calculate expression for offset or size of a region\r
1841 #\r
1842 # @return: None if invalid expression\r
1843 # Calculated number if successfully\r
1844 #\r
1845 def __CalcRegionExpr(self):\r
1846 StartPos = self.GetFileBufferPos()\r
1847 Expr = ''\r
1848 PairCount = 0\r
1849 while not self.__EndOfFile():\r
1850 CurCh = self.__CurrentChar()\r
1851 if CurCh == '(':\r
1852 PairCount += 1\r
1853 elif CurCh == ')':\r
1854 PairCount -= 1\r
1855\r
1856 if CurCh in '|\r\n' and PairCount == 0:\r
1857 break\r
1858 Expr += CurCh\r
1859 self.__GetOneChar()\r
1860 try:\r
1861 return long(\r
1862 ValueExpression(Expr,\r
2bc3256c 1863 self.__CollectMacroPcd()\r
4afd3d04
LG
1864 )(True),0)\r
1865 except Exception:\r
1866 self.SetFileBufferPos(StartPos)\r
1867 return None\r
1868\r
30fdf114
LG
1869 ## __GetRegionLayout() method\r
1870 #\r
1871 # Get region layout for FD\r
1872 #\r
1873 # @param self The object pointer\r
1874 # @param Fd for whom region is got\r
1875 # @retval True Successfully find\r
1876 # @retval False Not able to find\r
1877 #\r
1878 def __GetRegionLayout(self, Fd):\r
4afd3d04
LG
1879 Offset = self.__CalcRegionExpr() \r
1880 if Offset == None:\r
30fdf114
LG
1881 return False\r
1882\r
1883 RegionObj = Region.Region()\r
4afd3d04 1884 RegionObj.Offset = Offset\r
30fdf114
LG
1885 Fd.RegionList.append(RegionObj)\r
1886\r
1887 if not self.__IsToken( "|"):\r
1888 raise Warning("expected '|'", self.FileName, self.CurrentLineNumber)\r
1889\r
4afd3d04
LG
1890 Size = self.__CalcRegionExpr()\r
1891 if Size == None:\r
30fdf114 1892 raise Warning("expected Region Size", self.FileName, self.CurrentLineNumber)\r
4afd3d04 1893 RegionObj.Size = Size\r
30fdf114
LG
1894\r
1895 if not self.__GetNextWord():\r
1896 return True\r
1897\r
b21a13fb 1898 if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE", "INF"):\r
2bc3256c
LG
1899 #\r
1900 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]\r
1901 # Or it might be next region's offset described by an expression which starts with a PCD.\r
1902 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size\r
1903 #\r
30fdf114 1904 self.__UndoToken()\r
2bc3256c
LG
1905 IsRegionPcd = (RegionSizeGuidPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]) or\r
1906 RegionOffsetPcdPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]))\r
1907 if IsRegionPcd:\r
1908 RegionObj.PcdOffset = self.__GetNextPcdName()\r
1909 self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0))\r
1910 self.__PcdDict['%s.%s' % (RegionObj.PcdOffset[1], RegionObj.PcdOffset[0])] = "0x%x" % RegionObj.Offset\r
d0acc87a 1911 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2bc3256c
LG
1912 self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple\r
1913 if self.__IsToken( "|"):\r
1914 RegionObj.PcdSize = self.__GetNextPcdName()\r
1915 self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size\r
1916 self.__PcdDict['%s.%s' % (RegionObj.PcdSize[1], RegionObj.PcdSize[0])] = "0x%x" % RegionObj.Size\r
1917 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1918 self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple\r
30fdf114
LG
1919\r
1920 if not self.__GetNextWord():\r
1921 return True\r
1922\r
1923 if self.__Token == "SET":\r
1924 self.__UndoToken()\r
1925 self.__GetSetStatements( RegionObj)\r
1926 if not self.__GetNextWord():\r
1927 return True\r
1928\r
fd171542 1929 elif self.__Token == "FV":\r
30fdf114
LG
1930 self.__UndoToken()\r
1931 self.__GetRegionFvType( RegionObj)\r
1932\r
fd171542 1933 elif self.__Token == "CAPSULE":\r
1934 self.__UndoToken()\r
1935 self.__GetRegionCapType( RegionObj)\r
1936\r
30fdf114
LG
1937 elif self.__Token == "FILE":\r
1938 self.__UndoToken()\r
b21a13fb
YZ
1939 self.__GetRegionFileType(RegionObj)\r
1940\r
1941 elif self.__Token == "INF":\r
1942 self.__UndoToken()\r
1943 RegionObj.RegionType = "INF"\r
1944 while self.__IsKeyword("INF"):\r
1945 self.__UndoToken()\r
1946 ffsInf = self.__ParseInfStatement()\r
1947 if not ffsInf:\r
1948 break\r
1949 RegionObj.RegionDataList.append(ffsInf)\r
30fdf114 1950\r
79b74a03 1951 elif self.__Token == "DATA":\r
30fdf114 1952 self.__UndoToken()\r
b21a13fb 1953 self.__GetRegionDataType(RegionObj)\r
79b74a03 1954 else:\r
2bc3256c
LG
1955 self.__UndoToken()\r
1956 if self.__GetRegionLayout(Fd):\r
1957 return True\r
79b74a03 1958 raise Warning("A valid region type was not found. "\r
b21a13fb 1959 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",\r
79b74a03 1960 self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
1961\r
1962 return True\r
1963\r
1964 ## __GetRegionFvType() method\r
1965 #\r
1966 # Get region fv data for region\r
1967 #\r
1968 # @param self The object pointer\r
1969 # @param RegionObj for whom region data is got\r
1970 #\r
1971 def __GetRegionFvType(self, RegionObj):\r
1972\r
1973 if not self.__IsKeyword( "FV"):\r
1974 raise Warning("expected Keyword 'FV'", self.FileName, self.CurrentLineNumber)\r
1975\r
1976 if not self.__IsToken( "="):\r
1977 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1978\r
1979 if not self.__GetNextToken():\r
1980 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)\r
1981\r
1982 RegionObj.RegionType = "FV"\r
0199377c 1983 RegionObj.RegionDataList.append((self.__Token).upper())\r
30fdf114
LG
1984\r
1985 while self.__IsKeyword( "FV"):\r
1986\r
1987 if not self.__IsToken( "="):\r
1988 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1989\r
1990 if not self.__GetNextToken():\r
1991 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)\r
1992\r
0199377c 1993 RegionObj.RegionDataList.append((self.__Token).upper())\r
30fdf114 1994\r
fd171542 1995 ## __GetRegionCapType() method\r
1996 #\r
1997 # Get region capsule data for region\r
1998 #\r
1999 # @param self The object pointer\r
2000 # @param RegionObj for whom region data is got\r
2001 #\r
2002 def __GetRegionCapType(self, RegionObj):\r
2003\r
2004 if not self.__IsKeyword("CAPSULE"):\r
2005 raise Warning("expected Keyword 'CAPSULE'", self.FileName, self.CurrentLineNumber)\r
2006\r
2007 if not self.__IsToken("="):\r
2008 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2009\r
2010 if not self.__GetNextToken():\r
2011 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)\r
2012\r
2013 RegionObj.RegionType = "CAPSULE"\r
2014 RegionObj.RegionDataList.append(self.__Token)\r
2015\r
2016 while self.__IsKeyword("CAPSULE"):\r
2017\r
2018 if not self.__IsToken("="):\r
2019 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2020\r
2021 if not self.__GetNextToken():\r
2022 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)\r
2023\r
2024 RegionObj.RegionDataList.append(self.__Token)\r
2025\r
30fdf114
LG
2026 ## __GetRegionFileType() method\r
2027 #\r
2028 # Get region file data for region\r
2029 #\r
2030 # @param self The object pointer\r
2031 # @param RegionObj for whom region data is got\r
2032 #\r
2033 def __GetRegionFileType(self, RegionObj):\r
2034\r
2035 if not self.__IsKeyword( "FILE"):\r
2036 raise Warning("expected Keyword 'FILE'", self.FileName, self.CurrentLineNumber)\r
2037\r
2038 if not self.__IsToken( "="):\r
2039 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2040\r
2041 if not self.__GetNextToken():\r
2042 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)\r
2043\r
2044 RegionObj.RegionType = "FILE"\r
2045 RegionObj.RegionDataList.append( self.__Token)\r
2046\r
2047 while self.__IsKeyword( "FILE"):\r
2048\r
2049 if not self.__IsToken( "="):\r
2050 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2051\r
2052 if not self.__GetNextToken():\r
2053 raise Warning("expected FILE name", self.FileName, self.CurrentLineNumber)\r
2054\r
2055 RegionObj.RegionDataList.append(self.__Token)\r
2056\r
2057 ## __GetRegionDataType() method\r
2058 #\r
2059 # Get region array data for region\r
2060 #\r
2061 # @param self The object pointer\r
2062 # @param RegionObj for whom region data is got\r
2063 #\r
2064 def __GetRegionDataType(self, RegionObj):\r
2065\r
2066 if not self.__IsKeyword( "DATA"):\r
2067 raise Warning("expected Region Data type", self.FileName, self.CurrentLineNumber)\r
2068\r
2069 if not self.__IsToken( "="):\r
2070 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2071\r
2072 if not self.__IsToken( "{"):\r
2073 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2074\r
2075 if not self.__GetNextHexNumber():\r
2076 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)\r
2077\r
636f2be6
LG
2078 if len(self.__Token) > 18:\r
2079 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)\r
2080\r
2081 # convert hex string value to byte hex string array\r
2082 AllString = self.__Token\r
2083 AllStrLen = len (AllString)\r
2084 DataString = ""\r
2085 while AllStrLen > 4:\r
2086 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","\r
2087 AllStrLen = AllStrLen - 2\r
2088 DataString = DataString + AllString[:AllStrLen] + ","\r
2089\r
2090 # byte value array\r
2091 if len (self.__Token) <= 4:\r
2092 while self.__IsToken(","):\r
2093 if not self.__GetNextHexNumber():\r
2094 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
2095 if len(self.__Token) > 4:\r
2096 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
2097 DataString += self.__Token\r
2098 DataString += ","\r
30fdf114
LG
2099\r
2100 if not self.__IsToken( "}"):\r
2101 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2102\r
2103 DataString = DataString.rstrip(",")\r
2104 RegionObj.RegionType = "DATA"\r
2105 RegionObj.RegionDataList.append( DataString)\r
2106\r
2107 while self.__IsKeyword( "DATA"):\r
2108\r
2109 if not self.__IsToken( "="):\r
2110 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2111\r
2112 if not self.__IsToken( "{"):\r
2113 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2114\r
2115 if not self.__GetNextHexNumber():\r
2116 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)\r
2117\r
636f2be6
LG
2118 if len(self.__Token) > 18:\r
2119 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)\r
2120\r
2121 # convert hex string value to byte hex string array\r
2122 AllString = self.__Token\r
2123 AllStrLen = len (AllString)\r
2124 DataString = ""\r
2125 while AllStrLen > 4:\r
2126 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","\r
2127 AllStrLen = AllStrLen - 2\r
2128 DataString = DataString + AllString[:AllStrLen] + ","\r
2129\r
2130 # byte value array\r
2131 if len (self.__Token) <= 4:\r
2132 while self.__IsToken(","):\r
2133 if not self.__GetNextHexNumber():\r
2134 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
2135 if len(self.__Token) > 4:\r
2136 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
2137 DataString += self.__Token\r
2138 DataString += ","\r
30fdf114
LG
2139\r
2140 if not self.__IsToken( "}"):\r
2141 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2142\r
2143 DataString = DataString.rstrip(",")\r
2144 RegionObj.RegionDataList.append( DataString)\r
2145\r
2146 ## __GetFv() method\r
2147 #\r
2148 # Get FV section contents and store its data into FV dictionary of self.Profile\r
2149 #\r
2150 # @param self The object pointer\r
2151 # @retval True Successfully find a FV\r
2152 # @retval False Not able to find a FV\r
2153 #\r
2154 def __GetFv(self):\r
2155 if not self.__GetNextToken():\r
2156 return False\r
2157\r
2158 S = self.__Token.upper()\r
2159 if S.startswith("[") and not S.startswith("[FV."):\r
df81077f 2160 self.SectionParser(S)\r
30fdf114
LG
2161 self.__UndoToken()\r
2162 return False\r
2163\r
2164 self.__UndoToken()\r
2165 if not self.__IsToken("[FV.", True):\r
2166 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2167 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
2168 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
2169 raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
2170\r
2171 FvName = self.__GetUiName()\r
2172 self.CurrentFvName = FvName.upper()\r
2173\r
2174 if not self.__IsToken( "]"):\r
2175 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
2176\r
2177 FvObj = Fv.FV()\r
2178 FvObj.UiFvName = self.CurrentFvName\r
2179 self.Profile.FvDict[self.CurrentFvName] = FvObj\r
2180\r
2181 Status = self.__GetCreateFile(FvObj)\r
2182 if not Status:\r
2183 raise Warning("FV name error", self.FileName, self.CurrentLineNumber)\r
2184\r
2185 self.__GetDefineStatements(FvObj)\r
2186\r
2187 self.__GetAddressStatements(FvObj)\r
2188\r
b303ea72
LG
2189 FvObj.FvExtEntryTypeValue = []\r
2190 FvObj.FvExtEntryType = []\r
2191 FvObj.FvExtEntryData = []\r
2192 while True:\r
e8a47801
LG
2193 self.__GetSetStatements(FvObj)\r
2194\r
2195 if not (self.__GetBlockStatement(FvObj) or self.__GetFvBaseAddress(FvObj) or \r
2196 self.__GetFvForceRebase(FvObj) or self.__GetFvAlignment(FvObj) or \r
2197 self.__GetFvAttributes(FvObj) or self.__GetFvNameGuid(FvObj) or \r
aaf8aa7b 2198 self.__GetFvExtEntryStatement(FvObj) or self.__GetFvNameString(FvObj)):\r
b303ea72
LG
2199 break\r
2200\r
aaf8aa7b
YL
2201 if FvObj.FvNameString == 'TRUE' and not FvObj.FvNameGuid:\r
2202 raise Warning("FvNameString found but FvNameGuid was not found", self.FileName, self.CurrentLineNumber)\r
2203\r
30fdf114
LG
2204 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())\r
2205 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())\r
2206\r
2207 while True:\r
2208 isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())\r
2209 isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())\r
2210 if not isInf and not isFile:\r
2211 break\r
2212\r
2213 return True\r
2214\r
2215 ## __GetFvAlignment() method\r
2216 #\r
2217 # Get alignment for FV\r
2218 #\r
2219 # @param self The object pointer\r
2220 # @param Obj for whom alignment is got\r
2221 # @retval True Successfully find a alignment statement\r
2222 # @retval False Not able to find a alignment statement\r
2223 #\r
2224 def __GetFvAlignment(self, Obj):\r
2225\r
2226 if not self.__IsKeyword( "FvAlignment"):\r
2227 return False\r
2228\r
2229 if not self.__IsToken( "="):\r
2230 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2231\r
2232 if not self.__GetNextToken():\r
2233 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)\r
2234\r
2235 if self.__Token.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \\r
2236 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \\r
2237 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \\r
2238 "1G", "2G"):\r
2239 raise Warning("Unknown alignment value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
2240 Obj.FvAlignment = self.__Token\r
2241 return True\r
4234283c
LG
2242 \r
2243 ## __GetFvBaseAddress() method\r
2244 #\r
2245 # Get BaseAddress for FV\r
2246 #\r
2247 # @param self The object pointer\r
2248 # @param Obj for whom FvBaseAddress is got\r
2249 # @retval True Successfully find a FvBaseAddress statement\r
2250 # @retval False Not able to find a FvBaseAddress statement\r
2251 #\r
2252 def __GetFvBaseAddress(self, Obj):\r
2253\r
2254 if not self.__IsKeyword("FvBaseAddress"):\r
2255 return False\r
2256\r
2257 if not self.__IsToken( "="):\r
2258 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2259\r
2260 if not self.__GetNextToken():\r
2261 raise Warning("expected FV base address value", self.FileName, self.CurrentLineNumber)\r
2262\r
2263 IsValidBaseAddrValue = re.compile('^0[x|X][0-9a-fA-F]+')\r
2264\r
2265 if not IsValidBaseAddrValue.match(self.__Token.upper()):\r
79b74a03 2266 raise Warning("Unknown FV base address value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4234283c 2267 Obj.FvBaseAddress = self.__Token\r
0d2711a6
LG
2268 return True \r
2269 \r
79b74a03
LG
2270 ## __GetFvForceRebase() method\r
2271 #\r
2272 # Get FvForceRebase for FV\r
2273 #\r
2274 # @param self The object pointer\r
2275 # @param Obj for whom FvForceRebase is got\r
2276 # @retval True Successfully find a FvForceRebase statement\r
2277 # @retval False Not able to find a FvForceRebase statement\r
2278 #\r
2279 def __GetFvForceRebase(self, Obj):\r
2280\r
2281 if not self.__IsKeyword("FvForceRebase"):\r
2282 return False\r
2283\r
2284 if not self.__IsToken( "="):\r
2285 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2286\r
2287 if not self.__GetNextToken():\r
2288 raise Warning("expected FvForceRebase value", self.FileName, self.CurrentLineNumber)\r
30fdf114 2289\r
79b74a03
LG
2290 if self.__Token.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]:\r
2291 raise Warning("Unknown FvForceRebase value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
2292 \r
2293 if self.__Token.upper() in ["TRUE", "1", "0X1", "0X01"]:\r
2294 Obj.FvForceRebase = True\r
2295 elif self.__Token.upper() in ["FALSE", "0", "0X0", "0X00"]:\r
2296 Obj.FvForceRebase = False\r
2297 else:\r
2298 Obj.FvForceRebase = None\r
2299 \r
2300 return True\r
0d2711a6
LG
2301\r
2302\r
30fdf114
LG
2303 ## __GetFvAttributes() method\r
2304 #\r
2305 # Get attributes for FV\r
2306 #\r
2307 # @param self The object pointer\r
2308 # @param Obj for whom attribute is got\r
2309 # @retval None\r
2310 #\r
2311 def __GetFvAttributes(self, FvObj):\r
2bc3256c 2312 IsWordToken = False\r
30fdf114 2313 while self.__GetNextWord():\r
2bc3256c 2314 IsWordToken = True\r
30fdf114
LG
2315 name = self.__Token\r
2316 if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \\r
2317 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \\r
2318 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \\r
2319 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \\r
2320 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \\r
9425b349 2321 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"):\r
30fdf114 2322 self.__UndoToken()\r
e8a47801 2323 return False\r
30fdf114
LG
2324\r
2325 if not self.__IsToken( "="):\r
2326 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2327\r
2328 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):\r
2329 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)\r
2330\r
2331 FvObj.FvAttributeDict[name] = self.__Token\r
2332\r
2bc3256c 2333 return IsWordToken\r
30fdf114
LG
2334 \r
2335 ## __GetFvNameGuid() method\r
2336 #\r
2337 # Get FV GUID for FV\r
2338 #\r
2339 # @param self The object pointer\r
2340 # @param Obj for whom GUID is got\r
2341 # @retval None\r
2342 #\r
2343 def __GetFvNameGuid(self, FvObj):\r
2344\r
2345 if not self.__IsKeyword( "FvNameGuid"):\r
e8a47801 2346 return False\r
30fdf114
LG
2347\r
2348 if not self.__IsToken( "="):\r
2349 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2350\r
2351 if not self.__GetNextGuid():\r
2352 raise Warning("expected FV GUID value", self.FileName, self.CurrentLineNumber)\r
2353\r
2354 FvObj.FvNameGuid = self.__Token\r
2355\r
e8a47801 2356 return True\r
30fdf114 2357\r
aaf8aa7b
YL
2358 def __GetFvNameString(self, FvObj):\r
2359\r
2360 if not self.__IsKeyword( "FvNameString"):\r
2361 return False\r
2362\r
2363 if not self.__IsToken( "="):\r
2364 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2365\r
2366 if not self.__GetNextToken() or self.__Token not in ('TRUE', 'FALSE'):\r
2367 raise Warning("expected TRUE or FALSE for FvNameString", self.FileName, self.CurrentLineNumber)\r
2368\r
2369 FvObj.FvNameString = self.__Token\r
2370\r
2371 return True\r
2372\r
b303ea72
LG
2373 def __GetFvExtEntryStatement(self, FvObj):\r
2374\r
92d07e48 2375 if not (self.__IsKeyword( "FV_EXT_ENTRY") or self.__IsKeyword( "FV_EXT_ENTRY_TYPE")):\r
b303ea72
LG
2376 return False\r
2377\r
2378 if not self.__IsKeyword ("TYPE"):\r
2379 raise Warning("expected 'TYPE'", self.FileName, self.CurrentLineNumber)\r
2380 \r
2381 if not self.__IsToken( "="):\r
2382 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2383\r
2384 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():\r
2385 raise Warning("expected Hex FV extension entry type value At Line ", self.FileName, self.CurrentLineNumber)\r
2386\r
2387 FvObj.FvExtEntryTypeValue += [self.__Token]\r
2388\r
2389 if not self.__IsToken( "{"):\r
2390 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2391\r
2392 if not self.__IsKeyword ("FILE") and not self.__IsKeyword ("DATA"):\r
2393 raise Warning("expected 'FILE' or 'DATA'", self.FileName, self.CurrentLineNumber)\r
2394\r
2395 FvObj.FvExtEntryType += [self.__Token]\r
2396\r
2397 if self.__Token == 'DATA':\r
2398\r
2399 if not self.__IsToken( "="):\r
2400 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2401 \r
2402 if not self.__IsToken( "{"):\r
2403 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2404\r
2405 if not self.__GetNextHexNumber():\r
2406 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)\r
2407\r
2408 if len(self.__Token) > 4:\r
2409 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
2410\r
2411 DataString = self.__Token\r
2412 DataString += ","\r
2413\r
2414 while self.__IsToken(","):\r
2415 if not self.__GetNextHexNumber():\r
2416 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
2417 if len(self.__Token) > 4:\r
2418 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
2419 DataString += self.__Token\r
2420 DataString += ","\r
2421\r
2422 if not self.__IsToken( "}"):\r
2423 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2424\r
2425 if not self.__IsToken( "}"):\r
2426 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2427\r
2428 DataString = DataString.rstrip(",")\r
2429 FvObj.FvExtEntryData += [DataString]\r
2430\r
2431 if self.__Token == 'FILE':\r
2432 \r
2433 if not self.__IsToken( "="):\r
2434 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2435 \r
2436 if not self.__GetNextToken():\r
2437 raise Warning("expected FV Extension Entry file path At Line ", self.FileName, self.CurrentLineNumber)\r
2438 \r
2439 FvObj.FvExtEntryData += [self.__Token]\r
2440\r
2441 if not self.__IsToken( "}"):\r
2442 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2443\r
2444 return True\r
2445\r
30fdf114
LG
2446 ## __GetAprioriSection() method\r
2447 #\r
2448 # Get token statements\r
2449 #\r
2450 # @param self The object pointer\r
2451 # @param FvObj for whom apriori is got\r
2452 # @param MacroDict dictionary used to replace macro\r
2453 # @retval True Successfully find apriori statement\r
2454 # @retval False Not able to find apriori statement\r
2455 #\r
2456 def __GetAprioriSection(self, FvObj, MacroDict = {}):\r
2457\r
2458 if not self.__IsKeyword( "APRIORI"):\r
2459 return False\r
2460\r
2461 if not self.__IsKeyword("PEI") and not self.__IsKeyword("DXE"):\r
2462 raise Warning("expected Apriori file type", self.FileName, self.CurrentLineNumber)\r
2463 AprType = self.__Token\r
2464\r
2465 if not self.__IsToken( "{"):\r
2466 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2467\r
2468 AprSectionObj = AprioriSection.AprioriSection()\r
2469 AprSectionObj.AprioriType = AprType\r
2470\r
2471 self.__GetDefineStatements(AprSectionObj)\r
2472 MacroDict.update(AprSectionObj.DefineVarDict)\r
2473\r
2474 while True:\r
2475 IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict)\r
2476 IsFile = self.__GetFileStatement( AprSectionObj)\r
2477 if not IsInf and not IsFile:\r
2478 break\r
2479\r
2480 if not self.__IsToken( "}"):\r
2481 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2482\r
2483 FvObj.AprioriSectionList.append(AprSectionObj)\r
2484 return True\r
2485\r
b21a13fb
YZ
2486 def __ParseInfStatement(self):\r
2487 if not self.__IsKeyword("INF"):\r
2488 return None\r
30fdf114
LG
2489\r
2490 ffsInf = FfsInfStatement.FfsInfStatement()\r
b21a13fb 2491 self.__GetInfOptions(ffsInf)\r
30fdf114
LG
2492\r
2493 if not self.__GetNextToken():\r
2494 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)\r
2495 ffsInf.InfFileName = self.__Token\r
a87e79d9
YZ
2496 if not ffsInf.InfFileName.endswith('.inf'):\r
2497 raise Warning("expected .inf file path", self.FileName, self.CurrentLineNumber)\r
64b2609f
LG
2498\r
2499 ffsInf.CurrentLineNum = self.CurrentLineNumber\r
2500 ffsInf.CurrentLineContent = self.__CurrentLine()\r
2501\r
97fa0ee9
YL
2502 #Replace $(SAPCE) with real space\r
2503 ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ')\r
2504\r
14c48571 2505 if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:\r
2506 #do case sensitive check for file path\r
2507 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
2508 if ErrorCode != 0:\r
2509 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 2510\r
30fdf114
LG
2511 if not ffsInf.InfFileName in self.Profile.InfList:\r
2512 self.Profile.InfList.append(ffsInf.InfFileName)\r
d0acc87a
LG
2513 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2514 self.Profile.InfFileLineList.append(FileLineTuple)\r
2502b735
YZ
2515 if ffsInf.UseArch:\r
2516 if ffsInf.UseArch not in self.Profile.InfDict:\r
2517 self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]\r
2518 else:\r
2519 self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)\r
2520 else:\r
2521 self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)\r
30fdf114
LG
2522\r
2523 if self.__IsToken('|'):\r
2524 if self.__IsKeyword('RELOCS_STRIPPED'):\r
2525 ffsInf.KeepReloc = False\r
2526 elif self.__IsKeyword('RELOCS_RETAINED'):\r
2527 ffsInf.KeepReloc = True\r
2528 else:\r
2529 raise Warning("Unknown reloc strip flag '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
b21a13fb
YZ
2530 return ffsInf\r
2531\r
2532 ## __GetInfStatement() method\r
2533 #\r
2534 # Get INF statements\r
2535 #\r
2536 # @param self The object pointer\r
2537 # @param Obj for whom inf statement is got\r
2538 # @param MacroDict dictionary used to replace macro\r
2539 # @retval True Successfully find inf statement\r
2540 # @retval False Not able to find inf statement\r
2541 #\r
2542 def __GetInfStatement(self, Obj, ForCapsule=False, MacroDict={}):\r
2543 ffsInf = self.__ParseInfStatement()\r
2544 if not ffsInf:\r
2545 return False\r
2546\r
30fdf114
LG
2547 if ForCapsule:\r
2548 capsuleFfs = CapsuleData.CapsuleFfs()\r
2549 capsuleFfs.Ffs = ffsInf\r
2550 Obj.CapsuleDataList.append(capsuleFfs)\r
2551 else:\r
2552 Obj.FfsList.append(ffsInf)\r
2553 return True\r
2554\r
2555 ## __GetInfOptions() method\r
2556 #\r
2557 # Get options for INF\r
2558 #\r
2559 # @param self The object pointer\r
2560 # @param FfsInfObj for whom option is got\r
2561 #\r
2562 def __GetInfOptions(self, FfsInfObj):\r
97fa0ee9
YL
2563 if self.__IsKeyword("FILE_GUID"):\r
2564 if not self.__IsToken("="):\r
2565 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2566 if not self.__GetNextGuid():\r
2567 raise Warning("expected GUID value", self.FileName, self.CurrentLineNumber)\r
2568 FfsInfObj.OverrideGuid = self.__Token\r
30fdf114
LG
2569\r
2570 if self.__IsKeyword( "RuleOverride"):\r
2571 if not self.__IsToken( "="):\r
2572 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2573 if not self.__GetNextToken():\r
2574 raise Warning("expected Rule name", self.FileName, self.CurrentLineNumber)\r
2575 FfsInfObj.Rule = self.__Token\r
2576\r
2577 if self.__IsKeyword( "VERSION"):\r
2578 if not self.__IsToken( "="):\r
2579 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2580 if not self.__GetNextToken():\r
2581 raise Warning("expected Version", self.FileName, self.CurrentLineNumber)\r
2582\r
2583 if self.__GetStringData():\r
2584 FfsInfObj.Version = self.__Token\r
2585\r
2586 if self.__IsKeyword( "UI"):\r
2587 if not self.__IsToken( "="):\r
2588 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2589 if not self.__GetNextToken():\r
2590 raise Warning("expected UI name", self.FileName, self.CurrentLineNumber)\r
2591\r
2592 if self.__GetStringData():\r
2593 FfsInfObj.Ui = self.__Token\r
2594\r
2595 if self.__IsKeyword( "USE"):\r
2596 if not self.__IsToken( "="):\r
2597 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2598 if not self.__GetNextToken():\r
2599 raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber)\r
2600 FfsInfObj.UseArch = self.__Token\r
2601\r
2602 \r
2603 if self.__GetNextToken():\r
97fa0ee9
YL
2604 p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')\r
2605 if p.match(self.__Token) and p.match(self.__Token).span()[1] == len(self.__Token):\r
30fdf114
LG
2606 FfsInfObj.KeyStringList.append(self.__Token)\r
2607 if not self.__IsToken(","):\r
2608 return\r
2609 else:\r
2610 self.__UndoToken()\r
2611 return\r
2612\r
2613 while self.__GetNextToken():\r
2614 if not p.match(self.__Token):\r
2615 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
2616 FfsInfObj.KeyStringList.append(self.__Token)\r
2617\r
2618 if not self.__IsToken(","):\r
2619 break\r
2620\r
2621 ## __GetFileStatement() method\r
2622 #\r
2623 # Get FILE statements\r
2624 #\r
2625 # @param self The object pointer\r
2626 # @param Obj for whom FILE statement is got\r
2627 # @param MacroDict dictionary used to replace macro\r
2628 # @retval True Successfully find FILE statement\r
2629 # @retval False Not able to find FILE statement\r
2630 #\r
2631 def __GetFileStatement(self, Obj, ForCapsule = False, MacroDict = {}):\r
2632\r
2633 if not self.__IsKeyword( "FILE"):\r
2634 return False\r
2635\r
30fdf114
LG
2636 if not self.__GetNextWord():\r
2637 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)\r
b36d134f
LG
2638\r
2639 if ForCapsule and self.__Token == 'DATA':\r
2640 self.__UndoToken()\r
2641 self.__UndoToken()\r
2642 return False\r
2643 \r
2644 FfsFileObj = FfsFileStatement.FileStatement()\r
30fdf114
LG
2645 FfsFileObj.FvFileType = self.__Token\r
2646\r
2647 if not self.__IsToken( "="):\r
2648 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2649\r
2650 if not self.__GetNextGuid():\r
2651 if not self.__GetNextWord():\r
2652 raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber)\r
2653 if self.__Token == 'PCD':\r
2654 if not self.__IsToken( "("):\r
2655 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)\r
2656 PcdPair = self.__GetNextPcdName()\r
2657 if not self.__IsToken( ")"):\r
2658 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)\r
2659 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'\r
2660 \r
2661 FfsFileObj.NameGuid = self.__Token\r
79b74a03 2662 \r
30fdf114
LG
2663 self.__GetFilePart( FfsFileObj, MacroDict.copy())\r
2664\r
2665 if ForCapsule:\r
2666 capsuleFfs = CapsuleData.CapsuleFfs()\r
2667 capsuleFfs.Ffs = FfsFileObj\r
2668 Obj.CapsuleDataList.append(capsuleFfs)\r
2669 else:\r
2670 Obj.FfsList.append(FfsFileObj)\r
2671\r
2672 return True\r
2673\r
2674 ## __FileCouldHaveRelocFlag() method\r
2675 #\r
2676 # Check whether reloc strip flag can be set for a file type.\r
2677 #\r
2678 # @param self The object pointer\r
2679 # @param FileType The file type to check with\r
2680 # @retval True This type could have relocation strip flag\r
2681 # @retval False No way to have it\r
2682 #\r
2683\r
2684 def __FileCouldHaveRelocFlag (self, FileType):\r
2685 if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):\r
2686 return True\r
2687 else:\r
2688 return False\r
2689\r
2690 ## __SectionCouldHaveRelocFlag() method\r
2691 #\r
2692 # Check whether reloc strip flag can be set for a section type.\r
2693 #\r
2694 # @param self The object pointer\r
2695 # @param SectionType The section type to check with\r
2696 # @retval True This type could have relocation strip flag\r
2697 # @retval False No way to have it\r
2698 #\r
2699\r
2700 def __SectionCouldHaveRelocFlag (self, SectionType):\r
2701 if SectionType in ('TE', 'PE32'):\r
2702 return True\r
2703 else:\r
2704 return False\r
2705\r
2706 ## __GetFilePart() method\r
2707 #\r
2708 # Get components for FILE statement\r
2709 #\r
2710 # @param self The object pointer\r
2711 # @param FfsFileObj for whom component is got\r
2712 # @param MacroDict dictionary used to replace macro\r
2713 #\r
2714 def __GetFilePart(self, FfsFileObj, MacroDict = {}):\r
2715\r
2716 self.__GetFileOpts( FfsFileObj)\r
2717\r
2718 if not self.__IsToken("{"):\r
4afd3d04
LG
2719 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):\r
2720 if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType):\r
2721 if self.__Token == 'RELOCS_STRIPPED':\r
2722 FfsFileObj.KeepReloc = False\r
2723 else:\r
2724 FfsFileObj.KeepReloc = True\r
2725 else:\r
2726 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
2727\r
2728 if not self.__IsToken("{"):\r
30fdf114
LG
2729 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2730\r
2731 if not self.__GetNextToken():\r
2732 raise Warning("expected File name or section data", self.FileName, self.CurrentLineNumber)\r
2733\r
2734 if self.__Token == "FV":\r
2735 if not self.__IsToken( "="):\r
2736 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2737 if not self.__GetNextToken():\r
2738 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)\r
2739 FfsFileObj.FvName = self.__Token\r
2740\r
2741 elif self.__Token == "FD":\r
2742 if not self.__IsToken( "="):\r
2743 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2744 if not self.__GetNextToken():\r
2745 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)\r
2746 FfsFileObj.FdName = self.__Token\r
2747\r
2748 elif self.__Token in ("DEFINE", "APRIORI", "SECTION"):\r
2749 self.__UndoToken()\r
2750 self.__GetSectionData( FfsFileObj, MacroDict)\r
860992ed
YZ
2751\r
2752 elif hasattr(FfsFileObj, 'FvFileType') and FfsFileObj.FvFileType == 'RAW':\r
2753 self.__UndoToken()\r
2754 self.__GetRAWData(FfsFileObj, MacroDict)\r
2755\r
30fdf114 2756 else:\r
64b2609f
LG
2757 FfsFileObj.CurrentLineNum = self.CurrentLineNumber\r
2758 FfsFileObj.CurrentLineContent = self.__CurrentLine()\r
97fa0ee9 2759 FfsFileObj.FileName = self.__Token.replace('$(SPACE)', ' ')\r
2bc3256c 2760 self.__VerifyFile(FfsFileObj.FileName)\r
0d2711a6 2761\r
30fdf114
LG
2762 if not self.__IsToken( "}"):\r
2763 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2764\r
860992ed
YZ
2765 ## __GetRAWData() method\r
2766 #\r
2767 # Get RAW data for FILE statement\r
2768 #\r
2769 # @param self The object pointer\r
2770 # @param FfsFileObj for whom section is got\r
2771 # @param MacroDict dictionary used to replace macro\r
2772 #\r
2773 def __GetRAWData(self, FfsFileObj, MacroDict = {}):\r
2774 FfsFileObj.FileName = []\r
cfaaf99b 2775 FfsFileObj.SubAlignment = []\r
860992ed
YZ
2776 while True:\r
2777 AlignValue = None\r
2778 if self.__GetAlignment():\r
e921f58d
YZ
2779 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",\r
2780 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):\r
860992ed 2781 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
f475f1e2
YZ
2782 #For FFS, Auto is default option same to ""\r
2783 if not self.__Token == "Auto":\r
2784 AlignValue = self.__Token\r
860992ed
YZ
2785 if not self.__GetNextToken():\r
2786 raise Warning("expected Filename value", self.FileName, self.CurrentLineNumber)\r
2787\r
2788 FileName = self.__Token.replace('$(SPACE)', ' ')\r
2789 if FileName == '}':\r
2790 self.__UndoToken()\r
2791 raise Warning("expected Filename value", self.FileName, self.CurrentLineNumber)\r
860992ed
YZ
2792\r
2793 self.__VerifyFile(FileName)\r
2794 File = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir)\r
2795 FfsFileObj.FileName.append(File.Path)\r
cfaaf99b 2796 FfsFileObj.SubAlignment.append(AlignValue)\r
860992ed
YZ
2797\r
2798 if self.__IsToken( "}"):\r
2799 self.__UndoToken()\r
2800 break\r
2801\r
cfaaf99b
YZ
2802 if len(FfsFileObj.SubAlignment) == 1:\r
2803 FfsFileObj.SubAlignment = FfsFileObj.SubAlignment[0]\r
860992ed
YZ
2804 if len(FfsFileObj.FileName) == 1:\r
2805 FfsFileObj.FileName = FfsFileObj.FileName[0]\r
2806\r
30fdf114
LG
2807 ## __GetFileOpts() method\r
2808 #\r
2809 # Get options for FILE statement\r
2810 #\r
2811 # @param self The object pointer\r
2812 # @param FfsFileObj for whom options is got\r
2813 #\r
2814 def __GetFileOpts(self, FfsFileObj):\r
2815\r
2816 if self.__GetNextToken():\r
2817 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')\r
2818 if Pattern.match(self.__Token):\r
2819 FfsFileObj.KeyStringList.append(self.__Token)\r
2820 if self.__IsToken(","):\r
2821 while self.__GetNextToken():\r
2822 if not Pattern.match(self.__Token):\r
2823 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
2824 FfsFileObj.KeyStringList.append(self.__Token)\r
2825\r
2826 if not self.__IsToken(","):\r
2827 break\r
2828\r
2829 else:\r
2830 self.__UndoToken()\r
2831\r
2832 if self.__IsKeyword( "FIXED", True):\r
2833 FfsFileObj.Fixed = True\r
2834\r
2835 if self.__IsKeyword( "CHECKSUM", True):\r
2836 FfsFileObj.CheckSum = True\r
2837\r
2838 if self.__GetAlignment():\r
e921f58d
YZ
2839 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",\r
2840 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):\r
9053bc51 2841 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
2842 #For FFS, Auto is default option same to ""\r
2843 if not self.__Token == "Auto":\r
2844 FfsFileObj.Alignment = self.__Token\r
30fdf114
LG
2845\r
2846 ## __GetAlignment() method\r
2847 #\r
2848 # Return the alignment value\r
2849 #\r
2850 # @param self The object pointer\r
2851 # @retval True Successfully find alignment\r
2852 # @retval False Not able to find alignment\r
2853 #\r
2854 def __GetAlignment(self):\r
2855 if self.__IsKeyword( "Align", True):\r
2856 if not self.__IsToken( "="):\r
2857 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2858\r
2859 if not self.__GetNextToken():\r
2860 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)\r
2861 return True\r
2862\r
2863 return False\r
2864\r
2865 ## __GetFilePart() method\r
2866 #\r
2867 # Get section data for FILE statement\r
2868 #\r
2869 # @param self The object pointer\r
2870 # @param FfsFileObj for whom section is got\r
2871 # @param MacroDict dictionary used to replace macro\r
2872 #\r
2873 def __GetSectionData(self, FfsFileObj, MacroDict = {}):\r
2874 Dict = {}\r
2875 Dict.update(MacroDict)\r
2876\r
2877 self.__GetDefineStatements(FfsFileObj)\r
2878\r
2879 Dict.update(FfsFileObj.DefineVarDict)\r
2880 self.__GetAprioriSection(FfsFileObj, Dict.copy())\r
2881 self.__GetAprioriSection(FfsFileObj, Dict.copy())\r
2882\r
2883 while True:\r
2884 IsLeafSection = self.__GetLeafSection(FfsFileObj, Dict)\r
2885 IsEncapSection = self.__GetEncapsulationSec(FfsFileObj)\r
2886 if not IsLeafSection and not IsEncapSection:\r
2887 break\r
2888\r
2889 ## __GetLeafSection() method\r
2890 #\r
2891 # Get leaf section for Obj\r
2892 #\r
2893 # @param self The object pointer\r
2894 # @param Obj for whom leaf section is got\r
2895 # @param MacroDict dictionary used to replace macro\r
2896 # @retval True Successfully find section statement\r
2897 # @retval False Not able to find section statement\r
2898 #\r
2899 def __GetLeafSection(self, Obj, MacroDict = {}):\r
2900\r
2901 OldPos = self.GetFileBufferPos()\r
2902\r
2903 if not self.__IsKeyword( "SECTION"):\r
2904 if len(Obj.SectionList) == 0:\r
2905 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)\r
2906 else:\r
2907 return False\r
2908\r
2909 AlignValue = None\r
2910 if self.__GetAlignment():\r
e921f58d
YZ
2911 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",\r
2912 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):\r
52302d4d 2913 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2914 AlignValue = self.__Token\r
2915\r
2916 BuildNum = None\r
2917 if self.__IsKeyword( "BUILD_NUM"):\r
2918 if not self.__IsToken( "="):\r
2919 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2920\r
2921 if not self.__GetNextToken():\r
2922 raise Warning("expected Build number value", self.FileName, self.CurrentLineNumber)\r
2923\r
2924 BuildNum = self.__Token\r
2925\r
2926 if self.__IsKeyword( "VERSION"):\r
52302d4d
LG
2927 if AlignValue == 'Auto':\r
2928 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2929 if not self.__IsToken( "="):\r
2930 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2931 if not self.__GetNextToken():\r
2932 raise Warning("expected version", self.FileName, self.CurrentLineNumber)\r
2933 VerSectionObj = VerSection.VerSection()\r
2934 VerSectionObj.Alignment = AlignValue\r
2935 VerSectionObj.BuildNum = BuildNum\r
2936 if self.__GetStringData():\r
2937 VerSectionObj.StringData = self.__Token\r
2938 else:\r
2939 VerSectionObj.FileName = self.__Token\r
2940 Obj.SectionList.append(VerSectionObj)\r
52302d4d 2941 \r
30fdf114 2942 elif self.__IsKeyword( "UI"):\r
52302d4d
LG
2943 if AlignValue == 'Auto':\r
2944 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2945 if not self.__IsToken( "="):\r
2946 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2947 if not self.__GetNextToken():\r
2948 raise Warning("expected UI", self.FileName, self.CurrentLineNumber)\r
2949 UiSectionObj = UiSection.UiSection()\r
2950 UiSectionObj.Alignment = AlignValue\r
2951 if self.__GetStringData():\r
2952 UiSectionObj.StringData = self.__Token\r
2953 else:\r
2954 UiSectionObj.FileName = self.__Token\r
2955 Obj.SectionList.append(UiSectionObj)\r
2956\r
2957 elif self.__IsKeyword( "FV_IMAGE"):\r
52302d4d
LG
2958 if AlignValue == 'Auto':\r
2959 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2960 if not self.__IsToken( "="):\r
2961 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2962 if not self.__GetNextToken():\r
2963 raise Warning("expected FV name or FV file path", self.FileName, self.CurrentLineNumber)\r
2964\r
2965 FvName = self.__Token\r
2966 FvObj = None\r
2967\r
2968 if self.__IsToken( "{"):\r
2969 FvObj = Fv.FV()\r
2970 FvObj.UiFvName = FvName.upper()\r
2971 self.__GetDefineStatements(FvObj)\r
2972 MacroDict.update(FvObj.DefineVarDict)\r
2973 self.__GetBlockStatement(FvObj)\r
2974 self.__GetSetStatements(FvObj)\r
2975 self.__GetFvAlignment(FvObj)\r
2976 self.__GetFvAttributes(FvObj)\r
2977 self.__GetAprioriSection(FvObj, MacroDict.copy())\r
2978 self.__GetAprioriSection(FvObj, MacroDict.copy())\r
2979\r
2980 while True:\r
2981 IsInf = self.__GetInfStatement(FvObj, MacroDict.copy())\r
2982 IsFile = self.__GetFileStatement(FvObj, MacroDict.copy())\r
2983 if not IsInf and not IsFile:\r
2984 break\r
2985\r
2986 if not self.__IsToken( "}"):\r
2987 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2988\r
2989 FvImageSectionObj = FvImageSection.FvImageSection()\r
2990 FvImageSectionObj.Alignment = AlignValue\r
2991 if FvObj != None:\r
2992 FvImageSectionObj.Fv = FvObj\r
2993 FvImageSectionObj.FvName = None\r
2994 else:\r
2995 FvImageSectionObj.FvName = FvName.upper()\r
2996 FvImageSectionObj.FvFileName = FvName\r
2997\r
2998 Obj.SectionList.append(FvImageSectionObj)\r
2999\r
3000 elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP") or self.__IsKeyword("SMM_DEPEX_EXP"):\r
52302d4d
LG
3001 if AlignValue == 'Auto':\r
3002 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3003 DepexSectionObj = DepexSection.DepexSection()\r
3004 DepexSectionObj.Alignment = AlignValue\r
3005 DepexSectionObj.DepexType = self.__Token\r
3006\r
3007 if not self.__IsToken( "="):\r
3008 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3009 if not self.__IsToken( "{"):\r
3010 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
3011 if not self.__SkipToToken( "}"):\r
3012 raise Warning("expected Depex expression ending '}'", self.FileName, self.CurrentLineNumber)\r
3013\r
3014 DepexSectionObj.Expression = self.__SkippedChars.rstrip('}')\r
3015 Obj.SectionList.append(DepexSectionObj)\r
3016\r
3017 else:\r
30fdf114
LG
3018 if not self.__GetNextWord():\r
3019 raise Warning("expected section type", self.FileName, self.CurrentLineNumber)\r
3020\r
3021 # Encapsulation section appear, UndoToken and return\r
3022 if self.__Token == "COMPRESS" or self.__Token == "GUIDED":\r
3023 self.SetFileBufferPos(OldPos)\r
3024 return False\r
3025\r
3026 if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\\r
3027 "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"):\r
3028 raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
52302d4d
LG
3029 if AlignValue == 'Auto'and (not self.__Token == 'PE32') and (not self.__Token == 'TE'):\r
3030 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
3031\r
30fdf114
LG
3032 # DataSection\r
3033 DataSectionObj = DataSection.DataSection()\r
3034 DataSectionObj.Alignment = AlignValue\r
3035 DataSectionObj.SecType = self.__Token\r
3036\r
3037 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):\r
3038 if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType):\r
3039 if self.__Token == 'RELOCS_STRIPPED':\r
3040 DataSectionObj.KeepReloc = False\r
3041 else:\r
3042 DataSectionObj.KeepReloc = True\r
3043 else:\r
3044 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
3045\r
3046 if self.__IsToken("="):\r
3047 if not self.__GetNextToken():\r
3048 raise Warning("expected section file path", self.FileName, self.CurrentLineNumber)\r
3049 DataSectionObj.SectFileName = self.__Token\r
2bc3256c 3050 self.__VerifyFile(DataSectionObj.SectFileName)\r
30fdf114
LG
3051 else:\r
3052 if not self.__GetCglSection(DataSectionObj):\r
3053 return False\r
3054\r
3055 Obj.SectionList.append(DataSectionObj)\r
3056\r
3057 return True\r
3058\r
2bc3256c
LG
3059 ## __VerifyFile\r
3060 #\r
3061 # Check if file exists or not:\r
3062 # If current phase if GenFds, the file must exist;\r
3063 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist\r
3064 # @param FileName: File path to be verified.\r
3065 #\r
3066 def __VerifyFile(self, FileName):\r
3067 if FileName.replace('$(WORKSPACE)', '').find('$') != -1:\r
3068 return\r
3069 if not GlobalData.gAutoGenPhase or not self.__GetMacroValue("OUTPUT_DIRECTORY") in FileName:\r
3070 ErrorCode, ErrorInfo = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
3071 if ErrorCode != 0:\r
3072 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
3073\r
30fdf114
LG
3074 ## __GetCglSection() method\r
3075 #\r
3076 # Get compressed or GUIDed section for Obj\r
3077 #\r
3078 # @param self The object pointer\r
3079 # @param Obj for whom leaf section is got\r
3080 # @param AlignValue alignment value for complex section\r
3081 # @retval True Successfully find section statement\r
3082 # @retval False Not able to find section statement\r
3083 #\r
3084 def __GetCglSection(self, Obj, AlignValue = None):\r
3085\r
3086 if self.__IsKeyword( "COMPRESS"):\r
3087 type = "PI_STD"\r
3088 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):\r
3089 type = self.__Token\r
3090\r
3091 if not self.__IsToken("{"):\r
3092 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
3093\r
3094 CompressSectionObj = CompressSection.CompressSection()\r
3095 CompressSectionObj.Alignment = AlignValue\r
3096 CompressSectionObj.CompType = type\r
3097 # Recursive sections...\r
3098 while True:\r
3099 IsLeafSection = self.__GetLeafSection(CompressSectionObj)\r
3100 IsEncapSection = self.__GetEncapsulationSec(CompressSectionObj)\r
3101 if not IsLeafSection and not IsEncapSection:\r
3102 break\r
3103\r
3104\r
3105 if not self.__IsToken( "}"):\r
3106 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
3107 Obj.SectionList.append(CompressSectionObj)\r
3108\r
3109# else:\r
3110# raise Warning("Compress type not known")\r
3111\r
3112 return True\r
3113\r
3114 elif self.__IsKeyword( "GUIDED"):\r
3115 GuidValue = None\r
3116 if self.__GetNextGuid():\r
3117 GuidValue = self.__Token\r
3118\r
3119 AttribDict = self.__GetGuidAttrib()\r
3120 if not self.__IsToken("{"):\r
3121 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
3122 GuidSectionObj = GuidSection.GuidSection()\r
3123 GuidSectionObj.Alignment = AlignValue\r
3124 GuidSectionObj.NameGuid = GuidValue\r
3125 GuidSectionObj.SectionType = "GUIDED"\r
3126 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]\r
3127 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]\r
25918452 3128 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]\r
30fdf114
LG
3129 # Recursive sections...\r
3130 while True:\r
3131 IsLeafSection = self.__GetLeafSection(GuidSectionObj)\r
3132 IsEncapSection = self.__GetEncapsulationSec(GuidSectionObj)\r
3133 if not IsLeafSection and not IsEncapSection:\r
3134 break\r
3135\r
3136 if not self.__IsToken( "}"):\r
3137 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
3138 Obj.SectionList.append(GuidSectionObj)\r
3139\r
3140 return True\r
3141\r
3142 return False\r
3143\r
3144 ## __GetGuidAttri() method\r
3145 #\r
3146 # Get attributes for GUID section\r
3147 #\r
3148 # @param self The object pointer\r
3149 # @retval AttribDict Dictionary of key-value pair of section attributes\r
3150 #\r
3151 def __GetGuidAttrib(self):\r
3152\r
3153 AttribDict = {}\r
14c48571 3154 AttribDict["PROCESSING_REQUIRED"] = "NONE"\r
3155 AttribDict["AUTH_STATUS_VALID"] = "NONE"\r
25918452
LG
3156 AttribDict["EXTRA_HEADER_SIZE"] = -1\r
3157 while self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID") \\r
3158 or self.__IsKeyword("EXTRA_HEADER_SIZE"):\r
30fdf114
LG
3159 AttribKey = self.__Token\r
3160\r
3161 if not self.__IsToken("="):\r
3162 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3163\r
25918452
LG
3164 if not self.__GetNextToken():\r
3165 raise Warning("expected TRUE(1)/FALSE(0)/Number", self.FileName, self.CurrentLineNumber)\r
3166 elif AttribKey == "EXTRA_HEADER_SIZE":\r
3167 Base = 10\r
3168 if self.__Token[0:2].upper() == "0X":\r
3169 Base = 16\r
3170 try:\r
3171 AttribDict[AttribKey] = int(self.__Token, Base)\r
3172 continue\r
3173 except ValueError:\r
3174 raise Warning("expected Number", self.FileName, self.CurrentLineNumber)\r
3175 elif self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):\r
30fdf114
LG
3176 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)\r
3177 AttribDict[AttribKey] = self.__Token\r
3178\r
3179 return AttribDict\r
3180\r
3181 ## __GetEncapsulationSec() method\r
3182 #\r
3183 # Get encapsulation section for FILE\r
3184 #\r
3185 # @param self The object pointer\r
3186 # @param FfsFile for whom section is got\r
3187 # @retval True Successfully find section statement\r
3188 # @retval False Not able to find section statement\r
3189 #\r
3190 def __GetEncapsulationSec(self, FfsFileObj):\r
3191\r
3192 OldPos = self.GetFileBufferPos()\r
3193 if not self.__IsKeyword( "SECTION"):\r
3194 if len(FfsFileObj.SectionList) == 0:\r
3195 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)\r
3196 else:\r
3197 return False\r
3198\r
3199 AlignValue = None\r
3200 if self.__GetAlignment():\r
e921f58d
YZ
3201 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",\r
3202 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):\r
52302d4d 3203 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3204 AlignValue = self.__Token\r
3205\r
3206 if not self.__GetCglSection(FfsFileObj, AlignValue):\r
3207 self.SetFileBufferPos(OldPos)\r
3208 return False\r
3209 else:\r
3210 return True\r
3211\r
a3251d84
YL
3212 def __GetFmp(self):\r
3213 if not self.__GetNextToken():\r
3214 return False\r
3215 S = self.__Token.upper()\r
df81077f
YZ
3216 if S.startswith("[") and not S.startswith("[FMPPAYLOAD."):\r
3217 self.SectionParser(S)\r
a3251d84
YL
3218 self.__UndoToken()\r
3219 return False\r
3220\r
3221 self.__UndoToken()\r
3222 self.__SkipToToken("[FMPPAYLOAD.", True)\r
3223 FmpUiName = self.__GetUiName().upper()\r
3224 if FmpUiName in self.Profile.FmpPayloadDict:\r
3225 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName, self.FileName, self.CurrentLineNumber)\r
3226\r
3227 FmpData = CapsuleData.CapsulePayload()\r
3228 FmpData.UiName = FmpUiName\r
3229\r
3230 if not self.__IsToken( "]"):\r
3231 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
3232\r
3233 if not self.__GetNextToken():\r
3234 raise Warning("The FMP payload section is empty!", self.FileName, self.CurrentLineNumber)\r
91ae2988 3235 FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']\r
a3251d84
YL
3236 while self.__Token in FmpKeyList:\r
3237 Name = self.__Token\r
3238 FmpKeyList.remove(Name)\r
3239 if not self.__IsToken("="):\r
3240 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3241 if Name == 'IMAGE_TYPE_ID':\r
3242 if not self.__GetNextGuid():\r
91ae2988 3243 raise Warning("expected GUID value for IMAGE_TYPE_ID.", self.FileName, self.CurrentLineNumber)\r
a3251d84 3244 FmpData.ImageTypeId = self.__Token\r
91ae2988
YZ
3245 elif Name == 'CERTIFICATE_GUID':\r
3246 if not self.__GetNextGuid():\r
3247 raise Warning("expected GUID value for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)\r
3248 FmpData.Certificate_Guid = self.__Token\r
3249 if uuid.UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_RSA2048_SHA256_GUID and uuid.UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_PKCS7_GUID:\r
3250 raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)\r
a3251d84
YL
3251 else:\r
3252 if not self.__GetNextToken():\r
3253 raise Warning("expected value of %s" % Name, self.FileName, self.CurrentLineNumber)\r
3254 Value = self.__Token\r
3255 if Name == 'IMAGE_HEADER_INIT_VERSION':\r
91ae2988
YZ
3256 if self.__Verify(Name, Value, 'UINT8'):\r
3257 FmpData.Version = Value\r
a3251d84 3258 elif Name == 'IMAGE_INDEX':\r
91ae2988
YZ
3259 if self.__Verify(Name, Value, 'UINT8'):\r
3260 FmpData.ImageIndex = Value\r
a3251d84 3261 elif Name == 'HARDWARE_INSTANCE':\r
91ae2988
YZ
3262 if self.__Verify(Name, Value, 'UINT8'):\r
3263 FmpData.HardwareInstance = Value\r
3264 elif Name == 'MONOTONIC_COUNT':\r
3265 if self.__Verify(Name, Value, 'UINT64'):\r
3266 FmpData.MonotonicCount = Value\r
3267 if FmpData.MonotonicCount.upper().startswith('0X'):\r
3268 FmpData.MonotonicCount = (long)(FmpData.MonotonicCount, 16)\r
3269 else:\r
3270 FmpData.MonotonicCount = (long)(FmpData.MonotonicCount)\r
a3251d84
YL
3271 if not self.__GetNextToken():\r
3272 break\r
3273 else:\r
3274 self.__UndoToken()\r
3275\r
91ae2988
YZ
3276 if (FmpData.MonotonicCount and not FmpData.Certificate_Guid) or (not FmpData.MonotonicCount and FmpData.Certificate_Guid):\r
3277 EdkLogger.error("FdfParser", FORMAT_INVALID, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")\r
9ce9bf53
YZ
3278\r
3279 # Only the IMAGE_TYPE_ID is required item\r
3280 if FmpKeyList and 'IMAGE_TYPE_ID' in FmpKeyList:\r
3281 raise Warning("Missing keywords IMAGE_TYPE_ID in FMP payload section.", self.FileName, self.CurrentLineNumber)\r
19e3aa7a
YZ
3282 # get the Image file and Vendor code file\r
3283 self.__GetFMPCapsuleData(FmpData)\r
3284 if not FmpData.ImageFile:\r
91ae2988 3285 raise Warning("Missing image file in FMP payload section.", self.FileName, self.CurrentLineNumber)\r
19e3aa7a
YZ
3286 # check whether more than one Vendor code file\r
3287 if len(FmpData.VendorCodeFile) > 1:\r
91ae2988 3288 raise Warning("At most one Image file and one Vendor code file are allowed in FMP payload section.", self.FileName, self.CurrentLineNumber)\r
a3251d84
YL
3289 self.Profile.FmpPayloadDict[FmpUiName] = FmpData\r
3290 return True\r
3291\r
30fdf114
LG
3292 ## __GetCapsule() method\r
3293 #\r
3294 # Get capsule section contents and store its data into capsule list of self.Profile\r
3295 #\r
3296 # @param self The object pointer\r
3297 # @retval True Successfully find a capsule\r
3298 # @retval False Not able to find a capsule\r
3299 #\r
3300 def __GetCapsule(self):\r
3301\r
3302 if not self.__GetNextToken():\r
3303 return False\r
3304\r
3305 S = self.__Token.upper()\r
3306 if S.startswith("[") and not S.startswith("[CAPSULE."):\r
df81077f 3307 self.SectionParser(S)\r
30fdf114
LG
3308 self.__UndoToken()\r
3309 return False\r
3310\r
3311 self.__UndoToken()\r
3312 if not self.__IsToken("[CAPSULE.", True):\r
3313 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
3314 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
3315 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
3316 raise Warning("expected [Capsule.]", self.FileName, self.CurrentLineNumber)\r
3317\r
3318 CapsuleObj = Capsule.Capsule()\r
3319\r
3320 CapsuleName = self.__GetUiName()\r
3321 if not CapsuleName:\r
3322 raise Warning("expected capsule name", self.FileName, self.CurrentLineNumber)\r
3323\r
3324 CapsuleObj.UiCapsuleName = CapsuleName.upper()\r
3325\r
3326 if not self.__IsToken( "]"):\r
3327 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
3328\r
3329 if self.__IsKeyword("CREATE_FILE"):\r
3330 if not self.__IsToken( "="):\r
3331 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3332\r
3333 if not self.__GetNextToken():\r
3334 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)\r
3335\r
3336 CapsuleObj.CreateFile = self.__Token\r
3337\r
3338 self.__GetCapsuleStatements(CapsuleObj)\r
fd171542 3339 self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj\r
30fdf114
LG
3340 return True\r
3341\r
3342 ## __GetCapsuleStatements() method\r
3343 #\r
3344 # Get statements for capsule\r
3345 #\r
3346 # @param self The object pointer\r
3347 # @param Obj for whom statements are got\r
3348 #\r
3349 def __GetCapsuleStatements(self, Obj):\r
3350 self.__GetCapsuleTokens(Obj)\r
3351 self.__GetDefineStatements(Obj)\r
3352 self.__GetSetStatements(Obj)\r
30fdf114
LG
3353 self.__GetCapsuleData(Obj)\r
3354\r
fd171542 3355 ## __GetCapsuleTokens() method\r
30fdf114
LG
3356 #\r
3357 # Get token statements for capsule\r
3358 #\r
3359 # @param self The object pointer\r
3360 # @param Obj for whom token statements are got\r
3361 #\r
3362 def __GetCapsuleTokens(self, Obj):\r
b303ea72
LG
3363 if not self.__GetNextToken():\r
3364 return False\r
a3251d84 3365 while self.__Token in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"):\r
b303ea72
LG
3366 Name = self.__Token.strip()\r
3367 if not self.__IsToken("="):\r
3368 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3369 if not self.__GetNextToken():\r
3370 raise Warning("expected value", self.FileName, self.CurrentLineNumber)\r
3371 if Name == 'CAPSULE_FLAGS':\r
3372 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):\r
3373 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)\r
3374 Value = self.__Token.strip()\r
3375 while self.__IsToken(","):\r
3376 Value += ','\r
3377 if not self.__GetNextToken():\r
3378 raise Warning("expected value", self.FileName, self.CurrentLineNumber)\r
3379 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):\r
3380 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)\r
3381 Value += self.__Token.strip()\r
e8a47801
LG
3382 elif Name == 'OEM_CAPSULE_FLAGS':\r
3383 Value = self.__Token.strip()\r
2bc3256c
LG
3384 if not Value.upper().startswith('0X'):\r
3385 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)\r
e8a47801
LG
3386 try:\r
3387 Value = int(Value, 0)\r
3388 except ValueError:\r
2bc3256c 3389 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)\r
e8a47801 3390 if not 0x0000 <= Value <= 0xFFFF:\r
2bc3256c 3391 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)\r
e8a47801 3392 Value = self.__Token.strip()\r
b303ea72
LG
3393 else:\r
3394 Value = self.__Token.strip()\r
3395 Obj.TokensDict[Name] = Value \r
3396 if not self.__GetNextToken():\r
3397 return False\r
3398 self.__UndoToken()\r
30fdf114
LG
3399\r
3400 ## __GetCapsuleData() method\r
3401 #\r
3402 # Get capsule data for capsule\r
3403 #\r
3404 # @param self The object pointer\r
3405 # @param Obj for whom capsule data are got\r
3406 #\r
3407 def __GetCapsuleData(self, Obj):\r
3408\r
3409 while True:\r
3410 IsInf = self.__GetInfStatement(Obj, True)\r
3411 IsFile = self.__GetFileStatement(Obj, True)\r
3412 IsFv = self.__GetFvStatement(Obj)\r
b36d134f
LG
3413 IsFd = self.__GetFdStatement(Obj)\r
3414 IsAnyFile = self.__GetAnyFileStatement(Obj)\r
2bc3256c 3415 IsAfile = self.__GetAfileStatement(Obj)\r
a3251d84
YL
3416 IsFmp = self.__GetFmpStatement(Obj)\r
3417 if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile or IsAfile or IsFmp):\r
30fdf114
LG
3418 break\r
3419\r
19e3aa7a
YZ
3420 ## __GetFMPCapsuleData() method\r
3421 #\r
3422 # Get capsule data for FMP capsule\r
3423 #\r
3424 # @param self The object pointer\r
3425 # @param Obj for whom capsule data are got\r
3426 #\r
3427 def __GetFMPCapsuleData(self, Obj):\r
3428\r
3429 while True:\r
3430 IsFv = self.__GetFvStatement(Obj, True)\r
3431 IsFd = self.__GetFdStatement(Obj, True)\r
3432 IsAnyFile = self.__GetAnyFileStatement(Obj, True)\r
3433 if not (IsFv or IsFd or IsAnyFile):\r
3434 break\r
3435\r
30fdf114
LG
3436 ## __GetFvStatement() method\r
3437 #\r
3438 # Get FV for capsule\r
3439 #\r
3440 # @param self The object pointer\r
3441 # @param CapsuleObj for whom FV is got\r
3442 # @retval True Successfully find a FV statement\r
3443 # @retval False Not able to find a FV statement\r
3444 #\r
19e3aa7a 3445 def __GetFvStatement(self, CapsuleObj, FMPCapsule = False):\r
30fdf114
LG
3446\r
3447 if not self.__IsKeyword("FV"):\r
3448 return False\r
3449\r
3450 if not self.__IsToken("="):\r
3451 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3452\r
3453 if not self.__GetNextToken():\r
3454 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)\r
3455\r
2bcc713e
LG
3456 if self.__Token.upper() not in self.Profile.FvDict.keys():\r
3457 raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber)\r
3458\r
30fdf114
LG
3459 CapsuleFv = CapsuleData.CapsuleFv()\r
3460 CapsuleFv.FvName = self.__Token\r
19e3aa7a
YZ
3461 if FMPCapsule:\r
3462 if not CapsuleObj.ImageFile:\r
3463 CapsuleObj.ImageFile.append(CapsuleFv)\r
3464 else:\r
3465 CapsuleObj.VendorCodeFile.append(CapsuleFv)\r
3466 else:\r
3467 CapsuleObj.CapsuleDataList.append(CapsuleFv)\r
30fdf114
LG
3468 return True\r
3469\r
b36d134f
LG
3470 ## __GetFdStatement() method\r
3471 #\r
3472 # Get FD for capsule\r
3473 #\r
3474 # @param self The object pointer\r
3475 # @param CapsuleObj for whom FD is got\r
3476 # @retval True Successfully find a FD statement\r
3477 # @retval False Not able to find a FD statement\r
3478 #\r
19e3aa7a 3479 def __GetFdStatement(self, CapsuleObj, FMPCapsule = False):\r
b36d134f
LG
3480\r
3481 if not self.__IsKeyword("FD"):\r
3482 return False\r
3483\r
3484 if not self.__IsToken("="):\r
3485 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3486\r
3487 if not self.__GetNextToken():\r
3488 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)\r
3489\r
2bcc713e
LG
3490 if self.__Token.upper() not in self.Profile.FdDict.keys():\r
3491 raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber)\r
3492\r
b36d134f
LG
3493 CapsuleFd = CapsuleData.CapsuleFd()\r
3494 CapsuleFd.FdName = self.__Token\r
19e3aa7a
YZ
3495 if FMPCapsule:\r
3496 if not CapsuleObj.ImageFile:\r
3497 CapsuleObj.ImageFile.append(CapsuleFd)\r
3498 else:\r
3499 CapsuleObj.VendorCodeFile.append(CapsuleFd)\r
3500 else:\r
3501 CapsuleObj.CapsuleDataList.append(CapsuleFd)\r
b36d134f
LG
3502 return True\r
3503\r
a3251d84 3504 def __GetFmpStatement(self, CapsuleObj):\r
df81077f
YZ
3505 if not self.__IsKeyword("FMP_PAYLOAD"):\r
3506 if not self.__IsKeyword("FMP"):\r
3507 return False\r
b36d134f 3508\r
df81077f
YZ
3509 if not self.__IsKeyword("PAYLOAD"):\r
3510 self.__UndoToken()\r
3511 return False\r
b36d134f 3512\r
a3251d84
YL
3513 if not self.__IsToken("="):\r
3514 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3515\r
3516 if not self.__GetNextToken():\r
df81077f 3517 raise Warning("expected payload name after FMP_PAYLOAD =", self.FileName, self.CurrentLineNumber)\r
a3251d84
YL
3518 Payload = self.__Token.upper()\r
3519 if Payload not in self.Profile.FmpPayloadDict:\r
3520 raise Warning("This FMP Payload does not exist: %s" % self.__Token, self.FileName, self.CurrentLineNumber)\r
3521 CapsuleObj.FmpPayloadList.append(self.Profile.FmpPayloadDict[Payload])\r
3522 return True\r
3523\r
3524 def __ParseRawFileStatement(self):\r
3525 if not self.__IsKeyword("FILE"):\r
3526 return None\r
3527\r
b36d134f
LG
3528 if not self.__IsKeyword("DATA"):\r
3529 self.__UndoToken()\r
a3251d84 3530 return None\r
b36d134f
LG
3531\r
3532 if not self.__IsToken("="):\r
3533 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3534\r
3535 if not self.__GetNextToken():\r
3536 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)\r
3537 \r
3538 AnyFileName = self.__Token\r
35217a33
YZ
3539 self.__VerifyFile(AnyFileName)\r
3540\r
94e4bcbb
YZ
3541 if not os.path.isabs(AnyFileName):\r
3542 AnyFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, AnyFileName)\r
3543\r
a3251d84
YL
3544 return AnyFileName\r
3545\r
3546 ## __GetAnyFileStatement() method\r
3547 #\r
3548 # Get AnyFile for capsule\r
3549 #\r
3550 # @param self The object pointer\r
3551 # @param CapsuleObj for whom AnyFile is got\r
3552 # @retval True Successfully find a Anyfile statement\r
3553 # @retval False Not able to find a AnyFile statement\r
3554 #\r
19e3aa7a 3555 def __GetAnyFileStatement(self, CapsuleObj, FMPCapsule = False):\r
a3251d84
YL
3556 AnyFileName = self.__ParseRawFileStatement()\r
3557 if not AnyFileName:\r
3558 return False\r
b36d134f
LG
3559\r
3560 CapsuleAnyFile = CapsuleData.CapsuleAnyFile()\r
3561 CapsuleAnyFile.FileName = AnyFileName\r
19e3aa7a
YZ
3562 if FMPCapsule:\r
3563 if not CapsuleObj.ImageFile:\r
3564 CapsuleObj.ImageFile.append(CapsuleAnyFile)\r
3565 else:\r
3566 CapsuleObj.VendorCodeFile.append(CapsuleAnyFile)\r
3567 else:\r
3568 CapsuleObj.CapsuleDataList.append(CapsuleAnyFile)\r
b36d134f 3569 return True\r
2bc3256c
LG
3570 \r
3571 ## __GetAfileStatement() method\r
3572 #\r
3573 # Get Afile for capsule\r
3574 #\r
3575 # @param self The object pointer\r
3576 # @param CapsuleObj for whom Afile is got\r
3577 # @retval True Successfully find a Afile statement\r
3578 # @retval False Not able to find a Afile statement\r
3579 #\r
3580 def __GetAfileStatement(self, CapsuleObj):\r
3581\r
3582 if not self.__IsKeyword("APPEND"):\r
3583 return False\r
3584\r
3585 if not self.__IsToken("="):\r
3586 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3587\r
3588 if not self.__GetNextToken():\r
3589 raise Warning("expected Afile name", self.FileName, self.CurrentLineNumber)\r
3590 \r
3591 AfileName = self.__Token\r
3592 AfileBaseName = os.path.basename(AfileName)\r
3593 \r
3594 if os.path.splitext(AfileBaseName)[1] not in [".bin",".BIN",".Bin",".dat",".DAT",".Dat",".data",".DATA",".Data"]:\r
3595 raise Warning('invalid binary file type, should be one of "bin","BIN","Bin","dat","DAT","Dat","data","DATA","Data"', \\r
3596 self.FileName, self.CurrentLineNumber)\r
3597 \r
3598 if not os.path.isabs(AfileName):\r
3599 AfileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AfileName)\r
3600 self.__VerifyFile(AfileName)\r
3601 else:\r
3602 if not os.path.exists(AfileName):\r
3603 raise Warning('%s does not exist' % AfileName, self.FileName, self.CurrentLineNumber)\r
3604 else:\r
3605 pass\r
3606\r
3607 CapsuleAfile = CapsuleData.CapsuleAfile()\r
3608 CapsuleAfile.FileName = AfileName\r
3609 CapsuleObj.CapsuleDataList.append(CapsuleAfile)\r
3610 return True\r
b36d134f 3611\r
30fdf114
LG
3612 ## __GetRule() method\r
3613 #\r
3614 # Get Rule section contents and store its data into rule list of self.Profile\r
3615 #\r
3616 # @param self The object pointer\r
3617 # @retval True Successfully find a Rule\r
3618 # @retval False Not able to find a Rule\r
3619 #\r
3620 def __GetRule(self):\r
3621\r
3622 if not self.__GetNextToken():\r
3623 return False\r
3624\r
3625 S = self.__Token.upper()\r
3626 if S.startswith("[") and not S.startswith("[RULE."):\r
df81077f 3627 self.SectionParser(S)\r
30fdf114
LG
3628 self.__UndoToken()\r
3629 return False\r
3630 self.__UndoToken()\r
3631 if not self.__IsToken("[Rule.", True):\r
3632 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
3633 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
3634 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
3635 raise Warning("expected [Rule.]", self.FileName, self.CurrentLineNumber)\r
3636\r
3637 if not self.__SkipToToken("."):\r
3638 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)\r
3639\r
3640 Arch = self.__SkippedChars.rstrip(".")\r
4afd3d04 3641 if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "AARCH64", "COMMON"):\r
30fdf114
LG
3642 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)\r
3643\r
3644 ModuleType = self.__GetModuleType()\r
3645\r
3646 TemplateName = ""\r
3647 if self.__IsToken("."):\r
3648 if not self.__GetNextWord():\r
3649 raise Warning("expected template name", self.FileName, self.CurrentLineNumber)\r
3650 TemplateName = self.__Token\r
3651\r
3652 if not self.__IsToken( "]"):\r
3653 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
3654\r
3655 RuleObj = self.__GetRuleFileStatements()\r
3656 RuleObj.Arch = Arch.upper()\r
3657 RuleObj.ModuleType = ModuleType\r
3658 RuleObj.TemplateName = TemplateName\r
3659 if TemplateName == '' :\r
3660 self.Profile.RuleDict['RULE' + \\r
3661 '.' + \\r
3662 Arch.upper() + \\r
3663 '.' + \\r
3664 ModuleType.upper() ] = RuleObj\r
3665 else :\r
3666 self.Profile.RuleDict['RULE' + \\r
3667 '.' + \\r
3668 Arch.upper() + \\r
3669 '.' + \\r
3670 ModuleType.upper() + \\r
3671 '.' + \\r
3672 TemplateName.upper() ] = RuleObj\r
3673# self.Profile.RuleList.append(rule)\r
3674 return True\r
3675\r
3676 ## __GetModuleType() method\r
3677 #\r
3678 # Return the module type\r
3679 #\r
3680 # @param self The object pointer\r
3681 # @retval string module type\r
3682 #\r
3683 def __GetModuleType(self):\r
3684\r
3685 if not self.__GetNextWord():\r
3686 raise Warning("expected Module type", self.FileName, self.CurrentLineNumber)\r
3687 if self.__Token.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \\r
3688 "DXE_DRIVER", "DXE_SAL_DRIVER", \\r
3689 "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \\r
3690 "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \\r
3691 "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \\r
b19df640 3692 "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_CORE", "MM_STANDALONE", "MM_CORE_STANDALONE"):\r
30fdf114
LG
3693 raise Warning("Unknown Module type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
3694 return self.__Token\r
3695\r
3696 ## __GetFileExtension() method\r
3697 #\r
3698 # Return the file extension\r
3699 #\r
3700 # @param self The object pointer\r
3701 # @retval string file name extension\r
3702 #\r
3703 def __GetFileExtension(self):\r
3704 if not self.__IsToken("."):\r
df81077f 3705 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3706\r
3707 Ext = ""\r
3708 if self.__GetNextToken():\r
3709 Pattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)')\r
3710 if Pattern.match(self.__Token):\r
3711 Ext = self.__Token\r
3712 return '.' + Ext\r
3713 else:\r
3714 raise Warning("Unknown file extension '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
3715\r
3716 else:\r
3717 raise Warning("expected file extension", self.FileName, self.CurrentLineNumber)\r
3718\r
3719 ## __GetRuleFileStatement() method\r
3720 #\r
3721 # Get rule contents\r
3722 #\r
3723 # @param self The object pointer\r
3724 # @retval Rule Rule object\r
3725 #\r
3726 def __GetRuleFileStatements(self):\r
3727\r
3728 if not self.__IsKeyword("FILE"):\r
3729 raise Warning("expected FILE", self.FileName, self.CurrentLineNumber)\r
3730\r
3731 if not self.__GetNextWord():\r
3732 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)\r
3733\r
3734 Type = self.__Token.strip().upper()\r
3735 if Type not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\\r
b19df640 3736 "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM", "SMM_CORE", "MM_STANDALONE", "MM_CORE_STANDALONE"):\r
30fdf114
LG
3737 raise Warning("Unknown FV type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
3738\r
3739 if not self.__IsToken("="):\r
3740 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3741\r
3742 if not self.__IsKeyword("$(NAMED_GUID)"):\r
3743 if not self.__GetNextWord():\r
3744 raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber)\r
3745 if self.__Token == 'PCD':\r
3746 if not self.__IsToken( "("):\r
3747 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)\r
3748 PcdPair = self.__GetNextPcdName()\r
3749 if not self.__IsToken( ")"):\r
3750 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)\r
3751 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'\r
3752 \r
3753 NameGuid = self.__Token\r
3754\r
3755 KeepReloc = None\r
3756 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):\r
3757 if self.__FileCouldHaveRelocFlag(Type):\r
3758 if self.__Token == 'RELOCS_STRIPPED':\r
3759 KeepReloc = False\r
3760 else:\r
3761 KeepReloc = True\r
3762 else:\r
3763 raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3764\r
3765 KeyStringList = []\r
3766 if self.__GetNextToken():\r
3767 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')\r
3768 if Pattern.match(self.__Token):\r
3769 KeyStringList.append(self.__Token)\r
3770 if self.__IsToken(","):\r
3771 while self.__GetNextToken():\r
3772 if not Pattern.match(self.__Token):\r
3773 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
3774 KeyStringList.append(self.__Token)\r
3775\r
3776 if not self.__IsToken(","):\r
3777 break\r
3778\r
3779 else:\r
3780 self.__UndoToken()\r
3781\r
3782\r
3783 Fixed = False\r
3784 if self.__IsKeyword("Fixed", True):\r
3785 Fixed = True\r
3786\r
3787 CheckSum = False\r
3788 if self.__IsKeyword("CheckSum", True):\r
3789 CheckSum = True\r
3790\r
3791 AlignValue = ""\r
3792 if self.__GetAlignment():\r
e921f58d
YZ
3793 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",\r
3794 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):\r
30fdf114 3795 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
52302d4d
LG
3796 #For FFS, Auto is default option same to ""\r
3797 if not self.__Token == "Auto":\r
3798 AlignValue = self.__Token\r
30fdf114
LG
3799\r
3800 if self.__IsToken("{"):\r
3801 # Complex file rule expected\r
3802 Rule = RuleComplexFile.RuleComplexFile()\r
3803 Rule.FvFileType = Type\r
3804 Rule.NameGuid = NameGuid\r
3805 Rule.Alignment = AlignValue\r
3806 Rule.CheckSum = CheckSum\r
3807 Rule.Fixed = Fixed\r
3808 Rule.KeyStringList = KeyStringList\r
3809 if KeepReloc != None:\r
3810 Rule.KeepReloc = KeepReloc\r
3811\r
3812 while True:\r
3813 IsEncapsulate = self.__GetRuleEncapsulationSection(Rule)\r
3814 IsLeaf = self.__GetEfiSection(Rule)\r
3815 if not IsEncapsulate and not IsLeaf:\r
3816 break\r
3817\r
3818 if not self.__IsToken("}"):\r
3819 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
3820\r
3821 return Rule\r
3822\r
30fdf114
LG
3823 else:\r
3824 # Simple file rule expected\r
3825 if not self.__GetNextWord():\r
3826 raise Warning("expected leaf section type", self.FileName, self.CurrentLineNumber)\r
3827\r
3828 SectionName = self.__Token\r
3829\r
3830 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\\r
3831 "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"):\r
3832 raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)\r
3833\r
3834\r
3835 if self.__IsKeyword("Fixed", True):\r
3836 Fixed = True\r
3837\r
3838 if self.__IsKeyword("CheckSum", True):\r
3839 CheckSum = True\r
3840\r
52302d4d 3841 SectAlignment = ""\r
30fdf114 3842 if self.__GetAlignment():\r
e921f58d
YZ
3843 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",\r
3844 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):\r
30fdf114 3845 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
52302d4d
LG
3846 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):\r
3847 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
3848 SectAlignment = self.__Token\r
3849\r
3850 Ext = None\r
3851 if self.__IsToken('|'):\r
3852 Ext = self.__GetFileExtension()\r
3853 elif not self.__GetNextToken():\r
30fdf114
LG
3854 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)\r
3855\r
3856 Rule = RuleSimpleFile.RuleSimpleFile()\r
3857 Rule.SectionType = SectionName\r
3858 Rule.FvFileType = Type\r
3859 Rule.NameGuid = NameGuid\r
3860 Rule.Alignment = AlignValue\r
52302d4d 3861 Rule.SectAlignment = SectAlignment\r
30fdf114
LG
3862 Rule.CheckSum = CheckSum\r
3863 Rule.Fixed = Fixed\r
30fdf114
LG
3864 Rule.KeyStringList = KeyStringList\r
3865 if KeepReloc != None:\r
3866 Rule.KeepReloc = KeepReloc\r
52302d4d
LG
3867 Rule.FileExtension = Ext\r
3868 Rule.FileName = self.__Token\r
30fdf114
LG
3869 return Rule\r
3870\r
3871 ## __GetEfiSection() method\r
3872 #\r
3873 # Get section list for Rule\r
3874 #\r
3875 # @param self The object pointer\r
3876 # @param Obj for whom section is got\r
3877 # @retval True Successfully find section statement\r
3878 # @retval False Not able to find section statement\r
3879 #\r
3880 def __GetEfiSection(self, Obj):\r
3881\r
3882 OldPos = self.GetFileBufferPos()\r
3883 if not self.__GetNextWord():\r
3884 return False\r
3885 SectionName = self.__Token\r
3886\r
3887 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\\r
3888 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):\r
3889 self.__UndoToken()\r
3890 return False\r
3891\r
3892 if SectionName == "FV_IMAGE":\r
3893 FvImageSectionObj = FvImageSection.FvImageSection()\r
3894 if self.__IsKeyword("FV_IMAGE"):\r
3895 pass\r
3896 if self.__IsToken( "{"):\r
3897 FvObj = Fv.FV()\r
3898 self.__GetDefineStatements(FvObj)\r
3899 self.__GetBlockStatement(FvObj)\r
3900 self.__GetSetStatements(FvObj)\r
3901 self.__GetFvAlignment(FvObj)\r
3902 self.__GetFvAttributes(FvObj)\r
3903 self.__GetAprioriSection(FvObj)\r
3904 self.__GetAprioriSection(FvObj)\r
3905\r
3906 while True:\r
3907 IsInf = self.__GetInfStatement(FvObj)\r
3908 IsFile = self.__GetFileStatement(FvObj)\r
3909 if not IsInf and not IsFile:\r
3910 break\r
3911\r
3912 if not self.__IsToken( "}"):\r
3913 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
3914 FvImageSectionObj.Fv = FvObj\r
3915 FvImageSectionObj.FvName = None\r
3916\r
3917 else:\r
3918 if not self.__IsKeyword("FV"):\r
3919 raise Warning("expected 'FV'", self.FileName, self.CurrentLineNumber)\r
3920 FvImageSectionObj.FvFileType = self.__Token\r
3921\r
30fdf114 3922 if self.__GetAlignment():\r
e921f58d
YZ
3923 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",\r
3924 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):\r
30fdf114
LG
3925 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
3926 FvImageSectionObj.Alignment = self.__Token\r
3927\r
3928 if self.__IsToken('|'):\r
3929 FvImageSectionObj.FvFileExtension = self.__GetFileExtension()\r
3930 elif self.__GetNextToken():\r
3931 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\\r
3932 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):\r
3933 FvImageSectionObj.FvFileName = self.__Token\r
3934 else:\r
3935 self.__UndoToken()\r
3936 else:\r
3937 raise Warning("expected FV file name", self.FileName, self.CurrentLineNumber)\r
3938\r
3939 Obj.SectionList.append(FvImageSectionObj)\r
3940 return True\r
3941\r
3942 EfiSectionObj = EfiSection.EfiSection()\r
3943 EfiSectionObj.SectionType = SectionName\r
3944\r
3945 if not self.__GetNextToken():\r
3946 raise Warning("expected file type", self.FileName, self.CurrentLineNumber)\r
3947\r
3948 if self.__Token == "STRING":\r
3949 if not self.__RuleSectionCouldHaveString(EfiSectionObj.SectionType):\r
3950 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3951\r
3952 if not self.__IsToken('='):\r
3953 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3954\r
3955 if not self.__GetNextToken():\r
3956 raise Warning("expected Quoted String", self.FileName, self.CurrentLineNumber)\r
3957\r
3958 if self.__GetStringData():\r
3959 EfiSectionObj.StringData = self.__Token\r
3960\r
3961 if self.__IsKeyword("BUILD_NUM"):\r
3962 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):\r
3963 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3964\r
3965 if not self.__IsToken("="):\r
3966 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3967 if not self.__GetNextToken():\r
3968 raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)\r
3969 EfiSectionObj.BuildNum = self.__Token\r
3970\r
3971 else:\r
3972 EfiSectionObj.FileType = self.__Token\r
3973 self.__CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)\r
3974\r
3975 if self.__IsKeyword("Optional"):\r
3976 if not self.__RuleSectionCouldBeOptional(EfiSectionObj.SectionType):\r
3977 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3978 EfiSectionObj.Optional = True\r
3979\r
3980 if self.__IsKeyword("BUILD_NUM"):\r
3981 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):\r
3982 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3983\r
3984 if not self.__IsToken("="):\r
3985 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3986 if not self.__GetNextToken():\r
3987 raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)\r
3988 EfiSectionObj.BuildNum = self.__Token\r
3989\r
3990 if self.__GetAlignment():\r
e921f58d
YZ
3991 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",\r
3992 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):\r
52302d4d
LG
3993 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
3994 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):\r
3995 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3996 EfiSectionObj.Alignment = self.__Token\r
3997\r
3998 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):\r
3999 if self.__SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):\r
4000 if self.__Token == 'RELOCS_STRIPPED':\r
4001 EfiSectionObj.KeepReloc = False\r
4002 else:\r
4003 EfiSectionObj.KeepReloc = True\r
4004 if Obj.KeepReloc != None and Obj.KeepReloc != EfiSectionObj.KeepReloc:\r
4005 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)\r
4006 else:\r
4007 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)\r
4008\r
4009\r
4010 if self.__IsToken('|'):\r
4011 EfiSectionObj.FileExtension = self.__GetFileExtension()\r
4012 elif self.__GetNextToken():\r
4013 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\\r
4014 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):\r
4015 \r
4016 if self.__Token.startswith('PCD'):\r
4017 self.__UndoToken()\r
4018 self.__GetNextWord()\r
4019 \r
4020 if self.__Token == 'PCD':\r
4021 if not self.__IsToken( "("):\r
4022 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)\r
4023 PcdPair = self.__GetNextPcdName()\r
4024 if not self.__IsToken( ")"):\r
4025 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)\r
4026 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'\r
4027 \r
4028 EfiSectionObj.FileName = self.__Token \r
4029 \r
4030 else:\r
4031 self.__UndoToken()\r
4032 else:\r
4033 raise Warning("expected section file name", self.FileName, self.CurrentLineNumber)\r
4034\r
4035 Obj.SectionList.append(EfiSectionObj)\r
4036 return True\r
4037\r
4038 ## __RuleSectionCouldBeOptional() method\r
4039 #\r
4040 # Get whether a section could be optional\r
4041 #\r
4042 # @param self The object pointer\r
4043 # @param SectionType The section type to check\r
4044 # @retval True section could be optional\r
4045 # @retval False section never optional\r
4046 #\r
4047 def __RuleSectionCouldBeOptional(self, SectionType):\r
4048 if SectionType in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"):\r
4049 return True\r
4050 else:\r
4051 return False\r
4052\r
4053 ## __RuleSectionCouldHaveBuildNum() method\r
4054 #\r
4055 # Get whether a section could have build number information\r
4056 #\r
4057 # @param self The object pointer\r
4058 # @param SectionType The section type to check\r
4059 # @retval True section could have build number information\r
4060 # @retval False section never have build number information\r
4061 #\r
4062 def __RuleSectionCouldHaveBuildNum(self, SectionType):\r
4063 if SectionType in ("VERSION"):\r
4064 return True\r
4065 else:\r
4066 return False\r
4067\r
4068 ## __RuleSectionCouldHaveString() method\r
4069 #\r
4070 # Get whether a section could have string\r
4071 #\r
4072 # @param self The object pointer\r
4073 # @param SectionType The section type to check\r
4074 # @retval True section could have string\r
4075 # @retval False section never have string\r
4076 #\r
4077 def __RuleSectionCouldHaveString(self, SectionType):\r
4078 if SectionType in ("UI", "VERSION"):\r
4079 return True\r
4080 else:\r
4081 return False\r
4082\r
4083 ## __CheckRuleSectionFileType() method\r
4084 #\r
4085 # Get whether a section matches a file type\r
4086 #\r
4087 # @param self The object pointer\r
4088 # @param SectionType The section type to check\r
4089 # @param FileType The file type to check\r
4090 #\r
4091 def __CheckRuleSectionFileType(self, SectionType, FileType):\r
4092 if SectionType == "COMPAT16":\r
4093 if FileType not in ("COMPAT16", "SEC_COMPAT16"):\r
4094 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
4095 elif SectionType == "PE32":\r
4096 if FileType not in ("PE32", "SEC_PE32"):\r
4097 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
4098 elif SectionType == "PIC":\r
4099 if FileType not in ("PIC", "PIC"):\r
4100 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
4101 elif SectionType == "TE":\r
4102 if FileType not in ("TE", "SEC_TE"):\r
4103 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
4104 elif SectionType == "RAW":\r
4105 if FileType not in ("BIN", "SEC_BIN", "RAW", "ASL", "ACPI"):\r
4106 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
b303ea72
LG
4107 elif SectionType == "DXE_DEPEX" or SectionType == "SMM_DEPEX":\r
4108 if FileType not in ("DXE_DEPEX", "SEC_DXE_DEPEX", "SMM_DEPEX"):\r
30fdf114
LG
4109 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
4110 elif SectionType == "UI":\r
4111 if FileType not in ("UI", "SEC_UI"):\r
4112 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
4113 elif SectionType == "VERSION":\r
4114 if FileType not in ("VERSION", "SEC_VERSION"):\r
4115 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
4116 elif SectionType == "PEI_DEPEX":\r
4117 if FileType not in ("PEI_DEPEX", "SEC_PEI_DEPEX"):\r
4118 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
4119 elif SectionType == "GUID":\r
4120 if FileType not in ("PE32", "SEC_GUID"):\r
4121 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
4122\r
4123 ## __GetRuleEncapsulationSection() method\r
4124 #\r
4125 # Get encapsulation section for Rule\r
4126 #\r
4127 # @param self The object pointer\r
4128 # @param Rule for whom section is got\r
4129 # @retval True Successfully find section statement\r
4130 # @retval False Not able to find section statement\r
4131 #\r
4132 def __GetRuleEncapsulationSection(self, Rule):\r
4133\r
4134 if self.__IsKeyword( "COMPRESS"):\r
4135 Type = "PI_STD"\r
4136 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):\r
4137 Type = self.__Token\r
4138\r
4139 if not self.__IsToken("{"):\r
4140 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
4141\r
4142 CompressSectionObj = CompressSection.CompressSection()\r
4143\r
4144 CompressSectionObj.CompType = Type\r
4145 # Recursive sections...\r
4146 while True:\r
4147 IsEncapsulate = self.__GetRuleEncapsulationSection(CompressSectionObj)\r
4148 IsLeaf = self.__GetEfiSection(CompressSectionObj)\r
4149 if not IsEncapsulate and not IsLeaf:\r
4150 break\r
4151\r
4152 if not self.__IsToken( "}"):\r
4153 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
4154 Rule.SectionList.append(CompressSectionObj)\r
4155\r
4156 return True\r
4157\r
4158 elif self.__IsKeyword( "GUIDED"):\r
4159 GuidValue = None\r
4160 if self.__GetNextGuid():\r
4161 GuidValue = self.__Token\r
4162\r
4163 if self.__IsKeyword( "$(NAMED_GUID)"):\r
4164 GuidValue = self.__Token\r
4165\r
4166 AttribDict = self.__GetGuidAttrib()\r
4167\r
4168 if not self.__IsToken("{"):\r
4169 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
4170 GuidSectionObj = GuidSection.GuidSection()\r
4171 GuidSectionObj.NameGuid = GuidValue\r
4172 GuidSectionObj.SectionType = "GUIDED"\r
4173 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]\r
4174 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]\r
25918452 4175 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]\r
30fdf114
LG
4176\r
4177 # Efi sections...\r
4178 while True:\r
4179 IsEncapsulate = self.__GetRuleEncapsulationSection(GuidSectionObj)\r
4180 IsLeaf = self.__GetEfiSection(GuidSectionObj)\r
4181 if not IsEncapsulate and not IsLeaf:\r
4182 break\r
4183\r
4184 if not self.__IsToken( "}"):\r
4185 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
4186 Rule.SectionList.append(GuidSectionObj)\r
4187\r
4188 return True\r
4189\r
4190 return False\r
4191\r
4192 ## __GetVtf() method\r
4193 #\r
4194 # Get VTF section contents and store its data into VTF list of self.Profile\r
4195 #\r
4196 # @param self The object pointer\r
4197 # @retval True Successfully find a VTF\r
4198 # @retval False Not able to find a VTF\r
4199 #\r
4200 def __GetVtf(self):\r
4201\r
4202 if not self.__GetNextToken():\r
4203 return False\r
4204\r
4205 S = self.__Token.upper()\r
4206 if S.startswith("[") and not S.startswith("[VTF."):\r
df81077f 4207 self.SectionParser(S)\r
30fdf114
LG
4208 self.__UndoToken()\r
4209 return False\r
4210\r
4211 self.__UndoToken()\r
4212 if not self.__IsToken("[VTF.", True):\r
4213 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
4214 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
4215 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
4216 raise Warning("expected [VTF.]", self.FileName, self.CurrentLineNumber)\r
4217\r
4218 if not self.__SkipToToken("."):\r
4219 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)\r
4220\r
4221 Arch = self.__SkippedChars.rstrip(".").upper()\r
4afd3d04 4222 if Arch not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):\r
30fdf114
LG
4223 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)\r
4224\r
4225 if not self.__GetNextWord():\r
4226 raise Warning("expected VTF name", self.FileName, self.CurrentLineNumber)\r
4227 Name = self.__Token.upper()\r
4228\r
4229 VtfObj = Vtf.Vtf()\r
4230 VtfObj.UiName = Name\r
4231 VtfObj.KeyArch = Arch\r
4232\r
4233 if self.__IsToken(","):\r
4234 if not self.__GetNextWord():\r
4235 raise Warning("expected Arch list", self.FileName, self.CurrentLineNumber)\r
4afd3d04 4236 if self.__Token.upper() not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):\r
30fdf114
LG
4237 raise Warning("Unknown Arch '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4238 VtfObj.ArchList = self.__Token.upper()\r
4239\r
4240 if not self.__IsToken( "]"):\r
4241 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
4242\r
4243 if self.__IsKeyword("IA32_RST_BIN"):\r
4244 if not self.__IsToken("="):\r
4245 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4246\r
4247 if not self.__GetNextToken():\r
4248 raise Warning("expected Reset file", self.FileName, self.CurrentLineNumber)\r
4249\r
4250 VtfObj.ResetBin = self.__Token\r
6310ffd7 4251 if VtfObj.ResetBin.replace('$(WORKSPACE)', '').find('$') == -1:\r
4252 #check for file path\r
4253 ErrorCode, ErrorInfo = PathClass(NormPath(VtfObj.ResetBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4254 if ErrorCode != 0:\r
4255 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114
LG
4256\r
4257 while self.__GetComponentStatement(VtfObj):\r
4258 pass\r
4259\r
4260 self.Profile.VtfList.append(VtfObj)\r
4261 return True\r
4262\r
4263 ## __GetComponentStatement() method\r
4264 #\r
4265 # Get components in VTF\r
4266 #\r
4267 # @param self The object pointer\r
4268 # @param VtfObj for whom component is got\r
4269 # @retval True Successfully find a component\r
4270 # @retval False Not able to find a component\r
4271 #\r
4272 def __GetComponentStatement(self, VtfObj):\r
4273\r
4274 if not self.__IsKeyword("COMP_NAME"):\r
4275 return False\r
4276\r
4277 if not self.__IsToken("="):\r
4278 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4279\r
4280 if not self.__GetNextWord():\r
4281 raise Warning("expected Component Name", self.FileName, self.CurrentLineNumber)\r
4282\r
4283 CompStatementObj = ComponentStatement.ComponentStatement()\r
4284 CompStatementObj.CompName = self.__Token\r
4285\r
4286 if not self.__IsKeyword("COMP_LOC"):\r
4287 raise Warning("expected COMP_LOC", self.FileName, self.CurrentLineNumber)\r
4288\r
4289 if not self.__IsToken("="):\r
4290 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4291\r
4292 CompStatementObj.CompLoc = ""\r
4293 if self.__GetNextWord():\r
4294 CompStatementObj.CompLoc = self.__Token\r
4295 if self.__IsToken('|'):\r
4296 if not self.__GetNextWord():\r
4297 raise Warning("Expected Region Name", self.FileName, self.CurrentLineNumber)\r
4298\r
4299 if self.__Token not in ("F", "N", "S"): #, "H", "L", "PH", "PL"): not support\r
4300 raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4301\r
4302 CompStatementObj.FilePos = self.__Token\r
4303 else:\r
4304 self.CurrentLineNumber += 1\r
4305 self.CurrentOffsetWithinLine = 0\r
4306\r
4307 if not self.__IsKeyword("COMP_TYPE"):\r
4308 raise Warning("expected COMP_TYPE", self.FileName, self.CurrentLineNumber)\r
4309\r
4310 if not self.__IsToken("="):\r
4311 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4312\r
4313 if not self.__GetNextToken():\r
4314 raise Warning("expected Component type", self.FileName, self.CurrentLineNumber)\r
4315 if self.__Token not in ("FIT", "PAL_B", "PAL_A", "OEM"):\r
4316 if not self.__Token.startswith("0x") or len(self.__Token) < 3 or len(self.__Token) > 4 or \\r
4317 not self.__HexDigit(self.__Token[2]) or not self.__HexDigit(self.__Token[-1]):\r
4318 raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4319 CompStatementObj.CompType = self.__Token\r
4320\r
4321 if not self.__IsKeyword("COMP_VER"):\r
4322 raise Warning("expected COMP_VER", self.FileName, self.CurrentLineNumber)\r
4323\r
4324 if not self.__IsToken("="):\r
4325 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4326\r
4327 if not self.__GetNextToken():\r
4328 raise Warning("expected Component version", self.FileName, self.CurrentLineNumber)\r
4329\r
9fd2164e 4330 Pattern = re.compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', re.DOTALL)\r
30fdf114
LG
4331 if Pattern.match(self.__Token) == None:\r
4332 raise Warning("Unknown version format '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4333 CompStatementObj.CompVer = self.__Token\r
4334\r
4335 if not self.__IsKeyword("COMP_CS"):\r
4336 raise Warning("expected COMP_CS", self.FileName, self.CurrentLineNumber)\r
4337\r
4338 if not self.__IsToken("="):\r
4339 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4340\r
4341 if not self.__GetNextToken():\r
4342 raise Warning("expected Component CS", self.FileName, self.CurrentLineNumber)\r
4343 if self.__Token not in ("1", "0"):\r
4344 raise Warning("Unknown Component CS '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4345 CompStatementObj.CompCs = self.__Token\r
4346\r
4347\r
4348 if not self.__IsKeyword("COMP_BIN"):\r
4349 raise Warning("expected COMP_BIN", self.FileName, self.CurrentLineNumber)\r
4350\r
4351 if not self.__IsToken("="):\r
4352 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4353\r
4354 if not self.__GetNextToken():\r
4355 raise Warning("expected Component file", self.FileName, self.CurrentLineNumber)\r
4356\r
4357 CompStatementObj.CompBin = self.__Token\r
6310ffd7 4358 if CompStatementObj.CompBin != '-' and CompStatementObj.CompBin.replace('$(WORKSPACE)', '').find('$') == -1:\r
4359 #check for file path\r
4360 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4361 if ErrorCode != 0:\r
4362 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114
LG
4363\r
4364 if not self.__IsKeyword("COMP_SYM"):\r
4365 raise Warning("expected COMP_SYM", self.FileName, self.CurrentLineNumber)\r
4366\r
4367 if not self.__IsToken("="):\r
4368 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4369\r
4370 if not self.__GetNextToken():\r
4371 raise Warning("expected Component symbol file", self.FileName, self.CurrentLineNumber)\r
4372\r
4373 CompStatementObj.CompSym = self.__Token\r
6310ffd7 4374 if CompStatementObj.CompSym != '-' and CompStatementObj.CompSym.replace('$(WORKSPACE)', '').find('$') == -1:\r
4375 #check for file path\r
4376 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompSym), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4377 if ErrorCode != 0:\r
4378 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114
LG
4379\r
4380 if not self.__IsKeyword("COMP_SIZE"):\r
4381 raise Warning("expected COMP_SIZE", self.FileName, self.CurrentLineNumber)\r
4382\r
4383 if not self.__IsToken("="):\r
4384 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4385\r
4386 if self.__IsToken("-"):\r
4387 CompStatementObj.CompSize = self.__Token\r
4388 elif self.__GetNextDecimalNumber():\r
4389 CompStatementObj.CompSize = self.__Token\r
4390 elif self.__GetNextHexNumber():\r
4391 CompStatementObj.CompSize = self.__Token\r
4392 else:\r
4393 raise Warning("Unknown size '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4394\r
4395 VtfObj.ComponentStatementList.append(CompStatementObj)\r
4396 return True\r
4397\r
4398 ## __GetOptionRom() method\r
4399 #\r
4400 # Get OptionROM section contents and store its data into OptionROM list of self.Profile\r
4401 #\r
4402 # @param self The object pointer\r
4403 # @retval True Successfully find a OptionROM\r
4404 # @retval False Not able to find a OptionROM\r
4405 #\r
4406 def __GetOptionRom(self):\r
4407\r
4408 if not self.__GetNextToken():\r
4409 return False\r
4410\r
4411 S = self.__Token.upper()\r
4412 if S.startswith("[") and not S.startswith("[OPTIONROM."):\r
df81077f
YZ
4413 self.SectionParser(S)\r
4414 self.__UndoToken()\r
4415 return False\r
30fdf114
LG
4416 \r
4417 self.__UndoToken()\r
4418 if not self.__IsToken("[OptionRom.", True):\r
4419 raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4420\r
4421 OptRomName = self.__GetUiName()\r
4422\r
4423 if not self.__IsToken( "]"):\r
4424 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
4425\r
4426 OptRomObj = OptionRom.OPTIONROM()\r
4427 OptRomObj.DriverName = OptRomName\r
4428 self.Profile.OptRomDict[OptRomName] = OptRomObj\r
4429\r
4430 while True:\r
4431 isInf = self.__GetOptRomInfStatement(OptRomObj)\r
4432 isFile = self.__GetOptRomFileStatement(OptRomObj)\r
4433 if not isInf and not isFile:\r
4434 break\r
4435 \r
4436 return True\r
4437\r
4438 ## __GetOptRomInfStatement() method\r
4439 #\r
4440 # Get INF statements\r
4441 #\r
4442 # @param self The object pointer\r
4443 # @param Obj for whom inf statement is got\r
4444 # @retval True Successfully find inf statement\r
4445 # @retval False Not able to find inf statement\r
4446 #\r
4447 def __GetOptRomInfStatement(self, Obj):\r
4448\r
4449 if not self.__IsKeyword( "INF"):\r
4450 return False\r
4451\r
4452 ffsInf = OptRomInfStatement.OptRomInfStatement()\r
4453 self.__GetInfOptions( ffsInf)\r
4454\r
4455 if not self.__GetNextToken():\r
4456 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)\r
4457 ffsInf.InfFileName = self.__Token\r
6310ffd7 4458 if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:\r
4459 #check for file path\r
4460 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4461 if ErrorCode != 0:\r
4462 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114
LG
4463\r
4464 if not ffsInf.InfFileName in self.Profile.InfList:\r
4465 self.Profile.InfList.append(ffsInf.InfFileName)\r
d0acc87a
LG
4466 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
4467 self.Profile.InfFileLineList.append(FileLineTuple)\r
2502b735
YZ
4468 if ffsInf.UseArch:\r
4469 if ffsInf.UseArch not in self.Profile.InfDict:\r
4470 self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]\r
4471 else:\r
4472 self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)\r
4473 else:\r
4474 self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)\r
30fdf114
LG
4475\r
4476 \r
4477 self.__GetOptRomOverrides (ffsInf)\r
4478 \r
4479 Obj.FfsList.append(ffsInf)\r
4480 return True\r
4481\r
4482 ## __GetOptRomOverrides() method\r
4483 #\r
4484 # Get overrides for OptROM INF & FILE\r
4485 #\r
4486 # @param self The object pointer\r
4487 # @param FfsInfObj for whom overrides is got\r
4488 #\r
4489 def __GetOptRomOverrides(self, Obj):\r
4490 if self.__IsToken('{'):\r
4491 Overrides = OptionRom.OverrideAttribs()\r
fd171542 4492 while True:\r
4493 if self.__IsKeyword( "PCI_VENDOR_ID"):\r
4494 if not self.__IsToken( "="):\r
4495 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4496 if not self.__GetNextHexNumber():\r
4497 raise Warning("expected Hex vendor id", self.FileName, self.CurrentLineNumber)\r
4498 Overrides.PciVendorId = self.__Token\r
4499 continue\r
4500\r
4501 if self.__IsKeyword( "PCI_CLASS_CODE"):\r
4502 if not self.__IsToken( "="):\r
4503 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4504 if not self.__GetNextHexNumber():\r
4505 raise Warning("expected Hex class code", self.FileName, self.CurrentLineNumber)\r
4506 Overrides.PciClassCode = self.__Token\r
4507 continue\r
4508\r
4509 if self.__IsKeyword( "PCI_DEVICE_ID"):\r
4510 if not self.__IsToken( "="):\r
4511 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4512 if not self.__GetNextHexNumber():\r
4513 raise Warning("expected Hex device id", self.FileName, self.CurrentLineNumber)\r
4514\r
4515 Overrides.PciDeviceId = self.__Token\r
4516 continue\r
4517\r
4518 if self.__IsKeyword( "PCI_REVISION"):\r
4519 if not self.__IsToken( "="):\r
4520 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4521 if not self.__GetNextHexNumber():\r
4522 raise Warning("expected Hex revision", self.FileName, self.CurrentLineNumber)\r
4523 Overrides.PciRevision = self.__Token\r
4524 continue\r
4525\r
79b74a03 4526 if self.__IsKeyword( "PCI_COMPRESS"):\r
fd171542 4527 if not self.__IsToken( "="):\r
4528 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4529 if not self.__GetNextToken():\r
4530 raise Warning("expected TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)\r
4531 Overrides.NeedCompress = self.__Token.upper() == 'TRUE'\r
4532 continue\r
4533\r
4534 if self.__IsToken( "}"):\r
4535 break\r
4536 else:\r
4537 EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber)\r
4538\r
30fdf114
LG
4539 Obj.OverrideAttribs = Overrides\r
4540 \r
4541 ## __GetOptRomFileStatement() method\r
4542 #\r
4543 # Get FILE statements\r
4544 #\r
4545 # @param self The object pointer\r
4546 # @param Obj for whom FILE statement is got\r
4547 # @retval True Successfully find FILE statement\r
4548 # @retval False Not able to find FILE statement\r
4549 #\r
4550 def __GetOptRomFileStatement(self, Obj):\r
4551\r
4552 if not self.__IsKeyword( "FILE"):\r
4553 return False\r
4554\r
4555 FfsFileObj = OptRomFileStatement.OptRomFileStatement()\r
4556\r
4557 if not self.__IsKeyword("EFI") and not self.__IsKeyword("BIN"):\r
4558 raise Warning("expected Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber)\r
4559 FfsFileObj.FileType = self.__Token\r
4560\r
4561 if not self.__GetNextToken():\r
4562 raise Warning("expected File path", self.FileName, self.CurrentLineNumber)\r
4563 FfsFileObj.FileName = self.__Token\r
6310ffd7 4564 if FfsFileObj.FileName.replace('$(WORKSPACE)', '').find('$') == -1:\r
4565 #check for file path\r
4566 ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4567 if ErrorCode != 0:\r
4568 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114
LG
4569\r
4570 if FfsFileObj.FileType == 'EFI':\r
4571 self.__GetOptRomOverrides(FfsFileObj)\r
4572 \r
4573 Obj.FfsList.append(FfsFileObj)\r
4574\r
4575 return True\r
fd171542 4576\r
4577 ## __GetCapInFd() method\r
4578 #\r
4579 # Get Cap list contained in FD\r
4580 #\r
4581 # @param self The object pointer\r
4582 # @param FdName FD name\r
4583 # @retval CapList List of Capsule in FD\r
4584 #\r
4585 def __GetCapInFd (self, FdName):\r
4586\r
4587 CapList = []\r
4588 if FdName.upper() in self.Profile.FdDict.keys():\r
4589 FdObj = self.Profile.FdDict[FdName.upper()]\r
4590 for elementRegion in FdObj.RegionList:\r
4591 if elementRegion.RegionType == 'CAPSULE':\r
4592 for elementRegionData in elementRegion.RegionDataList:\r
4593 if elementRegionData.endswith(".cap"):\r
4594 continue\r
4595 if elementRegionData != None and elementRegionData.upper() not in CapList:\r
4596 CapList.append(elementRegionData.upper())\r
4597 return CapList\r
4598\r
4599 ## __GetReferencedFdCapTuple() method\r
4600 #\r
4601 # Get FV and FD list referenced by a capsule image\r
4602 #\r
4603 # @param self The object pointer\r
4604 # @param CapObj Capsule section to be searched\r
4605 # @param RefFdList referenced FD by section\r
4606 # @param RefFvList referenced FV by section\r
4607 #\r
4608 def __GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []):\r
4609\r
4610 for CapsuleDataObj in CapObj.CapsuleDataList :\r
b36d134f 4611 if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName != None and CapsuleDataObj.FvName.upper() not in RefFvList:\r
fd171542 4612 RefFvList.append (CapsuleDataObj.FvName.upper())\r
b36d134f
LG
4613 elif hasattr(CapsuleDataObj, 'FdName') and CapsuleDataObj.FdName != None and CapsuleDataObj.FdName.upper() not in RefFdList:\r
4614 RefFdList.append (CapsuleDataObj.FdName.upper()) \r
fd171542 4615 elif CapsuleDataObj.Ffs != None:\r
b36d134f
LG
4616 if isinstance(CapsuleDataObj.Ffs, FfsFileStatement.FileStatement):\r
4617 if CapsuleDataObj.Ffs.FvName != None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList:\r
4618 RefFvList.append(CapsuleDataObj.Ffs.FvName.upper())\r
4619 elif CapsuleDataObj.Ffs.FdName != None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList:\r
4620 RefFdList.append(CapsuleDataObj.Ffs.FdName.upper())\r
4621 else:\r
4622 self.__GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList)\r
fd171542 4623\r
30fdf114
LG
4624 ## __GetFvInFd() method\r
4625 #\r
4626 # Get FV list contained in FD\r
4627 #\r
4628 # @param self The object pointer\r
4629 # @param FdName FD name\r
4630 # @retval FvList list of FV in FD\r
4631 #\r
4632 def __GetFvInFd (self, FdName):\r
4633\r
4634 FvList = []\r
4635 if FdName.upper() in self.Profile.FdDict.keys():\r
4636 FdObj = self.Profile.FdDict[FdName.upper()]\r
4637 for elementRegion in FdObj.RegionList:\r
4638 if elementRegion.RegionType == 'FV':\r
4639 for elementRegionData in elementRegion.RegionDataList:\r
fd171542 4640 if elementRegionData.endswith(".fv"):\r
4641 continue\r
30fdf114
LG
4642 if elementRegionData != None and elementRegionData.upper() not in FvList:\r
4643 FvList.append(elementRegionData.upper())\r
4644 return FvList\r
4645\r
4646 ## __GetReferencedFdFvTuple() method\r
4647 #\r
4648 # Get FD and FV list referenced by a FFS file\r
4649 #\r
4650 # @param self The object pointer\r
4651 # @param FfsFile contains sections to be searched\r
4652 # @param RefFdList referenced FD by section\r
4653 # @param RefFvList referenced FV by section\r
4654 #\r
4655 def __GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):\r
4656\r
4657 for FfsObj in FvObj.FfsList:\r
4658 if isinstance(FfsObj, FfsFileStatement.FileStatement):\r
4659 if FfsObj.FvName != None and FfsObj.FvName.upper() not in RefFvList:\r
4660 RefFvList.append(FfsObj.FvName.upper())\r
4661 elif FfsObj.FdName != None and FfsObj.FdName.upper() not in RefFdList:\r
4662 RefFdList.append(FfsObj.FdName.upper())\r
4663 else:\r
4664 self.__GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)\r
4665\r
4666 ## __GetReferencedFdFvTupleFromSection() method\r
4667 #\r
4668 # Get FD and FV list referenced by a FFS section\r
4669 #\r
4670 # @param self The object pointer\r
4671 # @param FfsFile contains sections to be searched\r
4672 # @param FdList referenced FD by section\r
4673 # @param FvList referenced FV by section\r
4674 #\r
4675 def __GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):\r
4676\r
4677 SectionStack = []\r
4678 SectionStack.extend(FfsFile.SectionList)\r
4679 while SectionStack != []:\r
4680 SectionObj = SectionStack.pop()\r
4681 if isinstance(SectionObj, FvImageSection.FvImageSection):\r
4682 if SectionObj.FvName != None and SectionObj.FvName.upper() not in FvList:\r
4683 FvList.append(SectionObj.FvName.upper())\r
4684 if SectionObj.Fv != None and SectionObj.Fv.UiFvName != None and SectionObj.Fv.UiFvName.upper() not in FvList:\r
4685 FvList.append(SectionObj.Fv.UiFvName.upper())\r
4686 self.__GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)\r
4687\r
4688 if isinstance(SectionObj, CompressSection.CompressSection) or isinstance(SectionObj, GuidSection.GuidSection):\r
4689 SectionStack.extend(SectionObj.SectionList)\r
4690\r
4691 ## CycleReferenceCheck() method\r
4692 #\r
4693 # Check whether cycle reference exists in FDF\r
4694 #\r
4695 # @param self The object pointer\r
4696 # @retval True cycle reference exists\r
4697 # @retval False Not exists cycle reference\r
4698 #\r
4699 def CycleReferenceCheck(self):\r
fd171542 4700 #\r
4701 # Check the cycle between FV and FD image\r
4702 #\r
4703 MaxLength = len (self.Profile.FvDict)\r
4704 for FvName in self.Profile.FvDict.keys():\r
4705 LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName\r
4706 RefFvStack = []\r
4707 RefFvStack.append(FvName)\r
4708 FdAnalyzedList = []\r
4709 \r
4710 Index = 0\r
4711 while RefFvStack != [] and Index < MaxLength:\r
4712 Index = Index + 1\r
4713 FvNameFromStack = RefFvStack.pop()\r
4714 if FvNameFromStack.upper() in self.Profile.FvDict.keys():\r
4715 FvObj = self.Profile.FvDict[FvNameFromStack.upper()]\r
4716 else:\r
4717 continue\r
30fdf114 4718\r
fd171542 4719 RefFdList = []\r
4720 RefFvList = []\r
4721 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)\r
30fdf114 4722\r
fd171542 4723 for RefFdName in RefFdList:\r
4724 if RefFdName in FdAnalyzedList:\r
30fdf114
LG
4725 continue\r
4726\r
fd171542 4727 LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName)\r
4728 FvInFdList = self.__GetFvInFd(RefFdName)\r
4729 if FvInFdList != []:\r
4730 for FvNameInFd in FvInFdList:\r
4731 LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)\r
4732 if FvNameInFd not in RefFvStack:\r
4733 RefFvStack.append(FvNameInFd)\r
4734\r
4735 if FvName in RefFvStack or FvNameFromStack in RefFvStack:\r
4736 EdkLogger.info(LogStr)\r
4737 return True\r
4738 FdAnalyzedList.append(RefFdName)\r
30fdf114 4739\r
fd171542 4740 for RefFvName in RefFvList:\r
4741 LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName)\r
4742 if RefFvName not in RefFvStack:\r
4743 RefFvStack.append(RefFvName)\r
4744\r
4745 if FvName in RefFvStack or FvNameFromStack in RefFvStack:\r
4746 EdkLogger.info(LogStr)\r
4747 return True\r
4748\r
4749 #\r
4750 # Check the cycle between Capsule and FD image\r
4751 #\r
4752 MaxLength = len (self.Profile.CapsuleDict)\r
4753 for CapName in self.Profile.CapsuleDict.keys():\r
4754 #\r
4755 # Capsule image to be checked.\r
4756 #\r
4757 LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName\r
4758 RefCapStack = []\r
4759 RefCapStack.append(CapName)\r
4760 FdAnalyzedList = []\r
4761 FvAnalyzedList = []\r
4762 \r
4763 Index = 0\r
4764 while RefCapStack != [] and Index < MaxLength:\r
4765 Index = Index + 1\r
4766 CapNameFromStack = RefCapStack.pop()\r
4767 if CapNameFromStack.upper() in self.Profile.CapsuleDict.keys():\r
4768 CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()]\r
4769 else:\r
4770 continue\r
4771\r
4772 RefFvList = []\r
4773 RefFdList = []\r
4774 self.__GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList)\r
4775\r
4776 FvListLength = 0\r
4777 FdListLength = 0\r
4778 while FvListLength < len (RefFvList) or FdListLength < len (RefFdList):\r
30fdf114
LG
4779 for RefFdName in RefFdList:\r
4780 if RefFdName in FdAnalyzedList:\r
4781 continue\r
4782\r
fd171542 4783 LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName)\r
4784 CapInFdList = self.__GetCapInFd(RefFdName)\r
4785 if CapInFdList != []:\r
4786 for CapNameInFd in CapInFdList:\r
4787 LogStr += "FD %s contains Capsule %s\n" % (RefFdName,CapNameInFd)\r
4788 if CapNameInFd not in RefCapStack:\r
4789 RefCapStack.append(CapNameInFd)\r
4790\r
4791 if CapName in RefCapStack or CapNameFromStack in RefCapStack:\r
4792 EdkLogger.info(LogStr)\r
4793 return True\r
4794\r
30fdf114
LG
4795 FvInFdList = self.__GetFvInFd(RefFdName)\r
4796 if FvInFdList != []:\r
fd171542 4797 for FvNameInFd in FvInFdList:\r
4798 LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)\r
4799 if FvNameInFd not in RefFvList:\r
4800 RefFvList.append(FvNameInFd)\r
30fdf114 4801\r
fd171542 4802 FdAnalyzedList.append(RefFdName)\r
4803 #\r
4804 # the number of the parsed FV and FD image\r
4805 #\r
4806 FvListLength = len (RefFvList)\r
4807 FdListLength = len (RefFdList)\r
30fdf114 4808 for RefFvName in RefFvList:\r
fd171542 4809 if RefFvName in FvAnalyzedList:\r
4810 continue\r
4811 LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName)\r
4812 if RefFvName.upper() in self.Profile.FvDict.keys():\r
4813 FvObj = self.Profile.FvDict[RefFvName.upper()]\r
4814 else:\r
4815 continue\r
4816 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)\r
4817 FvAnalyzedList.append(RefFvName)\r
30fdf114 4818\r
fd171542 4819 return False\r
30fdf114 4820\r
c17956e0
DL
4821 def GetAllIncludedFile (self):\r
4822 global AllIncludeFileList\r
4823 return AllIncludeFileList\r
4824\r
30fdf114 4825if __name__ == "__main__":\r
b36d134f
LG
4826 import sys\r
4827 try:\r
4828 test_file = sys.argv[1]\r
4829 except IndexError, v:\r
4830 print "Usage: %s filename" % sys.argv[0]\r
4831 sys.exit(1)\r
4832\r
4833 parser = FdfParser(test_file)\r
30fdf114
LG
4834 try:\r
4835 parser.ParseFile()\r
4836 parser.CycleReferenceCheck()\r
4837 except Warning, X:\r
b36d134f 4838 print str(X)\r
30fdf114
LG
4839 else:\r
4840 print "Success!"\r
4841\r