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