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