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