1. Do not use tab characters 2. No trailing white space in one line 3. All files must end with CRLF Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Liming Gao <liming.gao@intel.com> Cc: Yonghong Zhu <yonghong.zhu@intel.com> Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
		
			
				
	
	
		
			273 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			273 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
## @file
 | 
						|
# This file is used to define common parser functions for meta-data
 | 
						|
#
 | 
						|
# Copyright (c) 2008 - 2018, 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
 |