summaryrefslogtreecommitdiff
path: root/BaseTools/Source/Python/UPT/Parser/DecParser.py
diff options
context:
space:
mode:
Diffstat (limited to 'BaseTools/Source/Python/UPT/Parser/DecParser.py')
-rw-r--r--BaseTools/Source/Python/UPT/Parser/DecParser.py1097
1 files changed, 0 insertions, 1097 deletions
diff --git a/BaseTools/Source/Python/UPT/Parser/DecParser.py b/BaseTools/Source/Python/UPT/Parser/DecParser.py
deleted file mode 100644
index 85b8a17fe4..0000000000
--- a/BaseTools/Source/Python/UPT/Parser/DecParser.py
+++ /dev/null
@@ -1,1097 +0,0 @@
-## @file
-# This file is used to parse DEC file. It will consumed by DecParser
-#
-# Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
-#
-# This program and the accompanying materials are licensed and made available
-# under the terms and conditions of the BSD License which accompanies this
-# distribution. The full text of the license may be found at
-# http://opensource.org/licenses/bsd-license.php
-#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-'''
-DecParser
-'''
-## Import modules
-#
-import Logger.Log as Logger
-from Logger.ToolError import FILE_PARSE_FAILURE
-from Logger.ToolError import FILE_OPEN_FAILURE
-from Logger import StringTable as ST
-from Logger.ToolError import FORMAT_INVALID
-
-import Library.DataType as DT
-from Library.ParserValidate import IsValidToken
-from Library.ParserValidate import IsValidPath
-from Library.ParserValidate import IsValidCFormatGuid
-from Library.ParserValidate import IsValidIdString
-from Library.ParserValidate import IsValidUserId
-from Library.ParserValidate import IsValidArch
-from Library.ParserValidate import IsValidWord
-from Library.ParserValidate import IsValidDecVersionVal
-from Parser.DecParserMisc import TOOL_NAME
-from Parser.DecParserMisc import CleanString
-from Parser.DecParserMisc import IsValidPcdDatum
-from Parser.DecParserMisc import ParserHelper
-from Parser.DecParserMisc import StripRoot
-from Parser.DecParserMisc import VERSION_PATTERN
-from Parser.DecParserMisc import CVAR_PATTERN
-from Parser.DecParserMisc import PCD_TOKEN_PATTERN
-from Parser.DecParserMisc import MACRO_PATTERN
-from Parser.DecParserMisc import FileContent
-from Object.Parser.DecObject import _DecComments
-from Object.Parser.DecObject import DecDefineObject
-from Object.Parser.DecObject import DecDefineItemObject
-from Object.Parser.DecObject import DecIncludeObject
-from Object.Parser.DecObject import DecIncludeItemObject
-from Object.Parser.DecObject import DecLibraryclassObject
-from Object.Parser.DecObject import DecLibraryclassItemObject
-from Object.Parser.DecObject import DecGuidObject
-from Object.Parser.DecObject import DecPpiObject
-from Object.Parser.DecObject import DecProtocolObject
-from Object.Parser.DecObject import DecGuidItemObject
-from Object.Parser.DecObject import DecUserExtensionObject
-from Object.Parser.DecObject import DecUserExtensionItemObject
-from Object.Parser.DecObject import DecPcdObject
-from Object.Parser.DecObject import DecPcdItemObject
-from Library.Misc import GuidStructureStringToGuidString
-from Library.Misc import CheckGuidRegFormat
-from Library.String import ReplaceMacro
-from Library.String import GetSplitValueList
-from Library.String import gMACRO_PATTERN
-from Library.String import ConvertSpecialChar
-from Library.CommentParsing import ParsePcdErrorCode
-
-##
-# _DecBase class for parsing
-#
-class _DecBase:
- def __init__(self, RawData):
- self._RawData = RawData
- self._ItemDict = {}
- self._LocalMacro = {}
- #
- # Data parsed by 'self' are saved to this object
- #
- self.ItemObject = None
-
- def GetDataObject(self):
- return self.ItemObject
-
- def GetLocalMacro(self):
- return self._LocalMacro
-
- ## BlockStart
- #
- # Called if a new section starts
- #
- def BlockStart(self):
- self._LocalMacro = {}
-
- ## _CheckReDefine
- #
- # @param Key: to be checked if multi-defined
- # @param Scope: Format: [[SectionName, Arch], ...].
- # If scope is none, use global scope
- #
- def _CheckReDefine(self, Key, Scope = None):
- if not Scope:
- Scope = self._RawData.CurrentScope
- return
-
- SecArch = []
- #
- # Copy scope to SecArch, avoid Scope be changed outside
- #
- SecArch[0:1] = Scope[:]
- if Key not in self._ItemDict:
- self._ItemDict[Key] = [[SecArch, self._RawData.LineIndex]]
- return
-
- for Value in self._ItemDict[Key]:
- for SubValue in Scope:
- #
- # If current is common section
- #
- if SubValue[-1] == 'COMMON':
- for Other in Value[0]:
- # Key in common cannot be redefined in other arches
- # [:-1] means stripping arch info
- if Other[:-1] == SubValue[:-1]:
- self._LoggerError(ST.ERR_DECPARSE_REDEFINE % (Key, Value[1]))
- return
- continue
- CommonScope = []
- CommonScope[0:1] = SubValue
- CommonScope[-1] = 'COMMON'
- #
- # Cannot be redefined if this key already defined in COMMON Or defined in same arch
- #
- if SubValue in Value[0] or CommonScope in Value[0]:
- self._LoggerError(ST.ERR_DECPARSE_REDEFINE % (Key, Value[1]))
- return
- self._ItemDict[Key].append([SecArch, self._RawData.LineIndex])
-
- ## CheckRequiredFields
- # Some sections need to check if some fields exist, define section for example
- # Derived class can re-implement, top parser will call this function after all parsing done
- #
- def CheckRequiredFields(self):
- if self._RawData:
- pass
- return True
-
- ## IsItemRequired
- # In DEC spec, sections must have at least one statement except user
- # extension.
- # For example: "[guids" [<attribs>] "]" <EOL> <statements>+
- # sub class can override this method to indicate if statement is a must.
- #
- def _IsStatementRequired(self):
- if self._RawData:
- pass
- return False
-
- def _LoggerError(self, ErrorString):
- Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
- Line = self._RawData.LineIndex,
- ExtraData=ErrorString + ST.ERR_DECPARSE_LINE % self._RawData.CurrentLine)
-
- def _ReplaceMacro(self, String):
- if gMACRO_PATTERN.findall(String):
- String = ReplaceMacro(String, self._LocalMacro, False,
- FileName = self._RawData.Filename,
- Line = ['', self._RawData.LineIndex])
- String = ReplaceMacro(String, self._RawData.Macros, False,
- FileName = self._RawData.Filename,
- Line = ['', self._RawData.LineIndex])
- MacroUsed = gMACRO_PATTERN.findall(String)
- if MacroUsed:
- Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE,
- File=self._RawData.Filename,
- Line = self._RawData.LineIndex,
- ExtraData = ST.ERR_DECPARSE_MACRO_RESOLVE % (str(MacroUsed), String))
- return String
-
- def _MacroParser(self, String):
- TokenList = GetSplitValueList(String, ' ', 1)
- if len(TokenList) < 2 or TokenList[1] == '':
- self._LoggerError(ST.ERR_DECPARSE_MACRO_PAIR)
-
- TokenList = GetSplitValueList(TokenList[1], DT.TAB_EQUAL_SPLIT, 1)
- if TokenList[0] == '':
- self._LoggerError(ST.ERR_DECPARSE_MACRO_NAME)
- elif not IsValidToken(MACRO_PATTERN, TokenList[0]):
- self._LoggerError(ST.ERR_DECPARSE_MACRO_NAME_UPPER % TokenList[0])
-
- if len(TokenList) == 1:
- self._LocalMacro[TokenList[0]] = ''
- else:
- self._LocalMacro[TokenList[0]] = self._ReplaceMacro(TokenList[1])
-
- ## _ParseItem
- #
- # Parse specified item, this function must be derived by subclass
- #
- def _ParseItem(self):
- if self._RawData:
- pass
- #
- # Should never be called
- #
- return None
-
-
- ## _TailCommentStrategy
- #
- # This function can be derived to parse tail comment
- # default is it will not consume any lines
- #
- # @param Comment: Comment of current line
- #
- def _TailCommentStrategy(self, Comment):
- if Comment:
- pass
- if self._RawData:
- pass
- return False
-
- ## _StopCurrentParsing
- #
- # Called in Parse if current parsing should be stopped when encounter some
- # keyword
- # Default is section start and end
- #
- # @param Line: Current line
- #
- def _StopCurrentParsing(self, Line):
- if self._RawData:
- pass
- return Line[0] == DT.TAB_SECTION_START and Line[-1] == DT.TAB_SECTION_END
-
- ## _TryBackSlash
- #
- # Split comment and DEC content, concatenate lines if end of char is '\'
- #
- # @param ProcessedLine: ProcessedLine line
- # @param ProcessedComments: ProcessedComments line
- #
- def _TryBackSlash(self, ProcessedLine, ProcessedComments):
- CatLine = ''
- Comment = ''
- Line = ProcessedLine
- CommentList = ProcessedComments
- while not self._RawData.IsEndOfFile():
- if Line == '':
- self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)
- break
-
- if Comment:
- CommentList.append((Comment, self._RawData.LineIndex))
- if Line[-1] != DT.TAB_SLASH:
- CatLine += Line
- break
- elif len(Line) < 2 or Line[-2] != ' ':
- self._LoggerError(ST.ERR_DECPARSE_BACKSLASH)
- else:
- CatLine += Line[:-1]
- Line, Comment = CleanString(self._RawData.GetNextLine())
- #
- # Reach end of content
- #
- if self._RawData.IsEndOfFile():
- if not CatLine:
- if ProcessedLine[-1] == DT.TAB_SLASH:
- self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)
- CatLine = ProcessedLine
- else:
- if not Line or Line[-1] == DT.TAB_SLASH:
- self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)
- CatLine += Line
-
- #
- # All MACRO values defined by the DEFINE statements in any section
- # (except [Userextensions] sections for Intel) of the INF or DEC file
- # must be expanded before processing of the file.
- #
- __IsReplaceMacro = True
- Header = self._RawData.CurrentScope[0] if self._RawData.CurrentScope else None
- if Header and len(Header) > 2:
- if Header[0].upper() == 'USEREXTENSIONS' and not (Header[1] == 'TianoCore' and Header[2] == '"ExtraFiles"'):
- __IsReplaceMacro = False
- if __IsReplaceMacro:
- self._RawData.CurrentLine = self._ReplaceMacro(CatLine)
- else:
- self._RawData.CurrentLine = CatLine
-
- return CatLine, CommentList
-
- ## Parse
- # This is a template method in which other member functions which might
- # override by sub class are called. It is responsible for reading file
- # line by line, and call other member functions to parse. This function
- # should not be re-implement by sub class.
- #
- def Parse(self):
- HeadComments = []
- TailComments = []
-
- #======================================================================
- # CurComments may pointer to HeadComments or TailComments
- #======================================================================
- CurComments = HeadComments
- CurObj = None
- ItemNum = 0
- FromBuf = False
-
- #======================================================================
- # Used to report error information if empty section found
- #======================================================================
- Index = self._RawData.LineIndex
- LineStr = self._RawData.CurrentLine
- while not self._RawData.IsEndOfFile() or self._RawData.NextLine:
- if self._RawData.NextLine:
- #==============================================================
- # Have processed line in buffer
- #==============================================================
- Line = self._RawData.NextLine
- HeadComments.extend(self._RawData.HeadComment)
- TailComments.extend(self._RawData.TailComment)
- self._RawData.ResetNext()
- Comment = ''
- FromBuf = True
- else:
- #==============================================================
- # No line in buffer, read next line
- #==============================================================
- Line, Comment = CleanString(self._RawData.GetNextLine())
- FromBuf = False
- if Line:
- if not FromBuf and CurObj and TailComments:
- #==========================================================
- # Set tail comments to previous statement if not empty.
- #==========================================================
- CurObj.SetTailComment(CurObj.GetTailComment()+TailComments)
-
- if not FromBuf:
- del TailComments[:]
- CurComments = TailComments
- Comments = []
- if Comment:
- Comments = [(Comment, self._RawData.LineIndex)]
-
- #==============================================================
- # Try if last char of line has backslash
- #==============================================================
- Line, Comments = self._TryBackSlash(Line, Comments)
- CurComments.extend(Comments)
-
- #==============================================================
- # Macro found
- #==============================================================
- if Line.startswith('DEFINE '):
- self._MacroParser(Line)
- del HeadComments[:]
- del TailComments[:]
- CurComments = HeadComments
- continue
-
- if self._StopCurrentParsing(Line):
- #==========================================================
- # This line does not belong to this parse,
- # Save it, can be used by next parse
- #==========================================================
- self._RawData.SetNext(Line, HeadComments, TailComments)
- break
-
- Obj = self._ParseItem()
- ItemNum += 1
- if Obj:
- Obj.SetHeadComment(Obj.GetHeadComment()+HeadComments)
- Obj.SetTailComment(Obj.GetTailComment()+TailComments)
- del HeadComments[:]
- del TailComments[:]
- CurObj = Obj
- else:
- CurObj = None
- else:
- if id(CurComments) == id(TailComments):
- #==========================================================
- # Check if this comment belongs to tail comment
- #==========================================================
- if not self._TailCommentStrategy(Comment):
- CurComments = HeadComments
-
- if Comment:
- CurComments.append(((Comment, self._RawData.LineIndex)))
- else:
- del CurComments[:]
-
- if self._IsStatementRequired() and ItemNum == 0:
- Logger.Error(
- TOOL_NAME, FILE_PARSE_FAILURE,
- File=self._RawData.Filename,
- Line=Index,
- ExtraData=ST.ERR_DECPARSE_STATEMENT_EMPTY % LineStr
- )
-
-## _DecDefine
-# Parse define section
-#
-class _DecDefine(_DecBase):
- def __init__(self, RawData):
- _DecBase.__init__(self, RawData)
- self.ItemObject = DecDefineObject(RawData.Filename)
- self._LocalMacro = self._RawData.Macros
- self._DefSecNum = 0
-
- #
- # Each field has a function to validate
- #
- self.DefineValidation = {
- DT.TAB_DEC_DEFINES_DEC_SPECIFICATION : self._SetDecSpecification,
- DT.TAB_DEC_DEFINES_PACKAGE_NAME : self._SetPackageName,
- DT.TAB_DEC_DEFINES_PACKAGE_GUID : self._SetPackageGuid,
- DT.TAB_DEC_DEFINES_PACKAGE_VERSION : self._SetPackageVersion,
- DT.TAB_DEC_DEFINES_PKG_UNI_FILE : self._SetPackageUni,
- }
-
- def BlockStart(self):
- self._DefSecNum += 1
- if self._DefSecNum > 1:
- self._LoggerError(ST.ERR_DECPARSE_DEFINE_MULTISEC)
-
- ## CheckRequiredFields
- #
- # Check required fields: DEC_SPECIFICATION, PACKAGE_NAME
- # PACKAGE_GUID, PACKAGE_VERSION
- #
- def CheckRequiredFields(self):
- Ret = False
- if self.ItemObject.GetPackageSpecification() == '':
- Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
- ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)
- elif self.ItemObject.GetPackageName() == '':
- Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
- ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)
- elif self.ItemObject.GetPackageGuid() == '':
- Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
- ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)
- elif self.ItemObject.GetPackageVersion() == '':
- Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
- ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)
- else:
- Ret = True
- return Ret
-
- def _ParseItem(self):
- Line = self._RawData.CurrentLine
- TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)
- if TokenList[0] == DT.TAB_DEC_DEFINES_PKG_UNI_FILE:
- self.DefineValidation[TokenList[0]](TokenList[1])
- elif len(TokenList) < 2:
- self._LoggerError(ST.ERR_DECPARSE_DEFINE_FORMAT)
- elif TokenList[0] not in self.DefineValidation:
- self._LoggerError(ST.ERR_DECPARSE_DEFINE_UNKNOWKEY % TokenList[0])
- else:
- self.DefineValidation[TokenList[0]](TokenList[1])
-
- DefineItem = DecDefineItemObject()
- DefineItem.Key = TokenList[0]
- DefineItem.Value = TokenList[1]
- self.ItemObject.AddItem(DefineItem, self._RawData.CurrentScope)
- return DefineItem
-
- def _SetDecSpecification(self, Token):
- if self.ItemObject.GetPackageSpecification():
- self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)
- if not IsValidToken('0[xX][0-9a-fA-F]{8}', Token):
- if not IsValidDecVersionVal(Token):
- self._LoggerError(ST.ERR_DECPARSE_DEFINE_SPEC)
- self.ItemObject.SetPackageSpecification(Token)
-
- def _SetPackageName(self, Token):
- if self.ItemObject.GetPackageName():
- self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)
- if not IsValidWord(Token):
- self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGNAME)
- self.ItemObject.SetPackageName(Token)
-
- def _SetPackageGuid(self, Token):
- if self.ItemObject.GetPackageGuid():
- self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)
- if not CheckGuidRegFormat(Token):
- self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGGUID)
- self.ItemObject.SetPackageGuid(Token)
-
- def _SetPackageVersion(self, Token):
- if self.ItemObject.GetPackageVersion():
- self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)
- if not IsValidToken(VERSION_PATTERN, Token):
- self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGVERSION)
- else:
- if not DT.TAB_SPLIT in Token:
- Token = Token + '.0'
- self.ItemObject.SetPackageVersion(Token)
-
- def _SetPackageUni(self, Token):
- if self.ItemObject.GetPackageUniFile():
- self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PKG_UNI_FILE)
- self.ItemObject.SetPackageUniFile(Token)
-
-## _DecInclude
-#
-# Parse include section
-#
-class _DecInclude(_DecBase):
- def __init__(self, RawData):
- _DecBase.__init__(self, RawData)
- self.ItemObject = DecIncludeObject(RawData.Filename)
-
- def _ParseItem(self):
- Line = self._RawData.CurrentLine
-
- if not IsValidPath(Line, self._RawData.PackagePath):
- self._LoggerError(ST.ERR_DECPARSE_INCLUDE % Line)
-
- Item = DecIncludeItemObject(StripRoot(self._RawData.PackagePath, Line), self._RawData.PackagePath)
- self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
- return Item
-
-## _DecLibraryclass
-#
-# Parse library class section
-#
-class _DecLibraryclass(_DecBase):
- def __init__(self, RawData):
- _DecBase.__init__(self, RawData)
- self.ItemObject = DecLibraryclassObject(RawData.Filename)
-
- def _ParseItem(self):
- Line = self._RawData.CurrentLine
- TokenList = GetSplitValueList(Line, DT.TAB_VALUE_SPLIT)
- if len(TokenList) != 2:
- self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_SPLIT)
- if TokenList[0] == '' or TokenList[1] == '':
- self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_EMPTY)
- if not IsValidToken('[A-Z][0-9A-Za-z]*', TokenList[0]):
- self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_LIB)
-
- self._CheckReDefine(TokenList[0])
-
- Value = TokenList[1]
- #
- # Must end with .h
- #
- if not Value.endswith('.h'):
- self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_PATH_EXT)
-
- #
- # Path must be existed
- #
- if not IsValidPath(Value, self._RawData.PackagePath):
- self._LoggerError(ST.ERR_DECPARSE_INCLUDE % Value)
-
- Item = DecLibraryclassItemObject(TokenList[0], StripRoot(self._RawData.PackagePath, Value),
- self._RawData.PackagePath)
- self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
- return Item
-
-## _DecPcd
-#
-# Parse PCD section
-#
-class _DecPcd(_DecBase):
- def __init__(self, RawData):
- _DecBase.__init__(self, RawData)
- self.ItemObject = DecPcdObject(RawData.Filename)
- #
- # Used to check duplicate token
- # Key is token space and token number (integer), value is C name
- #
- self.TokenMap = {}
-
- def _ParseItem(self):
- Line = self._RawData.CurrentLine
- TokenList = Line.split(DT.TAB_VALUE_SPLIT)
- if len(TokenList) < 4:
- self._LoggerError(ST.ERR_DECPARSE_PCD_SPLIT)
-
- #
- # Token space guid C name
- #
- PcdName = GetSplitValueList(TokenList[0], DT.TAB_SPLIT)
- if len(PcdName) != 2 or PcdName[0] == '' or PcdName[1] == '':
- self._LoggerError(ST.ERR_DECPARSE_PCD_NAME)
-
- Guid = PcdName[0]
- if not IsValidToken(CVAR_PATTERN, Guid):
- self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_GUID)
-
- #
- # PCD C name
- #
- CName = PcdName[1]
- if not IsValidToken(CVAR_PATTERN, CName):
- self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_PCDCNAME)
-
- self._CheckReDefine(Guid + DT.TAB_SPLIT + CName)
-
- #
- # Default value, may be C array, string or number
- #
- Data = DT.TAB_VALUE_SPLIT.join(TokenList[1:-2]).strip()
-
- #
- # PCD data type
- #
- DataType = TokenList[-2].strip()
- Valid, Cause = IsValidPcdDatum(DataType, Data)
- if not Valid:
- self._LoggerError(Cause)
- PcdType = self._RawData.CurrentScope[0][0]
- if PcdType == DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() and DataType != 'BOOLEAN':
- self._LoggerError(ST.ERR_DECPARSE_PCD_FEATUREFLAG)
- #
- # Token value is the last element in list.
- #
- Token = TokenList[-1].strip()
- if not IsValidToken(PCD_TOKEN_PATTERN, Token):
- self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN % Token)
- elif not Token.startswith('0x') and not Token.startswith('0X'):
- if long(Token) > 4294967295:
- self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_INT % Token)
- Token = hex(long(Token))[:-1]
-
- IntToken = long(Token, 0)
- if (Guid, IntToken) in self.TokenMap:
- if self.TokenMap[Guid, IntToken] != CName:
- self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_UNIQUE%(Token))
- else:
- self.TokenMap[Guid, IntToken] = CName
-
- Item = DecPcdItemObject(Guid, CName, Data, DataType, Token)
- self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
- return Item
-
-## _DecGuid
-#
-# Parse GUID, PPI, Protocol section
-#
-class _DecGuid(_DecBase):
- def __init__(self, RawData):
- _DecBase.__init__(self, RawData)
- self.GuidObj = DecGuidObject(RawData.Filename)
- self.PpiObj = DecPpiObject(RawData.Filename)
- self.ProtocolObj = DecProtocolObject(RawData.Filename)
- self.ObjectDict = \
- {
- DT.TAB_GUIDS.upper() : self.GuidObj,
- DT.TAB_PPIS.upper() : self.PpiObj,
- DT.TAB_PROTOCOLS.upper() : self.ProtocolObj
- }
-
- def GetDataObject(self):
- if self._RawData.CurrentScope:
- return self.ObjectDict[self._RawData.CurrentScope[0][0]]
- return None
-
- def GetGuidObject(self):
- return self.GuidObj
-
- def GetPpiObject(self):
- return self.PpiObj
-
- def GetProtocolObject(self):
- return self.ProtocolObj
-
- def _ParseItem(self):
- Line = self._RawData.CurrentLine
- TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)
- if len(TokenList) < 2:
- self._LoggerError(ST.ERR_DECPARSE_CGUID)
- if TokenList[0] == '':
- self._LoggerError(ST.ERR_DECPARSE_CGUID_NAME)
- if TokenList[1] == '':
- self._LoggerError(ST.ERR_DECPARSE_CGUID_GUID)
- if not IsValidToken(CVAR_PATTERN, TokenList[0]):
- self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_GUID)
-
- self._CheckReDefine(TokenList[0])
-
- if TokenList[1][0] != '{':
- if not CheckGuidRegFormat(TokenList[1]):
- self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGGUID)
- GuidString = TokenList[1]
- else:
- #
- # Convert C format GUID to GUID string and Simple error check
- #
- GuidString = GuidStructureStringToGuidString(TokenList[1])
- if TokenList[1][0] != '{' or TokenList[1][-1] != '}' or GuidString == '':
- self._LoggerError(ST.ERR_DECPARSE_CGUID_GUIDFORMAT)
-
- #
- # Check C format GUID
- #
- if not IsValidCFormatGuid(TokenList[1]):
- self._LoggerError(ST.ERR_DECPARSE_CGUID_GUIDFORMAT)
-
- Item = DecGuidItemObject(TokenList[0], TokenList[1], GuidString)
- ItemObject = self.ObjectDict[self._RawData.CurrentScope[0][0]]
- ItemObject.AddItem(Item, self._RawData.CurrentScope)
- return Item
-
-## _DecUserExtension
-#
-# Parse user extention section
-#
-class _DecUserExtension(_DecBase):
- def __init__(self, RawData):
- _DecBase.__init__(self, RawData)
- self.ItemObject = DecUserExtensionObject(RawData.Filename)
- self._Headers = []
- self._CurItems = []
-
- def BlockStart(self):
- self._CurItems = []
- for Header in self._RawData.CurrentScope:
- if Header in self._Headers:
- self._LoggerError(ST.ERR_DECPARSE_UE_DUPLICATE)
- else:
- self._Headers.append(Header)
-
- for Item in self._CurItems:
- if Item.UserId == Header[1] and Item.IdString == Header[2]:
- Item.ArchAndModuleType.append(Header[3])
- break
- else:
- Item = DecUserExtensionItemObject()
- Item.UserId = Header[1]
- Item.IdString = Header[2]
- Item.ArchAndModuleType.append(Header[3])
- self._CurItems.append(Item)
- self.ItemObject.AddItem(Item, None)
- self._LocalMacro = {}
-
- def _ParseItem(self):
- Line = self._RawData.CurrentLine
- Item = None
- for Item in self._CurItems:
- if Item.UserString:
- Item.UserString = '\n'.join([Item.UserString, Line])
- else:
- Item.UserString = Line
- return Item
-
-## Dec
-#
-# Top dec parser
-#
-class Dec(_DecBase, _DecComments):
- def __init__(self, DecFile, Parse = True):
- try:
- Content = ConvertSpecialChar(open(DecFile, 'rb').readlines())
- except BaseException:
- Logger.Error(TOOL_NAME, FILE_OPEN_FAILURE, File=DecFile,
- ExtraData=ST.ERR_DECPARSE_FILEOPEN % DecFile)
-
- #
- # Pre-parser for Private section
- #
- self._Private = ''
- __IsFoundPrivate = False
- NewContent = []
- for Line in Content:
- Line = Line.strip()
- if Line.startswith(DT.TAB_SECTION_START) and Line.endswith(DT.TAB_PRIVATE + DT.TAB_SECTION_END):
- __IsFoundPrivate = True
- if Line.startswith(DT.TAB_SECTION_START) and Line.endswith(DT.TAB_SECTION_END)\
- and not Line.endswith(DT.TAB_PRIVATE + DT.TAB_SECTION_END):
- __IsFoundPrivate = False
- if __IsFoundPrivate:
- self._Private += Line + '\r'
- if not __IsFoundPrivate:
- NewContent.append(Line + '\r')
-
- RawData = FileContent(DecFile, NewContent)
-
- _DecComments.__init__(self)
- _DecBase.__init__(self, RawData)
-
- self.BinaryHeadComment = []
- self.PcdErrorCommentDict = {}
-
- self._Define = _DecDefine(RawData)
- self._Include = _DecInclude(RawData)
- self._Guid = _DecGuid(RawData)
- self._LibClass = _DecLibraryclass(RawData)
- self._Pcd = _DecPcd(RawData)
- self._UserEx = _DecUserExtension(RawData)
-
- #
- # DEC file supported data types (one type per section)
- #
- self._SectionParser = {
- DT.TAB_DEC_DEFINES.upper() : self._Define,
- DT.TAB_INCLUDES.upper() : self._Include,
- DT.TAB_LIBRARY_CLASSES.upper() : self._LibClass,
- DT.TAB_GUIDS.upper() : self._Guid,
- DT.TAB_PPIS.upper() : self._Guid,
- DT.TAB_PROTOCOLS.upper() : self._Guid,
- DT.TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : self._Pcd,
- DT.TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : self._Pcd,
- DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() : self._Pcd,
- DT.TAB_PCDS_DYNAMIC_NULL.upper() : self._Pcd,
- DT.TAB_PCDS_DYNAMIC_EX_NULL.upper() : self._Pcd,
- DT.TAB_USER_EXTENSIONS.upper() : self._UserEx
- }
-
- if Parse:
- self.ParseDecComment()
- self.Parse()
- #
- # Parsing done, check required fields
- #
- self.CheckRequiredFields()
-
- def CheckRequiredFields(self):
- for SectionParser in self._SectionParser.values():
- if not SectionParser.CheckRequiredFields():
- return False
- return True
-
- ##
- # Parse DEC file
- #
- def ParseDecComment(self):
- IsFileHeader = False
- IsBinaryHeader = False
- FileHeaderLineIndex = -1
- BinaryHeaderLineIndex = -1
- TokenSpaceGuidCName = ''
-
- #
- # Parse PCD error comment section
- #
- while not self._RawData.IsEndOfFile():
- self._RawData.CurrentLine = self._RawData.GetNextLine()
- if self._RawData.CurrentLine.startswith(DT.TAB_COMMENT_SPLIT) and \
- DT.TAB_SECTION_START in self._RawData.CurrentLine and \
- DT.TAB_SECTION_END in self._RawData.CurrentLine:
- self._RawData.CurrentLine = self._RawData.CurrentLine.replace(DT.TAB_COMMENT_SPLIT, '').strip()
-
- if self._RawData.CurrentLine[0] == DT.TAB_SECTION_START and \
- self._RawData.CurrentLine[-1] == DT.TAB_SECTION_END:
- RawSection = self._RawData.CurrentLine[1:-1].strip()
- if RawSection.upper().startswith(DT.TAB_PCD_ERROR.upper()+'.'):
- TokenSpaceGuidCName = RawSection.split(DT.TAB_PCD_ERROR+'.')[1].strip()
- continue
-
- if TokenSpaceGuidCName and self._RawData.CurrentLine.startswith(DT.TAB_COMMENT_SPLIT):
- self._RawData.CurrentLine = self._RawData.CurrentLine.replace(DT.TAB_COMMENT_SPLIT, '').strip()
- if self._RawData.CurrentLine != '':
- if DT.TAB_VALUE_SPLIT not in self._RawData.CurrentLine:
- self._LoggerError(ST.ERR_DECPARSE_PCDERRORMSG_MISS_VALUE_SPLIT)
-
- PcdErrorNumber, PcdErrorMsg = GetSplitValueList(self._RawData.CurrentLine, DT.TAB_VALUE_SPLIT, 1)
- PcdErrorNumber = ParsePcdErrorCode(PcdErrorNumber, self._RawData.Filename, self._RawData.LineIndex)
- if not PcdErrorMsg.strip():
- self._LoggerError(ST.ERR_DECPARSE_PCD_MISS_ERRORMSG)
-
- self.PcdErrorCommentDict[(TokenSpaceGuidCName, PcdErrorNumber)] = PcdErrorMsg.strip()
- else:
- TokenSpaceGuidCName = ''
-
- self._RawData.LineIndex = 0
- self._RawData.CurrentLine = ''
- self._RawData.NextLine = ''
-
- while not self._RawData.IsEndOfFile():
- Line, Comment = CleanString(self._RawData.GetNextLine())
-
- #
- # Header must be pure comment
- #
- if Line != '':
- self._RawData.UndoNextLine()
- break
-
- if Comment and Comment.startswith(DT.TAB_SPECIAL_COMMENT) and Comment.find(DT.TAB_HEADER_COMMENT) > 0 \
- and not Comment[2:Comment.find(DT.TAB_HEADER_COMMENT)].strip():
- IsFileHeader = True
- IsBinaryHeader = False
- FileHeaderLineIndex = self._RawData.LineIndex
-
- #
- # Get license information before '@file'
- #
- if not IsFileHeader and not IsBinaryHeader and Comment and Comment.startswith(DT.TAB_COMMENT_SPLIT) and \
- DT.TAB_BINARY_HEADER_COMMENT not in Comment:
- self._HeadComment.append((Comment, self._RawData.LineIndex))
-
- if Comment and IsFileHeader and \
- not(Comment.startswith(DT.TAB_SPECIAL_COMMENT) \
- and Comment.find(DT.TAB_BINARY_HEADER_COMMENT) > 0):
- self._HeadComment.append((Comment, self._RawData.LineIndex))
- #
- # Double '#' indicates end of header comments
- #
- if (not Comment or Comment == DT.TAB_SPECIAL_COMMENT) and IsFileHeader:
- IsFileHeader = False
- continue
-
- if Comment and Comment.startswith(DT.TAB_SPECIAL_COMMENT) \
- and Comment.find(DT.TAB_BINARY_HEADER_COMMENT) > 0:
- IsBinaryHeader = True
- IsFileHeader = False
- BinaryHeaderLineIndex = self._RawData.LineIndex
-
- if Comment and IsBinaryHeader:
- self.BinaryHeadComment.append((Comment, self._RawData.LineIndex))
- #
- # Double '#' indicates end of header comments
- #
- if (not Comment or Comment == DT.TAB_SPECIAL_COMMENT) and IsBinaryHeader:
- IsBinaryHeader = False
- break
-
- if FileHeaderLineIndex > -1 and not IsFileHeader and not IsBinaryHeader:
- break
-
- if FileHeaderLineIndex > BinaryHeaderLineIndex and FileHeaderLineIndex > -1 and BinaryHeaderLineIndex > -1:
- self._LoggerError(ST.ERR_BINARY_HEADER_ORDER)
-
- if FileHeaderLineIndex == -1:
-# self._LoggerError(ST.ERR_NO_SOURCE_HEADER)
- Logger.Error(TOOL_NAME, FORMAT_INVALID,
- ST.ERR_NO_SOURCE_HEADER,
- File=self._RawData.Filename)
- return
-
- def _StopCurrentParsing(self, Line):
- return False
-
- def _ParseItem(self):
- self._SectionHeaderParser()
- if len(self._RawData.CurrentScope) == 0:
- self._LoggerError(ST.ERR_DECPARSE_SECTION_EMPTY)
- SectionObj = self._SectionParser[self._RawData.CurrentScope[0][0]]
- SectionObj.BlockStart()
- SectionObj.Parse()
- return SectionObj.GetDataObject()
-
- def _UserExtentionSectionParser(self):
- self._RawData.CurrentScope = []
- ArchList = set()
- Section = self._RawData.CurrentLine[1:-1]
- Par = ParserHelper(Section, self._RawData.Filename)
- while not Par.End():
- #
- # User extention
- #
- Token = Par.GetToken()
- if Token.upper() != DT.TAB_USER_EXTENSIONS.upper():
- self._LoggerError(ST.ERR_DECPARSE_SECTION_UE)
- UserExtension = Token.upper()
- Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)
-
- #
- # UserID
- #
- Token = Par.GetToken()
- if not IsValidUserId(Token):
- self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_USERID)
- UserId = Token
- Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)
- #
- # IdString
- #
- Token = Par.GetToken()
- if not IsValidIdString(Token):
- self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_IDSTRING)
- IdString = Token
- Arch = 'COMMON'
- if Par.Expect(DT.TAB_SPLIT):
- Token = Par.GetToken()
- Arch = Token.upper()
- if not IsValidArch(Arch):
- self._LoggerError(ST.ERR_DECPARSE_ARCH)
- ArchList.add(Arch)
- if [UserExtension, UserId, IdString, Arch] not in \
- self._RawData.CurrentScope:
- self._RawData.CurrentScope.append(
- [UserExtension, UserId, IdString, Arch]
- )
- if not Par.Expect(DT.TAB_COMMA_SPLIT):
- break
- elif Par.End():
- self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMA)
- Par.AssertEnd(ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)
- if 'COMMON' in ArchList and len(ArchList) > 1:
- self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON)
-
- ## Section header parser
- #
- # The section header is always in following format:
- #
- # [section_name.arch<.platform|module_type>]
- #
- def _SectionHeaderParser(self):
- if self._RawData.CurrentLine[0] != DT.TAB_SECTION_START or self._RawData.CurrentLine[-1] != DT.TAB_SECTION_END:
- self._LoggerError(ST.ERR_DECPARSE_SECTION_IDENTIFY)
-
- RawSection = self._RawData.CurrentLine[1:-1].strip().upper()
- #
- # Check defines section which is only allowed to occur once and
- # no arch can be followed
- #
- if RawSection.startswith(DT.TAB_DEC_DEFINES.upper()):
- if RawSection != DT.TAB_DEC_DEFINES.upper():
- self._LoggerError(ST.ERR_DECPARSE_DEFINE_SECNAME)
- #
- # Check user extension section
- #
- if RawSection.startswith(DT.TAB_USER_EXTENSIONS.upper()):
- return self._UserExtentionSectionParser()
- self._RawData.CurrentScope = []
- SectionNames = []
- ArchList = set()
- for Item in GetSplitValueList(RawSection, DT.TAB_COMMA_SPLIT):
- if Item == '':
- self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)
-
- ItemList = GetSplitValueList(Item, DT.TAB_SPLIT)
- #
- # different types of PCD are permissible in one section
- #
- SectionName = ItemList[0]
- if SectionName not in self._SectionParser:
- self._LoggerError(ST.ERR_DECPARSE_SECTION_UNKNOW % SectionName)
- if SectionName not in SectionNames:
- SectionNames.append(SectionName)
- #
- # In DEC specification, all section headers have at most two part:
- # SectionName.Arch except UserExtention
- #
- if len(ItemList) > 2:
- self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBTOOMANY % Item)
-
- if DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() in SectionNames and len(SectionNames) > 1:
- self._LoggerError(ST.ERR_DECPARSE_SECTION_FEATUREFLAG % DT.TAB_PCDS_FEATURE_FLAG_NULL)
- #
- # S1 is always Arch
- #
- if len(ItemList) > 1:
- Str1 = ItemList[1]
- if not IsValidArch(Str1):
- self._LoggerError(ST.ERR_DECPARSE_ARCH)
- else:
- Str1 = 'COMMON'
- ArchList.add(Str1)
-
- if [SectionName, Str1] not in self._RawData.CurrentScope:
- self._RawData.CurrentScope.append([SectionName, Str1])
- #
- # 'COMMON' must not be used with specific ARCHs at the same section
- #
- if 'COMMON' in ArchList and len(ArchList) > 1:
- self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON)
- if len(SectionNames) == 0:
- self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)
- if len(SectionNames) != 1:
- for Sec in SectionNames:
- if not Sec.startswith(DT.TAB_PCDS.upper()):
- self._LoggerError(ST.ERR_DECPARSE_SECTION_NAME % str(SectionNames))
-
- def GetDefineSectionMacro(self):
- return self._Define.GetLocalMacro()
- def GetDefineSectionObject(self):
- return self._Define.GetDataObject()
- def GetIncludeSectionObject(self):
- return self._Include.GetDataObject()
- def GetGuidSectionObject(self):
- return self._Guid.GetGuidObject()
- def GetProtocolSectionObject(self):
- return self._Guid.GetProtocolObject()
- def GetPpiSectionObject(self):
- return self._Guid.GetPpiObject()
- def GetLibraryClassSectionObject(self):
- return self._LibClass.GetDataObject()
- def GetPcdSectionObject(self):
- return self._Pcd.GetDataObject()
- def GetUserExtensionSectionObject(self):
- return self._UserEx.GetDataObject()
- def GetPackageSpecification(self):
- return self._Define.GetDataObject().GetPackageSpecification()
- def GetPackageName(self):
- return self._Define.GetDataObject().GetPackageName()
- def GetPackageGuid(self):
- return self._Define.GetDataObject().GetPackageGuid()
- def GetPackageVersion(self):
- return self._Define.GetDataObject().GetPackageVersion()
- def GetPackageUniFile(self):
- return self._Define.GetDataObject().GetPackageUniFile()
- def GetPrivateSections(self):
- return self._Private