BaseTools: Fixed metafile parser issues

https://bugzilla.tianocore.org/show_bug.cgi?id=1406
This patch is going to fix the regressions that
is introduced by commit 2f818ed0fb

The internal array for storing the metadata info should be cached
so that the meta file is parsed only once in one build.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
Feng, Bob C
2018-12-13 16:16:25 +08:00
committed by BobCF
parent 4c6e6f9f75
commit 643556fc48
4 changed files with 34 additions and 31 deletions

View File

@ -881,7 +881,7 @@ class DscBuildData(PlatformBuildClassObject):
return self._LibraryClasses return self._LibraryClasses
def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo): def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):
if self._DecPcds is None: if not self._DecPcds:
FdfInfList = [] FdfInfList = []
if GlobalData.gFdfParser: if GlobalData.gFdfParser:

View File

@ -206,9 +206,7 @@ class MetaFileParser(object):
## Set parsing complete flag in both class and table ## Set parsing complete flag in both class and table
def _Done(self): def _Done(self):
self._Finished = True self._Finished = True
## Do not set end flag when processing included files self._Table.SetEndFlag()
if self._From == -1:
self._Table.SetEndFlag()
def _PostProcess(self): def _PostProcess(self):
self._PostProcessed = True self._PostProcessed = True
@ -241,13 +239,7 @@ class MetaFileParser(object):
DataInfo = (DataInfo,) DataInfo = (DataInfo,)
# Parse the file first, if necessary # Parse the file first, if necessary
if not self._Finished: self.StartParse()
if self._RawTable.IsIntegrity():
self._Finished = True
else:
self._Table = self._RawTable
self._PostProcessed = False
self.Start()
# No specific ARCH or Platform given, use raw data # No specific ARCH or Platform given, use raw data
if self._RawTable and (len(DataInfo) == 1 or DataInfo[1] is None): if self._RawTable and (len(DataInfo) == 1 or DataInfo[1] is None):
@ -259,6 +251,14 @@ class MetaFileParser(object):
return self._FilterRecordList(self._Table.Query(*DataInfo), DataInfo[1]) return self._FilterRecordList(self._Table.Query(*DataInfo), DataInfo[1])
def StartParse(self):
if not self._Finished:
if self._RawTable.IsIntegrity():
self._Finished = True
else:
self._Table = self._RawTable
self._PostProcessed = False
self.Start()
## Data parser for the common format in different type of file ## Data parser for the common format in different type of file
# #
# The common format in the meatfile is like # The common format in the meatfile is like
@ -917,6 +917,7 @@ class DscParser(MetaFileParser):
self._PcdCodeValue = "" self._PcdCodeValue = ""
self._PcdDataTypeCODE = False self._PcdDataTypeCODE = False
self._CurrentPcdName = "" self._CurrentPcdName = ""
self._Content = None
## Parser starter ## Parser starter
def Start(self): def Start(self):
@ -1645,9 +1646,7 @@ class DscParser(MetaFileParser):
Parser._Scope = self._Scope Parser._Scope = self._Scope
Parser._Enabled = self._Enabled Parser._Enabled = self._Enabled
# Parse the included file # Parse the included file
Parser.Start() Parser.StartParse()
# Insert all records in the table for the included file into dsc file table # Insert all records in the table for the included file into dsc file table
Records = IncludedFileTable.GetAll() Records = IncludedFileTable.GetAll()
if Records: if Records:

View File

@ -26,8 +26,8 @@ from Common.DataType import *
class MetaFileTable(): class MetaFileTable():
# TRICK: use file ID as the part before '.' # TRICK: use file ID as the part before '.'
_ID_STEP_ = 0.00000001 _ID_STEP_ = 1
_ID_MAX_ = 0.99999999 _ID_MAX_ = 99999999
## Constructor ## Constructor
def __init__(self, DB, MetaFile, FileType, Temporary, FromItem=None): def __init__(self, DB, MetaFile, FileType, Temporary, FromItem=None):
@ -35,8 +35,7 @@ class MetaFileTable():
self.TableName = "" self.TableName = ""
self.DB = DB self.DB = DB
self._NumpyTab = None self._NumpyTab = None
self.FileId = len(DB.TblFile)
self.ID = self.FileId
self.CurrentContent = [] self.CurrentContent = []
DB.TblFile.append([MetaFile.Name, DB.TblFile.append([MetaFile.Name,
MetaFile.Ext, MetaFile.Ext,
@ -45,6 +44,8 @@ class MetaFileTable():
FileType, FileType,
MetaFile.TimeStamp, MetaFile.TimeStamp,
FromItem]) FromItem])
self.FileId = len(DB.TblFile)
self.ID = self.FileId * 10**8
if Temporary: if Temporary:
self.TableName = "_%s_%s_%s" % (FileType, len(DB.TblFile), uuid.uuid4().hex) self.TableName = "_%s_%s_%s" % (FileType, len(DB.TblFile), uuid.uuid4().hex)
else: else:
@ -53,7 +54,10 @@ class MetaFileTable():
def IsIntegrity(self): def IsIntegrity(self):
try: try:
TimeStamp = self.MetaFile.TimeStamp TimeStamp = self.MetaFile.TimeStamp
Result = int(self.CurrentContent[-1][0]) < 0 if not self.CurrentContent:
Result = False
else:
Result = self.CurrentContent[-1][0] < 0
if not Result: if not Result:
# update the timestamp in database # update the timestamp in database
self.DB.SetFileTimeStamp(self.FileId, TimeStamp) self.DB.SetFileTimeStamp(self.FileId, TimeStamp)
@ -72,12 +76,10 @@ class MetaFileTable():
self.CurrentContent.append(self._DUMMY_) self.CurrentContent.append(self._DUMMY_)
def GetAll(self): def GetAll(self):
return [item for item in self.CurrentContent if item[0] > 0 ] return [item for item in self.CurrentContent if item[0] >= 0 ]
## Python class representation of table storing module data ## Python class representation of table storing module data
class ModuleTable(MetaFileTable): class ModuleTable(MetaFileTable):
_ID_STEP_ = 0.00000001
_ID_MAX_ = 0.99999999
_COLUMN_ = ''' _COLUMN_ = '''
ID REAL PRIMARY KEY, ID REAL PRIMARY KEY,
Model INTEGER NOT NULL, Model INTEGER NOT NULL,
@ -140,7 +142,6 @@ class ModuleTable(MetaFileTable):
self.CurrentContent.append(row) self.CurrentContent.append(row)
return self.ID return self.ID
## Query table ## Query table
# #
# @param Model: The Model of Record # @param Model: The Model of Record
@ -215,8 +216,6 @@ class PackageTable(MetaFileTable):
BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0): BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):
(Value1, Value2, Value3, Scope1, Scope2) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip()) (Value1, Value2, Value3, Scope1, Scope2) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip())
self.ID = self.ID + self._ID_STEP_ self.ID = self.ID + self._ID_STEP_
if self.ID >= (MODEL_FILE_INF + self._ID_MAX_):
self.ID = MODEL_FILE_INF + self._ID_STEP_
row = [ self.ID, row = [ self.ID,
Model, Model,
@ -290,6 +289,7 @@ class PackageTable(MetaFileTable):
ExtraData=oricomment, File=self.MetaFile, Line=LineNum) ExtraData=oricomment, File=self.MetaFile, Line=LineNum)
return set(), set(), set() return set(), set(), set()
return set(validateranges), set(validlists), set(expressions) return set(validateranges), set(validlists), set(expressions)
## Python class representation of table storing platform data ## Python class representation of table storing platform data
class PlatformTable(MetaFileTable): class PlatformTable(MetaFileTable):
_COLUMN_ = ''' _COLUMN_ = '''
@ -338,8 +338,6 @@ class PlatformTable(MetaFileTable):
FromItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=1): FromItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=1):
(Value1, Value2, Value3, Scope1, Scope2, Scope3) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip(), Scope3.strip()) (Value1, Value2, Value3, Scope1, Scope2, Scope3) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip(), Scope3.strip())
self.ID = self.ID + self._ID_STEP_ self.ID = self.ID + self._ID_STEP_
if self.ID >= (MODEL_FILE_INF + self._ID_MAX_):
self.ID = MODEL_FILE_INF + self._ID_STEP_
row = [ self.ID, row = [ self.ID,
Model, Model,
@ -414,10 +412,13 @@ class MetaFileStorage(object):
".dec" : MODEL_FILE_DEC, ".dec" : MODEL_FILE_DEC,
".dsc" : MODEL_FILE_DSC, ".dsc" : MODEL_FILE_DSC,
} }
_ObjectCache = {}
## Constructor ## Constructor
def __new__(Class, Cursor, MetaFile, FileType=None, Temporary=False, FromItem=None): def __new__(Class, Cursor, MetaFile, FileType=None, Temporary=False, FromItem=None):
# no type given, try to find one # no type given, try to find one
key = (MetaFile.Path, FileType,Temporary,FromItem)
if key in Class._ObjectCache:
return Class._ObjectCache[key]
if not FileType: if not FileType:
if MetaFile.Type in self._FILE_TYPE_: if MetaFile.Type in self._FILE_TYPE_:
FileType = Class._FILE_TYPE_[MetaFile.Type] FileType = Class._FILE_TYPE_[MetaFile.Type]
@ -433,5 +434,8 @@ class MetaFileStorage(object):
Args = Args + (FromItem,) Args = Args + (FromItem,)
# create the storage object and return it to caller # create the storage object and return it to caller
return Class._FILE_TABLE_[FileType](*Args) reval = Class._FILE_TABLE_[FileType](*Args)
if not Temporary:
Class._ObjectCache[key] = reval
return reval

View File

@ -163,10 +163,10 @@ class WorkspaceDatabase(object):
self.TransformObject = WorkspaceDatabase.TransformObjectFactory(self) self.TransformObject = WorkspaceDatabase.TransformObjectFactory(self)
def SetFileTimeStamp(self,FileId,TimeStamp): def SetFileTimeStamp(self,FileId,TimeStamp):
self.TblFile[FileId][6] = TimeStamp self.TblFile[FileId-1][6] = TimeStamp
def GetFileTimeStamp(self,FileId): def GetFileTimeStamp(self,FileId):
return self.TblFile[FileId][6] return self.TblFile[FileId-1][6]
## Summarize all packages in the database ## Summarize all packages in the database