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