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