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 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 from __future__
import absolute_import
15 import Common
.LongFilePathOs
as os
16 from CommonDataClass
.DataClass
import *
17 from Ecc
.EccToolError
import *
18 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
19 from Ecc
import EccGlobalData
21 ## Get the include path list for a source file
23 # 1. Find the source file belongs to which inf file
24 # 2. Find the inf's package
25 # 3. Return the include path list of the package
27 def GetIncludeListOfFile(WorkSpace
, Filepath
, Db
):
29 Filepath
= os
.path
.normpath(Filepath
)
31 select Value1, FullPath from Inf, File where Inf.Model = %s and Inf.BelongsToFile in(
32 select distinct B.BelongsToFile from File as A left join Inf as B
33 where A.ID = B.BelongsToFile and B.Model = %s and (A.Path || '%s' || B.Value1) = '%s')
34 and Inf.BelongsToFile = File.ID""" \
35 % (MODEL_META_DATA_PACKAGE
, MODEL_EFI_SOURCE_FILE
, '\\', Filepath
)
36 RecordSet
= Db
.TblFile
.Exec(SqlCommand
)
37 for Record
in RecordSet
:
38 DecFullPath
= os
.path
.normpath(mws
.join(WorkSpace
, Record
[0]))
39 InfFullPath
= os
.path
.normpath(mws
.join(WorkSpace
, Record
[1]))
40 (DecPath
, DecName
) = os
.path
.split(DecFullPath
)
41 (InfPath
, InfName
) = os
.path
.split(InfFullPath
)
42 SqlCommand
= """select Value1 from Dec where BelongsToFile =
43 (select ID from File where FullPath = '%s') and Model = %s""" \
44 % (DecFullPath
, MODEL_EFI_INCLUDE
)
45 NewRecordSet
= Db
.TblDec
.Exec(SqlCommand
)
46 if InfPath
not in IncludeList
:
47 IncludeList
.append(InfPath
)
48 for NewRecord
in NewRecordSet
:
49 IncludePath
= os
.path
.normpath(os
.path
.join(DecPath
, NewRecord
[0]))
50 if IncludePath
not in IncludeList
:
51 IncludeList
.append(IncludePath
)
57 # Search table file and find all specific type files
59 def GetFileList(FileModel
, Db
):
61 SqlCommand
= """select FullPath from File where Model = %s""" % str(FileModel
)
62 RecordSet
= Db
.TblFile
.Exec(SqlCommand
)
63 for Record
in RecordSet
:
64 FileList
.append(Record
[0])
70 # Search table file and find all small tables
72 def GetTableList(FileModelList
, Table
, Db
):
74 SqlCommand
= """select ID from File where Model in %s""" % str(FileModelList
)
75 RecordSet
= Db
.TblFile
.Exec(SqlCommand
)
76 for Record
in RecordSet
:
77 TableName
= Table
+ str(Record
[0])
78 TableList
.append(TableName
)
82 ## ParseHeaderCommentSection
84 # Parse Header comment section lines, extract Abstract, Description, Copyright
87 # @param CommentList: List of (Comment, LineNumber)
88 # @param FileName: FileName of the comment
90 def ParseHeaderCommentSection(CommentList
, FileName
= None):
97 STR_HEADER_COMMENT_START
= "@file"
100 # used to indicate the state of processing header comment section of dec,
103 HEADER_COMMENT_NOT_STARTED
= -1
104 HEADER_COMMENT_STARTED
= 0
105 HEADER_COMMENT_FILE
= 1
106 HEADER_COMMENT_ABSTRACT
= 2
107 HEADER_COMMENT_DESCRIPTION
= 3
108 HEADER_COMMENT_COPYRIGHT
= 4
109 HEADER_COMMENT_LICENSE
= 5
110 HEADER_COMMENT_END
= 6
112 # first find the last copyright line
115 HeaderCommentStage
= HEADER_COMMENT_NOT_STARTED
116 for Index
in range(len(CommentList
) - 1, 0, -1):
117 Line
= CommentList
[Index
][0]
118 if _IsCopyrightLine(Line
):
122 for Item
in CommentList
:
126 if not Line
.startswith('#') and Line
:
127 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FileName
128 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
129 for Result
in ResultSet
:
130 Msg
= 'Comment must start with #'
131 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
132 Comment
= CleanString2(Line
)[1]
133 Comment
= Comment
.strip()
135 # if there are blank lines between License or Description, keep them as they would be
136 # indication of different block; or in the position that Abstract should be, also keep it
137 # as it indicates that no abstract
139 if not Comment
and HeaderCommentStage
not in [HEADER_COMMENT_LICENSE
, \
140 HEADER_COMMENT_DESCRIPTION
, HEADER_COMMENT_ABSTRACT
]:
143 if HeaderCommentStage
== HEADER_COMMENT_NOT_STARTED
:
144 if Comment
.startswith(STR_HEADER_COMMENT_START
):
145 HeaderCommentStage
= HEADER_COMMENT_ABSTRACT
147 License
+= Comment
+ EndOfLine
149 if HeaderCommentStage
== HEADER_COMMENT_ABSTRACT
:
151 # in case there is no abstract and description
155 HeaderCommentStage
= HEADER_COMMENT_DESCRIPTION
156 elif _IsCopyrightLine(Comment
):
157 Copyright
+= Comment
+ EndOfLine
158 HeaderCommentStage
= HEADER_COMMENT_COPYRIGHT
160 Abstract
+= Comment
+ EndOfLine
161 HeaderCommentStage
= HEADER_COMMENT_DESCRIPTION
162 elif HeaderCommentStage
== HEADER_COMMENT_DESCRIPTION
:
164 # in case there is no description
166 if _IsCopyrightLine(Comment
):
167 Copyright
+= Comment
+ EndOfLine
168 HeaderCommentStage
= HEADER_COMMENT_COPYRIGHT
170 Description
+= Comment
+ EndOfLine
171 elif HeaderCommentStage
== HEADER_COMMENT_COPYRIGHT
:
172 if _IsCopyrightLine(Comment
):
173 Copyright
+= Comment
+ EndOfLine
176 # Contents after copyright line are license, those non-copyright lines in between
177 # copyright line will be discarded
182 License
+= Comment
+ EndOfLine
183 HeaderCommentStage
= HEADER_COMMENT_LICENSE
185 if not Comment
and not License
:
187 License
+= Comment
+ EndOfLine
189 if not Copyright
.strip():
190 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FileName
191 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
192 for Result
in ResultSet
:
193 Msg
= 'Header comment section must have copyright information'
194 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
196 if not License
.strip():
197 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FileName
198 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
199 for Result
in ResultSet
:
200 Msg
= 'Header comment section must have license information'
201 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
203 if not Abstract
.strip() or Abstract
.find('Component description file') > -1:
204 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FileName
205 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
206 for Result
in ResultSet
:
207 Msg
= 'Header comment section must have Abstract information.'
208 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
210 return Abstract
.strip(), Description
.strip(), Copyright
.strip(), License
.strip()
213 # check whether current line is copyright line, the criteria is whether there is case insensitive keyword "Copyright"
214 # followed by zero or more white space characters followed by a "(" character
216 # @param LineContent: the line need to be checked
217 # @return: True if current line is copyright line, False else
219 def _IsCopyrightLine (LineContent
):
220 LineContent
= LineContent
.upper()
223 ReIsCopyrightRe
= re
.compile(r
"""(^|\s)COPYRIGHT *\(""", re
.DOTALL
)
224 if ReIsCopyrightRe
.search(LineContent
):
232 # Split comments in a string
235 # @param Line: The string to be cleaned
236 # @param CommentCharacter: Comment char, used to ignore comment content,
237 # default is DataType.TAB_COMMENT_SPLIT
239 def CleanString2(Line
, CommentCharacter
='#', AllowCppStyleComment
=False):
245 # Replace EDK1's comment character
247 if AllowCppStyleComment
:
248 Line
= Line
.replace('//', CommentCharacter
)
250 # separate comments and statements
252 LineParts
= Line
.split(CommentCharacter
, 1)
254 # remove whitespace again
256 Line
= LineParts
[0].strip()
257 if len(LineParts
) > 1:
258 Comment
= LineParts
[1].strip()
260 # Remove prefixed and trailing comment characters
264 while Start
< End
and Comment
.startswith(CommentCharacter
, Start
, End
):
266 while End
>= 0 and Comment
.endswith(CommentCharacter
, Start
, End
):
268 Comment
= Comment
[Start
:End
]
269 Comment
= Comment
.strip()