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