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