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