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