MdeModulePkg: Fix build warning on Xhci driver with XCode 32 tool chain.
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FdfParser.py
CommitLineData
30fdf114
LG
1## @file\r
2# parse FDF file\r
3#\r
40d841f6 4# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
30fdf114 5#\r
40d841f6 6# This program and the accompanying materials\r
30fdf114
LG
7# are licensed and made available under the terms and conditions of the BSD License\r
8# which accompanies this distribution. The full text of the license may be found at\r
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13#\r
14\r
15##\r
16# Import Modules\r
17#\r
0d2711a6
LG
18import re\r
19\r
30fdf114
LG
20import Fd\r
21import Region\r
22import Fv\r
23import AprioriSection\r
24import FfsInfStatement\r
25import FfsFileStatement\r
26import VerSection\r
27import UiSection\r
28import FvImageSection\r
29import DataSection\r
30import DepexSection\r
31import CompressSection\r
32import GuidSection\r
33import Capsule\r
34import CapsuleData\r
35import Rule\r
36import RuleComplexFile\r
37import RuleSimpleFile\r
38import EfiSection\r
39import Vtf\r
40import ComponentStatement\r
41import OptionRom\r
42import OptRomInfStatement\r
43import OptRomFileStatement\r
44\r
52302d4d 45from GenFdsGlobalVariable import GenFdsGlobalVariable\r
30fdf114
LG
46from Common.BuildToolError import *\r
47from Common import EdkLogger\r
14c48571 48from Common.Misc import PathClass\r
49from Common.String import NormPath\r
0d2711a6
LG
50import Common.GlobalData as GlobalData\r
51from Common.Expression import *\r
df692f02 52from Common import GlobalData\r
2bcc713e 53from Common.String import ReplaceMacro\r
30fdf114 54\r
d0acc87a
LG
55from Common.Misc import tdict\r
56\r
30fdf114
LG
57import re\r
58import os\r
59\r
60##define T_CHAR_SPACE ' '\r
61##define T_CHAR_NULL '\0'\r
62##define T_CHAR_CR '\r'\r
63##define T_CHAR_TAB '\t'\r
64##define T_CHAR_LF '\n'\r
65##define T_CHAR_SLASH '/'\r
66##define T_CHAR_BACKSLASH '\\'\r
67##define T_CHAR_DOUBLE_QUOTE '\"'\r
68##define T_CHAR_SINGLE_QUOTE '\''\r
69##define T_CHAR_STAR '*'\r
70##define T_CHAR_HASH '#'\r
71\r
72(T_CHAR_SPACE, T_CHAR_NULL, T_CHAR_CR, T_CHAR_TAB, T_CHAR_LF, T_CHAR_SLASH, \\r
73T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \\r
74(' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')\r
75\r
76SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')\r
77\r
0d2711a6
LG
78RegionSizePattern = re.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")\r
79RegionSizeGuidPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")\r
80\r
30fdf114 81IncludeFileList = []\r
30fdf114
LG
82\r
83def GetRealFileLine (File, Line):\r
84\r
85 InsertedLines = 0\r
86 for Profile in IncludeFileList:\r
87 if Line >= Profile.InsertStartLineNumber and Line < Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList):\r
88 return (Profile.FileName, Line - Profile.InsertStartLineNumber + 1)\r
89 if Line >= Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList):\r
90 InsertedLines += Profile.InsertAdjust + len(Profile.FileLinesList)\r
91\r
92 return (File, Line - InsertedLines)\r
93\r
94## The exception class that used to report error messages when parsing FDF\r
95#\r
96# Currently the "ToolName" is set to be "FDF Parser".\r
97#\r
98class Warning (Exception):\r
99 ## The constructor\r
100 #\r
101 # @param self The object pointer\r
102 # @param Str The message to record\r
103 # @param File The FDF name\r
104 # @param Line The Line number that error occurs\r
105 #\r
106 def __init__(self, Str, File = None, Line = None):\r
107\r
108 FileLineTuple = GetRealFileLine(File, Line)\r
109 self.FileName = FileLineTuple[0]\r
110 self.LineNumber = FileLineTuple[1]\r
111 self.Message = Str\r
112 self.ToolName = 'FdfParser'\r
113\r
114 def __str__(self):\r
115 return self.Message\r
116\r
117## The MACRO class that used to record macro value data when parsing include file\r
118#\r
119#\r
120class MacroProfile :\r
121 ## The constructor\r
122 #\r
123 # @param self The object pointer\r
124 # @param FileName The file that to be parsed\r
125 #\r
126 def __init__(self, FileName, Line):\r
127 self.FileName = FileName\r
128 self.DefinedAtLine = Line\r
129 self.MacroName = None\r
130 self.MacroValue = None\r
131\r
132## The Include file content class that used to record file data when parsing include file\r
133#\r
134# May raise Exception when opening file.\r
135#\r
136class IncludeFileProfile :\r
137 ## The constructor\r
138 #\r
139 # @param self The object pointer\r
140 # @param FileName The file that to be parsed\r
141 #\r
142 def __init__(self, FileName):\r
143 self.FileName = FileName\r
144 self.FileLinesList = []\r
145 try:\r
146 fsock = open(FileName, "rb", 0)\r
147 try:\r
148 self.FileLinesList = fsock.readlines()\r
149 finally:\r
150 fsock.close()\r
151\r
152 except:\r
153 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)\r
154\r
155 self.InsertStartLineNumber = None\r
156 self.InsertAdjust = 0\r
157\r
158## The FDF content class that used to record file data when parsing FDF\r
159#\r
160# May raise Exception when opening file.\r
161#\r
162class FileProfile :\r
163 ## The constructor\r
164 #\r
165 # @param self The object pointer\r
166 # @param FileName The file that to be parsed\r
167 #\r
168 def __init__(self, FileName):\r
169 self.FileLinesList = []\r
170 try:\r
171 fsock = open(FileName, "rb", 0)\r
172 try:\r
173 self.FileLinesList = fsock.readlines()\r
174 finally:\r
175 fsock.close()\r
176\r
177 except:\r
178 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)\r
179\r
180\r
181 self.PcdDict = {}\r
182 self.InfList = []\r
d0acc87a
LG
183 # ECC will use this Dict and List information\r
184 self.PcdFileLineDict = {}\r
185 self.InfFileLineList = []\r
186 \r
30fdf114 187 self.FdDict = {}\r
52302d4d 188 self.FdNameNotSet = False\r
30fdf114 189 self.FvDict = {}\r
fd171542 190 self.CapsuleDict = {}\r
30fdf114
LG
191 self.VtfList = []\r
192 self.RuleDict = {}\r
193 self.OptRomDict = {}\r
194\r
195## The syntax parser for FDF\r
196#\r
197# PreprocessFile method should be called prior to ParseFile\r
198# CycleReferenceCheck method can detect cycles in FDF contents\r
199#\r
200# GetNext*** procedures mean these procedures will get next token first, then make judgement.\r
201# Get*** procedures mean these procedures will make judgement on current token only.\r
202#\r
203class FdfParser:\r
204 ## The constructor\r
205 #\r
206 # @param self The object pointer\r
207 # @param FileName The file that to be parsed\r
208 #\r
209 def __init__(self, FileName):\r
210 self.Profile = FileProfile(FileName)\r
211 self.FileName = FileName\r
212 self.CurrentLineNumber = 1\r
213 self.CurrentOffsetWithinLine = 0\r
214 self.CurrentFdName = None\r
215 self.CurrentFvName = None\r
216 self.__Token = ""\r
217 self.__SkippedChars = ""\r
218\r
d0acc87a
LG
219 # Used to section info\r
220 self.__CurSection = []\r
221 # Key: [section name, UI name, arch]\r
222 # Value: {MACRO_NAME : MACRO_VALUE}\r
223 self.__MacroDict = tdict(True, 3)\r
224 self.__PcdDict = {}\r
225\r
30fdf114 226 self.__WipeOffArea = []\r
14c48571 227 if GenFdsGlobalVariable.WorkSpaceDir == '':\r
228 GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE")\r
30fdf114
LG
229\r
230 ## __IsWhiteSpace() method\r
231 #\r
232 # Whether char at current FileBufferPos is whitespace\r
233 #\r
234 # @param self The object pointer\r
235 # @param Char The char to test\r
236 # @retval True The char is a kind of white space\r
237 # @retval False The char is NOT a kind of white space\r
238 #\r
239 def __IsWhiteSpace(self, Char):\r
240 if Char in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_SPACE, T_CHAR_TAB, T_CHAR_LF):\r
241 return True\r
242 else:\r
243 return False\r
244\r
245 ## __SkipWhiteSpace() method\r
246 #\r
247 # Skip white spaces from current char, return number of chars skipped\r
248 #\r
249 # @param self The object pointer\r
250 # @retval Count The number of chars skipped\r
251 #\r
252 def __SkipWhiteSpace(self):\r
253 Count = 0\r
254 while not self.__EndOfFile():\r
255 Count += 1\r
256 if self.__CurrentChar() in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_LF, T_CHAR_SPACE, T_CHAR_TAB):\r
257 self.__SkippedChars += str(self.__CurrentChar())\r
258 self.__GetOneChar()\r
259\r
260 else:\r
261 Count = Count - 1\r
262 return Count\r
263\r
264 ## __EndOfFile() method\r
265 #\r
266 # Judge current buffer pos is at file end\r
267 #\r
268 # @param self The object pointer\r
269 # @retval True Current File buffer position is at file end\r
270 # @retval False Current File buffer position is NOT at file end\r
271 #\r
272 def __EndOfFile(self):\r
273 NumberOfLines = len(self.Profile.FileLinesList)\r
274 SizeOfLastLine = len(self.Profile.FileLinesList[-1])\r
275 if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1:\r
276 return True\r
277 elif self.CurrentLineNumber > NumberOfLines:\r
278 return True\r
279 else:\r
280 return False\r
281\r
282 ## __EndOfLine() method\r
283 #\r
284 # Judge current buffer pos is at line end\r
285 #\r
286 # @param self The object pointer\r
287 # @retval True Current File buffer position is at line end\r
288 # @retval False Current File buffer position is NOT at line end\r
289 #\r
290 def __EndOfLine(self):\r
291 if self.CurrentLineNumber > len(self.Profile.FileLinesList):\r
292 return True\r
293 SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1])\r
294 if self.CurrentOffsetWithinLine >= SizeOfCurrentLine:\r
295 return True\r
296 else:\r
297 return False\r
298\r
299 ## Rewind() method\r
300 #\r
301 # Reset file data buffer to the initial state\r
302 #\r
303 # @param self The object pointer\r
304 #\r
305 def Rewind(self):\r
306 self.CurrentLineNumber = 1\r
307 self.CurrentOffsetWithinLine = 0\r
308\r
309 ## __UndoOneChar() method\r
310 #\r
311 # Go back one char in the file buffer\r
312 #\r
313 # @param self The object pointer\r
314 # @retval True Successfully go back one char\r
315 # @retval False Not able to go back one char as file beginning reached\r
316 #\r
317 def __UndoOneChar(self):\r
318\r
319 if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0:\r
320 return False\r
321 elif self.CurrentOffsetWithinLine == 0:\r
322 self.CurrentLineNumber -= 1\r
323 self.CurrentOffsetWithinLine = len(self.__CurrentLine()) - 1\r
324 else:\r
325 self.CurrentOffsetWithinLine -= 1\r
326 return True\r
327\r
328 ## __GetOneChar() method\r
329 #\r
330 # Move forward one char in the file buffer\r
331 #\r
332 # @param self The object pointer\r
333 #\r
334 def __GetOneChar(self):\r
335 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:\r
0d2711a6
LG
336 self.CurrentLineNumber += 1\r
337 self.CurrentOffsetWithinLine = 0\r
30fdf114 338 else:\r
0d2711a6 339 self.CurrentOffsetWithinLine += 1\r
30fdf114
LG
340\r
341 ## __CurrentChar() method\r
342 #\r
343 # Get the char pointed to by the file buffer pointer\r
344 #\r
345 # @param self The object pointer\r
346 # @retval Char Current char\r
347 #\r
348 def __CurrentChar(self):\r
349 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine]\r
350\r
351 ## __NextChar() method\r
352 #\r
353 # Get the one char pass the char pointed to by the file buffer pointer\r
354 #\r
355 # @param self The object pointer\r
356 # @retval Char Next char\r
357 #\r
358 def __NextChar(self):\r
359 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:\r
360 return self.Profile.FileLinesList[self.CurrentLineNumber][0]\r
361 else:\r
362 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1]\r
363\r
364 ## __SetCurrentCharValue() method\r
365 #\r
366 # Modify the value of current char\r
367 #\r
368 # @param self The object pointer\r
369 # @param Value The new value of current char\r
370 #\r
371 def __SetCurrentCharValue(self, Value):\r
372 self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value\r
373\r
374 ## __CurrentLine() method\r
375 #\r
376 # Get the list that contains current line contents\r
377 #\r
378 # @param self The object pointer\r
379 # @retval List current line contents\r
380 #\r
381 def __CurrentLine(self):\r
382 return self.Profile.FileLinesList[self.CurrentLineNumber - 1]\r
383\r
384 def __StringToList(self):\r
385 self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList]\r
386 self.Profile.FileLinesList[-1].append(' ')\r
387\r
30fdf114
LG
388 def __ReplaceFragment(self, StartPos, EndPos, Value = ' '):\r
389 if StartPos[0] == EndPos[0]:\r
390 Offset = StartPos[1]\r
391 while Offset <= EndPos[1]:\r
392 self.Profile.FileLinesList[StartPos[0]][Offset] = Value\r
393 Offset += 1\r
394 return\r
395\r
396 Offset = StartPos[1]\r
397 while self.Profile.FileLinesList[StartPos[0]][Offset] not in ('\r', '\n'):\r
398 self.Profile.FileLinesList[StartPos[0]][Offset] = Value\r
399 Offset += 1\r
400\r
401 Line = StartPos[0]\r
402 while Line < EndPos[0]:\r
403 Offset = 0\r
404 while self.Profile.FileLinesList[Line][Offset] not in ('\r', '\n'):\r
405 self.Profile.FileLinesList[Line][Offset] = Value\r
406 Offset += 1\r
407 Line += 1\r
408\r
409 Offset = 0\r
410 while Offset <= EndPos[1]:\r
411 self.Profile.FileLinesList[EndPos[0]][Offset] = Value\r
412 Offset += 1\r
413\r
414\r
d5d56f1b
LG
415 def __GetMacroName(self):\r
416 if not self.__GetNextToken():\r
417 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)\r
418 MacroName = self.__Token\r
419 NotFlag = False\r
420 if MacroName.startswith('!'):\r
421 NotFlag = True\r
422 MacroName = MacroName[1:].strip()\r
423 \r
424 if not MacroName.startswith('$(') or not MacroName.endswith(')'):\r
425 raise Warning("Macro name expected(Please use '$(%(Token)s)' if '%(Token)s' is a macro.)" % {"Token" : MacroName},\r
426 self.FileName, self.CurrentLineNumber)\r
427 MacroName = MacroName[2:-1]\r
428 return MacroName, NotFlag\r
d0acc87a
LG
429\r
430 def __SetMacroValue(self, Macro, Value):\r
431 if not self.__CurSection:\r
432 return\r
433\r
434 MacroDict = {}\r
435 if not self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]]:\r
436 self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]] = MacroDict\r
437 else:\r
438 MacroDict = self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]]\r
439 MacroDict[Macro] = Value\r
440\r
441 def __GetMacroValue(self, Macro):\r
442 # Highest priority\r
443 if Macro in GlobalData.gCommandLineDefines:\r
444 return GlobalData.gCommandLineDefines[Macro]\r
445 if Macro in GlobalData.gGlobalDefines:\r
446 return GlobalData.gGlobalDefines[Macro]\r
447\r
448 if self.__CurSection:\r
449 MacroDict = self.__MacroDict[\r
450 self.__CurSection[0],\r
451 self.__CurSection[1],\r
452 self.__CurSection[2]\r
453 ]\r
454 if MacroDict and Macro in MacroDict:\r
455 return MacroDict[Macro]\r
456\r
457 # Lowest priority\r
458 if Macro in GlobalData.gPlatformDefines:\r
459 return GlobalData.gPlatformDefines[Macro]\r
460 return None\r
461\r
462 def __SectionHeaderParser(self, Section):\r
463 # [Defines]\r
464 # [FD.UiName]: use dummy instead if UI name is optional\r
465 # [FV.UiName]\r
466 # [Capsule.UiName]\r
467 # [Rule]: don't take rule section into account, macro is not allowed in this section\r
468 # [VTF.arch.UiName, arch]\r
469 # [OptionRom.DriverName]\r
470 self.__CurSection = []\r
471 Section = Section.strip()[1:-1].upper().replace(' ', '').strip('.')\r
472 ItemList = Section.split('.')\r
473 Item = ItemList[0]\r
474 if Item == '' or Item == 'RULE':\r
475 return\r
476\r
477 if Item == 'DEFINES':\r
478 self.__CurSection = ['COMMON', 'COMMON', 'COMMON']\r
479 elif Item == 'VTF' and len(ItemList) == 3:\r
480 UiName = ItemList[2]\r
481 Pos = UiName.find(',')\r
482 if Pos != -1:\r
483 UiName = UiName[:Pos]\r
484 self.__CurSection = ['VTF', UiName, ItemList[1]]\r
485 elif len(ItemList) > 1:\r
486 self.__CurSection = [ItemList[0], ItemList[1], 'COMMON']\r
487 elif len(ItemList) > 0:\r
488 self.__CurSection = [ItemList[0], 'DUMMY', 'COMMON']\r
489\r
30fdf114
LG
490 ## PreprocessFile() method\r
491 #\r
492 # Preprocess file contents, replace comments with spaces.\r
493 # In the end, rewind the file buffer pointer to the beginning\r
494 # BUGBUG: No !include statement processing contained in this procedure\r
495 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]\r
496 #\r
497 # @param self The object pointer\r
498 #\r
499 def PreprocessFile(self):\r
500\r
501 self.Rewind()\r
502 InComment = False\r
503 DoubleSlashComment = False\r
504 HashComment = False\r
505 # HashComment in quoted string " " is ignored.\r
506 InString = False\r
507\r
508 while not self.__EndOfFile():\r
509\r
510 if self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment:\r
511 InString = not InString\r
512 # meet new line, then no longer in a comment for // and '#'\r
513 if self.__CurrentChar() == T_CHAR_LF:\r
514 self.CurrentLineNumber += 1\r
515 self.CurrentOffsetWithinLine = 0\r
516 if InComment and DoubleSlashComment:\r
517 InComment = False\r
518 DoubleSlashComment = False\r
519 if InComment and HashComment:\r
520 InComment = False\r
521 HashComment = False\r
522 # check for */ comment end\r
523 elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH:\r
524 self.__SetCurrentCharValue(T_CHAR_SPACE)\r
525 self.__GetOneChar()\r
526 self.__SetCurrentCharValue(T_CHAR_SPACE)\r
527 self.__GetOneChar()\r
528 InComment = False\r
529 # set comments to spaces\r
530 elif InComment:\r
531 self.__SetCurrentCharValue(T_CHAR_SPACE)\r
532 self.__GetOneChar()\r
533 # check for // comment\r
534 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH and not self.__EndOfLine():\r
535 InComment = True\r
536 DoubleSlashComment = True\r
537 # check for '#' comment\r
538 elif self.__CurrentChar() == T_CHAR_HASH and not self.__EndOfLine() and not InString:\r
539 InComment = True\r
540 HashComment = True\r
541 # check for /* comment start\r
542 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR:\r
543 self.__SetCurrentCharValue( T_CHAR_SPACE)\r
544 self.__GetOneChar()\r
545 self.__SetCurrentCharValue( T_CHAR_SPACE)\r
546 self.__GetOneChar()\r
547 InComment = True\r
548 else:\r
549 self.__GetOneChar()\r
550\r
551 # restore from ListOfList to ListOfString\r
552 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]\r
553 self.Rewind()\r
554\r
555 ## PreprocessIncludeFile() method\r
556 #\r
557 # Preprocess file contents, replace !include statements with file contents.\r
558 # In the end, rewind the file buffer pointer to the beginning\r
559 #\r
560 # @param self The object pointer\r
561 #\r
562 def PreprocessIncludeFile(self):\r
563\r
564 while self.__GetNextToken():\r
565\r
566 if self.__Token == '!include':\r
567 IncludeLine = self.CurrentLineNumber\r
568 IncludeOffset = self.CurrentOffsetWithinLine - len('!include')\r
569 if not self.__GetNextToken():\r
570 raise Warning("expected include file name", self.FileName, self.CurrentLineNumber)\r
571 IncFileName = self.__Token\r
2bcc713e 572 __IncludeMacros = {}\r
d0acc87a
LG
573 for Macro in ['WORKSPACE', 'ECP_SOURCE', 'EFI_SOURCE', 'EDK_SOURCE']:\r
574 MacroVal = self.__GetMacroValue(Macro)\r
575 if MacroVal:\r
576 __IncludeMacros[Macro] = MacroVal\r
577\r
578 try:\r
579 IncludedFile = NormPath(ReplaceMacro(IncFileName, __IncludeMacros, RaiseError=True))\r
580 except:\r
581 raise Warning("only these system environment variables are permitted to start the path of the included file: "\r
582 "$(WORKSPACE), $(ECP_SOURCE), $(EFI_SOURCE), $(EDK_SOURCE)",\r
583 self.FileName, self.CurrentLineNumber)\r
2bcc713e
LG
584 #\r
585 # First search the include file under the same directory as FDF file\r
586 #\r
587 IncludedFile1 = PathClass(IncludedFile, os.path.dirname(self.FileName))\r
588 ErrorCode = IncludedFile1.Validate()[0]\r
589 if ErrorCode != 0:\r
590 #\r
591 # Then search the include file under the same directory as DSC file\r
592 #\r
d0acc87a
LG
593 PlatformDir = ''\r
594 if GenFdsGlobalVariable.ActivePlatform:\r
595 PlatformDir = GenFdsGlobalVariable.ActivePlatform.Dir\r
596 elif GlobalData.gActivePlatform:\r
597 PlatformDir = GlobalData.gActivePlatform.MetaFile.Dir\r
598 IncludedFile1 = PathClass(IncludedFile, PlatformDir)\r
2bcc713e
LG
599 ErrorCode = IncludedFile1.Validate()[0]\r
600 if ErrorCode != 0:\r
601 #\r
602 # Also search file under the WORKSPACE directory\r
603 #\r
604 IncludedFile1 = PathClass(IncludedFile, GlobalData.gWorkspace)\r
605 ErrorCode = IncludedFile1.Validate()[0]\r
606 if ErrorCode != 0:\r
d0acc87a 607 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 608 self.FileName, self.CurrentLineNumber)\r
30fdf114 609\r
2bcc713e 610 IncFileProfile = IncludeFileProfile(IncludedFile1.Path)\r
30fdf114
LG
611\r
612 CurrentLine = self.CurrentLineNumber\r
613 CurrentOffset = self.CurrentOffsetWithinLine\r
614 # list index of the insertion, note that line number is 'CurrentLine + 1'\r
615 InsertAtLine = CurrentLine\r
616 IncFileProfile.InsertStartLineNumber = InsertAtLine + 1\r
617 # deal with remaining portions after "!include filename", if exists.\r
618 if self.__GetNextToken():\r
619 if self.CurrentLineNumber == CurrentLine:\r
620 RemainingLine = self.__CurrentLine()[CurrentOffset:]\r
621 self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine)\r
622 IncFileProfile.InsertAdjust += 1\r
623 self.CurrentLineNumber += 1\r
624 self.CurrentOffsetWithinLine = 0\r
625\r
626 for Line in IncFileProfile.FileLinesList:\r
627 self.Profile.FileLinesList.insert(InsertAtLine, Line)\r
628 self.CurrentLineNumber += 1\r
629 InsertAtLine += 1\r
630\r
631 IncludeFileList.append(IncFileProfile)\r
632\r
633 # comment out the processed include file statement\r
634 TempList = list(self.Profile.FileLinesList[IncludeLine - 1])\r
635 TempList.insert(IncludeOffset, '#')\r
636 self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)\r
637\r
638 self.Rewind()\r
0d2711a6 639 \r
da92f276
LG
640 def __GetIfListCurrentItemStat(self, IfList):\r
641 if len(IfList) == 0:\r
642 return True\r
643 \r
644 for Item in IfList:\r
645 if Item[1] == False:\r
646 return False\r
647 \r
648 return True\r
0d2711a6 649 \r
6780eef1 650 ## PreprocessConditionalStatement() method\r
30fdf114 651 #\r
6780eef1 652 # Preprocess conditional statement.\r
30fdf114
LG
653 # In the end, rewind the file buffer pointer to the beginning\r
654 #\r
655 # @param self The object pointer\r
656 #\r
657 def PreprocessConditionalStatement(self):\r
658 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]\r
659 IfList = []\r
0d2711a6 660 RegionLayoutLine = 0\r
d0acc87a 661 ReplacedLine = -1\r
30fdf114 662 while self.__GetNextToken():\r
d0acc87a
LG
663 # Determine section name and the location dependent macro\r
664 if self.__GetIfListCurrentItemStat(IfList):\r
665 if self.__Token.startswith('['):\r
666 Header = self.__Token\r
667 if not self.__Token.endswith(']'):\r
668 self.__SkipToToken(']')\r
669 Header += self.__SkippedChars\r
670 if Header.find('$(') != -1:\r
671 raise Warning("macro cannot be used in section header", self.FileName, self.CurrentLineNumber)\r
672 self.__SectionHeaderParser(Header)\r
673 continue\r
674 # Replace macros except in RULE section or out of section\r
675 elif self.__CurSection and ReplacedLine != self.CurrentLineNumber:\r
676 ReplacedLine = self.CurrentLineNumber\r
677 self.__UndoToken()\r
678 CurLine = self.Profile.FileLinesList[ReplacedLine - 1]\r
679 PreIndex = 0\r
680 StartPos = CurLine.find('$(', PreIndex)\r
681 EndPos = CurLine.find(')', StartPos+2)\r
9508d0fa 682 while StartPos != -1 and EndPos != -1 and not (self.__Token == '!ifdef' or self.__Token == '!ifndef'):\r
d0acc87a
LG
683 MacroName = CurLine[StartPos+2 : EndPos]\r
684 MacorValue = self.__GetMacroValue(MacroName)\r
685 if MacorValue != None:\r
686 CurLine = CurLine.replace('$(' + MacroName + ')', MacorValue, 1)\r
687 if MacorValue.find('$(') != -1:\r
688 PreIndex = StartPos\r
689 else:\r
690 PreIndex = StartPos + len(MacorValue)\r
691 else:\r
692 PreIndex = EndPos + 1\r
693 StartPos = CurLine.find('$(', PreIndex)\r
694 EndPos = CurLine.find(')', StartPos+2)\r
695 self.Profile.FileLinesList[ReplacedLine - 1] = CurLine\r
696 continue\r
697\r
30fdf114 698 if self.__Token == 'DEFINE':\r
d0acc87a
LG
699 if self.__GetIfListCurrentItemStat(IfList):\r
700 if not self.__CurSection:\r
701 raise Warning("macro cannot be defined in Rule section or out of section", self.FileName, self.CurrentLineNumber)\r
da92f276
LG
702 DefineLine = self.CurrentLineNumber - 1\r
703 DefineOffset = self.CurrentOffsetWithinLine - len('DEFINE')\r
704 if not self.__GetNextToken():\r
705 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)\r
706 Macro = self.__Token\r
707 if not self.__IsToken( "="):\r
708 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
709 \r
d0acc87a
LG
710 Value = self.__GetExpression()\r
711 self.__SetMacroValue(Macro, Value)\r
da92f276 712 self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
0d2711a6
LG
713 elif self.__Token == 'SET':\r
714 PcdPair = self.__GetNextPcdName()\r
715 PcdName = "%s.%s" % (PcdPair[1], PcdPair[0])\r
716 if not self.__IsToken( "="):\r
717 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
718\r
d0acc87a
LG
719 Value = self.__GetExpression()\r
720 Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)\r
30fdf114 721\r
d0acc87a 722 self.__PcdDict[PcdName] = Value\r
30fdf114
LG
723 elif self.__Token in ('!ifdef', '!ifndef', '!if'):\r
724 IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))\r
725 IfList.append([IfStartPos, None, None])\r
0d2711a6 726\r
30fdf114 727 CondLabel = self.__Token\r
0d2711a6 728 Expression = self.__GetExpression()\r
d5d56f1b 729 \r
30fdf114 730 if CondLabel == '!if':\r
0d2711a6 731 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')\r
30fdf114 732 else:\r
0d2711a6
LG
733 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'in')\r
734 if CondLabel == '!ifndef':\r
30fdf114 735 ConditionSatisfied = not ConditionSatisfied\r
30fdf114 736\r
0d2711a6
LG
737 BranchDetermined = ConditionSatisfied\r
738 IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]\r
739 if ConditionSatisfied:\r
740 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) \r
30fdf114
LG
741 elif self.__Token in ('!elseif', '!else'):\r
742 ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))\r
743 if len(IfList) <= 0:\r
744 raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)\r
0d2711a6 745\r
30fdf114
LG
746 if IfList[-1][1]:\r
747 IfList[-1] = [ElseStartPos, False, True]\r
748 self.__WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
749 else:\r
750 self.__WipeOffArea.append((IfList[-1][0], ElseStartPos))\r
751 IfList[-1] = [ElseStartPos, True, IfList[-1][2]]\r
752 if self.__Token == '!elseif':\r
0d2711a6
LG
753 Expression = self.__GetExpression()\r
754 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')\r
30fdf114
LG
755 IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]]\r
756\r
757 if IfList[-1][1]:\r
758 if IfList[-1][2]:\r
759 IfList[-1][1] = False\r
760 else:\r
761 IfList[-1][2] = True\r
762 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
30fdf114 763 elif self.__Token == '!endif':\r
d0acc87a
LG
764 if len(IfList) <= 0:\r
765 raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
766 if IfList[-1][1]:\r
767 self.__WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
768 else:\r
769 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
770\r
771 IfList.pop()\r
0d2711a6
LG
772 elif not IfList: # Don't use PCDs inside conditional directive\r
773 if self.CurrentLineNumber <= RegionLayoutLine:\r
774 # Don't try the same line twice\r
775 continue\r
776 RegionSize = RegionSizePattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])\r
777 if not RegionSize:\r
778 RegionLayoutLine = self.CurrentLineNumber\r
779 continue\r
780 RegionSizeGuid = RegionSizeGuidPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber])\r
781 if not RegionSizeGuid:\r
782 RegionLayoutLine = self.CurrentLineNumber + 1\r
783 continue\r
d0acc87a
LG
784 self.__PcdDict[RegionSizeGuid.group('base')] = RegionSize.group('base')\r
785 self.__PcdDict[RegionSizeGuid.group('size')] = RegionSize.group('size')\r
0d2711a6
LG
786 RegionLayoutLine = self.CurrentLineNumber + 1\r
787\r
788 if IfList:\r
30fdf114
LG
789 raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber)\r
790 self.Rewind()\r
791\r
d0acc87a
LG
792 def __CollectMacroPcd(self):\r
793 MacroDict = {}\r
794\r
795 # PCD macro\r
796 MacroDict.update(self.__PcdDict)\r
797\r
798 # Lowest priority\r
799 MacroDict.update(GlobalData.gPlatformDefines)\r
800\r
801 if self.__CurSection:\r
802 # Defines macro\r
803 ScopeMacro = self.__MacroDict['COMMON', 'COMMON', 'COMMON']\r
804 if ScopeMacro:\r
805 MacroDict.update(ScopeMacro)\r
806 \r
807 # Section macro\r
808 ScopeMacro = self.__MacroDict[\r
809 self.__CurSection[0],\r
810 self.__CurSection[1],\r
811 self.__CurSection[2]\r
812 ]\r
813 if ScopeMacro:\r
814 MacroDict.update(ScopeMacro)\r
815\r
816 MacroDict.update(GlobalData.gGlobalDefines)\r
817 MacroDict.update(GlobalData.gCommandLineDefines)\r
818 # Highest priority\r
819\r
820 return MacroDict\r
821\r
0d2711a6 822 def __EvaluateConditional(self, Expression, Line, Op = None, Value = None):\r
30fdf114 823 FileLineTuple = GetRealFileLine(self.FileName, Line)\r
d0acc87a 824 MacroPcdDict = self.__CollectMacroPcd()\r
0d2711a6
LG
825 if Op == 'eval':\r
826 try:\r
d0acc87a
LG
827 if Value:\r
828 return ValueExpression(Expression, MacroPcdDict)(True)\r
829 else:\r
830 return ValueExpression(Expression, MacroPcdDict)()\r
0d2711a6
LG
831 except WrnExpression, Excpt:\r
832 # \r
833 # Catch expression evaluation warning here. We need to report\r
834 # the precise number of line and return the evaluation result\r
835 #\r
836 EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),\r
837 File=self.FileName, ExtraData=self.__CurrentLine(), \r
838 Line=Line)\r
839 return Excpt.result\r
840 except Exception, Excpt:\r
841 raise Warning("Invalid expression", *FileLineTuple)\r
842 else:\r
843 if Expression.startswith('$(') and Expression[-1] == ')':\r
844 Expression = Expression[2:-1] \r
d0acc87a 845 return Expression in MacroPcdDict\r
30fdf114
LG
846\r
847 ## __IsToken() method\r
848 #\r
849 # Check whether input string is found from current char position along\r
850 # If found, the string value is put into self.__Token\r
851 #\r
852 # @param self The object pointer\r
853 # @param String The string to search\r
854 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive\r
855 # @retval True Successfully find string, file buffer pointer moved forward\r
856 # @retval False Not able to find string, file buffer pointer not changed\r
857 #\r
858 def __IsToken(self, String, IgnoreCase = False):\r
859 self.__SkipWhiteSpace()\r
860\r
861 # Only consider the same line, no multi-line token allowed\r
862 StartPos = self.CurrentOffsetWithinLine\r
863 index = -1\r
864 if IgnoreCase:\r
865 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())\r
866 else:\r
867 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)\r
868 if index == 0:\r
869 self.CurrentOffsetWithinLine += len(String)\r
870 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]\r
871 return True\r
872 return False\r
873\r
874 ## __IsKeyword() method\r
875 #\r
876 # Check whether input keyword is found from current char position along, whole word only!\r
877 # If found, the string value is put into self.__Token\r
878 #\r
879 # @param self The object pointer\r
880 # @param Keyword The string to search\r
881 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive\r
882 # @retval True Successfully find string, file buffer pointer moved forward\r
883 # @retval False Not able to find string, file buffer pointer not changed\r
884 #\r
885 def __IsKeyword(self, KeyWord, IgnoreCase = False):\r
886 self.__SkipWhiteSpace()\r
887\r
888 # Only consider the same line, no multi-line token allowed\r
889 StartPos = self.CurrentOffsetWithinLine\r
890 index = -1\r
891 if IgnoreCase:\r
892 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(KeyWord.upper())\r
893 else:\r
894 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(KeyWord)\r
895 if index == 0:\r
896 followingChar = self.__CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)]\r
897 if not str(followingChar).isspace() and followingChar not in SEPERATOR_TUPLE:\r
898 return False\r
899 self.CurrentOffsetWithinLine += len(KeyWord)\r
900 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]\r
901 return True\r
902 return False\r
903\r
0d2711a6
LG
904 def __GetExpression(self):\r
905 Line = self.Profile.FileLinesList[self.CurrentLineNumber - 1]\r
906 Index = len(Line) - 1\r
907 while Line[Index] in ['\r', '\n']:\r
908 Index -= 1\r
909 ExpressionString = self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:Index+1]\r
910 self.CurrentOffsetWithinLine += len(ExpressionString)\r
911 ExpressionString = ExpressionString.strip()\r
912 return ExpressionString\r
913\r
30fdf114
LG
914 ## __GetNextWord() method\r
915 #\r
916 # Get next C name from file lines\r
917 # If found, the string value is put into self.__Token\r
918 #\r
919 # @param self The object pointer\r
920 # @retval True Successfully find a C name string, file buffer pointer moved forward\r
921 # @retval False Not able to find a C name string, file buffer pointer not changed\r
922 #\r
923 def __GetNextWord(self):\r
924 self.__SkipWhiteSpace()\r
925 if self.__EndOfFile():\r
926 return False\r
927\r
928 TempChar = self.__CurrentChar()\r
929 StartPos = self.CurrentOffsetWithinLine\r
930 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_':\r
931 self.__GetOneChar()\r
932 while not self.__EndOfLine():\r
933 TempChar = self.__CurrentChar()\r
934 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \\r
935 or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-':\r
936 self.__GetOneChar()\r
937\r
938 else:\r
939 break\r
940\r
941 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]\r
942 return True\r
943\r
944 return False\r
945\r
946 ## __GetNextToken() method\r
947 #\r
948 # Get next token unit before a seperator\r
949 # If found, the string value is put into self.__Token\r
950 #\r
951 # @param self The object pointer\r
952 # @retval True Successfully find a token unit, file buffer pointer moved forward\r
953 # @retval False Not able to find a token unit, file buffer pointer not changed\r
954 #\r
955 def __GetNextToken(self):\r
956 # Skip leading spaces, if exist.\r
957 self.__SkipWhiteSpace()\r
958 if self.__EndOfFile():\r
959 return False\r
960 # Record the token start position, the position of the first non-space char.\r
961 StartPos = self.CurrentOffsetWithinLine\r
962 StartLine = self.CurrentLineNumber\r
d0acc87a 963 while StartLine == self.CurrentLineNumber:\r
30fdf114
LG
964 TempChar = self.__CurrentChar()\r
965 # Try to find the end char that is not a space and not in seperator tuple.\r
966 # That is, when we got a space or any char in the tuple, we got the end of token.\r
967 if not str(TempChar).isspace() and TempChar not in SEPERATOR_TUPLE:\r
968 self.__GetOneChar()\r
969 # if we happen to meet a seperator as the first char, we must proceed to get it.\r
970 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.\r
971 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:\r
972 self.__GetOneChar()\r
973 break\r
974 else:\r
975 break\r
976# else:\r
977# return False\r
978\r
979 EndPos = self.CurrentOffsetWithinLine\r
980 if self.CurrentLineNumber != StartLine:\r
981 EndPos = len(self.Profile.FileLinesList[StartLine-1])\r
982 self.__Token = self.Profile.FileLinesList[StartLine-1][StartPos : EndPos]\r
983 if StartPos != self.CurrentOffsetWithinLine:\r
984 return True\r
985 else:\r
986 return False\r
987\r
988 def __GetNextOp(self):\r
989 # Skip leading spaces, if exist.\r
990 self.__SkipWhiteSpace()\r
991 if self.__EndOfFile():\r
992 return False\r
993 # Record the token start position, the position of the first non-space char.\r
994 StartPos = self.CurrentOffsetWithinLine\r
995 while not self.__EndOfLine():\r
996 TempChar = self.__CurrentChar()\r
997 # Try to find the end char that is not a space\r
998 if not str(TempChar).isspace():\r
999 self.__GetOneChar()\r
1000 else:\r
1001 break\r
1002 else:\r
1003 return False\r
1004\r
1005 if StartPos != self.CurrentOffsetWithinLine:\r
1006 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]\r
1007 return True\r
1008 else:\r
1009 return False\r
1010 ## __GetNextGuid() method\r
1011 #\r
1012 # Get next token unit before a seperator\r
1013 # If found, the GUID string is put into self.__Token\r
1014 #\r
1015 # @param self The object pointer\r
1016 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward\r
1017 # @retval False Not able to find a registry format GUID, file buffer pointer not changed\r
1018 #\r
1019 def __GetNextGuid(self):\r
1020\r
1021 if not self.__GetNextToken():\r
1022 return False\r
1023 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
1024 if p.match(self.__Token) != None:\r
1025 return True\r
1026 else:\r
1027 self.__UndoToken()\r
1028 return False\r
1029\r
1030 ## __UndoToken() method\r
1031 #\r
1032 # Go back one token unit in file buffer\r
1033 #\r
1034 # @param self The object pointer\r
1035 #\r
1036 def __UndoToken(self):\r
1037 self.__UndoOneChar()\r
1038 while self.__CurrentChar().isspace():\r
1039 if not self.__UndoOneChar():\r
1040 self.__GetOneChar()\r
1041 return\r
1042\r
1043\r
1044 StartPos = self.CurrentOffsetWithinLine\r
1045 CurrentLine = self.CurrentLineNumber\r
1046 while CurrentLine == self.CurrentLineNumber:\r
1047\r
1048 TempChar = self.__CurrentChar()\r
1049 # Try to find the end char that is not a space and not in seperator tuple.\r
1050 # That is, when we got a space or any char in the tuple, we got the end of token.\r
1051 if not str(TempChar).isspace() and not TempChar in SEPERATOR_TUPLE:\r
1052 if not self.__UndoOneChar():\r
d0acc87a 1053 return\r
30fdf114
LG
1054 # if we happen to meet a seperator as the first char, we must proceed to get it.\r
1055 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.\r
1056 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:\r
1057 return\r
1058 else:\r
1059 break\r
1060\r
1061 self.__GetOneChar()\r
1062\r
1063 ## __HexDigit() method\r
1064 #\r
1065 # Whether char input is a Hex data bit\r
1066 #\r
1067 # @param self The object pointer\r
1068 # @param TempChar The char to test\r
1069 # @retval True The char is a Hex data bit\r
1070 # @retval False The char is NOT a Hex data bit\r
1071 #\r
1072 def __HexDigit(self, TempChar):\r
1073 if (TempChar >= 'a' and TempChar <= 'f') or (TempChar >= 'A' and TempChar <= 'F') \\r
1074 or (TempChar >= '0' and TempChar <= '9'):\r
1075 return True\r
1076 else:\r
1077 return False\r
1078\r
1079 def __IsHex(self, HexStr):\r
1080 if not HexStr.upper().startswith("0X"):\r
1081 return False\r
1082 if len(self.__Token) <= 2:\r
1083 return False\r
1084 charList = [c for c in HexStr[2 : ] if not self.__HexDigit( c)]\r
1085 if len(charList) == 0:\r
1086 return True\r
1087 else:\r
1088 return False\r
1089 ## __GetNextHexNumber() method\r
1090 #\r
1091 # Get next HEX data before a seperator\r
1092 # If found, the HEX data is put into self.__Token\r
1093 #\r
1094 # @param self The object pointer\r
1095 # @retval True Successfully find a HEX data, file buffer pointer moved forward\r
1096 # @retval False Not able to find a HEX data, file buffer pointer not changed\r
1097 #\r
1098 def __GetNextHexNumber(self):\r
1099 if not self.__GetNextToken():\r
1100 return False\r
1101 if self.__IsHex(self.__Token):\r
1102 return True\r
1103 else:\r
1104 self.__UndoToken()\r
1105 return False\r
1106\r
1107 ## __GetNextDecimalNumber() method\r
1108 #\r
1109 # Get next decimal data before a seperator\r
1110 # If found, the decimal data is put into self.__Token\r
1111 #\r
1112 # @param self The object pointer\r
1113 # @retval True Successfully find a decimal data, file buffer pointer moved forward\r
1114 # @retval False Not able to find a decimal data, file buffer pointer not changed\r
1115 #\r
1116 def __GetNextDecimalNumber(self):\r
1117 if not self.__GetNextToken():\r
1118 return False\r
1119 if self.__Token.isdigit():\r
1120 return True\r
1121 else:\r
1122 self.__UndoToken()\r
1123 return False\r
1124\r
1125 ## __GetNextPcdName() method\r
1126 #\r
1127 # Get next PCD token space C name and PCD C name pair before a seperator\r
1128 # If found, the decimal data is put into self.__Token\r
1129 #\r
1130 # @param self The object pointer\r
1131 # @retval Tuple PCD C name and PCD token space C name pair\r
1132 #\r
1133 def __GetNextPcdName(self):\r
1134 if not self.__GetNextWord():\r
1135 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)\r
1136 pcdTokenSpaceCName = self.__Token\r
1137\r
1138 if not self.__IsToken( "."):\r
1139 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)\r
1140\r
1141 if not self.__GetNextWord():\r
1142 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)\r
1143 pcdCName = self.__Token\r
1144\r
1145 return (pcdCName, pcdTokenSpaceCName)\r
1146\r
1147 ## __GetStringData() method\r
1148 #\r
1149 # Get string contents quoted in ""\r
1150 # If found, the decimal data is put into self.__Token\r
1151 #\r
1152 # @param self The object pointer\r
1153 # @retval True Successfully find a string data, file buffer pointer moved forward\r
1154 # @retval False Not able to find a string data, file buffer pointer not changed\r
1155 #\r
1156 def __GetStringData(self):\r
1157 if self.__Token.startswith("\"") or self.__Token.startswith("L\""):\r
1158 self.__UndoToken()\r
1159 self.__SkipToToken("\"")\r
1160 currentLineNumber = self.CurrentLineNumber\r
1161\r
1162 if not self.__SkipToToken("\""):\r
1163 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber)\r
1164 if currentLineNumber != self.CurrentLineNumber:\r
1165 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber)\r
1166 self.__Token = self.__SkippedChars.rstrip('\"')\r
1167 return True\r
1168\r
1169 elif self.__Token.startswith("\'") or self.__Token.startswith("L\'"):\r
1170 self.__UndoToken()\r
1171 self.__SkipToToken("\'")\r
1172 currentLineNumber = self.CurrentLineNumber\r
1173\r
1174 if not self.__SkipToToken("\'"):\r
1175 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber)\r
1176 if currentLineNumber != self.CurrentLineNumber:\r
1177 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber)\r
1178 self.__Token = self.__SkippedChars.rstrip('\'')\r
1179 return True\r
1180\r
1181 else:\r
1182 return False\r
1183\r
1184 ## __SkipToToken() method\r
1185 #\r
1186 # Search forward in file buffer for the string\r
1187 # The skipped chars are put into self.__SkippedChars\r
1188 #\r
1189 # @param self The object pointer\r
1190 # @param String The string to search\r
1191 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive\r
1192 # @retval True Successfully find the string, file buffer pointer moved forward\r
1193 # @retval False Not able to find the string, file buffer pointer not changed\r
1194 #\r
1195 def __SkipToToken(self, String, IgnoreCase = False):\r
1196 StartPos = self.GetFileBufferPos()\r
1197\r
1198 self.__SkippedChars = ""\r
1199 while not self.__EndOfFile():\r
1200 index = -1\r
1201 if IgnoreCase:\r
1202 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())\r
1203 else:\r
1204 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)\r
1205 if index == 0:\r
1206 self.CurrentOffsetWithinLine += len(String)\r
1207 self.__SkippedChars += String\r
1208 return True\r
1209 self.__SkippedChars += str(self.__CurrentChar())\r
1210 self.__GetOneChar()\r
1211\r
1212 self.SetFileBufferPos( StartPos)\r
1213 self.__SkippedChars = ""\r
1214 return False\r
1215\r
1216 ## GetFileBufferPos() method\r
1217 #\r
1218 # Return the tuple of current line and offset within the line\r
1219 #\r
1220 # @param self The object pointer\r
1221 # @retval Tuple Line number and offset pair\r
1222 #\r
1223 def GetFileBufferPos(self):\r
1224 return (self.CurrentLineNumber, self.CurrentOffsetWithinLine)\r
1225\r
1226 ## SetFileBufferPos() method\r
1227 #\r
1228 # Restore the file buffer position\r
1229 #\r
1230 # @param self The object pointer\r
1231 # @param Pos The new file buffer position\r
1232 #\r
1233 def SetFileBufferPos(self, Pos):\r
1234 (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos\r
1235\r
d40b2ee6
LG
1236 ## Preprocess() method\r
1237 #\r
1238 # Preprocess comment, conditional directive, include directive, replace macro.\r
1239 # Exception will be raised if syntax error found\r
1240 #\r
1241 # @param self The object pointer\r
1242 #\r
1243 def Preprocess(self):\r
1244 self.__StringToList()\r
1245 self.PreprocessFile()\r
1246 self.PreprocessIncludeFile()\r
1247 self.__StringToList()\r
1248 self.PreprocessFile()\r
1249 self.PreprocessConditionalStatement()\r
1250 self.__StringToList()\r
1251 for Pos in self.__WipeOffArea:\r
1252 self.__ReplaceFragment(Pos[0], Pos[1])\r
1253 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]\r
1254\r
1255 while self.__GetDefines():\r
1256 pass\r
d40b2ee6 1257\r
30fdf114
LG
1258 ## ParseFile() method\r
1259 #\r
1260 # Parse the file profile buffer to extract fd, fv ... information\r
1261 # Exception will be raised if syntax error found\r
1262 #\r
1263 # @param self The object pointer\r
1264 #\r
1265 def ParseFile(self):\r
1266\r
1267 try:\r
d40b2ee6 1268 self.Preprocess()\r
30fdf114
LG
1269 while self.__GetFd():\r
1270 pass\r
1271\r
1272 while self.__GetFv():\r
1273 pass\r
1274\r
1275 while self.__GetCapsule():\r
1276 pass\r
1277\r
1278 while self.__GetVtf():\r
1279 pass\r
1280\r
1281 while self.__GetRule():\r
1282 pass\r
1283 \r
1284 while self.__GetOptionRom():\r
1285 pass\r
1286\r
1287 except Warning, X:\r
1288 self.__UndoToken()\r
1289 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1290 #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \\r
1291 X.Message += ' near line %d, column %d: %s' \\r
1292 % (FileLineTuple[1], self.CurrentOffsetWithinLine + 1, self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :].rstrip('\n').rstrip('\r'))\r
1293 raise\r
1294\r
1295 ## __GetDefines() method\r
1296 #\r
1297 # Get Defines section contents and store its data into AllMacrosList\r
1298 #\r
1299 # @param self The object pointer\r
1300 # @retval True Successfully find a Defines\r
1301 # @retval False Not able to find a Defines\r
1302 #\r
1303 def __GetDefines(self):\r
1304\r
1305 if not self.__GetNextToken():\r
1306 return False\r
1307\r
1308 S = self.__Token.upper()\r
1309 if S.startswith("[") and not S.startswith("[DEFINES"):\r
1310 if not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \\r
1311 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
1312 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
1313 self.__UndoToken()\r
1314 return False\r
1315\r
1316 self.__UndoToken()\r
1317 if not self.__IsToken("[DEFINES", True):\r
1318 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1319 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
1320 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
1321 raise Warning("expected [DEFINES", self.FileName, self.CurrentLineNumber)\r
1322\r
1323 if not self.__IsToken( "]"):\r
1324 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
1325\r
1326 while self.__GetNextWord():\r
6780eef1
LG
1327 # handle the SET statement\r
1328 if self.__Token == 'SET':\r
1329 self.__UndoToken()\r
1330 self.__GetSetStatement(None)\r
1331 continue\r
1332 \r
30fdf114
LG
1333 Macro = self.__Token\r
1334 \r
1335 if not self.__IsToken("="):\r
1336 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1337 if not self.__GetNextToken() or self.__Token.startswith('['):\r
1338 raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber)\r
1339 Value = self.__Token\r
30fdf114
LG
1340\r
1341 return False\r
1342\r
1343 ## __GetFd() method\r
1344 #\r
1345 # Get FD section contents and store its data into FD dictionary of self.Profile\r
1346 #\r
1347 # @param self The object pointer\r
1348 # @retval True Successfully find a FD\r
1349 # @retval False Not able to find a FD\r
1350 #\r
1351 def __GetFd(self):\r
1352\r
1353 if not self.__GetNextToken():\r
1354 return False\r
1355\r
1356 S = self.__Token.upper()\r
1357 if S.startswith("[") and not S.startswith("[FD."):\r
1358 if not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \\r
1359 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
1360 raise Warning("Unknown section", self.FileName, self.CurrentLineNumber)\r
1361 self.__UndoToken()\r
1362 return False\r
1363\r
1364 self.__UndoToken()\r
1365 if not self.__IsToken("[FD.", True):\r
1366 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1367 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
1368 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
1369 raise Warning("expected [FD.]", self.FileName, self.CurrentLineNumber)\r
1370\r
1371 FdName = self.__GetUiName()\r
52302d4d
LG
1372 if FdName == "":\r
1373 if len (self.Profile.FdDict) == 0:\r
1374 FdName = GenFdsGlobalVariable.PlatformName\r
d0acc87a
LG
1375 if FdName == "" and GlobalData.gActivePlatform:\r
1376 FdName = GlobalData.gActivePlatform.PlatformName\r
52302d4d
LG
1377 self.Profile.FdNameNotSet = True\r
1378 else:\r
1379 raise Warning("expected FdName in [FD.] section", self.FileName, self.CurrentLineNumber)\r
30fdf114 1380 self.CurrentFdName = FdName.upper()\r
52302d4d
LG
1381 \r
1382 if self.CurrentFdName in self.Profile.FdDict:\r
1383 raise Warning("Unexpected the same FD name", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
1384\r
1385 if not self.__IsToken( "]"):\r
1386 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
1387\r
1388 FdObj = Fd.FD()\r
1389 FdObj.FdUiName = self.CurrentFdName\r
1390 self.Profile.FdDict[self.CurrentFdName] = FdObj\r
52302d4d
LG
1391\r
1392 if len (self.Profile.FdDict) > 1 and self.Profile.FdNameNotSet:\r
1393 raise Warning("expected all FDs have their name", self.FileName, self.CurrentLineNumber)\r
1394\r
30fdf114
LG
1395 Status = self.__GetCreateFile(FdObj)\r
1396 if not Status:\r
1397 raise Warning("FD name error", self.FileName, self.CurrentLineNumber)\r
1398\r
52302d4d 1399 self.__GetTokenStatements(FdObj)\r
30fdf114
LG
1400\r
1401 self.__GetDefineStatements(FdObj)\r
1402\r
1403 self.__GetSetStatements(FdObj)\r
1404\r
1405 if not self.__GetRegionLayout(FdObj):\r
1406 raise Warning("expected region layout", self.FileName, self.CurrentLineNumber)\r
1407\r
1408 while self.__GetRegionLayout(FdObj):\r
1409 pass\r
1410 return True\r
1411\r
1412 ## __GetUiName() method\r
1413 #\r
1414 # Return the UI name of a section\r
1415 #\r
1416 # @param self The object pointer\r
1417 # @retval FdName UI name\r
1418 #\r
1419 def __GetUiName(self):\r
1420 Name = ""\r
1421 if self.__GetNextWord():\r
1422 Name = self.__Token\r
1423\r
1424 return Name\r
1425\r
1426 ## __GetCreateFile() method\r
1427 #\r
1428 # Return the output file name of object\r
1429 #\r
1430 # @param self The object pointer\r
1431 # @param Obj object whose data will be stored in file\r
1432 # @retval FdName UI name\r
1433 #\r
1434 def __GetCreateFile(self, Obj):\r
1435\r
1436 if self.__IsKeyword( "CREATE_FILE"):\r
1437 if not self.__IsToken( "="):\r
1438 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1439\r
1440 if not self.__GetNextToken():\r
1441 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)\r
1442\r
1443 FileName = self.__Token\r
1444 Obj.CreateFileName = FileName\r
1445\r
1446 return True\r
1447\r
1448 ## __GetTokenStatements() method\r
1449 #\r
1450 # Get token statements\r
1451 #\r
1452 # @param self The object pointer\r
1453 # @param Obj for whom token statement is got\r
30fdf114
LG
1454 #\r
1455 def __GetTokenStatements(self, Obj):\r
1456 if not self.__IsKeyword( "BaseAddress"):\r
1457 raise Warning("BaseAddress missing", self.FileName, self.CurrentLineNumber)\r
1458\r
1459 if not self.__IsToken( "="):\r
1460 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1461\r
1462 if not self.__GetNextHexNumber():\r
1463 raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber)\r
1464\r
1465 Obj.BaseAddress = self.__Token\r
1466\r
1467 if self.__IsToken( "|"):\r
1468 pcdPair = self.__GetNextPcdName()\r
1469 Obj.BaseAddressPcd = pcdPair\r
1470 self.Profile.PcdDict[pcdPair] = Obj.BaseAddress\r
d0acc87a
LG
1471 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1472 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple\r
30fdf114
LG
1473\r
1474 if not self.__IsKeyword( "Size"):\r
1475 raise Warning("Size missing", self.FileName, self.CurrentLineNumber)\r
1476\r
1477 if not self.__IsToken( "="):\r
1478 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1479\r
1480 if not self.__GetNextHexNumber():\r
1481 raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber)\r
1482\r
1483\r
1484 Size = self.__Token\r
1485 if self.__IsToken( "|"):\r
1486 pcdPair = self.__GetNextPcdName()\r
1487 Obj.SizePcd = pcdPair\r
1488 self.Profile.PcdDict[pcdPair] = Size\r
d0acc87a
LG
1489 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1490 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple\r
30fdf114
LG
1491 Obj.Size = long(Size, 0)\r
1492\r
1493 if not self.__IsKeyword( "ErasePolarity"):\r
1494 raise Warning("ErasePolarity missing", self.FileName, self.CurrentLineNumber)\r
1495\r
1496 if not self.__IsToken( "="):\r
1497 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1498\r
1499 if not self.__GetNextToken():\r
1500 raise Warning("expected Erase Polarity", self.FileName, self.CurrentLineNumber)\r
1501\r
1502 if self.__Token != "1" and self.__Token != "0":\r
1503 raise Warning("expected 1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)\r
1504\r
1505 Obj.ErasePolarity = self.__Token\r
1506\r
52302d4d 1507 self.__GetBlockStatements(Obj)\r
30fdf114
LG
1508\r
1509 ## __GetAddressStatements() method\r
1510 #\r
1511 # Get address statements\r
1512 #\r
1513 # @param self The object pointer\r
1514 # @param Obj for whom address statement is got\r
1515 # @retval True Successfully find\r
1516 # @retval False Not able to find\r
1517 #\r
1518 def __GetAddressStatements(self, Obj):\r
1519\r
1520 if self.__IsKeyword("BsBaseAddress"):\r
1521 if not self.__IsToken( "="):\r
1522 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1523\r
1524 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():\r
1525 raise Warning("expected address", self.FileName, self.CurrentLineNumber)\r
1526\r
1527 BsAddress = long(self.__Token, 0)\r
1528 Obj.BsBaseAddress = BsAddress\r
1529\r
1530 if self.__IsKeyword("RtBaseAddress"):\r
1531 if not self.__IsToken( "="):\r
1532 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1533\r
1534 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():\r
1535 raise Warning("expected address", self.FileName, self.CurrentLineNumber)\r
1536\r
1537 RtAddress = long(self.__Token, 0)\r
1538 Obj.RtBaseAddress = RtAddress\r
1539\r
1540 ## __GetBlockStatements() method\r
1541 #\r
1542 # Get block statements\r
1543 #\r
1544 # @param self The object pointer\r
1545 # @param Obj for whom block statement is got\r
30fdf114
LG
1546 #\r
1547 def __GetBlockStatements(self, Obj):\r
1548\r
1549 if not self.__GetBlockStatement(Obj):\r
52302d4d
LG
1550 #set default block size is 1\r
1551 Obj.BlockSizeList.append((1, Obj.Size, None))\r
1552 return\r
30fdf114
LG
1553\r
1554 while self.__GetBlockStatement(Obj):\r
1555 pass\r
52302d4d
LG
1556 \r
1557 for Item in Obj.BlockSizeList:\r
1558 if Item[0] == None or Item[1] == None:\r
6780eef1 1559 raise Warning("expected block statement", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
1560\r
1561 ## __GetBlockStatement() method\r
1562 #\r
1563 # Get block statement\r
1564 #\r
1565 # @param self The object pointer\r
1566 # @param Obj for whom block statement is got\r
1567 # @retval True Successfully find\r
1568 # @retval False Not able to find\r
1569 #\r
1570 def __GetBlockStatement(self, Obj):\r
1571 if not self.__IsKeyword( "BlockSize"):\r
1572 return False\r
1573\r
1574 if not self.__IsToken( "="):\r
1575 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1576\r
1577 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():\r
6780eef1 1578 raise Warning("expected Hex or Integer block size", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
1579\r
1580 BlockSize = self.__Token\r
1581 BlockSizePcd = None\r
1582 if self.__IsToken( "|"):\r
1583 PcdPair = self.__GetNextPcdName()\r
1584 BlockSizePcd = PcdPair\r
1585 self.Profile.PcdDict[PcdPair] = BlockSize\r
d0acc87a
LG
1586 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1587 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple\r
52302d4d 1588 BlockSize = long(BlockSize, 0)\r
30fdf114
LG
1589\r
1590 BlockNumber = None\r
1591 if self.__IsKeyword( "NumBlocks"):\r
1592 if not self.__IsToken( "="):\r
1593 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1594\r
1595 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():\r
1596 raise Warning("expected block numbers", self.FileName, self.CurrentLineNumber)\r
1597\r
1598 BlockNumber = long(self.__Token, 0)\r
1599\r
1600 Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd))\r
1601 return True\r
1602\r
1603 ## __GetDefineStatements() method\r
1604 #\r
1605 # Get define statements\r
1606 #\r
1607 # @param self The object pointer\r
1608 # @param Obj for whom define statement is got\r
1609 # @retval True Successfully find\r
1610 # @retval False Not able to find\r
1611 #\r
1612 def __GetDefineStatements(self, Obj):\r
1613 while self.__GetDefineStatement( Obj):\r
1614 pass\r
1615\r
1616 ## __GetDefineStatement() method\r
1617 #\r
1618 # Get define statement\r
1619 #\r
1620 # @param self The object pointer\r
1621 # @param Obj for whom define statement is got\r
1622 # @retval True Successfully find\r
1623 # @retval False Not able to find\r
1624 #\r
1625 def __GetDefineStatement(self, Obj):\r
1626 if self.__IsKeyword("DEFINE"):\r
1627 self.__GetNextToken()\r
1628 Macro = self.__Token\r
1629 if not self.__IsToken( "="):\r
1630 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1631\r
1632 if not self.__GetNextToken():\r
1633 raise Warning("expected value", self.FileName, self.CurrentLineNumber)\r
1634\r
1635 Value = self.__Token\r
1636 Macro = '$(' + Macro + ')'\r
1637 Obj.DefineVarDict[Macro] = Value\r
1638 return True\r
1639\r
1640 return False\r
1641\r
1642 ## __GetSetStatements() method\r
1643 #\r
1644 # Get set statements\r
1645 #\r
1646 # @param self The object pointer\r
1647 # @param Obj for whom set statement is got\r
1648 # @retval True Successfully find\r
1649 # @retval False Not able to find\r
1650 #\r
1651 def __GetSetStatements(self, Obj):\r
1652 while self.__GetSetStatement(Obj):\r
1653 pass\r
1654\r
1655 ## __GetSetStatement() method\r
1656 #\r
1657 # Get set statement\r
1658 #\r
1659 # @param self The object pointer\r
1660 # @param Obj for whom set statement is got\r
1661 # @retval True Successfully find\r
1662 # @retval False Not able to find\r
1663 #\r
1664 def __GetSetStatement(self, Obj):\r
1665 if self.__IsKeyword("SET"):\r
1666 PcdPair = self.__GetNextPcdName()\r
1667\r
1668 if not self.__IsToken( "="):\r
1669 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1670\r
d0acc87a
LG
1671 Value = self.__GetExpression()\r
1672 Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)\r
30fdf114 1673\r
6780eef1
LG
1674 if Obj:\r
1675 Obj.SetVarDict[PcdPair] = Value\r
30fdf114 1676 self.Profile.PcdDict[PcdPair] = Value\r
d0acc87a
LG
1677 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1678 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple\r
30fdf114
LG
1679 return True\r
1680\r
1681 return False\r
1682\r
1683 ## __GetRegionLayout() method\r
1684 #\r
1685 # Get region layout for FD\r
1686 #\r
1687 # @param self The object pointer\r
1688 # @param Fd for whom region is got\r
1689 # @retval True Successfully find\r
1690 # @retval False Not able to find\r
1691 #\r
1692 def __GetRegionLayout(self, Fd):\r
1693 if not self.__GetNextHexNumber():\r
1694 return False\r
1695\r
1696 RegionObj = Region.Region()\r
1697 RegionObj.Offset = long(self.__Token, 0)\r
1698 Fd.RegionList.append(RegionObj)\r
1699\r
1700 if not self.__IsToken( "|"):\r
1701 raise Warning("expected '|'", self.FileName, self.CurrentLineNumber)\r
1702\r
1703 if not self.__GetNextHexNumber():\r
1704 raise Warning("expected Region Size", self.FileName, self.CurrentLineNumber)\r
1705 RegionObj.Size = long(self.__Token, 0)\r
1706\r
1707 if not self.__GetNextWord():\r
1708 return True\r
1709\r
fd171542 1710 if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE"):\r
30fdf114
LG
1711 self.__UndoToken()\r
1712 RegionObj.PcdOffset = self.__GetNextPcdName()\r
1713 self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0))\r
d0acc87a
LG
1714 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1715 self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple\r
30fdf114
LG
1716 if self.__IsToken( "|"):\r
1717 RegionObj.PcdSize = self.__GetNextPcdName()\r
1718 self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size\r
d0acc87a
LG
1719 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1720 self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple\r
30fdf114
LG
1721\r
1722 if not self.__GetNextWord():\r
1723 return True\r
1724\r
1725 if self.__Token == "SET":\r
1726 self.__UndoToken()\r
1727 self.__GetSetStatements( RegionObj)\r
1728 if not self.__GetNextWord():\r
1729 return True\r
1730\r
fd171542 1731 elif self.__Token == "FV":\r
30fdf114
LG
1732 self.__UndoToken()\r
1733 self.__GetRegionFvType( RegionObj)\r
1734\r
fd171542 1735 elif self.__Token == "CAPSULE":\r
1736 self.__UndoToken()\r
1737 self.__GetRegionCapType( RegionObj)\r
1738\r
30fdf114
LG
1739 elif self.__Token == "FILE":\r
1740 self.__UndoToken()\r
1741 self.__GetRegionFileType( RegionObj)\r
1742\r
79b74a03 1743 elif self.__Token == "DATA":\r
30fdf114
LG
1744 self.__UndoToken()\r
1745 self.__GetRegionDataType( RegionObj)\r
79b74a03
LG
1746 else:\r
1747 raise Warning("A valid region type was not found. "\r
1748 "Valid types are [SET, FV, CAPSULE, FILE, DATA]. This error occurred",\r
1749 self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
1750\r
1751 return True\r
1752\r
1753 ## __GetRegionFvType() method\r
1754 #\r
1755 # Get region fv data for region\r
1756 #\r
1757 # @param self The object pointer\r
1758 # @param RegionObj for whom region data is got\r
1759 #\r
1760 def __GetRegionFvType(self, RegionObj):\r
1761\r
1762 if not self.__IsKeyword( "FV"):\r
1763 raise Warning("expected Keyword 'FV'", self.FileName, self.CurrentLineNumber)\r
1764\r
1765 if not self.__IsToken( "="):\r
1766 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1767\r
1768 if not self.__GetNextToken():\r
1769 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)\r
1770\r
1771 RegionObj.RegionType = "FV"\r
1772 RegionObj.RegionDataList.append(self.__Token)\r
1773\r
1774 while self.__IsKeyword( "FV"):\r
1775\r
1776 if not self.__IsToken( "="):\r
1777 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1778\r
1779 if not self.__GetNextToken():\r
1780 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)\r
1781\r
1782 RegionObj.RegionDataList.append(self.__Token)\r
1783\r
fd171542 1784 ## __GetRegionCapType() method\r
1785 #\r
1786 # Get region capsule data for region\r
1787 #\r
1788 # @param self The object pointer\r
1789 # @param RegionObj for whom region data is got\r
1790 #\r
1791 def __GetRegionCapType(self, RegionObj):\r
1792\r
1793 if not self.__IsKeyword("CAPSULE"):\r
1794 raise Warning("expected Keyword 'CAPSULE'", self.FileName, self.CurrentLineNumber)\r
1795\r
1796 if not self.__IsToken("="):\r
1797 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1798\r
1799 if not self.__GetNextToken():\r
1800 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)\r
1801\r
1802 RegionObj.RegionType = "CAPSULE"\r
1803 RegionObj.RegionDataList.append(self.__Token)\r
1804\r
1805 while self.__IsKeyword("CAPSULE"):\r
1806\r
1807 if not self.__IsToken("="):\r
1808 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1809\r
1810 if not self.__GetNextToken():\r
1811 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)\r
1812\r
1813 RegionObj.RegionDataList.append(self.__Token)\r
1814\r
30fdf114
LG
1815 ## __GetRegionFileType() method\r
1816 #\r
1817 # Get region file data for region\r
1818 #\r
1819 # @param self The object pointer\r
1820 # @param RegionObj for whom region data is got\r
1821 #\r
1822 def __GetRegionFileType(self, RegionObj):\r
1823\r
1824 if not self.__IsKeyword( "FILE"):\r
1825 raise Warning("expected Keyword 'FILE'", self.FileName, self.CurrentLineNumber)\r
1826\r
1827 if not self.__IsToken( "="):\r
1828 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1829\r
1830 if not self.__GetNextToken():\r
1831 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)\r
1832\r
1833 RegionObj.RegionType = "FILE"\r
1834 RegionObj.RegionDataList.append( self.__Token)\r
1835\r
1836 while self.__IsKeyword( "FILE"):\r
1837\r
1838 if not self.__IsToken( "="):\r
1839 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1840\r
1841 if not self.__GetNextToken():\r
1842 raise Warning("expected FILE name", self.FileName, self.CurrentLineNumber)\r
1843\r
1844 RegionObj.RegionDataList.append(self.__Token)\r
1845\r
1846 ## __GetRegionDataType() method\r
1847 #\r
1848 # Get region array data for region\r
1849 #\r
1850 # @param self The object pointer\r
1851 # @param RegionObj for whom region data is got\r
1852 #\r
1853 def __GetRegionDataType(self, RegionObj):\r
1854\r
1855 if not self.__IsKeyword( "DATA"):\r
1856 raise Warning("expected Region Data type", self.FileName, self.CurrentLineNumber)\r
1857\r
1858 if not self.__IsToken( "="):\r
1859 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1860\r
1861 if not self.__IsToken( "{"):\r
1862 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
1863\r
1864 if not self.__GetNextHexNumber():\r
1865 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)\r
1866\r
636f2be6
LG
1867 if len(self.__Token) > 18:\r
1868 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)\r
1869\r
1870 # convert hex string value to byte hex string array\r
1871 AllString = self.__Token\r
1872 AllStrLen = len (AllString)\r
1873 DataString = ""\r
1874 while AllStrLen > 4:\r
1875 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","\r
1876 AllStrLen = AllStrLen - 2\r
1877 DataString = DataString + AllString[:AllStrLen] + ","\r
1878\r
1879 # byte value array\r
1880 if len (self.__Token) <= 4:\r
1881 while self.__IsToken(","):\r
1882 if not self.__GetNextHexNumber():\r
1883 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
1884 if len(self.__Token) > 4:\r
1885 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
1886 DataString += self.__Token\r
1887 DataString += ","\r
30fdf114
LG
1888\r
1889 if not self.__IsToken( "}"):\r
1890 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
1891\r
1892 DataString = DataString.rstrip(",")\r
1893 RegionObj.RegionType = "DATA"\r
1894 RegionObj.RegionDataList.append( DataString)\r
1895\r
1896 while self.__IsKeyword( "DATA"):\r
1897\r
1898 if not self.__IsToken( "="):\r
1899 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1900\r
1901 if not self.__IsToken( "{"):\r
1902 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
1903\r
1904 if not self.__GetNextHexNumber():\r
1905 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)\r
1906\r
636f2be6
LG
1907 if len(self.__Token) > 18:\r
1908 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)\r
1909\r
1910 # convert hex string value to byte hex string array\r
1911 AllString = self.__Token\r
1912 AllStrLen = len (AllString)\r
1913 DataString = ""\r
1914 while AllStrLen > 4:\r
1915 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","\r
1916 AllStrLen = AllStrLen - 2\r
1917 DataString = DataString + AllString[:AllStrLen] + ","\r
1918\r
1919 # byte value array\r
1920 if len (self.__Token) <= 4:\r
1921 while self.__IsToken(","):\r
1922 if not self.__GetNextHexNumber():\r
1923 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
1924 if len(self.__Token) > 4:\r
1925 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
1926 DataString += self.__Token\r
1927 DataString += ","\r
30fdf114
LG
1928\r
1929 if not self.__IsToken( "}"):\r
1930 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
1931\r
1932 DataString = DataString.rstrip(",")\r
1933 RegionObj.RegionDataList.append( DataString)\r
1934\r
1935 ## __GetFv() method\r
1936 #\r
1937 # Get FV section contents and store its data into FV dictionary of self.Profile\r
1938 #\r
1939 # @param self The object pointer\r
1940 # @retval True Successfully find a FV\r
1941 # @retval False Not able to find a FV\r
1942 #\r
1943 def __GetFv(self):\r
1944 if not self.__GetNextToken():\r
1945 return False\r
1946\r
1947 S = self.__Token.upper()\r
1948 if S.startswith("[") and not S.startswith("[FV."):\r
1949 if not S.startswith("[CAPSULE.") \\r
1950 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
1951 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
1952 self.__UndoToken()\r
1953 return False\r
1954\r
1955 self.__UndoToken()\r
1956 if not self.__IsToken("[FV.", True):\r
1957 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1958 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
1959 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
1960 raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
1961\r
1962 FvName = self.__GetUiName()\r
1963 self.CurrentFvName = FvName.upper()\r
1964\r
1965 if not self.__IsToken( "]"):\r
1966 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
1967\r
1968 FvObj = Fv.FV()\r
1969 FvObj.UiFvName = self.CurrentFvName\r
1970 self.Profile.FvDict[self.CurrentFvName] = FvObj\r
1971\r
1972 Status = self.__GetCreateFile(FvObj)\r
1973 if not Status:\r
1974 raise Warning("FV name error", self.FileName, self.CurrentLineNumber)\r
1975\r
1976 self.__GetDefineStatements(FvObj)\r
1977\r
1978 self.__GetAddressStatements(FvObj)\r
1979\r
6780eef1
LG
1980 while self.__GetBlockStatement(FvObj):\r
1981 pass\r
30fdf114
LG
1982\r
1983 self.__GetSetStatements(FvObj)\r
4234283c
LG
1984 \r
1985 self.__GetFvBaseAddress(FvObj)\r
79b74a03
LG
1986 \r
1987 self.__GetFvForceRebase(FvObj)\r
30fdf114
LG
1988\r
1989 self.__GetFvAlignment(FvObj)\r
1990\r
1991 self.__GetFvAttributes(FvObj)\r
1992 \r
1993 self.__GetFvNameGuid(FvObj)\r
1994\r
b303ea72
LG
1995 FvObj.FvExtEntryTypeValue = []\r
1996 FvObj.FvExtEntryType = []\r
1997 FvObj.FvExtEntryData = []\r
1998 while True:\r
1999 isFvExtEntry = self.__GetFvExtEntryStatement(FvObj)\r
2000 if not isFvExtEntry:\r
2001 break\r
2002\r
30fdf114
LG
2003 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())\r
2004 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())\r
2005\r
2006 while True:\r
2007 isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())\r
2008 isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())\r
2009 if not isInf and not isFile:\r
2010 break\r
2011\r
2012 return True\r
2013\r
2014 ## __GetFvAlignment() method\r
2015 #\r
2016 # Get alignment for FV\r
2017 #\r
2018 # @param self The object pointer\r
2019 # @param Obj for whom alignment is got\r
2020 # @retval True Successfully find a alignment statement\r
2021 # @retval False Not able to find a alignment statement\r
2022 #\r
2023 def __GetFvAlignment(self, Obj):\r
2024\r
2025 if not self.__IsKeyword( "FvAlignment"):\r
2026 return False\r
2027\r
2028 if not self.__IsToken( "="):\r
2029 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2030\r
2031 if not self.__GetNextToken():\r
2032 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)\r
2033\r
2034 if self.__Token.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \\r
2035 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \\r
2036 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \\r
2037 "1G", "2G"):\r
2038 raise Warning("Unknown alignment value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
2039 Obj.FvAlignment = self.__Token\r
2040 return True\r
4234283c
LG
2041 \r
2042 ## __GetFvBaseAddress() method\r
2043 #\r
2044 # Get BaseAddress for FV\r
2045 #\r
2046 # @param self The object pointer\r
2047 # @param Obj for whom FvBaseAddress is got\r
2048 # @retval True Successfully find a FvBaseAddress statement\r
2049 # @retval False Not able to find a FvBaseAddress statement\r
2050 #\r
2051 def __GetFvBaseAddress(self, Obj):\r
2052\r
2053 if not self.__IsKeyword("FvBaseAddress"):\r
2054 return False\r
2055\r
2056 if not self.__IsToken( "="):\r
2057 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2058\r
2059 if not self.__GetNextToken():\r
2060 raise Warning("expected FV base address value", self.FileName, self.CurrentLineNumber)\r
2061\r
2062 IsValidBaseAddrValue = re.compile('^0[x|X][0-9a-fA-F]+')\r
2063\r
2064 if not IsValidBaseAddrValue.match(self.__Token.upper()):\r
79b74a03 2065 raise Warning("Unknown FV base address value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4234283c 2066 Obj.FvBaseAddress = self.__Token\r
0d2711a6
LG
2067 return True \r
2068 \r
79b74a03
LG
2069 ## __GetFvForceRebase() method\r
2070 #\r
2071 # Get FvForceRebase for FV\r
2072 #\r
2073 # @param self The object pointer\r
2074 # @param Obj for whom FvForceRebase is got\r
2075 # @retval True Successfully find a FvForceRebase statement\r
2076 # @retval False Not able to find a FvForceRebase statement\r
2077 #\r
2078 def __GetFvForceRebase(self, Obj):\r
2079\r
2080 if not self.__IsKeyword("FvForceRebase"):\r
2081 return False\r
2082\r
2083 if not self.__IsToken( "="):\r
2084 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2085\r
2086 if not self.__GetNextToken():\r
2087 raise Warning("expected FvForceRebase value", self.FileName, self.CurrentLineNumber)\r
30fdf114 2088\r
79b74a03
LG
2089 if self.__Token.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]:\r
2090 raise Warning("Unknown FvForceRebase value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
2091 \r
2092 if self.__Token.upper() in ["TRUE", "1", "0X1", "0X01"]:\r
2093 Obj.FvForceRebase = True\r
2094 elif self.__Token.upper() in ["FALSE", "0", "0X0", "0X00"]:\r
2095 Obj.FvForceRebase = False\r
2096 else:\r
2097 Obj.FvForceRebase = None\r
2098 \r
2099 return True\r
0d2711a6
LG
2100\r
2101\r
30fdf114
LG
2102 ## __GetFvAttributes() method\r
2103 #\r
2104 # Get attributes for FV\r
2105 #\r
2106 # @param self The object pointer\r
2107 # @param Obj for whom attribute is got\r
2108 # @retval None\r
2109 #\r
2110 def __GetFvAttributes(self, FvObj):\r
2111\r
2112 while self.__GetNextWord():\r
2113 name = self.__Token\r
2114 if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \\r
2115 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \\r
2116 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \\r
2117 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \\r
2118 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \\r
2119 "WRITE_POLICY_RELIABLE"):\r
2120 self.__UndoToken()\r
2121 return\r
2122\r
2123 if not self.__IsToken( "="):\r
2124 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2125\r
2126 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):\r
2127 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)\r
2128\r
2129 FvObj.FvAttributeDict[name] = self.__Token\r
2130\r
2131 return\r
2132 \r
2133 ## __GetFvNameGuid() method\r
2134 #\r
2135 # Get FV GUID for FV\r
2136 #\r
2137 # @param self The object pointer\r
2138 # @param Obj for whom GUID is got\r
2139 # @retval None\r
2140 #\r
2141 def __GetFvNameGuid(self, FvObj):\r
2142\r
2143 if not self.__IsKeyword( "FvNameGuid"):\r
2144 return\r
2145\r
2146 if not self.__IsToken( "="):\r
2147 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2148\r
2149 if not self.__GetNextGuid():\r
2150 raise Warning("expected FV GUID value", self.FileName, self.CurrentLineNumber)\r
2151\r
2152 FvObj.FvNameGuid = self.__Token\r
2153\r
2154 return\r
2155\r
b303ea72
LG
2156 def __GetFvExtEntryStatement(self, FvObj):\r
2157\r
2158 if not self.__IsKeyword( "FV_EXT_ENTRY"):\r
2159 return False\r
2160\r
2161 if not self.__IsKeyword ("TYPE"):\r
2162 raise Warning("expected 'TYPE'", self.FileName, self.CurrentLineNumber)\r
2163 \r
2164 if not self.__IsToken( "="):\r
2165 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2166\r
2167 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():\r
2168 raise Warning("expected Hex FV extension entry type value At Line ", self.FileName, self.CurrentLineNumber)\r
2169\r
2170 FvObj.FvExtEntryTypeValue += [self.__Token]\r
2171\r
2172 if not self.__IsToken( "{"):\r
2173 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2174\r
2175 if not self.__IsKeyword ("FILE") and not self.__IsKeyword ("DATA"):\r
2176 raise Warning("expected 'FILE' or 'DATA'", self.FileName, self.CurrentLineNumber)\r
2177\r
2178 FvObj.FvExtEntryType += [self.__Token]\r
2179\r
2180 if self.__Token == 'DATA':\r
2181\r
2182 if not self.__IsToken( "="):\r
2183 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2184 \r
2185 if not self.__IsToken( "{"):\r
2186 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2187\r
2188 if not self.__GetNextHexNumber():\r
2189 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)\r
2190\r
2191 if len(self.__Token) > 4:\r
2192 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
2193\r
2194 DataString = self.__Token\r
2195 DataString += ","\r
2196\r
2197 while self.__IsToken(","):\r
2198 if not self.__GetNextHexNumber():\r
2199 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
2200 if len(self.__Token) > 4:\r
2201 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
2202 DataString += self.__Token\r
2203 DataString += ","\r
2204\r
2205 if not self.__IsToken( "}"):\r
2206 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2207\r
2208 if not self.__IsToken( "}"):\r
2209 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2210\r
2211 DataString = DataString.rstrip(",")\r
2212 FvObj.FvExtEntryData += [DataString]\r
2213\r
2214 if self.__Token == 'FILE':\r
2215 \r
2216 if not self.__IsToken( "="):\r
2217 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2218 \r
2219 if not self.__GetNextToken():\r
2220 raise Warning("expected FV Extension Entry file path At Line ", self.FileName, self.CurrentLineNumber)\r
2221 \r
2222 FvObj.FvExtEntryData += [self.__Token]\r
2223\r
2224 if not self.__IsToken( "}"):\r
2225 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2226\r
2227 return True\r
2228\r
30fdf114
LG
2229 ## __GetAprioriSection() method\r
2230 #\r
2231 # Get token statements\r
2232 #\r
2233 # @param self The object pointer\r
2234 # @param FvObj for whom apriori is got\r
2235 # @param MacroDict dictionary used to replace macro\r
2236 # @retval True Successfully find apriori statement\r
2237 # @retval False Not able to find apriori statement\r
2238 #\r
2239 def __GetAprioriSection(self, FvObj, MacroDict = {}):\r
2240\r
2241 if not self.__IsKeyword( "APRIORI"):\r
2242 return False\r
2243\r
2244 if not self.__IsKeyword("PEI") and not self.__IsKeyword("DXE"):\r
2245 raise Warning("expected Apriori file type", self.FileName, self.CurrentLineNumber)\r
2246 AprType = self.__Token\r
2247\r
2248 if not self.__IsToken( "{"):\r
2249 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2250\r
2251 AprSectionObj = AprioriSection.AprioriSection()\r
2252 AprSectionObj.AprioriType = AprType\r
2253\r
2254 self.__GetDefineStatements(AprSectionObj)\r
2255 MacroDict.update(AprSectionObj.DefineVarDict)\r
2256\r
2257 while True:\r
2258 IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict)\r
2259 IsFile = self.__GetFileStatement( AprSectionObj)\r
2260 if not IsInf and not IsFile:\r
2261 break\r
2262\r
2263 if not self.__IsToken( "}"):\r
2264 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2265\r
2266 FvObj.AprioriSectionList.append(AprSectionObj)\r
2267 return True\r
2268\r
2269 ## __GetInfStatement() method\r
2270 #\r
2271 # Get INF statements\r
2272 #\r
2273 # @param self The object pointer\r
2274 # @param Obj for whom inf statement is got\r
2275 # @param MacroDict dictionary used to replace macro\r
2276 # @retval True Successfully find inf statement\r
2277 # @retval False Not able to find inf statement\r
2278 #\r
2279 def __GetInfStatement(self, Obj, ForCapsule = False, MacroDict = {}):\r
2280\r
2281 if not self.__IsKeyword( "INF"):\r
2282 return False\r
2283\r
2284 ffsInf = FfsInfStatement.FfsInfStatement()\r
2285 self.__GetInfOptions( ffsInf)\r
2286\r
2287 if not self.__GetNextToken():\r
2288 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)\r
2289 ffsInf.InfFileName = self.__Token\r
14c48571 2290 if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:\r
2291 #do case sensitive check for file path\r
2292 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
2293 if ErrorCode != 0:\r
2294 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 2295\r
30fdf114
LG
2296 if not ffsInf.InfFileName in self.Profile.InfList:\r
2297 self.Profile.InfList.append(ffsInf.InfFileName)\r
d0acc87a
LG
2298 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2299 self.Profile.InfFileLineList.append(FileLineTuple)\r
30fdf114
LG
2300\r
2301 if self.__IsToken('|'):\r
2302 if self.__IsKeyword('RELOCS_STRIPPED'):\r
2303 ffsInf.KeepReloc = False\r
2304 elif self.__IsKeyword('RELOCS_RETAINED'):\r
2305 ffsInf.KeepReloc = True\r
2306 else:\r
2307 raise Warning("Unknown reloc strip flag '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
79b74a03
LG
2308 \r
2309 ffsInf.CurrentLineNum = self.CurrentLineNumber\r
2310 ffsInf.CurrentLineContent = self.__CurrentLine()\r
2311 \r
30fdf114
LG
2312 if ForCapsule:\r
2313 capsuleFfs = CapsuleData.CapsuleFfs()\r
2314 capsuleFfs.Ffs = ffsInf\r
2315 Obj.CapsuleDataList.append(capsuleFfs)\r
2316 else:\r
2317 Obj.FfsList.append(ffsInf)\r
2318 return True\r
2319\r
2320 ## __GetInfOptions() method\r
2321 #\r
2322 # Get options for INF\r
2323 #\r
2324 # @param self The object pointer\r
2325 # @param FfsInfObj for whom option is got\r
2326 #\r
2327 def __GetInfOptions(self, FfsInfObj):\r
2328\r
2329 if self.__IsKeyword( "RuleOverride"):\r
2330 if not self.__IsToken( "="):\r
2331 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2332 if not self.__GetNextToken():\r
2333 raise Warning("expected Rule name", self.FileName, self.CurrentLineNumber)\r
2334 FfsInfObj.Rule = self.__Token\r
2335\r
2336 if self.__IsKeyword( "VERSION"):\r
2337 if not self.__IsToken( "="):\r
2338 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2339 if not self.__GetNextToken():\r
2340 raise Warning("expected Version", self.FileName, self.CurrentLineNumber)\r
2341\r
2342 if self.__GetStringData():\r
2343 FfsInfObj.Version = self.__Token\r
2344\r
2345 if self.__IsKeyword( "UI"):\r
2346 if not self.__IsToken( "="):\r
2347 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2348 if not self.__GetNextToken():\r
2349 raise Warning("expected UI name", self.FileName, self.CurrentLineNumber)\r
2350\r
2351 if self.__GetStringData():\r
2352 FfsInfObj.Ui = self.__Token\r
2353\r
2354 if self.__IsKeyword( "USE"):\r
2355 if not self.__IsToken( "="):\r
2356 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2357 if not self.__GetNextToken():\r
2358 raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber)\r
2359 FfsInfObj.UseArch = self.__Token\r
2360\r
2361 \r
2362 if self.__GetNextToken():\r
2363 p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')\r
2364 if p.match(self.__Token):\r
2365 FfsInfObj.KeyStringList.append(self.__Token)\r
2366 if not self.__IsToken(","):\r
2367 return\r
2368 else:\r
2369 self.__UndoToken()\r
2370 return\r
2371\r
2372 while self.__GetNextToken():\r
2373 if not p.match(self.__Token):\r
2374 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
2375 FfsInfObj.KeyStringList.append(self.__Token)\r
2376\r
2377 if not self.__IsToken(","):\r
2378 break\r
2379\r
2380 ## __GetFileStatement() method\r
2381 #\r
2382 # Get FILE statements\r
2383 #\r
2384 # @param self The object pointer\r
2385 # @param Obj for whom FILE statement is got\r
2386 # @param MacroDict dictionary used to replace macro\r
2387 # @retval True Successfully find FILE statement\r
2388 # @retval False Not able to find FILE statement\r
2389 #\r
2390 def __GetFileStatement(self, Obj, ForCapsule = False, MacroDict = {}):\r
2391\r
2392 if not self.__IsKeyword( "FILE"):\r
2393 return False\r
2394\r
30fdf114
LG
2395 if not self.__GetNextWord():\r
2396 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)\r
b36d134f
LG
2397\r
2398 if ForCapsule and self.__Token == 'DATA':\r
2399 self.__UndoToken()\r
2400 self.__UndoToken()\r
2401 return False\r
2402 \r
2403 FfsFileObj = FfsFileStatement.FileStatement()\r
30fdf114
LG
2404 FfsFileObj.FvFileType = self.__Token\r
2405\r
2406 if not self.__IsToken( "="):\r
2407 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2408\r
2409 if not self.__GetNextGuid():\r
2410 if not self.__GetNextWord():\r
2411 raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber)\r
2412 if self.__Token == 'PCD':\r
2413 if not self.__IsToken( "("):\r
2414 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)\r
2415 PcdPair = self.__GetNextPcdName()\r
2416 if not self.__IsToken( ")"):\r
2417 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)\r
2418 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'\r
2419 \r
2420 FfsFileObj.NameGuid = self.__Token\r
79b74a03
LG
2421 \r
2422 FfsFileObj.CurrentLineNum = self.CurrentLineNumber\r
2423 FfsFileObj.CurrentLineContent = self.__CurrentLine()\r
2424 \r
30fdf114
LG
2425 self.__GetFilePart( FfsFileObj, MacroDict.copy())\r
2426\r
2427 if ForCapsule:\r
2428 capsuleFfs = CapsuleData.CapsuleFfs()\r
2429 capsuleFfs.Ffs = FfsFileObj\r
2430 Obj.CapsuleDataList.append(capsuleFfs)\r
2431 else:\r
2432 Obj.FfsList.append(FfsFileObj)\r
2433\r
2434 return True\r
2435\r
2436 ## __FileCouldHaveRelocFlag() method\r
2437 #\r
2438 # Check whether reloc strip flag can be set for a file type.\r
2439 #\r
2440 # @param self The object pointer\r
2441 # @param FileType The file type to check with\r
2442 # @retval True This type could have relocation strip flag\r
2443 # @retval False No way to have it\r
2444 #\r
2445\r
2446 def __FileCouldHaveRelocFlag (self, FileType):\r
2447 if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):\r
2448 return True\r
2449 else:\r
2450 return False\r
2451\r
2452 ## __SectionCouldHaveRelocFlag() method\r
2453 #\r
2454 # Check whether reloc strip flag can be set for a section type.\r
2455 #\r
2456 # @param self The object pointer\r
2457 # @param SectionType The section type to check with\r
2458 # @retval True This type could have relocation strip flag\r
2459 # @retval False No way to have it\r
2460 #\r
2461\r
2462 def __SectionCouldHaveRelocFlag (self, SectionType):\r
2463 if SectionType in ('TE', 'PE32'):\r
2464 return True\r
2465 else:\r
2466 return False\r
2467\r
2468 ## __GetFilePart() method\r
2469 #\r
2470 # Get components for FILE statement\r
2471 #\r
2472 # @param self The object pointer\r
2473 # @param FfsFileObj for whom component is got\r
2474 # @param MacroDict dictionary used to replace macro\r
2475 #\r
2476 def __GetFilePart(self, FfsFileObj, MacroDict = {}):\r
2477\r
2478 self.__GetFileOpts( FfsFileObj)\r
2479\r
2480 if not self.__IsToken("{"):\r
2481# if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):\r
2482# if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType):\r
2483# if self.__Token == 'RELOCS_STRIPPED':\r
2484# FfsFileObj.KeepReloc = False\r
2485# else:\r
2486# FfsFileObj.KeepReloc = True\r
2487# else:\r
2488# raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
2489#\r
2490# if not self.__IsToken("{"):\r
2491 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2492\r
2493 if not self.__GetNextToken():\r
2494 raise Warning("expected File name or section data", self.FileName, self.CurrentLineNumber)\r
2495\r
2496 if self.__Token == "FV":\r
2497 if not self.__IsToken( "="):\r
2498 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2499 if not self.__GetNextToken():\r
2500 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)\r
2501 FfsFileObj.FvName = self.__Token\r
2502\r
2503 elif self.__Token == "FD":\r
2504 if not self.__IsToken( "="):\r
2505 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2506 if not self.__GetNextToken():\r
2507 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)\r
2508 FfsFileObj.FdName = self.__Token\r
2509\r
2510 elif self.__Token in ("DEFINE", "APRIORI", "SECTION"):\r
2511 self.__UndoToken()\r
2512 self.__GetSectionData( FfsFileObj, MacroDict)\r
2513 else:\r
2514 FfsFileObj.FileName = self.__Token\r
14c48571 2515 if FfsFileObj.FileName.replace('$(WORKSPACE)', '').find('$') == -1:\r
df692f02
LG
2516 #\r
2517 # For file in OUTPUT_DIRECTORY will not check whether it exist or not at AutoGen phase.\r
2518 #\r
2519 if not GlobalData.gAutoGenPhase:\r
2520 #do case sensitive check for file path\r
2521 ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
2522 if ErrorCode != 0:\r
2523 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
2524 else:\r
d0acc87a 2525 if not self.__GetMacroValue("OUTPUT_DIRECTORY") in FfsFileObj.FileName:\r
df692f02
LG
2526 #do case sensitive check for file path\r
2527 ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
2528 if ErrorCode != 0:\r
2529 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) \r
30fdf114 2530\r
0d2711a6 2531\r
30fdf114
LG
2532 if not self.__IsToken( "}"):\r
2533 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2534\r
2535 ## __GetFileOpts() method\r
2536 #\r
2537 # Get options for FILE statement\r
2538 #\r
2539 # @param self The object pointer\r
2540 # @param FfsFileObj for whom options is got\r
2541 #\r
2542 def __GetFileOpts(self, FfsFileObj):\r
2543\r
2544 if self.__GetNextToken():\r
2545 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')\r
2546 if Pattern.match(self.__Token):\r
2547 FfsFileObj.KeyStringList.append(self.__Token)\r
2548 if self.__IsToken(","):\r
2549 while self.__GetNextToken():\r
2550 if not Pattern.match(self.__Token):\r
2551 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
2552 FfsFileObj.KeyStringList.append(self.__Token)\r
2553\r
2554 if not self.__IsToken(","):\r
2555 break\r
2556\r
2557 else:\r
2558 self.__UndoToken()\r
2559\r
2560 if self.__IsKeyword( "FIXED", True):\r
2561 FfsFileObj.Fixed = True\r
2562\r
2563 if self.__IsKeyword( "CHECKSUM", True):\r
2564 FfsFileObj.CheckSum = True\r
2565\r
2566 if self.__GetAlignment():\r
9053bc51 2567 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):\r
2568 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
2569 #For FFS, Auto is default option same to ""\r
2570 if not self.__Token == "Auto":\r
2571 FfsFileObj.Alignment = self.__Token\r
30fdf114
LG
2572\r
2573 ## __GetAlignment() method\r
2574 #\r
2575 # Return the alignment value\r
2576 #\r
2577 # @param self The object pointer\r
2578 # @retval True Successfully find alignment\r
2579 # @retval False Not able to find alignment\r
2580 #\r
2581 def __GetAlignment(self):\r
2582 if self.__IsKeyword( "Align", True):\r
2583 if not self.__IsToken( "="):\r
2584 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2585\r
2586 if not self.__GetNextToken():\r
2587 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)\r
2588 return True\r
2589\r
2590 return False\r
2591\r
2592 ## __GetFilePart() method\r
2593 #\r
2594 # Get section data for FILE statement\r
2595 #\r
2596 # @param self The object pointer\r
2597 # @param FfsFileObj for whom section is got\r
2598 # @param MacroDict dictionary used to replace macro\r
2599 #\r
2600 def __GetSectionData(self, FfsFileObj, MacroDict = {}):\r
2601 Dict = {}\r
2602 Dict.update(MacroDict)\r
2603\r
2604 self.__GetDefineStatements(FfsFileObj)\r
2605\r
2606 Dict.update(FfsFileObj.DefineVarDict)\r
2607 self.__GetAprioriSection(FfsFileObj, Dict.copy())\r
2608 self.__GetAprioriSection(FfsFileObj, Dict.copy())\r
2609\r
2610 while True:\r
2611 IsLeafSection = self.__GetLeafSection(FfsFileObj, Dict)\r
2612 IsEncapSection = self.__GetEncapsulationSec(FfsFileObj)\r
2613 if not IsLeafSection and not IsEncapSection:\r
2614 break\r
2615\r
2616 ## __GetLeafSection() method\r
2617 #\r
2618 # Get leaf section for Obj\r
2619 #\r
2620 # @param self The object pointer\r
2621 # @param Obj for whom leaf section is got\r
2622 # @param MacroDict dictionary used to replace macro\r
2623 # @retval True Successfully find section statement\r
2624 # @retval False Not able to find section statement\r
2625 #\r
2626 def __GetLeafSection(self, Obj, MacroDict = {}):\r
2627\r
2628 OldPos = self.GetFileBufferPos()\r
2629\r
2630 if not self.__IsKeyword( "SECTION"):\r
2631 if len(Obj.SectionList) == 0:\r
2632 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)\r
2633 else:\r
2634 return False\r
2635\r
2636 AlignValue = None\r
2637 if self.__GetAlignment():\r
52302d4d
LG
2638 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):\r
2639 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2640 AlignValue = self.__Token\r
2641\r
2642 BuildNum = None\r
2643 if self.__IsKeyword( "BUILD_NUM"):\r
2644 if not self.__IsToken( "="):\r
2645 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2646\r
2647 if not self.__GetNextToken():\r
2648 raise Warning("expected Build number value", self.FileName, self.CurrentLineNumber)\r
2649\r
2650 BuildNum = self.__Token\r
2651\r
2652 if self.__IsKeyword( "VERSION"):\r
52302d4d
LG
2653 if AlignValue == 'Auto':\r
2654 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2655 if not self.__IsToken( "="):\r
2656 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2657 if not self.__GetNextToken():\r
2658 raise Warning("expected version", self.FileName, self.CurrentLineNumber)\r
2659 VerSectionObj = VerSection.VerSection()\r
2660 VerSectionObj.Alignment = AlignValue\r
2661 VerSectionObj.BuildNum = BuildNum\r
2662 if self.__GetStringData():\r
2663 VerSectionObj.StringData = self.__Token\r
2664 else:\r
2665 VerSectionObj.FileName = self.__Token\r
2666 Obj.SectionList.append(VerSectionObj)\r
52302d4d 2667 \r
30fdf114 2668 elif self.__IsKeyword( "UI"):\r
52302d4d
LG
2669 if AlignValue == 'Auto':\r
2670 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2671 if not self.__IsToken( "="):\r
2672 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2673 if not self.__GetNextToken():\r
2674 raise Warning("expected UI", self.FileName, self.CurrentLineNumber)\r
2675 UiSectionObj = UiSection.UiSection()\r
2676 UiSectionObj.Alignment = AlignValue\r
2677 if self.__GetStringData():\r
2678 UiSectionObj.StringData = self.__Token\r
2679 else:\r
2680 UiSectionObj.FileName = self.__Token\r
2681 Obj.SectionList.append(UiSectionObj)\r
2682\r
2683 elif self.__IsKeyword( "FV_IMAGE"):\r
52302d4d
LG
2684 if AlignValue == 'Auto':\r
2685 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2686 if not self.__IsToken( "="):\r
2687 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2688 if not self.__GetNextToken():\r
2689 raise Warning("expected FV name or FV file path", self.FileName, self.CurrentLineNumber)\r
2690\r
2691 FvName = self.__Token\r
2692 FvObj = None\r
2693\r
2694 if self.__IsToken( "{"):\r
2695 FvObj = Fv.FV()\r
2696 FvObj.UiFvName = FvName.upper()\r
2697 self.__GetDefineStatements(FvObj)\r
2698 MacroDict.update(FvObj.DefineVarDict)\r
2699 self.__GetBlockStatement(FvObj)\r
2700 self.__GetSetStatements(FvObj)\r
2701 self.__GetFvAlignment(FvObj)\r
2702 self.__GetFvAttributes(FvObj)\r
2703 self.__GetAprioriSection(FvObj, MacroDict.copy())\r
2704 self.__GetAprioriSection(FvObj, MacroDict.copy())\r
2705\r
2706 while True:\r
2707 IsInf = self.__GetInfStatement(FvObj, MacroDict.copy())\r
2708 IsFile = self.__GetFileStatement(FvObj, MacroDict.copy())\r
2709 if not IsInf and not IsFile:\r
2710 break\r
2711\r
2712 if not self.__IsToken( "}"):\r
2713 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2714\r
2715 FvImageSectionObj = FvImageSection.FvImageSection()\r
2716 FvImageSectionObj.Alignment = AlignValue\r
2717 if FvObj != None:\r
2718 FvImageSectionObj.Fv = FvObj\r
2719 FvImageSectionObj.FvName = None\r
2720 else:\r
2721 FvImageSectionObj.FvName = FvName.upper()\r
2722 FvImageSectionObj.FvFileName = FvName\r
2723\r
2724 Obj.SectionList.append(FvImageSectionObj)\r
2725\r
2726 elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP") or self.__IsKeyword("SMM_DEPEX_EXP"):\r
52302d4d
LG
2727 if AlignValue == 'Auto':\r
2728 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2729 DepexSectionObj = DepexSection.DepexSection()\r
2730 DepexSectionObj.Alignment = AlignValue\r
2731 DepexSectionObj.DepexType = self.__Token\r
2732\r
2733 if not self.__IsToken( "="):\r
2734 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2735 if not self.__IsToken( "{"):\r
2736 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2737 if not self.__SkipToToken( "}"):\r
2738 raise Warning("expected Depex expression ending '}'", self.FileName, self.CurrentLineNumber)\r
2739\r
2740 DepexSectionObj.Expression = self.__SkippedChars.rstrip('}')\r
2741 Obj.SectionList.append(DepexSectionObj)\r
2742\r
2743 else:\r
30fdf114
LG
2744 if not self.__GetNextWord():\r
2745 raise Warning("expected section type", self.FileName, self.CurrentLineNumber)\r
2746\r
2747 # Encapsulation section appear, UndoToken and return\r
2748 if self.__Token == "COMPRESS" or self.__Token == "GUIDED":\r
2749 self.SetFileBufferPos(OldPos)\r
2750 return False\r
2751\r
2752 if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\\r
2753 "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"):\r
2754 raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
52302d4d
LG
2755 if AlignValue == 'Auto'and (not self.__Token == 'PE32') and (not self.__Token == 'TE'):\r
2756 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
2757\r
30fdf114
LG
2758 # DataSection\r
2759 DataSectionObj = DataSection.DataSection()\r
2760 DataSectionObj.Alignment = AlignValue\r
2761 DataSectionObj.SecType = self.__Token\r
2762\r
2763 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):\r
2764 if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType):\r
2765 if self.__Token == 'RELOCS_STRIPPED':\r
2766 DataSectionObj.KeepReloc = False\r
2767 else:\r
2768 DataSectionObj.KeepReloc = True\r
2769 else:\r
2770 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
2771\r
2772 if self.__IsToken("="):\r
2773 if not self.__GetNextToken():\r
2774 raise Warning("expected section file path", self.FileName, self.CurrentLineNumber)\r
2775 DataSectionObj.SectFileName = self.__Token\r
14c48571 2776 if DataSectionObj.SectFileName.replace('$(WORKSPACE)', '').find('$') == -1:\r
2777 #do case sensitive check for file path\r
2778 ErrorCode, ErrorInfo = PathClass(NormPath(DataSectionObj.SectFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
2779 if ErrorCode != 0:\r
2780 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114
LG
2781 else:\r
2782 if not self.__GetCglSection(DataSectionObj):\r
2783 return False\r
2784\r
2785 Obj.SectionList.append(DataSectionObj)\r
2786\r
2787 return True\r
2788\r
2789 ## __GetCglSection() method\r
2790 #\r
2791 # Get compressed or GUIDed section for Obj\r
2792 #\r
2793 # @param self The object pointer\r
2794 # @param Obj for whom leaf section is got\r
2795 # @param AlignValue alignment value for complex section\r
2796 # @retval True Successfully find section statement\r
2797 # @retval False Not able to find section statement\r
2798 #\r
2799 def __GetCglSection(self, Obj, AlignValue = None):\r
2800\r
2801 if self.__IsKeyword( "COMPRESS"):\r
2802 type = "PI_STD"\r
2803 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):\r
2804 type = self.__Token\r
2805\r
2806 if not self.__IsToken("{"):\r
2807 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2808\r
2809 CompressSectionObj = CompressSection.CompressSection()\r
2810 CompressSectionObj.Alignment = AlignValue\r
2811 CompressSectionObj.CompType = type\r
2812 # Recursive sections...\r
2813 while True:\r
2814 IsLeafSection = self.__GetLeafSection(CompressSectionObj)\r
2815 IsEncapSection = self.__GetEncapsulationSec(CompressSectionObj)\r
2816 if not IsLeafSection and not IsEncapSection:\r
2817 break\r
2818\r
2819\r
2820 if not self.__IsToken( "}"):\r
2821 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2822 Obj.SectionList.append(CompressSectionObj)\r
2823\r
2824# else:\r
2825# raise Warning("Compress type not known")\r
2826\r
2827 return True\r
2828\r
2829 elif self.__IsKeyword( "GUIDED"):\r
2830 GuidValue = None\r
2831 if self.__GetNextGuid():\r
2832 GuidValue = self.__Token\r
2833\r
2834 AttribDict = self.__GetGuidAttrib()\r
2835 if not self.__IsToken("{"):\r
2836 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2837 GuidSectionObj = GuidSection.GuidSection()\r
2838 GuidSectionObj.Alignment = AlignValue\r
2839 GuidSectionObj.NameGuid = GuidValue\r
2840 GuidSectionObj.SectionType = "GUIDED"\r
2841 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]\r
2842 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]\r
2843 # Recursive sections...\r
2844 while True:\r
2845 IsLeafSection = self.__GetLeafSection(GuidSectionObj)\r
2846 IsEncapSection = self.__GetEncapsulationSec(GuidSectionObj)\r
2847 if not IsLeafSection and not IsEncapSection:\r
2848 break\r
2849\r
2850 if not self.__IsToken( "}"):\r
2851 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2852 Obj.SectionList.append(GuidSectionObj)\r
2853\r
2854 return True\r
2855\r
2856 return False\r
2857\r
2858 ## __GetGuidAttri() method\r
2859 #\r
2860 # Get attributes for GUID section\r
2861 #\r
2862 # @param self The object pointer\r
2863 # @retval AttribDict Dictionary of key-value pair of section attributes\r
2864 #\r
2865 def __GetGuidAttrib(self):\r
2866\r
2867 AttribDict = {}\r
14c48571 2868 AttribDict["PROCESSING_REQUIRED"] = "NONE"\r
2869 AttribDict["AUTH_STATUS_VALID"] = "NONE"\r
30fdf114
LG
2870 if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"):\r
2871 AttribKey = self.__Token\r
2872\r
2873 if not self.__IsToken("="):\r
2874 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2875\r
2876 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):\r
2877 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)\r
2878 AttribDict[AttribKey] = self.__Token\r
2879\r
2880 if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"):\r
2881 AttribKey = self.__Token\r
2882\r
2883 if not self.__IsToken("="):\r
2884 raise Warning("expected '='")\r
2885\r
2886 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):\r
2887 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)\r
2888 AttribDict[AttribKey] = self.__Token\r
2889\r
2890 return AttribDict\r
2891\r
2892 ## __GetEncapsulationSec() method\r
2893 #\r
2894 # Get encapsulation section for FILE\r
2895 #\r
2896 # @param self The object pointer\r
2897 # @param FfsFile for whom section is got\r
2898 # @retval True Successfully find section statement\r
2899 # @retval False Not able to find section statement\r
2900 #\r
2901 def __GetEncapsulationSec(self, FfsFileObj):\r
2902\r
2903 OldPos = self.GetFileBufferPos()\r
2904 if not self.__IsKeyword( "SECTION"):\r
2905 if len(FfsFileObj.SectionList) == 0:\r
2906 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)\r
2907 else:\r
2908 return False\r
2909\r
2910 AlignValue = None\r
2911 if self.__GetAlignment():\r
52302d4d
LG
2912 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):\r
2913 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2914 AlignValue = self.__Token\r
2915\r
2916 if not self.__GetCglSection(FfsFileObj, AlignValue):\r
2917 self.SetFileBufferPos(OldPos)\r
2918 return False\r
2919 else:\r
2920 return True\r
2921\r
2922 ## __GetCapsule() method\r
2923 #\r
2924 # Get capsule section contents and store its data into capsule list of self.Profile\r
2925 #\r
2926 # @param self The object pointer\r
2927 # @retval True Successfully find a capsule\r
2928 # @retval False Not able to find a capsule\r
2929 #\r
2930 def __GetCapsule(self):\r
2931\r
2932 if not self.__GetNextToken():\r
2933 return False\r
2934\r
2935 S = self.__Token.upper()\r
2936 if S.startswith("[") and not S.startswith("[CAPSULE."):\r
2937 if not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
2938 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
2939 self.__UndoToken()\r
2940 return False\r
2941\r
2942 self.__UndoToken()\r
2943 if not self.__IsToken("[CAPSULE.", True):\r
2944 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2945 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
2946 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
2947 raise Warning("expected [Capsule.]", self.FileName, self.CurrentLineNumber)\r
2948\r
2949 CapsuleObj = Capsule.Capsule()\r
2950\r
2951 CapsuleName = self.__GetUiName()\r
2952 if not CapsuleName:\r
2953 raise Warning("expected capsule name", self.FileName, self.CurrentLineNumber)\r
2954\r
2955 CapsuleObj.UiCapsuleName = CapsuleName.upper()\r
2956\r
2957 if not self.__IsToken( "]"):\r
2958 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
2959\r
2960 if self.__IsKeyword("CREATE_FILE"):\r
2961 if not self.__IsToken( "="):\r
2962 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2963\r
2964 if not self.__GetNextToken():\r
2965 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)\r
2966\r
2967 CapsuleObj.CreateFile = self.__Token\r
2968\r
2969 self.__GetCapsuleStatements(CapsuleObj)\r
fd171542 2970 self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj\r
30fdf114
LG
2971 return True\r
2972\r
2973 ## __GetCapsuleStatements() method\r
2974 #\r
2975 # Get statements for capsule\r
2976 #\r
2977 # @param self The object pointer\r
2978 # @param Obj for whom statements are got\r
2979 #\r
2980 def __GetCapsuleStatements(self, Obj):\r
2981 self.__GetCapsuleTokens(Obj)\r
2982 self.__GetDefineStatements(Obj)\r
2983 self.__GetSetStatements(Obj)\r
30fdf114
LG
2984 self.__GetCapsuleData(Obj)\r
2985\r
fd171542 2986 ## __GetCapsuleTokens() method\r
30fdf114
LG
2987 #\r
2988 # Get token statements for capsule\r
2989 #\r
2990 # @param self The object pointer\r
2991 # @param Obj for whom token statements are got\r
2992 #\r
2993 def __GetCapsuleTokens(self, Obj):\r
b303ea72
LG
2994 if not self.__GetNextToken():\r
2995 return False\r
2996 while self.__Token in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS"):\r
2997 Name = self.__Token.strip()\r
2998 if not self.__IsToken("="):\r
2999 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3000 if not self.__GetNextToken():\r
3001 raise Warning("expected value", self.FileName, self.CurrentLineNumber)\r
3002 if Name == 'CAPSULE_FLAGS':\r
3003 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):\r
3004 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)\r
3005 Value = self.__Token.strip()\r
3006 while self.__IsToken(","):\r
3007 Value += ','\r
3008 if not self.__GetNextToken():\r
3009 raise Warning("expected value", self.FileName, self.CurrentLineNumber)\r
3010 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):\r
3011 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)\r
3012 Value += self.__Token.strip()\r
3013 else:\r
3014 Value = self.__Token.strip()\r
3015 Obj.TokensDict[Name] = Value \r
3016 if not self.__GetNextToken():\r
3017 return False\r
3018 self.__UndoToken()\r
30fdf114
LG
3019\r
3020 ## __GetCapsuleData() method\r
3021 #\r
3022 # Get capsule data for capsule\r
3023 #\r
3024 # @param self The object pointer\r
3025 # @param Obj for whom capsule data are got\r
3026 #\r
3027 def __GetCapsuleData(self, Obj):\r
3028\r
3029 while True:\r
3030 IsInf = self.__GetInfStatement(Obj, True)\r
3031 IsFile = self.__GetFileStatement(Obj, True)\r
3032 IsFv = self.__GetFvStatement(Obj)\r
b36d134f
LG
3033 IsFd = self.__GetFdStatement(Obj)\r
3034 IsAnyFile = self.__GetAnyFileStatement(Obj)\r
3035 if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile):\r
30fdf114
LG
3036 break\r
3037\r
3038 ## __GetFvStatement() method\r
3039 #\r
3040 # Get FV for capsule\r
3041 #\r
3042 # @param self The object pointer\r
3043 # @param CapsuleObj for whom FV is got\r
3044 # @retval True Successfully find a FV statement\r
3045 # @retval False Not able to find a FV statement\r
3046 #\r
3047 def __GetFvStatement(self, CapsuleObj):\r
3048\r
3049 if not self.__IsKeyword("FV"):\r
3050 return False\r
3051\r
3052 if not self.__IsToken("="):\r
3053 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3054\r
3055 if not self.__GetNextToken():\r
3056 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)\r
3057\r
2bcc713e
LG
3058 if self.__Token.upper() not in self.Profile.FvDict.keys():\r
3059 raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber)\r
3060\r
30fdf114
LG
3061 CapsuleFv = CapsuleData.CapsuleFv()\r
3062 CapsuleFv.FvName = self.__Token\r
3063 CapsuleObj.CapsuleDataList.append(CapsuleFv)\r
3064 return True\r
3065\r
b36d134f
LG
3066 ## __GetFdStatement() method\r
3067 #\r
3068 # Get FD for capsule\r
3069 #\r
3070 # @param self The object pointer\r
3071 # @param CapsuleObj for whom FD is got\r
3072 # @retval True Successfully find a FD statement\r
3073 # @retval False Not able to find a FD statement\r
3074 #\r
3075 def __GetFdStatement(self, CapsuleObj):\r
3076\r
3077 if not self.__IsKeyword("FD"):\r
3078 return False\r
3079\r
3080 if not self.__IsToken("="):\r
3081 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3082\r
3083 if not self.__GetNextToken():\r
3084 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)\r
3085\r
2bcc713e
LG
3086 if self.__Token.upper() not in self.Profile.FdDict.keys():\r
3087 raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber)\r
3088\r
b36d134f
LG
3089 CapsuleFd = CapsuleData.CapsuleFd()\r
3090 CapsuleFd.FdName = self.__Token\r
3091 CapsuleObj.CapsuleDataList.append(CapsuleFd)\r
3092 return True\r
3093\r
3094 ## __GetAnyFileStatement() method\r
3095 #\r
3096 # Get AnyFile for capsule\r
3097 #\r
3098 # @param self The object pointer\r
3099 # @param CapsuleObj for whom AnyFile is got\r
3100 # @retval True Successfully find a Anyfile statement\r
3101 # @retval False Not able to find a AnyFile statement\r
3102 #\r
3103 def __GetAnyFileStatement(self, CapsuleObj):\r
3104\r
3105 if not self.__IsKeyword("FILE"):\r
3106 return False\r
3107\r
3108 if not self.__IsKeyword("DATA"):\r
3109 self.__UndoToken()\r
3110 return False\r
3111\r
3112 if not self.__IsToken("="):\r
3113 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3114\r
3115 if not self.__GetNextToken():\r
3116 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)\r
3117 \r
3118 AnyFileName = self.__Token\r
3119 AnyFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AnyFileName)\r
3120 if not os.path.exists(AnyFileName):\r