mirror of https://github.com/acidanthera/audk.git
273 lines
11 KiB
Python
273 lines
11 KiB
Python
## @file
|
|
# This file is used to define common parser functions for meta-data
|
|
#
|
|
# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
|
|
# This program and the accompanying materials
|
|
# are licensed and made available under the terms and conditions of the BSD License
|
|
# which accompanies this distribution. The full text of the license may be found at
|
|
# http://opensource.org/licenses/bsd-license.php
|
|
#
|
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
#
|
|
|
|
import Common.LongFilePathOs as os
|
|
from CommonDataClass.DataClass import *
|
|
from EccToolError import *
|
|
from Common.MultipleWorkspace import MultipleWorkspace as mws
|
|
import EccGlobalData
|
|
import re
|
|
## Get the inlcude path list for a source file
|
|
#
|
|
# 1. Find the source file belongs to which inf file
|
|
# 2. Find the inf's package
|
|
# 3. Return the include path list of the package
|
|
#
|
|
def GetIncludeListOfFile(WorkSpace, Filepath, Db):
|
|
IncludeList = []
|
|
Filepath = os.path.normpath(Filepath)
|
|
SqlCommand = """
|
|
select Value1, FullPath from Inf, File where Inf.Model = %s and Inf.BelongsToFile in(
|
|
select distinct B.BelongsToFile from File as A left join Inf as B
|
|
where A.ID = B.BelongsToFile and B.Model = %s and (A.Path || '%s' || B.Value1) = '%s')
|
|
and Inf.BelongsToFile = File.ID""" \
|
|
% (MODEL_META_DATA_PACKAGE, MODEL_EFI_SOURCE_FILE, '\\', Filepath)
|
|
RecordSet = Db.TblFile.Exec(SqlCommand)
|
|
for Record in RecordSet:
|
|
DecFullPath = os.path.normpath(mws.join(WorkSpace, Record[0]))
|
|
InfFullPath = os.path.normpath(mws.join(WorkSpace, Record[1]))
|
|
(DecPath, DecName) = os.path.split(DecFullPath)
|
|
(InfPath, InfName) = os.path.split(InfFullPath)
|
|
SqlCommand = """select Value1 from Dec where BelongsToFile =
|
|
(select ID from File where FullPath = '%s') and Model = %s""" \
|
|
% (DecFullPath, MODEL_EFI_INCLUDE)
|
|
NewRecordSet = Db.TblDec.Exec(SqlCommand)
|
|
if InfPath not in IncludeList:
|
|
IncludeList.append(InfPath)
|
|
for NewRecord in NewRecordSet:
|
|
IncludePath = os.path.normpath(os.path.join(DecPath, NewRecord[0]))
|
|
if IncludePath not in IncludeList:
|
|
IncludeList.append(IncludePath)
|
|
|
|
return IncludeList
|
|
|
|
## Get the file list
|
|
#
|
|
# Search table file and find all specific type files
|
|
#
|
|
def GetFileList(FileModel, Db):
|
|
FileList = []
|
|
SqlCommand = """select FullPath from File where Model = %s""" % str(FileModel)
|
|
RecordSet = Db.TblFile.Exec(SqlCommand)
|
|
for Record in RecordSet:
|
|
FileList.append(Record[0])
|
|
|
|
return FileList
|
|
|
|
## Get the table list
|
|
#
|
|
# Search table file and find all small tables
|
|
#
|
|
def GetTableList(FileModelList, Table, Db):
|
|
TableList = []
|
|
SqlCommand = """select ID from File where Model in %s""" % str(FileModelList)
|
|
RecordSet = Db.TblFile.Exec(SqlCommand)
|
|
for Record in RecordSet:
|
|
TableName = Table + str(Record[0])
|
|
TableList.append(TableName)
|
|
|
|
return TableList
|
|
|
|
## ParseHeaderCommentSection
|
|
#
|
|
# Parse Header comment section lines, extract Abstract, Description, Copyright
|
|
# , License lines
|
|
#
|
|
# @param CommentList: List of (Comment, LineNumber)
|
|
# @param FileName: FileName of the comment
|
|
#
|
|
def ParseHeaderCommentSection(CommentList, FileName = None):
|
|
|
|
Abstract = ''
|
|
Description = ''
|
|
Copyright = ''
|
|
License = ''
|
|
EndOfLine = "\n"
|
|
STR_HEADER_COMMENT_START = "@file"
|
|
|
|
#
|
|
# used to indicate the state of processing header comment section of dec,
|
|
# inf files
|
|
#
|
|
HEADER_COMMENT_NOT_STARTED = -1
|
|
HEADER_COMMENT_STARTED = 0
|
|
HEADER_COMMENT_FILE = 1
|
|
HEADER_COMMENT_ABSTRACT = 2
|
|
HEADER_COMMENT_DESCRIPTION = 3
|
|
HEADER_COMMENT_COPYRIGHT = 4
|
|
HEADER_COMMENT_LICENSE = 5
|
|
HEADER_COMMENT_END = 6
|
|
#
|
|
# first find the last copyright line
|
|
#
|
|
Last = 0
|
|
HeaderCommentStage = HEADER_COMMENT_NOT_STARTED
|
|
for Index in xrange(len(CommentList)-1, 0, -1):
|
|
Line = CommentList[Index][0]
|
|
if _IsCopyrightLine(Line):
|
|
Last = Index
|
|
break
|
|
|
|
for Item in CommentList:
|
|
Line = Item[0]
|
|
LineNo = Item[1]
|
|
|
|
if not Line.startswith('#') and Line:
|
|
SqlStatement = """ select ID from File where FullPath like '%s'""" % FileName
|
|
ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)
|
|
for Result in ResultSet:
|
|
Msg = 'Comment must start with #'
|
|
EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])
|
|
Comment = CleanString2(Line)[1]
|
|
Comment = Comment.strip()
|
|
#
|
|
# if there are blank lines between License or Description, keep them as they would be
|
|
# indication of different block; or in the position that Abstract should be, also keep it
|
|
# as it indicates that no abstract
|
|
#
|
|
if not Comment and HeaderCommentStage not in [HEADER_COMMENT_LICENSE, \
|
|
HEADER_COMMENT_DESCRIPTION, HEADER_COMMENT_ABSTRACT]:
|
|
continue
|
|
|
|
if HeaderCommentStage == HEADER_COMMENT_NOT_STARTED:
|
|
if Comment.startswith(STR_HEADER_COMMENT_START):
|
|
HeaderCommentStage = HEADER_COMMENT_ABSTRACT
|
|
else:
|
|
License += Comment + EndOfLine
|
|
else:
|
|
if HeaderCommentStage == HEADER_COMMENT_ABSTRACT:
|
|
#
|
|
# in case there is no abstract and description
|
|
#
|
|
if not Comment:
|
|
Abstract = ''
|
|
HeaderCommentStage = HEADER_COMMENT_DESCRIPTION
|
|
elif _IsCopyrightLine(Comment):
|
|
Copyright += Comment + EndOfLine
|
|
HeaderCommentStage = HEADER_COMMENT_COPYRIGHT
|
|
else:
|
|
Abstract += Comment + EndOfLine
|
|
HeaderCommentStage = HEADER_COMMENT_DESCRIPTION
|
|
elif HeaderCommentStage == HEADER_COMMENT_DESCRIPTION:
|
|
#
|
|
# in case there is no description
|
|
#
|
|
if _IsCopyrightLine(Comment):
|
|
Copyright += Comment + EndOfLine
|
|
HeaderCommentStage = HEADER_COMMENT_COPYRIGHT
|
|
else:
|
|
Description += Comment + EndOfLine
|
|
elif HeaderCommentStage == HEADER_COMMENT_COPYRIGHT:
|
|
if _IsCopyrightLine(Comment):
|
|
Copyright += Comment + EndOfLine
|
|
else:
|
|
#
|
|
# Contents after copyright line are license, those non-copyright lines in between
|
|
# copyright line will be discarded
|
|
#
|
|
if LineNo > Last:
|
|
if License:
|
|
License += EndOfLine
|
|
License += Comment + EndOfLine
|
|
HeaderCommentStage = HEADER_COMMENT_LICENSE
|
|
else:
|
|
if not Comment and not License:
|
|
continue
|
|
License += Comment + EndOfLine
|
|
|
|
if not Copyright.strip():
|
|
SqlStatement = """ select ID from File where FullPath like '%s'""" % FileName
|
|
ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)
|
|
for Result in ResultSet:
|
|
Msg = 'Header comment section must have copyright information'
|
|
EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])
|
|
|
|
if not License.strip():
|
|
SqlStatement = """ select ID from File where FullPath like '%s'""" % FileName
|
|
ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)
|
|
for Result in ResultSet:
|
|
Msg = 'Header comment section must have license information'
|
|
EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])
|
|
|
|
if not Abstract.strip() or Abstract.find('Component description file') > -1:
|
|
SqlStatement = """ select ID from File where FullPath like '%s'""" % FileName
|
|
ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)
|
|
for Result in ResultSet:
|
|
Msg = 'Header comment section must have Abstract information.'
|
|
EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])
|
|
|
|
return Abstract.strip(), Description.strip(), Copyright.strip(), License.strip()
|
|
|
|
## _IsCopyrightLine
|
|
# check whether current line is copyright line, the criteria is whether there is case insensitive keyword "Copyright"
|
|
# followed by zero or more white space characters followed by a "(" character
|
|
#
|
|
# @param LineContent: the line need to be checked
|
|
# @return: True if current line is copyright line, False else
|
|
#
|
|
def _IsCopyrightLine (LineContent):
|
|
LineContent = LineContent.upper()
|
|
Result = False
|
|
|
|
ReIsCopyrightRe = re.compile(r"""(^|\s)COPYRIGHT *\(""", re.DOTALL)
|
|
if ReIsCopyrightRe.search(LineContent):
|
|
Result = True
|
|
|
|
return Result
|
|
|
|
|
|
## CleanString2
|
|
#
|
|
# Split comments in a string
|
|
# Remove spaces
|
|
#
|
|
# @param Line: The string to be cleaned
|
|
# @param CommentCharacter: Comment char, used to ignore comment content,
|
|
# default is DataType.TAB_COMMENT_SPLIT
|
|
#
|
|
def CleanString2(Line, CommentCharacter='#', AllowCppStyleComment=False):
|
|
#
|
|
# remove whitespace
|
|
#
|
|
Line = Line.strip()
|
|
#
|
|
# Replace EDK1's comment character
|
|
#
|
|
if AllowCppStyleComment:
|
|
Line = Line.replace('//', CommentCharacter)
|
|
#
|
|
# separate comments and statements
|
|
#
|
|
LineParts = Line.split(CommentCharacter, 1)
|
|
#
|
|
# remove whitespace again
|
|
#
|
|
Line = LineParts[0].strip()
|
|
if len(LineParts) > 1:
|
|
Comment = LineParts[1].strip()
|
|
#
|
|
# Remove prefixed and trailing comment characters
|
|
#
|
|
Start = 0
|
|
End = len(Comment)
|
|
while Start < End and Comment.startswith(CommentCharacter, Start, End):
|
|
Start += 1
|
|
while End >= 0 and Comment.endswith(CommentCharacter, Start, End):
|
|
End -= 1
|
|
Comment = Comment[Start:End]
|
|
Comment = Comment.strip()
|
|
else:
|
|
Comment = ''
|
|
|
|
return Line, Comment
|