2 # This file is used to define common parser functions for meta-data
4 # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
5 # SPDX-License-Identifier: BSD-2-Clause-Patent
8 from __future__
import absolute_import
9 import Common
.LongFilePathOs
as os
10 from CommonDataClass
.DataClass
import *
11 from Ecc
.EccToolError
import *
12 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
13 from Ecc
import EccGlobalData
15 ## Get the include path list for a source file
17 # 1. Find the source file belongs to which inf file
18 # 2. Find the inf's package
19 # 3. Return the include path list of the package
21 def GetIncludeListOfFile(WorkSpace
, Filepath
, Db
):
23 Filepath
= os
.path
.normpath(Filepath
)
25 select Value1, FullPath from Inf, File where Inf.Model = %s and Inf.BelongsToFile in(
26 select distinct B.BelongsToFile from File as A left join Inf as B
27 where A.ID = B.BelongsToFile and B.Model = %s and (A.Path || '%s' || B.Value1) = '%s')
28 and Inf.BelongsToFile = File.ID""" \
29 % (MODEL_META_DATA_PACKAGE
, MODEL_EFI_SOURCE_FILE
, '\\', Filepath
)
30 RecordSet
= Db
.TblFile
.Exec(SqlCommand
)
31 for Record
in RecordSet
:
32 DecFullPath
= os
.path
.normpath(mws
.join(WorkSpace
, Record
[0]))
33 InfFullPath
= os
.path
.normpath(mws
.join(WorkSpace
, Record
[1]))
34 (DecPath
, DecName
) = os
.path
.split(DecFullPath
)
35 (InfPath
, InfName
) = os
.path
.split(InfFullPath
)
36 SqlCommand
= """select Value1 from Dec where BelongsToFile =
37 (select ID from File where FullPath = '%s') and Model = %s""" \
38 % (DecFullPath
, MODEL_EFI_INCLUDE
)
39 NewRecordSet
= Db
.TblDec
.Exec(SqlCommand
)
40 if InfPath
not in IncludeList
:
41 IncludeList
.append(InfPath
)
42 for NewRecord
in NewRecordSet
:
43 IncludePath
= os
.path
.normpath(os
.path
.join(DecPath
, NewRecord
[0]))
44 if IncludePath
not in IncludeList
:
45 IncludeList
.append(IncludePath
)
51 # Search table file and find all specific type files
53 def GetFileList(FileModel
, Db
):
55 SqlCommand
= """select FullPath from File where Model = %s""" % str(FileModel
)
56 RecordSet
= Db
.TblFile
.Exec(SqlCommand
)
57 for Record
in RecordSet
:
58 FileList
.append(Record
[0])
64 # Search table file and find all small tables
66 def GetTableList(FileModelList
, Table
, Db
):
68 SqlCommand
= """select ID from File where Model in %s""" % str(FileModelList
)
69 RecordSet
= Db
.TblFile
.Exec(SqlCommand
)
70 for Record
in RecordSet
:
71 TableName
= Table
+ str(Record
[0])
72 TableList
.append(TableName
)
76 ## ParseHeaderCommentSection
78 # Parse Header comment section lines, extract Abstract, Description, Copyright
81 # @param CommentList: List of (Comment, LineNumber)
82 # @param FileName: FileName of the comment
84 def ParseHeaderCommentSection(CommentList
, FileName
= None):
91 STR_HEADER_COMMENT_START
= "@file"
94 # used to indicate the state of processing header comment section of dec,
97 HEADER_COMMENT_NOT_STARTED
= -1
98 HEADER_COMMENT_STARTED
= 0
99 HEADER_COMMENT_FILE
= 1
100 HEADER_COMMENT_ABSTRACT
= 2
101 HEADER_COMMENT_DESCRIPTION
= 3
102 HEADER_COMMENT_COPYRIGHT
= 4
103 HEADER_COMMENT_LICENSE
= 5
104 HEADER_COMMENT_END
= 6
106 # first find the last copyright line
109 HeaderCommentStage
= HEADER_COMMENT_NOT_STARTED
110 for Index
in range(len(CommentList
) - 1, 0, -1):
111 Line
= CommentList
[Index
][0]
112 if _IsCopyrightLine(Line
):
116 for Item
in CommentList
:
120 if not Line
.startswith('#') and Line
:
121 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FileName
122 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
123 for Result
in ResultSet
:
124 Msg
= 'Comment must start with #'
125 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
126 Comment
= CleanString2(Line
)[1]
127 Comment
= Comment
.strip()
129 # if there are blank lines between License or Description, keep them as they would be
130 # indication of different block; or in the position that Abstract should be, also keep it
131 # as it indicates that no abstract
133 if not Comment
and HeaderCommentStage
not in [HEADER_COMMENT_LICENSE
, \
134 HEADER_COMMENT_DESCRIPTION
, HEADER_COMMENT_ABSTRACT
]:
137 if HeaderCommentStage
== HEADER_COMMENT_NOT_STARTED
:
138 if Comment
.startswith(STR_HEADER_COMMENT_START
):
139 HeaderCommentStage
= HEADER_COMMENT_ABSTRACT
141 License
+= Comment
+ EndOfLine
143 if HeaderCommentStage
== HEADER_COMMENT_ABSTRACT
:
145 # in case there is no abstract and description
149 HeaderCommentStage
= HEADER_COMMENT_DESCRIPTION
150 elif _IsCopyrightLine(Comment
):
151 Copyright
+= Comment
+ EndOfLine
152 HeaderCommentStage
= HEADER_COMMENT_COPYRIGHT
154 Abstract
+= Comment
+ EndOfLine
155 HeaderCommentStage
= HEADER_COMMENT_DESCRIPTION
156 elif HeaderCommentStage
== HEADER_COMMENT_DESCRIPTION
:
158 # in case there is no description
160 if _IsCopyrightLine(Comment
):
161 Copyright
+= Comment
+ EndOfLine
162 HeaderCommentStage
= HEADER_COMMENT_COPYRIGHT
164 Description
+= Comment
+ EndOfLine
165 elif HeaderCommentStage
== HEADER_COMMENT_COPYRIGHT
:
166 if _IsCopyrightLine(Comment
):
167 Copyright
+= Comment
+ EndOfLine
170 # Contents after copyright line are license, those non-copyright lines in between
171 # copyright line will be discarded
176 License
+= Comment
+ EndOfLine
177 HeaderCommentStage
= HEADER_COMMENT_LICENSE
179 if not Comment
and not License
:
181 License
+= Comment
+ EndOfLine
183 if not Copyright
.strip():
184 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FileName
185 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
186 for Result
in ResultSet
:
187 Msg
= 'Header comment section must have copyright information'
188 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
190 if not License
.strip():
191 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FileName
192 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
193 for Result
in ResultSet
:
194 Msg
= 'Header comment section must have license information'
195 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
197 if not Abstract
.strip() or Abstract
.find('Component description file') > -1:
198 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FileName
199 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
200 for Result
in ResultSet
:
201 Msg
= 'Header comment section must have Abstract information.'
202 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
204 return Abstract
.strip(), Description
.strip(), Copyright
.strip(), License
.strip()
207 # check whether current line is copyright line, the criteria is whether there is case insensitive keyword "Copyright"
208 # followed by zero or more white space characters followed by a "(" character
210 # @param LineContent: the line need to be checked
211 # @return: True if current line is copyright line, False else
213 def _IsCopyrightLine (LineContent
):
214 LineContent
= LineContent
.upper()
217 ReIsCopyrightRe
= re
.compile(r
"""(^|\s)COPYRIGHT *\(""", re
.DOTALL
)
218 if ReIsCopyrightRe
.search(LineContent
):
226 # Split comments in a string
229 # @param Line: The string to be cleaned
230 # @param CommentCharacter: Comment char, used to ignore comment content,
231 # default is DataType.TAB_COMMENT_SPLIT
233 def CleanString2(Line
, CommentCharacter
='#', AllowCppStyleComment
=False):
239 # Replace EDK1's comment character
241 if AllowCppStyleComment
:
242 Line
= Line
.replace('//', CommentCharacter
)
244 # separate comments and statements
246 LineParts
= Line
.split(CommentCharacter
, 1)
248 # remove whitespace again
250 Line
= LineParts
[0].strip()
251 if len(LineParts
) > 1:
252 Comment
= LineParts
[1].strip()
254 # Remove prefixed and trailing comment characters
258 while Start
< End
and Comment
.startswith(CommentCharacter
, Start
, End
):
260 while End
>= 0 and Comment
.endswith(CommentCharacter
, Start
, End
):
262 Comment
= Comment
[Start
:End
]
263 Comment
= Comment
.strip()