X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FUPT%2FParser%2FDecParser.py;h=f7eeb84127e1742710bbfd64744738229694d5e7;hb=174a9d3cc8f74f7a731ac5f16ce6864c8eb359ec;hp=823cf71e5e7f2aa3173fff9f7495d71abbf6878c;hpb=4234283c3acb8c35014acc1546621fbc2621b095;p=mirror_edk2.git diff --git a/BaseTools/Source/Python/UPT/Parser/DecParser.py b/BaseTools/Source/Python/UPT/Parser/DecParser.py index 823cf71e5e..f7eeb84127 100644 --- a/BaseTools/Source/Python/UPT/Parser/DecParser.py +++ b/BaseTools/Source/Python/UPT/Parser/DecParser.py @@ -1,11 +1,11 @@ ## @file # This file is used to parse DEC file. It will consumed by DecParser # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
# -# 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 +# 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, @@ -19,6 +19,7 @@ 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 @@ -28,6 +29,7 @@ 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 @@ -55,10 +57,11 @@ 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.StringUtils import ReplaceMacro +from Library.StringUtils import GetSplitValueList +from Library.StringUtils import gMACRO_PATTERN +from Library.StringUtils import ConvertSpecialChar +from Library.CommentParsing import ParsePcdErrorCode ## # _DecBase class for parsing @@ -72,28 +75,31 @@ class _DecBase: # 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], ...]. + # @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 @@ -102,7 +108,7 @@ class _DecBase: if Key not in self._ItemDict: self._ItemDict[Key] = [[SecArch, self._RawData.LineIndex]] return - + for Value in self._ItemDict[Key]: for SubValue in Scope: # @@ -126,18 +132,18 @@ class _DecBase: 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 + # In DEC spec, sections must have at least one statement except user # extension. # For example: "[guids" [] "]" + # sub class can override this method to indicate if statement is a must. @@ -146,12 +152,12 @@ class _DecBase: if self._RawData: pass return False - + def _LoggerError(self, ErrorString): - Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename, + 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, @@ -163,11 +169,11 @@ class _DecBase: MacroUsed = gMACRO_PATTERN.findall(String) if MacroUsed: Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, - File=self._RawData.Filename, + 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] == '': @@ -178,12 +184,12 @@ class _DecBase: 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 @@ -196,7 +202,7 @@ class _DecBase: # return None - + ## _TailCommentStrategy # # This function can be derived to parse tail comment @@ -210,7 +216,7 @@ class _DecBase: if self._RawData: pass return False - + ## _StopCurrentParsing # # Called in Parse if current parsing should be stopped when encounter some @@ -223,7 +229,7 @@ class _DecBase: 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 '\' @@ -240,7 +246,7 @@ class _DecBase: if Line == '': self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY) break - + if Comment: CommentList.append((Comment, self._RawData.LineIndex)) if Line[-1] != DT.TAB_SLASH: @@ -263,20 +269,34 @@ class _DecBase: if not Line or Line[-1] == DT.TAB_SLASH: self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY) CatLine += Line - - self._RawData.CurrentLine = self._ReplaceMacro(CatLine) + + # + # 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 + # 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 #====================================================================== @@ -284,7 +304,7 @@ class _DecBase: CurObj = None ItemNum = 0 FromBuf = False - + #====================================================================== # Used to report error information if empty section found #====================================================================== @@ -313,20 +333,20 @@ class _DecBase: # 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 #============================================================== @@ -336,7 +356,7 @@ class _DecBase: del TailComments[:] CurComments = HeadComments continue - + if self._StopCurrentParsing(Line): #========================================================== # This line does not belong to this parse, @@ -344,7 +364,7 @@ class _DecBase: #========================================================== self._RawData.SetNext(Line, HeadComments, TailComments) break - + Obj = self._ParseItem() ItemNum += 1 if Obj: @@ -367,7 +387,7 @@ class _DecBase: CurComments.append(((Comment, self._RawData.LineIndex))) else: del CurComments[:] - + if self._IsStatementRequired() and ItemNum == 0: Logger.Error( TOOL_NAME, FILE_PARSE_FAILURE, @@ -385,7 +405,7 @@ class _DecDefine(_DecBase): self.ItemObject = DecDefineObject(RawData.Filename) self._LocalMacro = self._RawData.Macros self._DefSecNum = 0 - + # # Each field has a function to validate # @@ -394,13 +414,14 @@ class _DecDefine(_DecBase): 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 @@ -409,61 +430,61 @@ class _DecDefine(_DecBase): def CheckRequiredFields(self): Ret = False if self.ItemObject.GetPackageSpecification() == '': - Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename, + 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, + 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, + 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, + 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: - pass + 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() - if TokenList[0] != DT.TAB_DEC_DEFINES_PKG_UNI_FILE: - DefineItem.Key = TokenList[0] - DefineItem.Value = TokenList[1] - self.ItemObject.AddItem(DefineItem, self._RawData.CurrentScope) + 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): - self._LoggerError(ST.ERR_DECPARSE_DEFINE_SPEC) + 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) @@ -472,7 +493,12 @@ class _DecDefine(_DecBase): else: if not DT.TAB_SPLIT in Token: Token = Token + '.0' - self.ItemObject._PkgVersion = Token + 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 # @@ -482,13 +508,13 @@ 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) - + 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 @@ -501,32 +527,32 @@ 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) + 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) @@ -545,38 +571,38 @@ class _DecPcd(_DecBase): # 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 # @@ -594,21 +620,21 @@ class _DecPcd(_DecBase): 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: + if int(Token) > 4294967295: self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_INT % Token) - Token = hex(long(Token))[:-1] - - IntToken = long(Token, 0) + Token = '0x%x' % int(Token) + + IntToken = int(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 @@ -625,21 +651,21 @@ class _DecGuid(_DecBase): 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) @@ -651,9 +677,9 @@ class _DecGuid(_DecBase): 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) @@ -665,7 +691,7 @@ class _DecGuid(_DecBase): 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 # @@ -687,7 +713,7 @@ class _DecUserExtension(_DecBase): self.ItemObject = DecUserExtensionObject(RawData.Filename) self._Headers = [] self._CurItems = [] - + def BlockStart(self): self._CurItems = [] for Header in self._RawData.CurrentScope: @@ -695,7 +721,7 @@ class _DecUserExtension(_DecBase): 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]) @@ -708,7 +734,7 @@ class _DecUserExtension(_DecBase): self._CurItems.append(Item) self.ItemObject.AddItem(Item, None) self._LocalMacro = {} - + def _ParseItem(self): Line = self._RawData.CurrentLine Item = None @@ -723,25 +749,47 @@ class _DecUserExtension(_DecBase): # # Top dec parser # -class Dec(_DecBase, _DecComments): - def __init__(self, DecFile, Parse = True): +class Dec(_DecBase, _DecComments): + def __init__(self, DecFile, Parse = True): try: - Content = ConvertSpecialChar(open(DecFile, 'rb').readlines()) + Content = ConvertSpecialChar(open(DecFile, 'r').readlines()) except BaseException: Logger.Error(TOOL_NAME, FILE_OPEN_FAILURE, File=DecFile, ExtraData=ST.ERR_DECPARSE_FILEOPEN % DecFile) - RawData = FileContent(DecFile, Content) - + + # + # 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) # @@ -767,56 +815,137 @@ class Dec(_DecBase, _DecComments): # 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: + + 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: + 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(): # @@ -826,8 +955,8 @@ class Dec(_DecBase, _DecComments): 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 # @@ -835,7 +964,6 @@ class Dec(_DecBase, _DecComments): 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 @@ -844,7 +972,6 @@ class Dec(_DecBase, _DecComments): 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() @@ -852,23 +979,19 @@ class Dec(_DecBase, _DecComments): 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: @@ -878,9 +1001,8 @@ class Dec(_DecBase, _DecComments): 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 @@ -888,13 +1010,11 @@ class Dec(_DecBase, _DecComments): 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() @@ -903,17 +1023,14 @@ class Dec(_DecBase, _DecComments): 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 @@ -922,7 +1039,7 @@ class Dec(_DecBase, _DecComments): 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) + self._LoggerError(ST.ERR_DECPARSE_SECTION_FEATUREFLAG % DT.TAB_PCDS_FEATURE_FLAG_NULL) # # S1 is always Arch # @@ -941,49 +1058,40 @@ class Dec(_DecBase, _DecComments): # 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