]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Common/FdfParserLite.py
BaseTools: Update Expression.py for string comparison and MACRO replace issue
[mirror_edk2.git] / BaseTools / Source / Python / Common / FdfParserLite.py
1 ## @file
2 # parse FDF file
3 #
4 # Copyright (c) 2007 - 2017, 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
25 ##define T_CHAR_SPACE ' '
26 ##define T_CHAR_NULL '\0'
27 ##define T_CHAR_CR '\r'
28 ##define T_CHAR_TAB '\t'
29 ##define T_CHAR_LF '\n'
30 ##define T_CHAR_SLASH '/'
31 ##define T_CHAR_BACKSLASH '\\'
32 ##define T_CHAR_DOUBLE_QUOTE '\"'
33 ##define T_CHAR_SINGLE_QUOTE '\''
34 ##define T_CHAR_STAR '*'
35 ##define T_CHAR_HASH '#'
36
37 (T_CHAR_SPACE, T_CHAR_NULL, T_CHAR_CR, T_CHAR_TAB, T_CHAR_LF, T_CHAR_SLASH, \
38 T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \
39 (' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')
40
41 SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')
42
43 IncludeFileList = []
44 # Macro passed from command line, which has greatest priority and can NOT be overridden by those in FDF
45 InputMacroDict = {}
46 # All Macro values when parsing file, not replace existing Macro
47 AllMacroList = []
48
49 def GetRealFileLine (File, Line):
50
51 InsertedLines = 0
52 for Profile in IncludeFileList:
53 if Line >= Profile.InsertStartLineNumber and Line < Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList):
54 return (Profile.FileName, Line - Profile.InsertStartLineNumber + 1)
55 if Line >= Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList):
56 InsertedLines += Profile.InsertAdjust + len(Profile.FileLinesList)
57
58 return (File, Line - InsertedLines)
59
60 ## The exception class that used to report error messages when parsing FDF
61 #
62 # Currently the "ToolName" is set to be "FDF Parser".
63 #
64 class Warning (Exception):
65 ## The constructor
66 #
67 # @param self The object pointer
68 # @param Str The message to record
69 # @param File The FDF name
70 # @param Line The Line number that error occurs
71 #
72 def __init__(self, Str, File=None, Line=None):
73
74 FileLineTuple = GetRealFileLine(File, Line)
75 self.FileName = FileLineTuple[0]
76 self.LineNumber = FileLineTuple[1]
77 self.message = Str + str(self.LineNumber)
78 self.ToolName = 'FDF Parser'
79
80 ## The MACRO class that used to record macro value data when parsing include file
81 #
82 #
83 class MacroProfile :
84 ## The constructor
85 #
86 # @param self The object pointer
87 # @param FileName The file that to be parsed
88 #
89 def __init__(self, FileName, Line):
90 self.FileName = FileName
91 self.DefinedAtLine = Line
92 self.MacroName = None
93 self.MacroValue = None
94
95 ## The Include file content class that used to record file data when parsing include file
96 #
97 # May raise Exception when opening file.
98 #
99 class IncludeFileProfile :
100 ## The constructor
101 #
102 # @param self The object pointer
103 # @param FileName The file that to be parsed
104 #
105 def __init__(self, FileName):
106 self.FileName = FileName
107 self.FileLinesList = []
108 try:
109 fsock = open(FileName, "rb", 0)
110 try:
111 self.FileLinesList = fsock.readlines()
112 finally:
113 fsock.close()
114
115 except IOError:
116 raise Warning("Error when opening file %s" % FileName)
117
118 self.InsertStartLineNumber = None
119 self.InsertAdjust = 0
120
121 ## The FDF content class that used to record file data when parsing FDF
122 #
123 # May raise Exception when opening file.
124 #
125 class FileProfile :
126 ## The constructor
127 #
128 # @param self The object pointer
129 # @param FileName The file that to be parsed
130 #
131 def __init__(self, FileName):
132 self.FileLinesList = []
133 try:
134 fsock = open(FileName, "rb", 0)
135 try:
136 self.FileLinesList = fsock.readlines()
137 finally:
138 fsock.close()
139
140 except IOError:
141 raise Warning("Error when opening file %s" % FileName)
142
143 self.PcdDict = {}
144 self.InfList = []
145
146 self.PcdFileLineDict = {}
147 self.InfFileLineList = []
148
149 self.FdDict = {}
150 self.FvDict = {}
151 self.CapsuleList = []
152 # self.VtfList = []
153 # self.RuleDict = {}
154
155 ## The syntax parser for FDF
156 #
157 # PreprocessFile method should be called prior to ParseFile
158 # CycleReferenceCheck method can detect cycles in FDF contents
159 #
160 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
161 # Get*** procedures mean these procedures will make judgement on current token only.
162 #
163 class FdfParser(object):
164 ## The constructor
165 #
166 # @param self The object pointer
167 # @param FileName The file that to be parsed
168 #
169 def __init__(self, FileName):
170 self.Profile = FileProfile(FileName)
171 self.FileName = FileName
172 self.CurrentLineNumber = 1
173 self.CurrentOffsetWithinLine = 0
174 self.CurrentFdName = None
175 self.CurrentFvName = None
176 self.__Token = ""
177 self.__SkippedChars = ""
178
179 self.__WipeOffArea = []
180
181 ## __IsWhiteSpace() method
182 #
183 # Whether char at current FileBufferPos is whitespace
184 #
185 # @param self The object pointer
186 # @param Char The char to test
187 # @retval True The char is a kind of white space
188 # @retval False The char is NOT a kind of white space
189 #
190 def __IsWhiteSpace(self, Char):
191 if Char in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_SPACE, T_CHAR_TAB, T_CHAR_LF):
192 return True
193 else:
194 return False
195
196 ## __SkipWhiteSpace() method
197 #
198 # Skip white spaces from current char, return number of chars skipped
199 #
200 # @param self The object pointer
201 # @retval Count The number of chars skipped
202 #
203 def __SkipWhiteSpace(self):
204 Count = 0
205 while not self.__EndOfFile():
206 Count += 1
207 if self.__CurrentChar() in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_LF, T_CHAR_SPACE, T_CHAR_TAB):
208 self.__SkippedChars += str(self.__CurrentChar())
209 self.__GetOneChar()
210
211 else:
212 Count = Count - 1
213 return Count
214
215 ## __EndOfFile() method
216 #
217 # Judge current buffer pos is at file end
218 #
219 # @param self The object pointer
220 # @retval True Current File buffer position is at file end
221 # @retval False Current File buffer position is NOT at file end
222 #
223 def __EndOfFile(self):
224 NumberOfLines = len(self.Profile.FileLinesList)
225 SizeOfLastLine = len(self.Profile.FileLinesList[-1])
226 if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1:
227 return True
228 elif self.CurrentLineNumber > NumberOfLines:
229 return True
230 else:
231 return False
232
233 ## __EndOfLine() method
234 #
235 # Judge current buffer pos is at line end
236 #
237 # @param self The object pointer
238 # @retval True Current File buffer position is at line end
239 # @retval False Current File buffer position is NOT at line end
240 #
241 def __EndOfLine(self):
242 if self.CurrentLineNumber > len(self.Profile.FileLinesList):
243 return True
244 SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
245 if self.CurrentOffsetWithinLine >= SizeOfCurrentLine:
246 return True
247 else:
248 return False
249
250 ## Rewind() method
251 #
252 # Reset file data buffer to the initial state
253 #
254 # @param self The object pointer
255 #
256 def Rewind(self):
257 self.CurrentLineNumber = 1
258 self.CurrentOffsetWithinLine = 0
259
260 ## __UndoOneChar() method
261 #
262 # Go back one char in the file buffer
263 #
264 # @param self The object pointer
265 # @retval True Successfully go back one char
266 # @retval False Not able to go back one char as file beginning reached
267 #
268 def __UndoOneChar(self):
269
270 if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0:
271 return False
272 elif self.CurrentOffsetWithinLine == 0:
273 self.CurrentLineNumber -= 1
274 self.CurrentOffsetWithinLine = len(self.__CurrentLine()) - 1
275 else:
276 self.CurrentOffsetWithinLine -= 1
277 return True
278
279 ## __GetOneChar() method
280 #
281 # Move forward one char in the file buffer
282 #
283 # @param self The object pointer
284 #
285 def __GetOneChar(self):
286 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
287 self.CurrentLineNumber += 1
288 self.CurrentOffsetWithinLine = 0
289 else:
290 self.CurrentOffsetWithinLine += 1
291
292 ## __CurrentChar() method
293 #
294 # Get the char pointed to by the file buffer pointer
295 #
296 # @param self The object pointer
297 # @retval Char Current char
298 #
299 def __CurrentChar(self):
300 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine]
301
302 ## __NextChar() method
303 #
304 # Get the one char pass the char pointed to by the file buffer pointer
305 #
306 # @param self The object pointer
307 # @retval Char Next char
308 #
309 def __NextChar(self):
310 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
311 return self.Profile.FileLinesList[self.CurrentLineNumber][0]
312 else:
313 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1]
314
315 ## __SetCurrentCharValue() method
316 #
317 # Modify the value of current char
318 #
319 # @param self The object pointer
320 # @param Value The new value of current char
321 #
322 def __SetCurrentCharValue(self, Value):
323 self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value
324
325 ## __CurrentLine() method
326 #
327 # Get the list that contains current line contents
328 #
329 # @param self The object pointer
330 # @retval List current line contents
331 #
332 def __CurrentLine(self):
333 return self.Profile.FileLinesList[self.CurrentLineNumber - 1]
334
335 def __StringToList(self):
336 self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList]
337 self.Profile.FileLinesList[-1].append(' ')
338
339 def __ReplaceMacros(self, Str, File, Line):
340 MacroEnd = 0
341 while Str.find('$(', MacroEnd) >= 0:
342 MacroStart = Str.find('$(', MacroEnd)
343 if Str.find(')', MacroStart) > 0:
344 MacroEnd = Str.find(')', MacroStart)
345 Name = Str[MacroStart + 2 : MacroEnd]
346 Value = None
347 if Name in InputMacroDict:
348 Value = InputMacroDict[Name]
349
350 else:
351 for Profile in AllMacroList:
352 if Profile.FileName == File and Profile.MacroName == Name and Profile.DefinedAtLine <= Line:
353 Value = Profile.MacroValue
354
355 if Value != None:
356 Str = Str.replace('$(' + Name + ')', Value)
357 MacroEnd = MacroStart + len(Value)
358
359 else:
360 raise Warning("Macro not complete At Line ", self.FileName, self.CurrentLineNumber)
361 return Str
362
363 def __ReplaceFragment(self, StartPos, EndPos, Value=' '):
364 if StartPos[0] == EndPos[0]:
365 Offset = StartPos[1]
366 while Offset <= EndPos[1]:
367 self.Profile.FileLinesList[StartPos[0]][Offset] = Value
368 Offset += 1
369 return
370
371 Offset = StartPos[1]
372 while self.Profile.FileLinesList[StartPos[0]][Offset] not in ('\r', '\n'):
373 self.Profile.FileLinesList[StartPos[0]][Offset] = Value
374 Offset += 1
375
376 Line = StartPos[0]
377 while Line < EndPos[0]:
378 Offset = 0
379 while self.Profile.FileLinesList[Line][Offset] not in ('\r', '\n'):
380 self.Profile.FileLinesList[Line][Offset] = Value
381 Offset += 1
382 Line += 1
383
384 Offset = 0
385 while Offset <= EndPos[1]:
386 self.Profile.FileLinesList[EndPos[0]][Offset] = Value
387 Offset += 1
388
389
390 def __GetMacroName(self):
391 if not self.__GetNextToken():
392 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)
393 MacroName = self.__Token
394 NotFlag = False
395 if MacroName.startswith('!'):
396 NotFlag = True
397 MacroName = MacroName[1:].strip()
398
399 if not MacroName.startswith('$(') or not MacroName.endswith(')'):
400 raise Warning("Macro name expected(Please use '$(%(Token)s)' if '%(Token)s' is a macro.)" % {"Token" : MacroName},
401 self.FileName, self.CurrentLineNumber)
402 MacroName = MacroName[2:-1]
403 return MacroName, NotFlag
404
405 ## PreprocessFile() method
406 #
407 # Preprocess file contents, replace comments with spaces.
408 # In the end, rewind the file buffer pointer to the beginning
409 # BUGBUG: No !include statement processing contained in this procedure
410 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
411 #
412 # @param self The object pointer
413 #
414 def PreprocessFile(self):
415
416 self.Rewind()
417 InComment = False
418 DoubleSlashComment = False
419 HashComment = False
420 # HashComment in quoted string " " is ignored.
421 InString = False
422
423 while not self.__EndOfFile():
424
425 if self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment:
426 InString = not InString
427 # meet new line, then no longer in a comment for // and '#'
428 if self.__CurrentChar() == T_CHAR_LF:
429 self.CurrentLineNumber += 1
430 self.CurrentOffsetWithinLine = 0
431 if InComment and DoubleSlashComment:
432 InComment = False
433 DoubleSlashComment = False
434 if InComment and HashComment:
435 InComment = False
436 HashComment = False
437 # check for */ comment end
438 elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH:
439 self.__SetCurrentCharValue(T_CHAR_SPACE)
440 self.__GetOneChar()
441 self.__SetCurrentCharValue(T_CHAR_SPACE)
442 self.__GetOneChar()
443 InComment = False
444 # set comments to spaces
445 elif InComment:
446 self.__SetCurrentCharValue(T_CHAR_SPACE)
447 self.__GetOneChar()
448 # check for // comment
449 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH and not self.__EndOfLine():
450 InComment = True
451 DoubleSlashComment = True
452 # check for '#' comment
453 elif self.__CurrentChar() == T_CHAR_HASH and not self.__EndOfLine() and not InString:
454 InComment = True
455 HashComment = True
456 # check for /* comment start
457 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR:
458 self.__SetCurrentCharValue( T_CHAR_SPACE)
459 self.__GetOneChar()
460 self.__SetCurrentCharValue( T_CHAR_SPACE)
461 self.__GetOneChar()
462 InComment = True
463 else:
464 self.__GetOneChar()
465
466 # restore from ListOfList to ListOfString
467 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
468 self.Rewind()
469
470 ## PreprocessIncludeFile() method
471 #
472 # Preprocess file contents, replace !include statements with file contents.
473 # In the end, rewind the file buffer pointer to the beginning
474 #
475 # @param self The object pointer
476 #
477 def PreprocessIncludeFile(self):
478
479 while self.__GetNextToken():
480
481 if self.__Token == '!include':
482 IncludeLine = self.CurrentLineNumber
483 IncludeOffset = self.CurrentOffsetWithinLine - len('!include')
484 if not self.__GetNextToken():
485 raise Warning("expected include file name At Line ", self.FileName, self.CurrentLineNumber)
486 IncFileName = self.__Token
487 if not os.path.isabs(IncFileName):
488 if IncFileName.startswith('$(WORKSPACE)'):
489 Str = mws.handleWsMacro(IncFileName)
490 Str = Str.replace('$(WORKSPACE)', os.environ.get('WORKSPACE'))
491 if os.path.exists(Str):
492 if not os.path.isabs(Str):
493 Str = os.path.abspath(Str)
494 IncFileName = Str
495 else:
496 # file is in the same dir with FDF file
497 FullFdf = self.FileName
498 if not os.path.isabs(self.FileName):
499 FullFdf = mws.join(os.environ.get('WORKSPACE'), self.FileName)
500
501 IncFileName = os.path.join(os.path.dirname(FullFdf), IncFileName)
502
503 if not os.path.exists(os.path.normpath(IncFileName)):
504 raise Warning("Include file not exists At Line ", self.FileName, self.CurrentLineNumber)
505
506 IncFileProfile = IncludeFileProfile(os.path.normpath(IncFileName))
507
508 CurrentLine = self.CurrentLineNumber
509 CurrentOffset = self.CurrentOffsetWithinLine
510 # list index of the insertion, note that line number is 'CurrentLine + 1'
511 InsertAtLine = CurrentLine
512 IncFileProfile.InsertStartLineNumber = InsertAtLine + 1
513 # deal with remaining portions after "!include filename", if exists.
514 if self.__GetNextToken():
515 if self.CurrentLineNumber == CurrentLine:
516 RemainingLine = self.__CurrentLine()[CurrentOffset:]
517 self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine)
518 IncFileProfile.InsertAdjust += 1
519 self.CurrentLineNumber += 1
520 self.CurrentOffsetWithinLine = 0
521
522 for Line in IncFileProfile.FileLinesList:
523 self.Profile.FileLinesList.insert(InsertAtLine, Line)
524 self.CurrentLineNumber += 1
525 InsertAtLine += 1
526
527 IncludeFileList.append(IncFileProfile)
528
529 # comment out the processed include file statement
530 TempList = list(self.Profile.FileLinesList[IncludeLine - 1])
531 TempList.insert(IncludeOffset, '#')
532 self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)
533
534 self.Rewind()
535
536 ## PreprocessIncludeFile() method
537 #
538 # Preprocess file contents, replace !include statements with file contents.
539 # In the end, rewind the file buffer pointer to the beginning
540 #
541 # @param self The object pointer
542 #
543 def PreprocessConditionalStatement(self):
544 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
545 IfList = []
546 while self.__GetNextToken():
547 if self.__Token == 'DEFINE':
548 DefineLine = self.CurrentLineNumber - 1
549 DefineOffset = self.CurrentOffsetWithinLine - len('DEFINE')
550 if not self.__GetNextToken():
551 raise Warning("expected Macro name At Line ", self.FileName, self.CurrentLineNumber)
552 Macro = self.__Token
553 if not self.__IsToken( "="):
554 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
555
556 if not self.__GetNextToken():
557 raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber)
558
559 if self.__GetStringData():
560 pass
561 Value = self.__Token
562 if not Macro in InputMacroDict:
563 FileLineTuple = GetRealFileLine(self.FileName, DefineLine + 1)
564 MacProfile = MacroProfile(FileLineTuple[0], FileLineTuple[1])
565 MacProfile.MacroName = Macro
566 MacProfile.MacroValue = Value
567 AllMacroList.append(MacProfile)
568 self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
569
570 elif self.__Token in ('!ifdef', '!ifndef', '!if'):
571 IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
572 IfList.append([IfStartPos, None, None])
573 CondLabel = self.__Token
574
575 MacroName, NotFlag = self.__GetMacroName()
576 NotDefineFlag = False
577 if CondLabel == '!ifndef':
578 NotDefineFlag = True
579 if CondLabel == '!ifdef' or CondLabel == '!ifndef':
580 if NotFlag:
581 raise Warning("'NOT' operation not allowed for Macro name At Line ", self.FileName, self.CurrentLineNumber)
582
583 if CondLabel == '!if':
584
585 if not self.__GetNextOp():
586 raise Warning("expected !endif At Line ", self.FileName, self.CurrentLineNumber)
587
588 if self.__Token in ('!=', '==', '>', '<', '>=', '<='):
589 Op = self.__Token
590 if not self.__GetNextToken():
591 raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber)
592 if self.__GetStringData():
593 pass
594 MacroValue = self.__Token
595 ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue)
596 if NotFlag:
597 ConditionSatisfied = not ConditionSatisfied
598 BranchDetermined = ConditionSatisfied
599 else:
600 self.CurrentOffsetWithinLine -= len(self.__Token)
601 ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool')
602 if NotFlag:
603 ConditionSatisfied = not ConditionSatisfied
604 BranchDetermined = ConditionSatisfied
605 IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
606 if ConditionSatisfied:
607 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
608
609 else:
610 ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1)
611 if NotDefineFlag:
612 ConditionSatisfied = not ConditionSatisfied
613 BranchDetermined = ConditionSatisfied
614 IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
615 if ConditionSatisfied:
616 self.__WipeOffArea.append((IfStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
617
618 elif self.__Token in ('!elseif', '!else'):
619 ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
620 if len(IfList) <= 0:
621 raise Warning("Missing !if statement At Line ", self.FileName, self.CurrentLineNumber)
622 if IfList[-1][1]:
623 IfList[-1] = [ElseStartPos, False, True]
624 self.__WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
625 else:
626 self.__WipeOffArea.append((IfList[-1][0], ElseStartPos))
627 IfList[-1] = [ElseStartPos, True, IfList[-1][2]]
628 if self.__Token == '!elseif':
629 MacroName, NotFlag = self.__GetMacroName()
630 if not self.__GetNextOp():
631 raise Warning("expected !endif At Line ", self.FileName, self.CurrentLineNumber)
632
633 if self.__Token in ('!=', '==', '>', '<', '>=', '<='):
634 Op = self.__Token
635 if not self.__GetNextToken():
636 raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber)
637 if self.__GetStringData():
638 pass
639 MacroValue = self.__Token
640 ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue)
641 if NotFlag:
642 ConditionSatisfied = not ConditionSatisfied
643
644 else:
645 self.CurrentOffsetWithinLine -= len(self.__Token)
646 ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool')
647 if NotFlag:
648 ConditionSatisfied = not ConditionSatisfied
649
650 IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]]
651
652 if IfList[-1][1]:
653 if IfList[-1][2]:
654 IfList[-1][1] = False
655 else:
656 IfList[-1][2] = True
657 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
658
659
660 elif self.__Token == '!endif':
661 if IfList[-1][1]:
662 self.__WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
663 else:
664 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
665
666 IfList.pop()
667
668
669 if len(IfList) > 0:
670 raise Warning("Missing !endif At Line ", self.FileName, self.CurrentLineNumber)
671 self.Rewind()
672
673 def __EvaluateConditional(self, Name, Line, Op = None, Value = None):
674
675 FileLineTuple = GetRealFileLine(self.FileName, Line)
676 if Name in InputMacroDict:
677 MacroValue = InputMacroDict[Name]
678 if Op == None:
679 if Value == 'Bool' and MacroValue == None or MacroValue.upper() == 'FALSE':
680 return False
681 return True
682 elif Op == '!=':
683 if Value != MacroValue:
684 return True
685 else:
686 return False
687 elif Op == '==':
688 if Value == MacroValue:
689 return True
690 else:
691 return False
692 else:
693 if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(MacroValue) or (MacroValue != None and MacroValue.isdigit())):
694 InputVal = long(Value, 0)
695 MacroVal = long(MacroValue, 0)
696 if Op == '>':
697 if MacroVal > InputVal:
698 return True
699 else:
700 return False
701 elif Op == '>=':
702 if MacroVal >= InputVal:
703 return True
704 else:
705 return False
706 elif Op == '<':
707 if MacroVal < InputVal:
708 return True
709 else:
710 return False
711 elif Op == '<=':
712 if MacroVal <= InputVal:
713 return True
714 else:
715 return False
716 else:
717 return False
718 else:
719 raise Warning("Value %s is not a number At Line ", self.FileName, Line)
720
721 for Profile in AllMacroList:
722 if Profile.FileName == FileLineTuple[0] and Profile.MacroName == Name and Profile.DefinedAtLine <= FileLineTuple[1]:
723 if Op == None:
724 if Value == 'Bool' and Profile.MacroValue == None or Profile.MacroValue.upper() == 'FALSE':
725 return False
726 return True
727 elif Op == '!=':
728 if Value != Profile.MacroValue:
729 return True
730 else:
731 return False
732 elif Op == '==':
733 if Value == Profile.MacroValue:
734 return True
735 else:
736 return False
737 else:
738 if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(Profile.MacroValue) or (Profile.MacroValue != None and Profile.MacroValue.isdigit())):
739 InputVal = long(Value, 0)
740 MacroVal = long(Profile.MacroValue, 0)
741 if Op == '>':
742 if MacroVal > InputVal:
743 return True
744 else:
745 return False
746 elif Op == '>=':
747 if MacroVal >= InputVal:
748 return True
749 else:
750 return False
751 elif Op == '<':
752 if MacroVal < InputVal:
753 return True
754 else:
755 return False
756 elif Op == '<=':
757 if MacroVal <= InputVal:
758 return True
759 else:
760 return False
761 else:
762 return False
763 else:
764 raise Warning("Value %s is not a number At Line ", self.FileName, Line)
765
766 return False
767
768 ## __IsToken() method
769 #
770 # Check whether input string is found from current char position along
771 # If found, the string value is put into self.__Token
772 #
773 # @param self The object pointer
774 # @param String The string to search
775 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
776 # @retval True Successfully find string, file buffer pointer moved forward
777 # @retval False Not able to find string, file buffer pointer not changed
778 #
779 def __IsToken(self, String, IgnoreCase = False):
780 self.__SkipWhiteSpace()
781
782 # Only consider the same line, no multi-line token allowed
783 StartPos = self.CurrentOffsetWithinLine
784 index = -1
785 if IgnoreCase:
786 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())
787 else:
788 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)
789 if index == 0:
790 self.CurrentOffsetWithinLine += len(String)
791 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
792 return True
793 return False
794
795 ## __IsKeyword() method
796 #
797 # Check whether input keyword is found from current char position along, whole word only!
798 # If found, the string value is put into self.__Token
799 #
800 # @param self The object pointer
801 # @param Keyword The string to search
802 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
803 # @retval True Successfully find string, file buffer pointer moved forward
804 # @retval False Not able to find string, file buffer pointer not changed
805 #
806 def __IsKeyword(self, KeyWord, IgnoreCase = False):
807 self.__SkipWhiteSpace()
808
809 # Only consider the same line, no multi-line token allowed
810 StartPos = self.CurrentOffsetWithinLine
811 index = -1
812 if IgnoreCase:
813 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(KeyWord.upper())
814 else:
815 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(KeyWord)
816 if index == 0:
817 followingChar = self.__CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)]
818 if not str(followingChar).isspace() and followingChar not in SEPERATOR_TUPLE:
819 return False
820 self.CurrentOffsetWithinLine += len(KeyWord)
821 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
822 return True
823 return False
824
825 ## __GetNextWord() method
826 #
827 # Get next C name from file lines
828 # If found, the string value is put into self.__Token
829 #
830 # @param self The object pointer
831 # @retval True Successfully find a C name string, file buffer pointer moved forward
832 # @retval False Not able to find a C name string, file buffer pointer not changed
833 #
834 def __GetNextWord(self):
835 self.__SkipWhiteSpace()
836 if self.__EndOfFile():
837 return False
838
839 TempChar = self.__CurrentChar()
840 StartPos = self.CurrentOffsetWithinLine
841 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_':
842 self.__GetOneChar()
843 while not self.__EndOfLine():
844 TempChar = self.__CurrentChar()
845 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \
846 or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-':
847 self.__GetOneChar()
848
849 else:
850 break
851
852 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
853 return True
854
855 return False
856
857 ## __GetNextToken() method
858 #
859 # Get next token unit before a seperator
860 # If found, the string value is put into self.__Token
861 #
862 # @param self The object pointer
863 # @retval True Successfully find a token unit, file buffer pointer moved forward
864 # @retval False Not able to find a token unit, file buffer pointer not changed
865 #
866 def __GetNextToken(self):
867 # Skip leading spaces, if exist.
868 self.__SkipWhiteSpace()
869 if self.__EndOfFile():
870 return False
871 # Record the token start position, the position of the first non-space char.
872 StartPos = self.CurrentOffsetWithinLine
873 StartLine = self.CurrentLineNumber
874 while not self.__EndOfLine():
875 TempChar = self.__CurrentChar()
876 # Try to find the end char that is not a space and not in seperator tuple.
877 # That is, when we got a space or any char in the tuple, we got the end of token.
878 if not str(TempChar).isspace() and TempChar not in SEPERATOR_TUPLE:
879 self.__GetOneChar()
880 # if we happen to meet a seperator as the first char, we must proceed to get it.
881 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
882 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:
883 self.__GetOneChar()
884 break
885 else:
886 break
887 # else:
888 # return False
889
890 EndPos = self.CurrentOffsetWithinLine
891 if self.CurrentLineNumber != StartLine:
892 EndPos = len(self.Profile.FileLinesList[StartLine-1])
893 self.__Token = self.Profile.FileLinesList[StartLine-1][StartPos : EndPos]
894 if StartPos != self.CurrentOffsetWithinLine:
895 return True
896 else:
897 return False
898
899 def __GetNextOp(self):
900 # Skip leading spaces, if exist.
901 self.__SkipWhiteSpace()
902 if self.__EndOfFile():
903 return False
904 # Record the token start position, the position of the first non-space char.
905 StartPos = self.CurrentOffsetWithinLine
906 while not self.__EndOfLine():
907 TempChar = self.__CurrentChar()
908 # Try to find the end char that is not a space
909 if not str(TempChar).isspace():
910 self.__GetOneChar()
911 else:
912 break
913 else:
914 return False
915
916 if StartPos != self.CurrentOffsetWithinLine:
917 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
918 return True
919 else:
920 return False
921 ## __GetNextGuid() method
922 #
923 # Get next token unit before a seperator
924 # If found, the GUID string is put into self.__Token
925 #
926 # @param self The object pointer
927 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
928 # @retval False Not able to find a registry format GUID, file buffer pointer not changed
929 #
930 def __GetNextGuid(self):
931
932 if not self.__GetNextToken():
933 return False
934 p = re.compile('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}')
935 if p.match(self.__Token) != None:
936 return True
937 else:
938 self.__UndoToken()
939 return False
940
941 ## __UndoToken() method
942 #
943 # Go back one token unit in file buffer
944 #
945 # @param self The object pointer
946 #
947 def __UndoToken(self):
948 self.__UndoOneChar()
949 while self.__CurrentChar().isspace():
950 if not self.__UndoOneChar():
951 self.__GetOneChar()
952 return
953
954
955 StartPos = self.CurrentOffsetWithinLine
956 CurrentLine = self.CurrentLineNumber
957 while CurrentLine == self.CurrentLineNumber:
958
959 TempChar = self.__CurrentChar()
960 # Try to find the end char that is not a space and not in seperator tuple.
961 # That is, when we got a space or any char in the tuple, we got the end of token.
962 if not str(TempChar).isspace() and not TempChar in SEPERATOR_TUPLE:
963 if not self.__UndoOneChar():
964 break
965 # if we happen to meet a seperator as the first char, we must proceed to get it.
966 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
967 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:
968 return
969 else:
970 break
971
972 self.__GetOneChar()
973
974 ## __HexDigit() method
975 #
976 # Whether char input is a Hex data bit
977 #
978 # @param self The object pointer
979 # @param TempChar The char to test
980 # @retval True The char is a Hex data bit
981 # @retval False The char is NOT a Hex data bit
982 #
983 def __HexDigit(self, TempChar):
984 if (TempChar >= 'a' and TempChar <= 'f') or (TempChar >= 'A' and TempChar <= 'F') \
985 or (TempChar >= '0' and TempChar <= '9'):
986 return True
987 else:
988 return False
989
990 def __IsHex(self, HexStr):
991 if not HexStr.upper().startswith("0X"):
992 return False
993 if len(self.__Token) <= 2:
994 return False
995 charList = [c for c in HexStr[2 : ] if not self.__HexDigit( c)]
996 if len(charList) == 0:
997 return True
998 else:
999 return False
1000 ## __GetNextHexNumber() method
1001 #
1002 # Get next HEX data before a seperator
1003 # If found, the HEX data is put into self.__Token
1004 #
1005 # @param self The object pointer
1006 # @retval True Successfully find a HEX data, file buffer pointer moved forward
1007 # @retval False Not able to find a HEX data, file buffer pointer not changed
1008 #
1009 def __GetNextHexNumber(self):
1010 if not self.__GetNextToken():
1011 return False
1012 if self.__IsHex(self.__Token):
1013 return True
1014 else:
1015 self.__UndoToken()
1016 return False
1017
1018 ## __GetNextDecimalNumber() method
1019 #
1020 # Get next decimal data before a seperator
1021 # If found, the decimal data is put into self.__Token
1022 #
1023 # @param self The object pointer
1024 # @retval True Successfully find a decimal data, file buffer pointer moved forward
1025 # @retval False Not able to find a decimal data, file buffer pointer not changed
1026 #
1027 def __GetNextDecimalNumber(self):
1028 if not self.__GetNextToken():
1029 return False
1030 if self.__Token.isdigit():
1031 return True
1032 else:
1033 self.__UndoToken()
1034 return False
1035
1036 ## __GetNextPcdName() method
1037 #
1038 # Get next PCD token space C name and PCD C name pair before a seperator
1039 # If found, the decimal data is put into self.__Token
1040 #
1041 # @param self The object pointer
1042 # @retval Tuple PCD C name and PCD token space C name pair
1043 #
1044 def __GetNextPcdName(self):
1045 if not self.__GetNextWord():
1046 raise Warning("expected PcdTokenSpaceCName.PcdCName At Line ", self.FileName, self.CurrentLineNumber)
1047 pcdTokenSpaceCName = self.__Token
1048
1049 if not self.__IsToken( "."):
1050 raise Warning("expected PcdTokenSpaceCName.PcdCName At Line ", self.FileName, self.CurrentLineNumber)
1051
1052 if not self.__GetNextWord():
1053 raise Warning("expected PcdTokenSpaceCName.PcdCName At Line ", self.FileName, self.CurrentLineNumber)
1054 pcdCName = self.__Token
1055
1056 return (pcdCName, pcdTokenSpaceCName)
1057
1058 ## __GetStringData() method
1059 #
1060 # Get string contents quoted in ""
1061 # If found, the decimal data is put into self.__Token
1062 #
1063 # @param self The object pointer
1064 # @retval True Successfully find a string data, file buffer pointer moved forward
1065 # @retval False Not able to find a string data, file buffer pointer not changed
1066 #
1067 def __GetStringData(self):
1068 if self.__Token.startswith("\"") or self.__Token.startswith("L\""):
1069 self.__UndoToken()
1070 self.__SkipToToken("\"")
1071 currentLineNumber = self.CurrentLineNumber
1072
1073 if not self.__SkipToToken("\""):
1074 raise Warning("Missing Quote \" for String At Line ", self.FileName, self.CurrentLineNumber)
1075 if currentLineNumber != self.CurrentLineNumber:
1076 raise Warning("Missing Quote \" for String At Line ", self.FileName, self.CurrentLineNumber)
1077 self.__Token = self.__SkippedChars.rstrip('\"')
1078 return True
1079
1080 elif self.__Token.startswith("\'") or self.__Token.startswith("L\'"):
1081 self.__UndoToken()
1082 self.__SkipToToken("\'")
1083 currentLineNumber = self.CurrentLineNumber
1084
1085 if not self.__SkipToToken("\'"):
1086 raise Warning("Missing Quote \' for String At Line ", self.FileName, self.CurrentLineNumber)
1087 if currentLineNumber != self.CurrentLineNumber:
1088 raise Warning("Missing Quote \' for String At Line ", self.FileName, self.CurrentLineNumber)
1089 self.__Token = self.__SkippedChars.rstrip('\'')
1090 return True
1091
1092 else:
1093 return False
1094
1095 ## __SkipToToken() method
1096 #
1097 # Search forward in file buffer for the string
1098 # The skipped chars are put into self.__SkippedChars
1099 #
1100 # @param self The object pointer
1101 # @param String The string to search
1102 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
1103 # @retval True Successfully find the string, file buffer pointer moved forward
1104 # @retval False Not able to find the string, file buffer pointer not changed
1105 #
1106 def __SkipToToken(self, String, IgnoreCase = False):
1107 StartPos = self.GetFileBufferPos()
1108
1109 self.__SkippedChars = ""
1110 while not self.__EndOfFile():
1111 index = -1
1112 if IgnoreCase:
1113 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())
1114 else:
1115 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)
1116 if index == 0:
1117 self.CurrentOffsetWithinLine += len(String)
1118 self.__SkippedChars += String
1119 return True
1120 self.__SkippedChars += str(self.__CurrentChar())
1121 self.__GetOneChar()
1122
1123 self.SetFileBufferPos( StartPos)
1124 self.__SkippedChars = ""
1125 return False
1126
1127 ## GetFileBufferPos() method
1128 #
1129 # Return the tuple of current line and offset within the line
1130 #
1131 # @param self The object pointer
1132 # @retval Tuple Line number and offset pair
1133 #
1134 def GetFileBufferPos(self):
1135 return (self.CurrentLineNumber, self.CurrentOffsetWithinLine)
1136
1137 ## SetFileBufferPos() method
1138 #
1139 # Restore the file buffer position
1140 #
1141 # @param self The object pointer
1142 # @param Pos The new file buffer position
1143 #
1144 def SetFileBufferPos(self, Pos):
1145 (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos
1146
1147 ## ParseFile() method
1148 #
1149 # Parse the file profile buffer to extract fd, fv ... information
1150 # Exception will be raised if syntax error found
1151 #
1152 # @param self The object pointer
1153 #
1154 def ParseFile(self):
1155
1156 try:
1157 self.__StringToList()
1158 self.PreprocessFile()
1159 self.PreprocessIncludeFile()
1160 self.__StringToList()
1161 self.PreprocessFile()
1162 self.PreprocessConditionalStatement()
1163 self.__StringToList()
1164 for Pos in self.__WipeOffArea:
1165 self.__ReplaceFragment(Pos[0], Pos[1])
1166 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
1167
1168 while self.__GetDefines():
1169 pass
1170
1171 Index = 0
1172 while Index < len(self.Profile.FileLinesList):
1173 FileLineTuple = GetRealFileLine(self.FileName, Index + 1)
1174 self.Profile.FileLinesList[Index] = self.__ReplaceMacros(self.Profile.FileLinesList[Index], FileLineTuple[0], FileLineTuple[1])
1175 Index += 1
1176
1177 while self.__GetFd():
1178 pass
1179
1180 while self.__GetFv():
1181 pass
1182
1183 while self.__GetCapsule():
1184 pass
1185
1186 # while self.__GetVtf():
1187 # pass
1188 #
1189 # while self.__GetRule():
1190 # pass
1191
1192
1193 except Warning, X:
1194 self.__UndoToken()
1195 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1196 X.message += '\nGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \
1197 'Previous Token: \"%s\" At line: %d, Offset Within Line: %d\n' \
1198 % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :].rstrip('\n').rstrip('\r'), FileLineTuple[1], self.CurrentOffsetWithinLine)
1199 raise
1200
1201 ## __GetDefines() method
1202 #
1203 # Get Defines section contents and store its data into AllMacrosList
1204 #
1205 # @param self The object pointer
1206 # @retval True Successfully find a Defines
1207 # @retval False Not able to find a Defines
1208 #
1209 def __GetDefines(self):
1210
1211 if not self.__GetNextToken():
1212 return False
1213
1214 S = self.__Token.upper()
1215 if S.startswith("[") and not S.startswith("[DEFINES"):
1216 if not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \
1217 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
1218 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)
1219 self.__UndoToken()
1220 return False
1221
1222 self.__UndoToken()
1223 if not self.__IsToken("[DEFINES", True):
1224 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1225 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1226 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1227 raise Warning("expected [DEFINES", self.FileName, self.CurrentLineNumber)
1228
1229 if not self.__IsToken( "]"):
1230 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
1231
1232 while self.__GetNextWord():
1233 Macro = self.__Token
1234
1235 if not self.__IsToken("="):
1236 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1237 if not self.__GetNextToken() or self.__Token.startswith('['):
1238 raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber)
1239 Value = self.__Token
1240 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1241 MacProfile = MacroProfile(FileLineTuple[0], FileLineTuple[1])
1242 MacProfile.MacroName = Macro
1243 MacProfile.MacroValue = Value
1244 AllMacroList.append(MacProfile)
1245
1246 return False
1247
1248 ## __GetFd() method
1249 #
1250 # Get FD section contents and store its data into FD dictionary of self.Profile
1251 #
1252 # @param self The object pointer
1253 # @retval True Successfully find a FD
1254 # @retval False Not able to find a FD
1255 #
1256 def __GetFd(self):
1257
1258 if not self.__GetNextToken():
1259 return False
1260
1261 S = self.__Token.upper()
1262 if S.startswith("[") and not S.startswith("[FD."):
1263 if not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \
1264 and not S.startswith("[VTF.") and not S.startswith("[RULE."):
1265 raise Warning("Unknown section At Line ", self.FileName, self.CurrentLineNumber)
1266 self.__UndoToken()
1267 return False
1268
1269 self.__UndoToken()
1270 if not self.__IsToken("[FD.", True):
1271 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1272 print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1273 % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1274 raise Warning("expected [FD.] At Line ", self.FileName, self.CurrentLineNumber)
1275
1276 FdName = self.__GetUiName()
1277 self.CurrentFdName = FdName.upper()
1278
1279 if not self.__IsToken( "]"):
1280 raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber)
1281
1282 FdObj = CommonDataClass.FdfClass.FDClassObject()
1283 FdObj.FdUiName = self.CurrentFdName
1284 self.Profile.FdDict[self.CurrentFdName] = FdObj
1285 Status = self.__GetCreateFile(FdObj)
1286 if not Status:
1287 raise Warning("FD name error At Line ", self.FileName, self.CurrentLineNumber)
1288
1289 if not self.__GetTokenStatements(FdObj):
1290 return False
1291
1292 self.__GetDefineStatements(FdObj)
1293
1294 self.__GetSetStatements(FdObj)
1295
1296 if not self.__GetRegionLayout(FdObj):
1297 raise Warning("expected region layout At Line ", self.FileName, self.CurrentLineNumber)
1298
1299 while self.__GetRegionLayout(FdObj):
1300 pass
1301 return True
1302
1303 ## __GetUiName() method
1304 #
1305 # Return the UI name of a section
1306 #
1307 # @param self The object pointer
1308 # @retval FdName UI name
1309 #
1310 def __GetUiName(self):
1311 FdName = ""
1312 if self.__GetNextWord():
1313 FdName = self.__Token
1314
1315 return FdName
1316
1317 ## __GetCreateFile() method
1318 #
1319 # Return the output file name of object
1320 #
1321 # @param self The object pointer
1322 # @param Obj object whose data will be stored in file
1323 # @retval FdName UI name
1324 #
1325 def __GetCreateFile(self, Obj):
1326
1327 if self.__IsKeyword( "CREATE_FILE"):
1328 if not self.__IsToken( "="):
1329 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1330
1331 if not self.__GetNextToken():
1332 raise Warning("expected file name At Line ", self.FileName, self.CurrentLineNumber)
1333
1334 FileName = self.__Token
1335 Obj.CreateFileName = FileName
1336
1337 return True
1338
1339 ## __GetTokenStatements() method
1340 #
1341 # Get token statements
1342 #
1343 # @param self The object pointer
1344 # @param Obj for whom token statement is got
1345 # @retval True Successfully find a token statement
1346 # @retval False Not able to find a token statement
1347 #
1348 def __GetTokenStatements(self, Obj):
1349 if not self.__IsKeyword( "BaseAddress"):
1350 raise Warning("BaseAddress missing At Line ", self.FileName, self.CurrentLineNumber)
1351
1352 if not self.__IsToken( "="):
1353 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1354
1355 if not self.__GetNextHexNumber():
1356 raise Warning("expected Hex base address At Line ", self.FileName, self.CurrentLineNumber)
1357
1358 Obj.BaseAddress = self.__Token
1359
1360 if self.__IsToken( "|"):
1361 pcdPair = self.__GetNextPcdName()
1362 Obj.BaseAddressPcd = pcdPair
1363 self.Profile.PcdDict[pcdPair] = long(Obj.BaseAddress, 0)
1364 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1365 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
1366
1367 if not self.__IsKeyword( "Size"):
1368 raise Warning("Size missing At Line ", self.FileName, self.CurrentLineNumber)
1369
1370 if not self.__IsToken( "="):
1371 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1372
1373 if not self.__GetNextHexNumber():
1374 raise Warning("expected Hex size At Line ", self.FileName, self.CurrentLineNumber)
1375
1376
1377 Obj.Size = long(self.__Token, 0)
1378
1379 if self.__IsToken( "|"):
1380 pcdPair = self.__GetNextPcdName()
1381 Obj.SizePcd = pcdPair
1382 self.Profile.PcdDict[pcdPair] = Obj.Size
1383 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1384 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
1385
1386 if not self.__IsKeyword( "ErasePolarity"):
1387 raise Warning("ErasePolarity missing At Line ", self.FileName, self.CurrentLineNumber)
1388
1389 if not self.__IsToken( "="):
1390 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1391
1392 if not self.__GetNextToken():
1393 raise Warning("expected Erase Polarity At Line ", self.FileName, self.CurrentLineNumber)
1394
1395 if self.__Token != "1" and self.__Token != "0":
1396 raise Warning("expected 1 or 0 Erase Polarity At Line ", self.FileName, self.CurrentLineNumber)
1397
1398 Obj.ErasePolarity = self.__Token
1399
1400 Status = self.__GetBlockStatements(Obj)
1401 return Status
1402
1403 ## __GetAddressStatements() method
1404 #
1405 # Get address statements
1406 #
1407 # @param self The object pointer
1408 # @param Obj for whom address statement is got
1409 # @retval True Successfully find
1410 # @retval False Not able to find
1411 #
1412 def __GetAddressStatements(self, Obj):
1413
1414 if self.__IsKeyword("BsBaseAddress"):
1415 if not self.__IsToken( "="):
1416 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1417
1418 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
1419 raise Warning("expected address At Line ", self.FileName, self.CurrentLineNumber)
1420
1421 BsAddress = long(self.__Token, 0)
1422 Obj.BsBaseAddress = BsAddress
1423
1424 if self.__IsKeyword("RtBaseAddress"):
1425 if not self.__IsToken( "="):
1426 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1427
1428 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
1429 raise Warning("expected address At Line ", self.FileName, self.CurrentLineNumber)
1430
1431 RtAddress = long(self.__Token, 0)
1432 Obj.RtBaseAddress = RtAddress
1433
1434 ## __GetBlockStatements() method
1435 #
1436 # Get block statements
1437 #
1438 # @param self The object pointer
1439 # @param Obj for whom block statement is got
1440 # @retval True Successfully find
1441 # @retval False Not able to find
1442 #
1443 def __GetBlockStatements(self, Obj):
1444
1445 if not self.__GetBlockStatement(Obj):
1446 #set default block size is 1
1447 Obj.BlockSizeList.append((1, Obj.Size, None))
1448 return True
1449
1450 while self.__GetBlockStatement(Obj):
1451 pass
1452
1453 for Item in Obj.BlockSizeList:
1454 if Item[0] == None or Item[1] == None:
1455 raise Warning("expected block statement for Fd Section", self.FileName, self.CurrentLineNumber)
1456
1457 return True
1458
1459 ## __GetBlockStatement() method
1460 #
1461 # Get block statement
1462 #
1463 # @param self The object pointer
1464 # @param Obj for whom block statement is got
1465 # @retval True Successfully find
1466 # @retval False Not able to find
1467 #
1468 def __GetBlockStatement(self, Obj):
1469 if not self.__IsKeyword( "BlockSize"):
1470 return False
1471
1472 if not self.__IsToken( "="):
1473 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1474
1475 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():
1476 raise Warning("expected Hex block size At Line ", self.FileName, self.CurrentLineNumber)
1477
1478 BlockSize = long(self.__Token, 0)
1479 BlockSizePcd = None
1480 if self.__IsToken( "|"):
1481 PcdPair = self.__GetNextPcdName()
1482 BlockSizePcd = PcdPair
1483 self.Profile.PcdDict[PcdPair] = BlockSize
1484 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1485 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
1486
1487 BlockNumber = None
1488 if self.__IsKeyword( "NumBlocks"):
1489 if not self.__IsToken( "="):
1490 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1491
1492 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
1493 raise Warning("expected block numbers At Line ", self.FileName, self.CurrentLineNumber)
1494
1495 BlockNumber = long(self.__Token, 0)
1496
1497 Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd))
1498 return True
1499
1500 ## __GetDefineStatements() method
1501 #
1502 # Get define statements
1503 #
1504 # @param self The object pointer
1505 # @param Obj for whom define statement is got
1506 # @retval True Successfully find
1507 # @retval False Not able to find
1508 #
1509 def __GetDefineStatements(self, Obj):
1510 while self.__GetDefineStatement( Obj):
1511 pass
1512
1513 ## __GetDefineStatement() method
1514 #
1515 # Get define statement
1516 #
1517 # @param self The object pointer
1518 # @param Obj for whom define statement is got
1519 # @retval True Successfully find
1520 # @retval False Not able to find
1521 #
1522 def __GetDefineStatement(self, Obj):
1523 if self.__IsKeyword("DEFINE"):
1524 self.__GetNextToken()
1525 Macro = self.__Token
1526 if not self.__IsToken( "="):
1527 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1528
1529 if not self.__GetNextToken():
1530 raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber)
1531
1532 Value = self.__Token
1533 Macro = '$(' + Macro + ')'
1534 Obj.DefineVarDict[Macro] = Value
1535 return True
1536
1537 return False
1538
1539 ## __GetSetStatements() method
1540 #
1541 # Get set statements
1542 #
1543 # @param self The object pointer
1544 # @param Obj for whom set statement is got
1545 # @retval True Successfully find
1546 # @retval False Not able to find
1547 #
1548 def __GetSetStatements(self, Obj):
1549 while self.__GetSetStatement(Obj):
1550 pass
1551
1552 ## __GetSetStatement() method
1553 #
1554 # Get set statement
1555 #
1556 # @param self The object pointer
1557 # @param Obj for whom set statement is got
1558 # @retval True Successfully find
1559 # @retval False Not able to find
1560 #
1561 def __GetSetStatement(self, Obj):
1562 if self.__IsKeyword("SET"):
1563 PcdPair = self.__GetNextPcdName()
1564
1565 if not self.__IsToken( "="):
1566 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1567
1568 if not self.__GetNextToken():
1569 raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber)
1570
1571 Value = self.__Token
1572 if Value.startswith("{"):
1573 # deal with value with {}
1574 if not self.__SkipToToken( "}"):
1575 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
1576 Value += self.__SkippedChars
1577
1578 Obj.SetVarDict[PcdPair] = Value
1579 self.Profile.PcdDict[PcdPair] = Value
1580 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1581 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
1582 return True
1583
1584 return False
1585
1586 ## __GetRegionLayout() method
1587 #
1588 # Get region layout for FD
1589 #
1590 # @param self The object pointer
1591 # @param Fd for whom region is got
1592 # @retval True Successfully find
1593 # @retval False Not able to find
1594 #
1595 def __GetRegionLayout(self, Fd):
1596 if not self.__GetNextHexNumber():
1597 return False
1598
1599 RegionObj = CommonDataClass.FdfClass.RegionClassObject()
1600 RegionObj.Offset = long(self.__Token, 0)
1601 Fd.RegionList.append(RegionObj)
1602
1603 if not self.__IsToken( "|"):
1604 raise Warning("expected '|' At Line ", self.FileName, self.CurrentLineNumber)
1605
1606 if not self.__GetNextHexNumber():
1607 raise Warning("expected Region Size At Line ", self.FileName, self.CurrentLineNumber)
1608 RegionObj.Size = long(self.__Token, 0)
1609
1610 if not self.__GetNextWord():
1611 return True
1612
1613 if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE"):
1614 self.__UndoToken()
1615 RegionObj.PcdOffset = self.__GetNextPcdName()
1616 self.Profile.PcdDict[RegionObj.PcdOffset] = RegionObj.Offset + long(Fd.BaseAddress, 0)
1617 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1618 self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple
1619 if self.__IsToken( "|"):
1620 RegionObj.PcdSize = self.__GetNextPcdName()
1621 self.Profile.PcdDict[RegionObj.PcdSize] = RegionObj.Size
1622 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1623 self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple
1624
1625 if not self.__GetNextWord():
1626 return True
1627
1628 if self.__Token == "SET":
1629 self.__UndoToken()
1630 self.__GetSetStatements( RegionObj)
1631 if not self.__GetNextWord():
1632 return True
1633
1634 elif self.__Token == "FV":
1635 self.__UndoToken()
1636 self.__GetRegionFvType( RegionObj)
1637
1638 elif self.__Token == "CAPSULE":
1639 self.__UndoToken()
1640 self.__GetRegionCapType( RegionObj)
1641
1642 elif self.__Token == "FILE":
1643 self.__UndoToken()
1644 self.__GetRegionFileType( RegionObj)
1645
1646 else:
1647 self.__UndoToken()
1648 self.__GetRegionDataType( RegionObj)
1649
1650 return True
1651
1652 ## __GetRegionFvType() method
1653 #
1654 # Get region fv data for region
1655 #
1656 # @param self The object pointer
1657 # @param RegionObj for whom region data is got
1658 #
1659 def __GetRegionFvType(self, RegionObj):
1660
1661 if not self.__IsKeyword( "FV"):
1662 raise Warning("expected Keyword 'FV' At Line ", self.FileName, self.CurrentLineNumber)
1663
1664 if not self.__IsToken( "="):
1665 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1666
1667 if not self.__GetNextToken():
1668 raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber)
1669
1670 RegionObj.RegionType = "FV"
1671 RegionObj.RegionDataList.append(self.__Token)
1672
1673 while self.__IsKeyword( "FV"):
1674
1675 if not self.__IsToken( "="):
1676 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1677
1678 if not self.__GetNextToken():
1679 raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber)
1680
1681 RegionObj.RegionDataList.append(self.__Token)
1682
1683 ## __GetRegionCapType() method
1684 #
1685 # Get region capsule data for region
1686 #
1687 # @param self The object pointer
1688 # @param RegionObj for whom region data is got
1689 #
1690 def __GetRegionCapType(self, RegionObj):
1691
1692 if not self.__IsKeyword("CAPSULE"):
1693 raise Warning("expected Keyword 'CAPSULE' at line", self.FileName, self.CurrentLineNumber)
1694
1695 if not self.__IsToken("="):
1696 raise Warning("expected '=' at line", self.FileName, self.CurrentLineNumber)
1697
1698 if not self.__GetNextToken():
1699 raise Warning("expected CAPSULE name at line", self.FileName, self.CurrentLineNumber)
1700
1701 RegionObj.RegionType = "CAPSULE"
1702 RegionObj.RegionDataList.append(self.__Token)
1703
1704 while self.__IsKeyword("CAPSULE"):
1705
1706 if not self.__IsToken("="):
1707 raise Warning("expected '=' at line", self.FileName, self.CurrentLineNumber)
1708
1709 if not self.__GetNextToken():
1710 raise Warning("expected CAPSULE name at line", self.FileName, self.CurrentLineNumber)
1711
1712 RegionObj.RegionDataList.append(self.__Token)
1713
1714 ## __GetRegionFileType() method
1715 #
1716 # Get region file data for region
1717 #
1718 # @param self The object pointer
1719 # @param RegionObj for whom region data is got
1720 #
1721 def __GetRegionFileType(self, RegionObj):
1722
1723 if not self.__IsKeyword( "FILE"):
1724 raise Warning("expected Keyword 'FILE' At Line ", self.FileName, self.CurrentLineNumber)
1725
1726 if not self.__IsToken( "="):
1727 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1728
1729 if not self.__GetNextToken():
1730 raise Warning("expected File name At Line ", self.FileName, self.CurrentLineNumber)
1731
1732 RegionObj.RegionType = "FILE"
1733 RegionObj.RegionDataList.append( self.__Token)
1734
1735 while self.__IsKeyword( "FILE"):
1736
1737 if not self.__IsToken( "="):
1738 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1739
1740 if not self.__GetNextToken():
1741 raise Warning("expected FILE name At Line ", self.FileName, self.CurrentLineNumber)
1742
1743 RegionObj.RegionDataList.append(self.__Token)
1744
1745 ## __GetRegionDataType() method
1746 #
1747 # Get region array data for region
1748 #
1749 # @param self The object pointer
1750 # @param RegionObj for whom region data is got
1751 #
1752 def __GetRegionDataType(self, RegionObj):
1753
1754 if not self.__IsKeyword( "DATA"):
1755 raise Warning("expected Region Data type At Line ", self.FileName, self.CurrentLineNumber)
1756
1757 if not self.__IsToken( "="):
1758 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1759
1760 if not self.__IsToken( "{"):
1761 raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
1762
1763 if not self.__GetNextHexNumber():
1764 raise Warning("expected Hex byte At Line ", self.FileName, self.CurrentLineNumber)
1765
1766 if len(self.__Token) > 18:
1767 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)
1768
1769 DataString = self.__Token
1770 DataString += ","
1771
1772 while self.__IsToken(","):
1773 if not self.__GetNextHexNumber():
1774 raise Warning("Invalid Hex number At Line ", self.FileName, self.CurrentLineNumber)
1775 if len(self.__Token) > 4:
1776 raise Warning("Hex byte(must be 2 digits) too long At Line ", self.FileName, self.CurrentLineNumber)
1777 DataString += self.__Token
1778 DataString += ","
1779
1780 if not self.__IsToken( "}"):
1781 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
1782
1783 DataString = DataString.rstrip(",")
1784 RegionObj.RegionType = "DATA"
1785 RegionObj.RegionDataList.append( DataString)
1786
1787 while self.__IsKeyword( "DATA"):
1788
1789 if not self.__IsToken( "="):
1790 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1791
1792 if not self.__IsToken( "{"):
1793 raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
1794
1795 if not self.__GetNextHexNumber():
1796 raise Warning("expected Hex byte At Line ", self.FileName, self.CurrentLineNumber)
1797
1798 if len(self.__Token) > 18:
1799 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)
1800
1801 DataString = self.__Token
1802 DataString += ","
1803
1804 while self.__IsToken(","):
1805 self.__GetNextHexNumber()
1806 if len(self.__Token) > 4:
1807 raise Warning("Hex byte(must be 2 digits) too long At Line ", self.FileName, self.CurrentLineNumber)
1808 DataString += self.__Token
1809 DataString += ","
1810
1811 if not self.__IsToken( "}"):
1812 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
1813
1814 DataString = DataString.rstrip(",")
1815 RegionObj.RegionDataList.append( DataString)
1816
1817 ## __GetFv() method
1818 #
1819 # Get FV section contents and store its data into FV dictionary of self.Profile
1820 #
1821 # @param self The object pointer
1822 # @retval True Successfully find a FV
1823 # @retval False Not able to find a FV
1824 #
1825 def __GetFv(self):
1826 if not self.__GetNextToken():
1827 return False
1828
1829 S = self.__Token.upper()
1830 if S.startswith("[") and not S.startswith("[FV."):
1831 if not S.startswith("[CAPSULE.") \
1832 and not S.startswith("[VTF.") and not S.startswith("[RULE."):
1833 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)
1834 self.__UndoToken()
1835 return False
1836
1837 self.__UndoToken()
1838 if not self.__IsToken("[FV.", True):
1839 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1840 print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1841 % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1842 raise Warning("Unknown Keyword At Line ", self.FileName, self.CurrentLineNumber)
1843
1844 FvName = self.__GetUiName()
1845 self.CurrentFvName = FvName.upper()
1846
1847 if not self.__IsToken( "]"):
1848 raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber)
1849
1850 FvObj = CommonDataClass.FdfClass.FvClassObject()
1851 FvObj.UiFvName = self.CurrentFvName
1852 self.Profile.FvDict[self.CurrentFvName] = FvObj
1853
1854 Status = self.__GetCreateFile(FvObj)
1855 if not Status:
1856 raise Warning("FV name error At Line ", self.FileName, self.CurrentLineNumber)
1857
1858 self.__GetDefineStatements(FvObj)
1859
1860 self.__GetAddressStatements(FvObj)
1861
1862 self.__GetBlockStatement(FvObj)
1863
1864 self.__GetSetStatements(FvObj)
1865
1866 self.__GetFvAlignment(FvObj)
1867
1868 self.__GetFvAttributes(FvObj)
1869
1870 self.__GetFvNameGuid(FvObj)
1871
1872 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
1873 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
1874
1875 while True:
1876 isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())
1877 isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())
1878 if not isInf and not isFile:
1879 break
1880
1881 return True
1882
1883 ## __GetFvAlignment() method
1884 #
1885 # Get alignment for FV
1886 #
1887 # @param self The object pointer
1888 # @param Obj for whom alignment is got
1889 # @retval True Successfully find a alignment statement
1890 # @retval False Not able to find a alignment statement
1891 #
1892 def __GetFvAlignment(self, Obj):
1893
1894 if not self.__IsKeyword( "FvAlignment"):
1895 return False
1896
1897 if not self.__IsToken( "="):
1898 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1899
1900 if not self.__GetNextToken():
1901 raise Warning("expected alignment value At Line ", self.FileName, self.CurrentLineNumber)
1902
1903 if self.__Token.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
1904 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
1905 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
1906 "1G", "2G"):
1907 raise Warning("Unknown alignment value At Line ", self.FileName, self.CurrentLineNumber)
1908 Obj.FvAlignment = self.__Token
1909 return True
1910
1911 ## __GetFvAttributes() method
1912 #
1913 # Get attributes for FV
1914 #
1915 # @param self The object pointer
1916 # @param Obj for whom attribute is got
1917 # @retval None
1918 #
1919 def __GetFvAttributes(self, FvObj):
1920
1921 while self.__GetNextWord():
1922 name = self.__Token
1923 if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \
1924 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
1925 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
1926 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
1927 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
1928 "WRITE_POLICY_RELIABLE"):
1929 self.__UndoToken()
1930 return
1931
1932 if not self.__IsToken( "="):
1933 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1934
1935 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
1936 raise Warning("expected TRUE/FALSE (1/0) At Line ", self.FileName, self.CurrentLineNumber)
1937
1938 FvObj.FvAttributeDict[name] = self.__Token
1939
1940 return
1941
1942 ## __GetFvNameGuid() method
1943 #
1944 # Get FV GUID for FV
1945 #
1946 # @param self The object pointer
1947 # @param Obj for whom GUID is got
1948 # @retval None
1949 #
1950 def __GetFvNameGuid(self, FvObj):
1951
1952 if not self.__IsKeyword( "FvNameGuid"):
1953 return
1954
1955 if not self.__IsToken( "="):
1956 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1957
1958 if not self.__GetNextGuid():
1959 raise Warning("expected FV GUID value", self.FileName, self.CurrentLineNumber)
1960
1961 FvObj.FvNameGuid = self.__Token
1962
1963 return
1964
1965 ## __GetAprioriSection() method
1966 #
1967 # Get token statements
1968 #
1969 # @param self The object pointer
1970 # @param FvObj for whom apriori is got
1971 # @param MacroDict dictionary used to replace macro
1972 # @retval True Successfully find apriori statement
1973 # @retval False Not able to find apriori statement
1974 #
1975 def __GetAprioriSection(self, FvObj, MacroDict = {}):
1976
1977 if not self.__IsKeyword( "APRIORI"):
1978 return False
1979
1980 if not self.__IsKeyword("PEI") and not self.__IsKeyword("DXE"):
1981 raise Warning("expected Apriori file type At Line ", self.FileName, self.CurrentLineNumber)
1982 AprType = self.__Token
1983
1984 if not self.__IsToken( "{"):
1985 raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
1986
1987 AprSectionObj = CommonDataClass.FdfClass.AprioriSectionClassObject()
1988 AprSectionObj.AprioriType = AprType
1989
1990 self.__GetDefineStatements(AprSectionObj)
1991 MacroDict.update(AprSectionObj.DefineVarDict)
1992
1993 while True:
1994 IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict)
1995 IsFile = self.__GetFileStatement( AprSectionObj)
1996 if not IsInf and not IsFile:
1997 break
1998
1999 if not self.__IsToken( "}"):
2000 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
2001
2002 FvObj.AprioriSectionList.append(AprSectionObj)
2003 return True
2004
2005 ## __GetInfStatement() method
2006 #
2007 # Get INF statements
2008 #
2009 # @param self The object pointer
2010 # @param Obj for whom inf statement is got
2011 # @param MacroDict dictionary used to replace macro
2012 # @retval True Successfully find inf statement
2013 # @retval False Not able to find inf statement
2014 #
2015 def __GetInfStatement(self, Obj, ForCapsule = False, MacroDict = {}):
2016
2017 if not self.__IsKeyword( "INF"):
2018 return False
2019
2020 ffsInf = CommonDataClass.FdfClass.FfsInfStatementClassObject()
2021 self.__GetInfOptions( ffsInf)
2022
2023 if not self.__GetNextToken():
2024 raise Warning("expected INF file path At Line ", self.FileName, self.CurrentLineNumber)
2025 ffsInf.InfFileName = self.__Token
2026
2027 # if ffsInf.InfFileName.find('$') >= 0:
2028 # ffsInf.InfFileName = GenFdsGlobalVariable.GenFdsGlobalVariable.MacroExtend(ffsInf.InfFileName, MacroDict)
2029
2030 if not ffsInf.InfFileName in self.Profile.InfList:
2031 self.Profile.InfList.append(ffsInf.InfFileName)
2032 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
2033 self.Profile.InfFileLineList.append(FileLineTuple)
2034
2035 if self.__IsToken('|'):
2036 if self.__IsKeyword('RELOCS_STRIPPED'):
2037 ffsInf.KeepReloc = False
2038 elif self.__IsKeyword('RELOCS_RETAINED'):
2039 ffsInf.KeepReloc = True
2040 else:
2041 raise Warning("Unknown reloc strip flag At Line ", self.FileName, self.CurrentLineNumber)
2042
2043 if ForCapsule:
2044 capsuleFfs = CapsuleData.CapsuleFfs()
2045 capsuleFfs.Ffs = ffsInf
2046 Obj.CapsuleDataList.append(capsuleFfs)
2047 else:
2048 Obj.FfsList.append(ffsInf)
2049 return True
2050
2051 ## __GetInfOptions() method
2052 #
2053 # Get options for INF
2054 #
2055 # @param self The object pointer
2056 # @param FfsInfObj for whom option is got
2057 #
2058 def __GetInfOptions(self, FfsInfObj):
2059
2060 if self.__IsKeyword( "RuleOverride"):
2061 if not self.__IsToken( "="):
2062 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2063 if not self.__GetNextToken():
2064 raise Warning("expected Rule name At Line ", self.FileName, self.CurrentLineNumber)
2065 FfsInfObj.Rule = self.__Token
2066
2067 if self.__IsKeyword( "VERSION"):
2068 if not self.__IsToken( "="):
2069 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2070 if not self.__GetNextToken():
2071 raise Warning("expected Version At Line ", self.FileName, self.CurrentLineNumber)
2072
2073 if self.__GetStringData():
2074 FfsInfObj.Version = self.__Token
2075
2076 if self.__IsKeyword( "UI"):
2077 if not self.__IsToken( "="):
2078 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2079 if not self.__GetNextToken():
2080 raise Warning("expected UI name At Line ", self.FileName, self.CurrentLineNumber)
2081
2082 if self.__GetStringData():
2083 FfsInfObj.Ui = self.__Token
2084
2085 if self.__IsKeyword( "USE"):
2086 if not self.__IsToken( "="):
2087 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2088 if not self.__GetNextToken():
2089 raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber)
2090 FfsInfObj.UseArch = self.__Token
2091
2092
2093 if self.__GetNextToken():
2094 p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
2095 if p.match(self.__Token):
2096 FfsInfObj.KeyStringList.append(self.__Token)
2097 if not self.__IsToken(","):
2098 return
2099 else:
2100 self.__UndoToken()
2101 return
2102
2103 while self.__GetNextToken():
2104 if not p.match(self.__Token):
2105 raise Warning("expected KeyString \"Target_Tag_Arch\" At Line ", self.FileName, self.CurrentLineNumber)
2106 FfsInfObj.KeyStringList.append(self.__Token)
2107
2108 if not self.__IsToken(","):
2109 break
2110
2111 ## __GetFileStatement() method
2112 #
2113 # Get FILE statements
2114 #
2115 # @param self The object pointer
2116 # @param Obj for whom FILE statement is got
2117 # @param MacroDict dictionary used to replace macro
2118 # @retval True Successfully find FILE statement
2119 # @retval False Not able to find FILE statement
2120 #
2121 def __GetFileStatement(self, Obj, ForCapsule = False, MacroDict = {}):
2122
2123 if not self.__IsKeyword( "FILE"):
2124 return False
2125
2126 FfsFileObj = CommonDataClass.FdfClass.FileStatementClassObject()
2127
2128 if not self.__GetNextWord():
2129 raise Warning("expected FFS type At Line ", self.FileName, self.CurrentLineNumber)
2130 FfsFileObj.FvFileType = self.__Token
2131
2132 if not self.__IsToken( "="):
2133 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2134
2135 if not self.__GetNextGuid():
2136 if not self.__GetNextWord():
2137 raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber)
2138 if self.__Token == 'PCD':
2139 if not self.__IsToken( "("):
2140 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
2141 PcdPair = self.__GetNextPcdName()
2142 if not self.__IsToken( ")"):
2143 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
2144 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
2145
2146 FfsFileObj.NameGuid = self.__Token
2147
2148 self.__GetFilePart( FfsFileObj, MacroDict.copy())
2149
2150 if ForCapsule:
2151 capsuleFfs = CapsuleData.CapsuleFfs()
2152 capsuleFfs.Ffs = FfsFileObj
2153 Obj.CapsuleDataList.append(capsuleFfs)
2154 else:
2155 Obj.FfsList.append(FfsFileObj)
2156
2157 return True
2158
2159 ## __FileCouldHaveRelocFlag() method
2160 #
2161 # Check whether reloc strip flag can be set for a file type.
2162 #
2163 # @param self The object pointer
2164 # @param FileType The file type to check with
2165 # @retval True This type could have relocation strip flag
2166 # @retval False No way to have it
2167 #
2168
2169 def __FileCouldHaveRelocFlag (self, FileType):
2170 if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):
2171 return True
2172 else:
2173 return False
2174
2175 ## __SectionCouldHaveRelocFlag() method
2176 #
2177 # Check whether reloc strip flag can be set for a section type.
2178 #
2179 # @param self The object pointer
2180 # @param SectionType The section type to check with
2181 # @retval True This type could have relocation strip flag
2182 # @retval False No way to have it
2183 #
2184
2185 def __SectionCouldHaveRelocFlag (self, SectionType):
2186 if SectionType in ('TE', 'PE32'):
2187 return True
2188 else:
2189 return False
2190
2191 ## __GetFilePart() method
2192 #
2193 # Get components for FILE statement
2194 #
2195 # @param self The object pointer
2196 # @param FfsFileObj for whom component is got
2197 # @param MacroDict dictionary used to replace macro
2198 #
2199 def __GetFilePart(self, FfsFileObj, MacroDict = {}):
2200
2201 self.__GetFileOpts( FfsFileObj)
2202
2203 if not self.__IsToken("{"):
2204 # if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
2205 # if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType):
2206 # if self.__Token == 'RELOCS_STRIPPED':
2207 # FfsFileObj.KeepReloc = False
2208 # else:
2209 # FfsFileObj.KeepReloc = True
2210 # else:
2211 # raise Warning("File type %s could not have reloc strip flag At Line %d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
2212 #
2213 # if not self.__IsToken("{"):
2214 raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
2215
2216 if not self.__GetNextToken():
2217 raise Warning("expected File name or section data At Line ", self.FileName, self.CurrentLineNumber)
2218
2219 if self.__Token == "FV":
2220 if not self.__IsToken( "="):
2221 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2222 if not self.__GetNextToken():
2223 raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber)
2224 FfsFileObj.FvName = self.__Token
2225
2226 elif self.__Token == "FD":
2227 if not self.__IsToken( "="):
2228 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2229 if not self.__GetNextToken():
2230 raise Warning("expected FD name At Line ", self.FileName, self.CurrentLineNumber)
2231 FfsFileObj.FdName = self.__Token
2232
2233 elif self.__Token in ("DEFINE", "APRIORI", "SECTION"):
2234 self.__UndoToken()
2235 self.__GetSectionData( FfsFileObj, MacroDict)
2236 else:
2237 FfsFileObj.FileName = self.__Token
2238
2239 if not self.__IsToken( "}"):
2240 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
2241
2242 ## __GetFileOpts() method
2243 #
2244 # Get options for FILE statement
2245 #
2246 # @param self The object pointer
2247 # @param FfsFileObj for whom options is got
2248 #
2249 def __GetFileOpts(self, FfsFileObj):
2250
2251 if self.__GetNextToken():
2252 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
2253 if Pattern.match(self.__Token):
2254 FfsFileObj.KeyStringList.append(self.__Token)
2255 if self.__IsToken(","):
2256 while self.__GetNextToken():
2257 if not Pattern.match(self.__Token):
2258 raise Warning("expected KeyString \"Target_Tag_Arch\" At Line ", self.FileName, self.CurrentLineNumber)
2259 FfsFileObj.KeyStringList.append(self.__Token)
2260
2261 if not self.__IsToken(","):
2262 break
2263
2264 else:
2265 self.__UndoToken()
2266
2267 if self.__IsKeyword( "FIXED", True):
2268 FfsFileObj.Fixed = True
2269
2270 if self.__IsKeyword( "CHECKSUM", True):
2271 FfsFileObj.CheckSum = True
2272
2273 if self.__GetAlignment():
2274 FfsFileObj.Alignment = self.__Token
2275
2276
2277
2278 ## __GetAlignment() method
2279 #
2280 # Return the alignment value
2281 #
2282 # @param self The object pointer
2283 # @retval True Successfully find alignment
2284 # @retval False Not able to find alignment
2285 #
2286 def __GetAlignment(self):
2287 if self.__IsKeyword( "Align", True):
2288 if not self.__IsToken( "="):
2289 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2290
2291 if not self.__GetNextToken():
2292 raise Warning("expected alignment value At Line ", self.FileName, self.CurrentLineNumber)
2293 return True
2294
2295 return False
2296
2297 ## __GetFilePart() method
2298 #
2299 # Get section data for FILE statement
2300 #
2301 # @param self The object pointer
2302 # @param FfsFileObj for whom section is got
2303 # @param MacroDict dictionary used to replace macro
2304 #
2305 def __GetSectionData(self, FfsFileObj, MacroDict = {}):
2306 Dict = {}
2307 Dict.update(MacroDict)
2308
2309 self.__GetDefineStatements(FfsFileObj)
2310
2311 Dict.update(FfsFileObj.DefineVarDict)
2312 self.__GetAprioriSection(FfsFileObj, Dict.copy())
2313 self.__GetAprioriSection(FfsFileObj, Dict.copy())
2314
2315 while True:
2316 IsLeafSection = self.__GetLeafSection(FfsFileObj, Dict)
2317 IsEncapSection = self.__GetEncapsulationSec(FfsFileObj)
2318 if not IsLeafSection and not IsEncapSection:
2319 break
2320
2321 ## __GetLeafSection() method
2322 #
2323 # Get leaf section for Obj
2324 #
2325 # @param self The object pointer
2326 # @param Obj for whom leaf section is got
2327 # @param MacroDict dictionary used to replace macro
2328 # @retval True Successfully find section statement
2329 # @retval False Not able to find section statement
2330 #
2331 def __GetLeafSection(self, Obj, MacroDict = {}):
2332
2333 OldPos = self.GetFileBufferPos()
2334
2335 if not self.__IsKeyword( "SECTION"):
2336 if len(Obj.SectionList) == 0:
2337 raise Warning("expected SECTION At Line ", self.FileName, self.CurrentLineNumber)
2338 else:
2339 return False
2340
2341 AlignValue = None
2342 if self.__GetAlignment():
2343 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
2344 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
2345 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2346 AlignValue = self.__Token
2347
2348 BuildNum = None
2349 if self.__IsKeyword( "BUILD_NUM"):
2350 if not self.__IsToken( "="):
2351 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2352
2353 if not self.__GetNextToken():
2354 raise Warning("expected Build number value At Line ", self.FileName, self.CurrentLineNumber)
2355
2356 BuildNum = self.__Token
2357
2358 if self.__IsKeyword( "VERSION"):
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 version At Line ", self.FileName, self.CurrentLineNumber)
2365 VerSectionObj = CommonDataClass.FdfClass.VerSectionClassObject()
2366 VerSectionObj.Alignment = AlignValue
2367 VerSectionObj.BuildNum = BuildNum
2368 if self.__GetStringData():
2369 VerSectionObj.StringData = self.__Token
2370 else:
2371 VerSectionObj.FileName = self.__Token
2372 Obj.SectionList.append(VerSectionObj)
2373
2374 elif self.__IsKeyword( "UI"):
2375 if AlignValue == 'Auto':
2376 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2377 if not self.__IsToken( "="):
2378 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2379 if not self.__GetNextToken():
2380 raise Warning("expected UI At Line ", self.FileName, self.CurrentLineNumber)
2381 UiSectionObj = CommonDataClass.FdfClass.UiSectionClassObject()
2382 UiSectionObj.Alignment = AlignValue
2383 if self.__GetStringData():
2384 UiSectionObj.StringData = self.__Token
2385 else:
2386 UiSectionObj.FileName = self.__Token
2387 Obj.SectionList.append(UiSectionObj)
2388
2389 elif self.__IsKeyword( "FV_IMAGE"):
2390 if AlignValue == 'Auto':
2391 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2392 if not self.__IsToken( "="):
2393 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2394 if not self.__GetNextWord():
2395 raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber)
2396
2397 FvName = self.__Token.upper()
2398 FvObj = None
2399
2400 if self.__IsToken( "{"):
2401 FvObj = Fv.FV()
2402 FvObj.UiFvName = FvName
2403 self.__GetDefineStatements(FvObj)
2404 MacroDict.update(FvObj.DefineVarDict)
2405 self.__GetBlockStatement(FvObj)
2406 self.__GetSetStatements(FvObj)
2407 self.__GetFvAlignment(FvObj)
2408 self.__GetFvAttributes(FvObj)
2409 self.__GetAprioriSection(FvObj, MacroDict.copy())
2410 self.__GetAprioriSection(FvObj, MacroDict.copy())
2411
2412 while True:
2413 IsInf = self.__GetInfStatement(FvObj, MacroDict.copy())
2414 IsFile = self.__GetFileStatement(FvObj, MacroDict.copy())
2415 if not IsInf and not IsFile:
2416 break
2417
2418 if not self.__IsToken( "}"):
2419 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
2420
2421 FvImageSectionObj = CommonDataClass.FdfClass.FvImageSectionClassObject()
2422 FvImageSectionObj.Alignment = AlignValue
2423 if FvObj != None:
2424 FvImageSectionObj.Fv = FvObj
2425 FvImageSectionObj.FvName = None
2426 else:
2427 FvImageSectionObj.FvName = FvName
2428
2429 Obj.SectionList.append(FvImageSectionObj)
2430
2431 elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP") or self.__IsKeyword("SMM_DEPEX_EXP"):
2432 if AlignValue == 'Auto':
2433 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2434 DepexSectionObj = CommonDataClass.FdfClass.DepexSectionClassObject()
2435 DepexSectionObj.Alignment = AlignValue
2436 DepexSectionObj.DepexType = self.__Token
2437
2438 if not self.__IsToken( "="):
2439 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2440 if not self.__IsToken( "{"):
2441 raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
2442 if not self.__SkipToToken( "}"):
2443 raise Warning("expected Depex expression ending '}' At Line ", self.FileName, self.CurrentLineNumber)
2444
2445 DepexSectionObj.Expression = self.__SkippedChars.rstrip('}')
2446 Obj.SectionList.append(DepexSectionObj)
2447
2448 else:
2449
2450 if not self.__GetNextWord():
2451 raise Warning("expected section type At Line ", self.FileName, self.CurrentLineNumber)
2452
2453 # Encapsulation section appear, UndoToken and return
2454 if self.__Token == "COMPRESS" or self.__Token == "GUIDED":
2455 self.SetFileBufferPos(OldPos)
2456 return False
2457
2458 if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
2459 "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"):
2460 raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2461 if AlignValue == 'Auto'and (not self.__Token == 'PE32') and (not self.__Token == 'TE'):
2462 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2463 # DataSection
2464 DataSectionObj = CommonDataClass.FdfClass.DataSectionClassObject()
2465 DataSectionObj.Alignment = AlignValue
2466 DataSectionObj.SecType = self.__Token
2467
2468 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
2469 if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType):
2470 if self.__Token == 'RELOCS_STRIPPED':
2471 DataSectionObj.KeepReloc = False
2472 else:
2473 DataSectionObj.KeepReloc = True
2474 else:
2475 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)
2476
2477 if self.__IsToken("="):
2478 if not self.__GetNextToken():
2479 raise Warning("expected section file path At Line ", self.FileName, self.CurrentLineNumber)
2480 DataSectionObj.SectFileName = self.__Token
2481 else:
2482 if not self.__GetCglSection(DataSectionObj):
2483 return False
2484
2485 Obj.SectionList.append(DataSectionObj)
2486
2487 return True
2488
2489 ## __GetCglSection() method
2490 #
2491 # Get compressed or GUIDed section for Obj
2492 #
2493 # @param self The object pointer
2494 # @param Obj for whom leaf section is got
2495 # @param AlignValue alignment value for complex section
2496 # @retval True Successfully find section statement
2497 # @retval False Not able to find section statement
2498 #
2499 def __GetCglSection(self, Obj, AlignValue = None):
2500
2501 if self.__IsKeyword( "COMPRESS"):
2502 type = "PI_STD"
2503 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
2504 type = self.__Token
2505
2506 if not self.__IsToken("{"):
2507 raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
2508
2509 CompressSectionObj = CommonDataClass.FdfClass.CompressSectionClassObject()
2510 CompressSectionObj.Alignment = AlignValue
2511 CompressSectionObj.CompType = type
2512 # Recursive sections...
2513 while True:
2514 IsLeafSection = self.__GetLeafSection(CompressSectionObj)
2515 IsEncapSection = self.__GetEncapsulationSec(CompressSectionObj)
2516 if not IsLeafSection and not IsEncapSection:
2517 break
2518
2519
2520 if not self.__IsToken( "}"):
2521 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
2522 Obj.SectionList.append(CompressSectionObj)
2523
2524 # else:
2525 # raise Warning("Compress type not known At Line ")
2526
2527 return True
2528
2529 elif self.__IsKeyword( "GUIDED"):
2530 GuidValue = None
2531 if self.__GetNextGuid():
2532 GuidValue = self.__Token
2533
2534 AttribDict = self.__GetGuidAttrib()
2535 if not self.__IsToken("{"):
2536 raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
2537 GuidSectionObj = CommonDataClass.FdfClass.GuidSectionClassObject()
2538 GuidSectionObj.Alignment = AlignValue
2539 GuidSectionObj.NameGuid = GuidValue
2540 GuidSectionObj.SectionType = "GUIDED"
2541 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
2542 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
2543 # Recursive sections...
2544 while True:
2545 IsLeafSection = self.__GetLeafSection(GuidSectionObj)
2546 IsEncapSection = self.__GetEncapsulationSec(GuidSectionObj)
2547 if not IsLeafSection and not IsEncapSection:
2548 break
2549
2550 if not self.__IsToken( "}"):
2551 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
2552 Obj.SectionList.append(GuidSectionObj)
2553
2554 return True
2555
2556 return False
2557
2558 ## __GetGuidAttri() method
2559 #
2560 # Get attributes for GUID section
2561 #
2562 # @param self The object pointer
2563 # @retval AttribDict Dictionary of key-value pair of section attributes
2564 #
2565 def __GetGuidAttrib(self):
2566
2567 AttribDict = {}
2568 AttribDict["PROCESSING_REQUIRED"] = False
2569 AttribDict["AUTH_STATUS_VALID"] = False
2570 if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"):
2571 AttribKey = self.__Token
2572
2573 if not self.__IsToken("="):
2574 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2575
2576 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
2577 raise Warning("expected TRUE/FALSE (1/0) At Line ", self.FileName, self.CurrentLineNumber)
2578 AttribDict[AttribKey] = self.__Token
2579
2580 if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"):
2581 AttribKey = self.__Token
2582
2583 if not self.__IsToken("="):
2584 raise Warning("expected '=' At Line ")
2585
2586 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
2587 raise Warning("expected TRUE/FALSE (1/0) At Line ", self.FileName, self.CurrentLineNumber)
2588 AttribDict[AttribKey] = self.__Token
2589
2590 return AttribDict
2591
2592 ## __GetEncapsulationSec() method
2593 #
2594 # Get encapsulation section for FILE
2595 #
2596 # @param self The object pointer
2597 # @param FfsFile for whom section is got
2598 # @retval True Successfully find section statement
2599 # @retval False Not able to find section statement
2600 #
2601 def __GetEncapsulationSec(self, FfsFileObj):
2602
2603 OldPos = self.GetFileBufferPos()
2604 if not self.__IsKeyword( "SECTION"):
2605 if len(FfsFileObj.SectionList) == 0:
2606 raise Warning("expected SECTION At Line ", self.FileName, self.CurrentLineNumber)
2607 else:
2608 return False
2609
2610 AlignValue = None
2611 if self.__GetAlignment():
2612 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
2613 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
2614 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2615 AlignValue = self.__Token
2616
2617 if not self.__GetCglSection(FfsFileObj, AlignValue):
2618 self.SetFileBufferPos(OldPos)
2619 return False
2620 else:
2621 return True
2622
2623 ## __GetCapsule() method
2624 #
2625 # Get capsule section contents and store its data into capsule list of self.Profile
2626 #
2627 # @param self The object pointer
2628 # @retval True Successfully find a capsule
2629 # @retval False Not able to find a capsule
2630 #
2631 def __GetCapsule(self):
2632
2633 if not self.__GetNextToken():
2634 return False
2635
2636 S = self.__Token.upper()
2637 if S.startswith("[") and not S.startswith("[CAPSULE."):
2638 if not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
2639 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
2640 self.__UndoToken()
2641 return False
2642
2643 self.__UndoToken()
2644 if not self.__IsToken("[CAPSULE.", True):
2645 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
2646 print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2647 % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2648 raise Warning("expected [Capsule.] At Line ", self.FileName, self.CurrentLineNumber)
2649
2650 CapsuleObj = CommonDataClass.FdfClass.CapsuleClassObject()
2651
2652 CapsuleName = self.__GetUiName()
2653 if not CapsuleName:
2654 raise Warning("expected capsule name At line ", self.FileName, self.CurrentLineNumber)
2655
2656 CapsuleObj.UiCapsuleName = CapsuleName.upper()
2657
2658 if not self.__IsToken( "]"):
2659 raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber)
2660
2661 if self.__IsKeyword("CREATE_FILE"):
2662 if not self.__IsToken( "="):
2663 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2664
2665 if not self.__GetNextToken():
2666 raise Warning("expected file name At Line ", self.FileName, self.CurrentLineNumber)
2667
2668 CapsuleObj.CreateFile = self.__Token
2669
2670 self.__GetCapsuleStatements(CapsuleObj)
2671 self.Profile.CapsuleList.append(CapsuleObj)
2672 return True
2673
2674 ## __GetCapsuleStatements() method
2675 #
2676 # Get statements for capsule
2677 #
2678 # @param self The object pointer
2679 # @param Obj for whom statements are got
2680 #
2681 def __GetCapsuleStatements(self, Obj):
2682 self.__GetCapsuleTokens(Obj)
2683 self.__GetDefineStatements(Obj)
2684 self.__GetSetStatements(Obj)
2685
2686 self.__GetCapsuleData(Obj)
2687
2688 ## __GetCapsuleStatements() method
2689 #
2690 # Get token statements for capsule
2691 #
2692 # @param self The object pointer
2693 # @param Obj for whom token statements are got
2694 #
2695 def __GetCapsuleTokens(self, Obj):
2696
2697 if not self.__IsKeyword("CAPSULE_GUID"):
2698 raise Warning("expected 'CAPSULE_GUID' At Line ", self.FileName, self.CurrentLineNumber)
2699
2700 while self.__CurrentLine().find("=") != -1:
2701 NameValue = self.__CurrentLine().split("=")
2702 Obj.TokensDict[NameValue[0].strip()] = NameValue[1].strip()
2703 self.CurrentLineNumber += 1
2704 self.CurrentOffsetWithinLine = 0
2705
2706 ## __GetCapsuleData() method
2707 #
2708 # Get capsule data for capsule
2709 #
2710 # @param self The object pointer
2711 # @param Obj for whom capsule data are got
2712 #
2713 def __GetCapsuleData(self, Obj):
2714
2715 while True:
2716 IsInf = self.__GetInfStatement(Obj, True)
2717 IsFile = self.__GetFileStatement(Obj, True)
2718 IsFv = self.__GetFvStatement(Obj)
2719 if not IsInf and not IsFile and not IsFv:
2720 break
2721
2722 ## __GetFvStatement() method
2723 #
2724 # Get FV for capsule
2725 #
2726 # @param self The object pointer
2727 # @param CapsuleObj for whom FV is got
2728 # @retval True Successfully find a FV statement
2729 # @retval False Not able to find a FV statement
2730 #
2731 def __GetFvStatement(self, CapsuleObj):
2732
2733 if not self.__IsKeyword("FV"):
2734 return False
2735
2736 if not self.__IsToken("="):
2737 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2738
2739 if not self.__GetNextToken():
2740 raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber)
2741
2742 # CapsuleFv = CapsuleData.CapsuleFv()
2743 # CapsuleFv.FvName = self.__Token
2744 # CapsuleObj.CapsuleDataList.append(CapsuleFv)
2745 return True
2746
2747 ## __GetRule() method
2748 #
2749 # Get Rule section contents and store its data into rule list of self.Profile
2750 #
2751 # @param self The object pointer
2752 # @retval True Successfully find a Rule
2753 # @retval False Not able to find a Rule
2754 #
2755 def __GetRule(self):
2756
2757 if not self.__GetNextToken():
2758 return False
2759
2760 S = self.__Token.upper()
2761 if S.startswith("[") and not S.startswith("[RULE."):
2762 if not S.startswith("[OPTIONROM."):
2763 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
2764 self.__UndoToken()
2765 return False
2766 self.__UndoToken()
2767 if not self.__IsToken("[Rule.", True):
2768 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
2769 print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2770 % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2771 raise Warning("expected [Rule.] At Line ", self.FileName, self.CurrentLineNumber)
2772
2773 if not self.__SkipToToken("."):
2774 raise Warning("expected '.' At Line ", self.FileName, self.CurrentLineNumber)
2775
2776 Arch = self.__SkippedChars.rstrip(".")
2777 if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "AARCH64", "COMMON"):
2778 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
2779
2780 ModuleType = self.__GetModuleType()
2781
2782 TemplateName = ""
2783 if self.__IsToken("."):
2784 if not self.__GetNextWord():
2785 raise Warning("expected template name At Line ", self.FileName, self.CurrentLineNumber)
2786 TemplateName = self.__Token
2787
2788 if not self.__IsToken( "]"):
2789 raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber)
2790
2791 RuleObj = self.__GetRuleFileStatements()
2792 RuleObj.Arch = Arch.upper()
2793 RuleObj.ModuleType = ModuleType
2794 RuleObj.TemplateName = TemplateName
2795 if TemplateName == '' :
2796 self.Profile.RuleDict['RULE' + \
2797 '.' + \
2798 Arch.upper() + \
2799 '.' + \
2800 ModuleType.upper() ] = RuleObj
2801 else :
2802 self.Profile.RuleDict['RULE' + \
2803 '.' + \
2804 Arch.upper() + \
2805 '.' + \
2806 ModuleType.upper() + \
2807 '.' + \
2808 TemplateName.upper() ] = RuleObj
2809 # self.Profile.RuleList.append(rule)
2810 return True
2811
2812 ## __GetModuleType() method
2813 #
2814 # Return the module type
2815 #
2816 # @param self The object pointer
2817 # @retval string module type
2818 #
2819 def __GetModuleType(self):
2820
2821 if not self.__GetNextWord():
2822 raise Warning("expected Module type At Line ", self.FileName, self.CurrentLineNumber)
2823 if self.__Token.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \
2824 "DXE_DRIVER", "DXE_SAL_DRIVER", \
2825 "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \
2826 "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \
2827 "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \
2828 "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_CORE", "MM_STANDALONE", "MM_CORE_STANDALONE"):
2829 raise Warning("Unknown Module type At line ", self.FileName, self.CurrentLineNumber)
2830 return self.__Token
2831
2832 ## __GetFileExtension() method
2833 #
2834 # Return the file extension
2835 #
2836 # @param self The object pointer
2837 # @retval string file name extension
2838 #
2839 def __GetFileExtension(self):
2840 if not self.__IsToken("."):
2841 raise Warning("expected '.' At Line ", self.FileName, self.CurrentLineNumber)
2842
2843 Ext = ""
2844 if self.__GetNextToken():
2845 Pattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)')
2846 if Pattern.match(self.__Token):
2847 Ext = self.__Token
2848 return '.' + Ext
2849 else:
2850 raise Warning("Unknown file extension At Line ", self.FileName, self.CurrentLineNumber)
2851
2852 else:
2853 raise Warning("expected file extension At Line ", self.FileName, self.CurrentLineNumber)
2854
2855 ## __GetRuleFileStatement() method
2856 #
2857 # Get rule contents
2858 #
2859 # @param self The object pointer
2860 # @retval Rule Rule object
2861 #
2862 def __GetRuleFileStatements(self):
2863
2864 if not self.__IsKeyword("FILE"):
2865 raise Warning("expected FILE At Line ", self.FileName, self.CurrentLineNumber)
2866
2867 if not self.__GetNextWord():
2868 raise Warning("expected FFS type At Line ", self.FileName, self.CurrentLineNumber)
2869
2870 Type = self.__Token.strip().upper()
2871 if Type not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\
2872 "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM", "SMM_CORE", "MM_STANDALONE"):
2873 raise Warning("Unknown FV type At line ", self.FileName, self.CurrentLineNumber)
2874
2875 if not self.__IsToken("="):
2876 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2877
2878 if not self.__IsKeyword("$(NAMED_GUID)"):
2879 if not self.__GetNextWord():
2880 raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber)
2881 if self.__Token == 'PCD':
2882 if not self.__IsToken( "("):
2883 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
2884 PcdPair = self.__GetNextPcdName()
2885 if not self.__IsToken( ")"):
2886 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
2887 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
2888
2889 NameGuid = self.__Token
2890
2891 KeepReloc = None
2892 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
2893 if self.__FileCouldHaveRelocFlag(Type):
2894 if self.__Token == 'RELOCS_STRIPPED':
2895 KeepReloc = False
2896 else:
2897 KeepReloc = True
2898 else:
2899 raise Warning("File type %s could not have reloc strip flag At Line %d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
2900
2901 KeyStringList = []
2902 if self.__GetNextToken():
2903 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
2904 if Pattern.match(self.__Token):
2905 KeyStringList.append(self.__Token)
2906 if self.__IsToken(","):
2907 while self.__GetNextToken():
2908 if not Pattern.match(self.__Token):
2909 raise Warning("expected KeyString \"Target_Tag_Arch\" At Line ", self.FileName, self.CurrentLineNumber)
2910 KeyStringList.append(self.__Token)
2911
2912 if not self.__IsToken(","):
2913 break
2914
2915 else:
2916 self.__UndoToken()
2917
2918
2919 Fixed = False
2920 if self.__IsKeyword("Fixed", True):
2921 Fixed = True
2922
2923 CheckSum = False
2924 if self.__IsKeyword("CheckSum", True):
2925 CheckSum = True
2926
2927 AlignValue = ""
2928 if self.__GetAlignment():
2929 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
2930 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
2931 raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber)
2932 AlignValue = self.__Token
2933
2934 if self.__IsToken("{"):
2935 # Complex file rule expected
2936 Rule = RuleComplexFile.RuleComplexFile()
2937 Rule.FvFileType = Type
2938 Rule.NameGuid = NameGuid
2939 Rule.Alignment = AlignValue
2940 Rule.CheckSum = CheckSum
2941 Rule.Fixed = Fixed
2942 Rule.KeyStringList = KeyStringList
2943 if KeepReloc != None:
2944 Rule.KeepReloc = KeepReloc
2945
2946 while True:
2947 IsEncapsulate = self.__GetRuleEncapsulationSection(Rule)
2948 IsLeaf = self.__GetEfiSection(Rule)
2949 if not IsEncapsulate and not IsLeaf:
2950 break
2951
2952 if not self.__IsToken("}"):
2953 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
2954
2955 return Rule
2956
2957 elif self.__IsToken("|"):
2958 # Ext rule expected
2959 Ext = self.__GetFileExtension()
2960
2961 Rule = RuleSimpleFile.RuleSimpleFile()
2962
2963 Rule.FvFileType = Type
2964 Rule.NameGuid = NameGuid
2965 Rule.Alignment = AlignValue
2966 Rule.CheckSum = CheckSum
2967 Rule.Fixed = Fixed
2968 Rule.FileExtension = Ext
2969 Rule.KeyStringList = KeyStringList
2970 if KeepReloc != None:
2971 Rule.KeepReloc = KeepReloc
2972
2973 return Rule
2974
2975 else:
2976 # Simple file rule expected
2977 if not self.__GetNextWord():
2978 raise Warning("expected leaf section type At Line ", self.FileName, self.CurrentLineNumber)
2979
2980 SectionName = self.__Token
2981
2982 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
2983 "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"):
2984 raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)
2985
2986
2987 if self.__IsKeyword("Fixed", True):
2988 Fixed = True
2989
2990 if self.__IsKeyword("CheckSum", True):
2991 CheckSum = True
2992
2993 if self.__GetAlignment():
2994 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
2995 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
2996 raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber)
2997 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
2998 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2999 AlignValue = self.__Token
3000
3001 if not self.__GetNextToken():
3002 raise Warning("expected File name At Line ", self.FileName, self.CurrentLineNumber)
3003
3004 Rule = RuleSimpleFile.RuleSimpleFile()
3005 Rule.SectionType = SectionName
3006 Rule.FvFileType = Type
3007 Rule.NameGuid = NameGuid
3008 Rule.Alignment = AlignValue
3009 Rule.CheckSum = CheckSum
3010 Rule.Fixed = Fixed
3011 Rule.FileName = self.__Token
3012 Rule.KeyStringList = KeyStringList
3013 if KeepReloc != None:
3014 Rule.KeepReloc = KeepReloc
3015 return Rule
3016
3017 ## __GetEfiSection() method
3018 #
3019 # Get section list for Rule
3020 #
3021 # @param self The object pointer
3022 # @param Obj for whom section is got
3023 # @retval True Successfully find section statement
3024 # @retval False Not able to find section statement
3025 #
3026 def __GetEfiSection(self, Obj):
3027
3028 OldPos = self.GetFileBufferPos()
3029 if not self.__GetNextWord():
3030 return False
3031 SectionName = self.__Token
3032
3033 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3034 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3035 self.__UndoToken()
3036 return False
3037
3038 if SectionName == "FV_IMAGE":
3039 FvImageSectionObj = FvImageSection.FvImageSection()
3040 if self.__IsKeyword("FV_IMAGE"):
3041 pass
3042 if self.__IsToken( "{"):
3043 FvObj = Fv.FV()
3044 self.__GetDefineStatements(FvObj)
3045 self.__GetBlockStatement(FvObj)
3046 self.__GetSetStatements(FvObj)
3047 self.__GetFvAlignment(FvObj)
3048 self.__GetFvAttributes(FvObj)
3049 self.__GetAprioriSection(FvObj)
3050 self.__GetAprioriSection(FvObj)
3051
3052 while True:
3053 IsInf = self.__GetInfStatement(FvObj)
3054 IsFile = self.__GetFileStatement(FvObj)
3055 if not IsInf and not IsFile:
3056 break
3057
3058 if not self.__IsToken( "}"):
3059 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
3060 FvImageSectionObj.Fv = FvObj
3061 FvImageSectionObj.FvName = None
3062
3063 else:
3064 if not self.__IsKeyword("FV"):
3065 raise Warning("expected 'FV' At Line ", self.FileName, self.CurrentLineNumber)
3066 FvImageSectionObj.FvFileType = self.__Token
3067
3068 if self.__GetAlignment():
3069 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
3070 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
3071 raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber)
3072 FvImageSectionObj.Alignment = self.__Token
3073
3074 if self.__IsToken('|'):
3075 FvImageSectionObj.FvFileExtension = self.__GetFileExtension()
3076 elif self.__GetNextToken():
3077 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3078 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3079 FvImageSectionObj.FvFileName = self.__Token
3080 else:
3081 self.__UndoToken()
3082 else:
3083 raise Warning("expected FV file name At Line ", self.FileName, self.CurrentLineNumber)
3084
3085 Obj.SectionList.append(FvImageSectionObj)
3086 return True
3087
3088 EfiSectionObj = EfiSection.EfiSection()
3089 EfiSectionObj.SectionType = SectionName
3090
3091 if not self.__GetNextToken():
3092 raise Warning("expected file type At Line ", self.FileName, self.CurrentLineNumber)
3093
3094 if self.__Token == "STRING":
3095 if not self.__RuleSectionCouldHaveString(EfiSectionObj.SectionType):
3096 raise Warning("%s section could NOT have string data At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3097
3098 if not self.__IsToken('='):
3099 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3100
3101 if not self.__GetNextToken():
3102 raise Warning("expected Quoted String At Line ", self.FileName, self.CurrentLineNumber)
3103
3104 if self.__GetStringData():
3105 EfiSectionObj.StringData = self.__Token
3106
3107 if self.__IsKeyword("BUILD_NUM"):
3108 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
3109 raise Warning("%s section could NOT have BUILD_NUM At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3110
3111 if not self.__IsToken("="):
3112 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3113 if not self.__GetNextToken():
3114 raise Warning("expected Build number At Line ", self.FileName, self.CurrentLineNumber)
3115 EfiSectionObj.BuildNum = self.__Token
3116
3117 else:
3118 EfiSectionObj.FileType = self.__Token
3119 self.__CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)
3120
3121 if self.__IsKeyword("Optional"):
3122 if not self.__RuleSectionCouldBeOptional(EfiSectionObj.SectionType):
3123 raise Warning("%s section could NOT be optional At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3124 EfiSectionObj.Optional = True
3125
3126 if self.__IsKeyword("BUILD_NUM"):
3127 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
3128 raise Warning("%s section could NOT have BUILD_NUM At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3129
3130 if not self.__IsToken("="):
3131 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3132 if not self.__GetNextToken():
3133 raise Warning("expected Build number At Line ", self.FileName, self.CurrentLineNumber)
3134 EfiSectionObj.BuildNum = self.__Token
3135
3136 if self.__GetAlignment():
3137 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
3138 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
3139 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3140 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
3141 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
3142 EfiSectionObj.Alignment = self.__Token
3143
3144 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
3145 if self.__SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):
3146 if self.__Token == 'RELOCS_STRIPPED':
3147 EfiSectionObj.KeepReloc = False
3148 else:
3149 EfiSectionObj.KeepReloc = True
3150 if Obj.KeepReloc != None and Obj.KeepReloc != EfiSectionObj.KeepReloc:
3151 raise Warning("Section type %s has reloc strip flag conflict with Rule At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3152 else:
3153 raise Warning("Section type %s could not have reloc strip flag At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3154
3155
3156 if self.__IsToken('|'):
3157 EfiSectionObj.FileExtension = self.__GetFileExtension()
3158 elif self.__GetNextToken():
3159 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3160 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3161
3162 if self.__Token.startswith('PCD'):
3163 self.__UndoToken()
3164 self.__GetNextWord()
3165
3166 if self.__Token == 'PCD':
3167 if not self.__IsToken( "("):
3168 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
3169 PcdPair = self.__GetNextPcdName()
3170 if not self.__IsToken( ")"):
3171 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
3172 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
3173
3174 EfiSectionObj.FileName = self.__Token
3175
3176 else:
3177 self.__UndoToken()
3178 else:
3179 raise Warning("expected section file name At Line ", self.FileName, self.CurrentLineNumber)
3180
3181 Obj.SectionList.append(EfiSectionObj)
3182 return True
3183
3184 ## __RuleSectionCouldBeOptional() method
3185 #
3186 # Get whether a section could be optional
3187 #
3188 # @param self The object pointer
3189 # @param SectionType The section type to check
3190 # @retval True section could be optional
3191 # @retval False section never optional
3192 #
3193 def __RuleSectionCouldBeOptional(self, SectionType):
3194 if SectionType in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"):
3195 return True
3196 else:
3197 return False
3198
3199 ## __RuleSectionCouldHaveBuildNum() method
3200 #
3201 # Get whether a section could have build number information
3202 #
3203 # @param self The object pointer
3204 # @param SectionType The section type to check
3205 # @retval True section could have build number information
3206 # @retval False section never have build number information
3207 #
3208 def __RuleSectionCouldHaveBuildNum(self, SectionType):
3209 if SectionType in ("VERSION"):
3210 return True
3211 else:
3212 return False
3213
3214 ## __RuleSectionCouldHaveString() method
3215 #
3216 # Get whether a section could have string
3217 #
3218 # @param self The object pointer
3219 # @param SectionType The section type to check
3220 # @retval True section could have string
3221 # @retval False section never have string
3222 #
3223 def __RuleSectionCouldHaveString(self, SectionType):
3224 if SectionType in ("UI", "VERSION"):
3225 return True
3226 else:
3227 return False
3228
3229 ## __CheckRuleSectionFileType() method
3230 #
3231 # Get whether a section matches a file type
3232 #
3233 # @param self The object pointer
3234 # @param SectionType The section type to check
3235 # @param FileType The file type to check
3236 #
3237 def __CheckRuleSectionFileType(self, SectionType, FileType):
3238 if SectionType == "COMPAT16":
3239 if FileType not in ("COMPAT16", "SEC_COMPAT16"):
3240 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3241 elif SectionType == "PE32":
3242 if FileType not in ("PE32", "SEC_PE32"):
3243 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3244 elif SectionType == "PIC":
3245 if FileType not in ("PIC", "PIC"):
3246 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3247 elif SectionType == "TE":
3248 if FileType not in ("TE", "SEC_TE"):
3249 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3250 elif SectionType == "RAW":
3251 if FileType not in ("BIN", "SEC_BIN", "RAW", "ASL", "ACPI"):
3252 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3253 elif SectionType == "DXE_DEPEX" or SectionType == "SMM_DEPEX":
3254 if FileType not in ("DXE_DEPEX", "SEC_DXE_DEPEX", "SMM_DEPEX"):
3255 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3256 elif SectionType == "UI":
3257 if FileType not in ("UI", "SEC_UI"):
3258 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3259 elif SectionType == "VERSION":
3260 if FileType not in ("VERSION", "SEC_VERSION"):
3261 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3262 elif SectionType == "PEI_DEPEX":
3263 if FileType not in ("PEI_DEPEX", "SEC_PEI_DEPEX"):
3264 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3265 elif SectionType == "GUID":
3266 if FileType not in ("PE32", "SEC_GUID"):
3267 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3268
3269 ## __GetRuleEncapsulationSection() method
3270 #
3271 # Get encapsulation section for Rule
3272 #
3273 # @param self The object pointer
3274 # @param Rule for whom section is got
3275 # @retval True Successfully find section statement
3276 # @retval False Not able to find section statement
3277 #
3278 def __GetRuleEncapsulationSection(self, Rule):
3279
3280 if self.__IsKeyword( "COMPRESS"):
3281 Type = "PI_STD"
3282 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
3283 Type = self.__Token
3284
3285 if not self.__IsToken("{"):
3286 raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
3287
3288 CompressSectionObj = CompressSection.CompressSection()
3289
3290 CompressSectionObj.CompType = Type
3291 # Recursive sections...
3292 while True:
3293 IsEncapsulate = self.__GetRuleEncapsulationSection(CompressSectionObj)
3294 IsLeaf = self.__GetEfiSection(CompressSectionObj)
3295 if not IsEncapsulate and not IsLeaf:
3296 break
3297
3298 if not self.__IsToken( "}"):
3299 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
3300 Rule.SectionList.append(CompressSectionObj)
3301
3302 return True
3303
3304 elif self.__IsKeyword( "GUIDED"):
3305 GuidValue = None
3306 if self.__GetNextGuid():
3307 GuidValue = self.__Token
3308
3309 if self.__IsKeyword( "$(NAMED_GUID)"):
3310 GuidValue = self.__Token
3311
3312 AttribDict = self.__GetGuidAttrib()
3313
3314 if not self.__IsToken("{"):
3315 raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
3316 GuidSectionObj = GuidSection.GuidSection()
3317 GuidSectionObj.NameGuid = GuidValue
3318 GuidSectionObj.SectionType = "GUIDED"
3319 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
3320 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
3321
3322 # Efi sections...
3323 while True:
3324 IsEncapsulate = self.__GetRuleEncapsulationSection(GuidSectionObj)
3325 IsLeaf = self.__GetEfiSection(GuidSectionObj)
3326 if not IsEncapsulate and not IsLeaf:
3327 break
3328
3329 if not self.__IsToken( "}"):
3330 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
3331 Rule.SectionList.append(GuidSectionObj)
3332
3333 return True
3334
3335 return False
3336
3337 ## __GetVtf() method
3338 #
3339 # Get VTF section contents and store its data into VTF list of self.Profile
3340 #
3341 # @param self The object pointer
3342 # @retval True Successfully find a VTF
3343 # @retval False Not able to find a VTF
3344 #
3345 def __GetVtf(self):
3346
3347 if not self.__GetNextToken():
3348 return False
3349
3350 S = self.__Token.upper()
3351 if S.startswith("[") and not S.startswith("[VTF."):
3352 if not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
3353 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
3354 self.__UndoToken()
3355 return False
3356
3357 self.__UndoToken()
3358 if not self.__IsToken("[VTF.", True):
3359 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
3360 print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3361 % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3362 raise Warning("expected [VTF.] At Line ", self.FileName, self.CurrentLineNumber)
3363
3364 if not self.__SkipToToken("."):
3365 raise Warning("expected '.' At Line ", self.FileName, self.CurrentLineNumber)
3366
3367 Arch = self.__SkippedChars.rstrip(".").upper()
3368 if Arch not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
3369 raise Warning("Unknown Arch At line ", self.FileName, self.CurrentLineNumber)
3370
3371 if not self.__GetNextWord():
3372 raise Warning("expected VTF name At Line ", self.FileName, self.CurrentLineNumber)
3373 Name = self.__Token.upper()
3374
3375 VtfObj = Vtf.Vtf()
3376 VtfObj.UiName = Name
3377 VtfObj.KeyArch = Arch
3378
3379 if self.__IsToken(","):
3380 if not self.__GetNextWord():
3381 raise Warning("expected Arch list At Line ", self.FileName, self.CurrentLineNumber)
3382 if self.__Token.upper() not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
3383 raise Warning("Unknown Arch At line ", self.FileName, self.CurrentLineNumber)
3384 VtfObj.ArchList = self.__Token.upper()
3385
3386 if not self.__IsToken( "]"):
3387 raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber)
3388
3389 if self.__IsKeyword("IA32_RST_BIN"):
3390 if not self.__IsToken("="):
3391 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3392
3393 if not self.__GetNextToken():
3394 raise Warning("expected Reset file At Line ", self.FileName, self.CurrentLineNumber)
3395
3396 VtfObj.ResetBin = self.__Token
3397
3398 while self.__GetComponentStatement(VtfObj):
3399 pass
3400
3401 self.Profile.VtfList.append(VtfObj)
3402 return True
3403
3404 ## __GetComponentStatement() method
3405 #
3406 # Get components in VTF
3407 #
3408 # @param self The object pointer
3409 # @param VtfObj for whom component is got
3410 # @retval True Successfully find a component
3411 # @retval False Not able to find a component
3412 #
3413 def __GetComponentStatement(self, VtfObj):
3414
3415 if not self.__IsKeyword("COMP_NAME"):
3416 return False
3417
3418 if not self.__IsToken("="):
3419 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3420
3421 if not self.__GetNextWord():
3422 raise Warning("expected Component Name At Line ", self.FileName, self.CurrentLineNumber)
3423
3424 CompStatementObj = ComponentStatement.ComponentStatement()
3425 CompStatementObj.CompName = self.__Token
3426
3427 if not self.__IsKeyword("COMP_LOC"):
3428 raise Warning("expected COMP_LOC At Line ", self.FileName, self.CurrentLineNumber)
3429
3430 if not self.__IsToken("="):
3431 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3432
3433 CompStatementObj.CompLoc = ""
3434 if self.__GetNextWord():
3435 CompStatementObj.CompLoc = self.__Token
3436 if self.__IsToken('|'):
3437 if not self.__GetNextWord():
3438 raise Warning("Expected Region Name At Line ", self.FileName, self.CurrentLineNumber)
3439
3440 if self.__Token not in ("F", "N", "S"): #, "H", "L", "PH", "PL"): not support
3441 raise Warning("Unknown location type At line ", self.FileName, self.CurrentLineNumber)
3442
3443 CompStatementObj.FilePos = self.__Token
3444 else:
3445 self.CurrentLineNumber += 1
3446 self.CurrentOffsetWithinLine = 0
3447
3448 if not self.__IsKeyword("COMP_TYPE"):
3449 raise Warning("expected COMP_TYPE At Line ", self.FileName, self.CurrentLineNumber)
3450
3451 if not self.__IsToken("="):
3452 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3453
3454 if not self.__GetNextToken():
3455 raise Warning("expected Component type At Line ", self.FileName, self.CurrentLineNumber)
3456 if self.__Token not in ("FIT", "PAL_B", "PAL_A", "OEM"):
3457 if not self.__Token.startswith("0x") or len(self.__Token) < 3 or len(self.__Token) > 4 or \
3458 not self.__HexDigit(self.__Token[2]) or not self.__HexDigit(self.__Token[-1]):
3459 raise Warning("Unknown location type At line ", self.FileName, self.CurrentLineNumber)
3460 CompStatementObj.CompType = self.__Token
3461
3462 if not self.__IsKeyword("COMP_VER"):
3463 raise Warning("expected COMP_VER At Line ", self.FileName, self.CurrentLineNumber)
3464
3465 if not self.__IsToken("="):
3466 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3467
3468 if not self.__GetNextToken():
3469 raise Warning("expected Component version At Line ", self.FileName, self.CurrentLineNumber)
3470
3471 Pattern = re.compile('-$|[0-9]{0,1}[0-9]{1}\.[0-9]{0,1}[0-9]{1}')
3472 if Pattern.match(self.__Token) == None:
3473 raise Warning("Unknown version format At line ", self.FileName, self.CurrentLineNumber)
3474 CompStatementObj.CompVer = self.__Token
3475
3476 if not self.__IsKeyword("COMP_CS"):
3477 raise Warning("expected COMP_CS At Line ", self.FileName, self.CurrentLineNumber)
3478
3479 if not self.__IsToken("="):
3480 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3481
3482 if not self.__GetNextToken():
3483 raise Warning("expected Component CS At Line ", self.FileName, self.CurrentLineNumber)
3484 if self.__Token not in ("1", "0"):
3485 raise Warning("Unknown Component CS At line ", self.FileName, self.CurrentLineNumber)
3486 CompStatementObj.CompCs = self.__Token
3487
3488
3489 if not self.__IsKeyword("COMP_BIN"):
3490 raise Warning("expected COMP_BIN At Line ", self.FileName, self.CurrentLineNumber)
3491
3492 if not self.__IsToken("="):
3493 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3494
3495 if not self.__GetNextToken():
3496 raise Warning("expected Component file At Line ", self.FileName, self.CurrentLineNumber)
3497
3498 CompStatementObj.CompBin = self.__Token
3499
3500 if not self.__IsKeyword("COMP_SYM"):
3501 raise Warning("expected COMP_SYM At Line ", self.FileName, self.CurrentLineNumber)
3502
3503 if not self.__IsToken("="):
3504 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3505
3506 if not self.__GetNextToken():
3507 raise Warning("expected Component symbol file At Line ", self.FileName, self.CurrentLineNumber)
3508
3509 CompStatementObj.CompSym = self.__Token
3510
3511 if not self.__IsKeyword("COMP_SIZE"):
3512 raise Warning("expected COMP_SIZE At Line ", self.FileName, self.CurrentLineNumber)
3513
3514 if not self.__IsToken("="):
3515 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3516
3517 if self.__IsToken("-"):
3518 CompStatementObj.CompSize = self.__Token
3519 elif self.__GetNextDecimalNumber():
3520 CompStatementObj.CompSize = self.__Token
3521 elif self.__GetNextHexNumber():
3522 CompStatementObj.CompSize = self.__Token
3523 else:
3524 raise Warning("Unknown size At line ", self.FileName, self.CurrentLineNumber)
3525
3526 VtfObj.ComponentStatementList.append(CompStatementObj)
3527 return True
3528
3529 ## __GetFvInFd() method
3530 #
3531 # Get FV list contained in FD
3532 #
3533 # @param self The object pointer
3534 # @param FdName FD name
3535 # @retval FvList list of FV in FD
3536 #
3537 def __GetFvInFd (self, FdName):
3538
3539 FvList = []
3540 if FdName.upper() in self.Profile.FdDict.keys():
3541 FdObj = self.Profile.FdDict[FdName.upper()]
3542 for elementRegion in FdObj.RegionList:
3543 if elementRegion.RegionType == 'FV':
3544 for elementRegionData in elementRegion.RegionDataList:
3545 if elementRegionData != None and elementRegionData.upper() not in FvList:
3546 FvList.append(elementRegionData.upper())
3547 return FvList
3548
3549 ## __GetReferencedFdFvTuple() method
3550 #
3551 # Get FD and FV list referenced by a FFS file
3552 #
3553 # @param self The object pointer
3554 # @param FfsFile contains sections to be searched
3555 # @param RefFdList referenced FD by section
3556 # @param RefFvList referenced FV by section
3557 #
3558 def __GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):
3559
3560 for FfsObj in FvObj.FfsList:
3561 if isinstance(FfsObj, FfsFileStatement.FileStatement):
3562 if FfsObj.FvName != None and FfsObj.FvName.upper() not in RefFvList:
3563 RefFvList.append(FfsObj.FvName.upper())
3564 elif FfsObj.FdName != None and FfsObj.FdName.upper() not in RefFdList:
3565 RefFdList.append(FfsObj.FdName.upper())
3566 else:
3567 self.__GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)
3568
3569 ## __GetReferencedFdFvTupleFromSection() method
3570 #
3571 # Get FD and FV list referenced by a FFS section
3572 #
3573 # @param self The object pointer
3574 # @param FfsFile contains sections to be searched
3575 # @param FdList referenced FD by section
3576 # @param FvList referenced FV by section
3577 #
3578 def __GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):
3579
3580 SectionStack = []
3581 SectionStack.extend(FfsFile.SectionList)
3582 while SectionStack != []:
3583 SectionObj = SectionStack.pop()
3584 if isinstance(SectionObj, FvImageSection.FvImageSection):
3585 if SectionObj.FvName != None and SectionObj.FvName.upper() not in FvList:
3586 FvList.append(SectionObj.FvName.upper())
3587 if SectionObj.Fv != None and SectionObj.Fv.UiFvName != None and SectionObj.Fv.UiFvName.upper() not in FvList:
3588 FvList.append(SectionObj.Fv.UiFvName.upper())
3589 self.__GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)
3590
3591 if isinstance(SectionObj, CompressSection.CompressSection) or isinstance(SectionObj, GuidSection.GuidSection):
3592 SectionStack.extend(SectionObj.SectionList)
3593
3594 ## CycleReferenceCheck() method
3595 #
3596 # Check whether cycle reference exists in FDF
3597 #
3598 # @param self The object pointer
3599 # @retval True cycle reference exists
3600 # @retval False Not exists cycle reference
3601 #
3602 def CycleReferenceCheck(self):
3603
3604 CycleRefExists = False
3605
3606 try:
3607 for FvName in self.Profile.FvDict.keys():
3608 LogStr = "Cycle Reference Checking for FV: %s\n" % FvName
3609 RefFvStack = []
3610 RefFvStack.append(FvName)
3611 FdAnalyzedList = []
3612
3613 while RefFvStack != []:
3614 FvNameFromStack = RefFvStack.pop()
3615 if FvNameFromStack.upper() in self.Profile.FvDict.keys():
3616 FvObj = self.Profile.FvDict[FvNameFromStack.upper()]
3617 else:
3618 continue
3619
3620 RefFdList = []
3621 RefFvList = []
3622 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
3623
3624 for RefFdName in RefFdList:
3625 if RefFdName in FdAnalyzedList:
3626 continue
3627
3628 LogStr += "FD %s is referenced by FV %s\n" % (RefFdName, FvNameFromStack)
3629 FvInFdList = self.__GetFvInFd(RefFdName)
3630 if FvInFdList != []:
3631 LogStr += "FD %s contains FV: " % RefFdName
3632 for FvObj in FvInFdList:
3633 LogStr += FvObj
3634 LogStr += ' \n'
3635 if FvObj not in RefFvStack:
3636 RefFvStack.append(FvObj)
3637
3638 if FvName in RefFvStack:
3639 CycleRefExists = True
3640 raise Warning(LogStr)
3641 FdAnalyzedList.append(RefFdName)
3642
3643 for RefFvName in RefFvList:
3644 LogStr += "FV %s is referenced by FV %s\n" % (RefFvName, FvNameFromStack)
3645 if RefFvName not in RefFvStack:
3646 RefFvStack.append(RefFvName)
3647
3648 if FvName in RefFvStack:
3649 CycleRefExists = True
3650 raise Warning(LogStr)
3651
3652 except Warning:
3653 print LogStr
3654
3655 finally:
3656 return CycleRefExists
3657
3658 if __name__ == "__main__":
3659 import sys
3660 try:
3661 test_file = sys.argv[1]
3662 except IndexError, v:
3663 print "Usage: %s filename" % sys.argv[0]
3664 sys.exit(1)
3665
3666 parser = FdfParser(test_file)
3667 try:
3668 parser.ParseFile()
3669 parser.CycleReferenceCheck()
3670 except Warning, X:
3671 print X.message
3672 else:
3673 print "Success!"
3674