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