]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Ecc/MetaDataParser.py
BaseTools: Enhance BaseTools supports FixedAtBuild usage in VFR file
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / MetaDataParser.py
CommitLineData
30fdf114
LG
1## @file\r
2# This file is used to define common parser functions for meta-data\r
3#\r
1be2ed90 4# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>\r
40d841f6 5# This program and the accompanying materials\r
30fdf114
LG
6# are licensed and made available under the terms and conditions of the BSD License\r
7# which accompanies this distribution. The full text of the license may be found at\r
8# http://opensource.org/licenses/bsd-license.php\r
9#\r
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12#\r
13\r
1be2ed90 14import Common.LongFilePathOs as os\r
30fdf114 15from CommonDataClass.DataClass import *\r
d0acc87a 16from EccToolError import *\r
c4f52e12 17from Common.MultipleWorkspace import MultipleWorkspace as mws\r
d0acc87a
LG
18import EccGlobalData\r
19import re\r
30fdf114
LG
20## Get the inlcude path list for a source file\r
21#\r
22# 1. Find the source file belongs to which inf file\r
23# 2. Find the inf's package\r
24# 3. Return the include path list of the package\r
25#\r
26def GetIncludeListOfFile(WorkSpace, Filepath, Db):\r
27 IncludeList = []\r
28 Filepath = os.path.normpath(Filepath)\r
29 SqlCommand = """\r
30 select Value1, FullPath from Inf, File where Inf.Model = %s and Inf.BelongsToFile in(\r
e56468c0 31 select distinct B.BelongsToFile from File as A left join Inf as B\r
30fdf114
LG
32 where A.ID = B.BelongsToFile and B.Model = %s and (A.Path || '%s' || B.Value1) = '%s')\r
33 and Inf.BelongsToFile = File.ID""" \\r
34 % (MODEL_META_DATA_PACKAGE, MODEL_EFI_SOURCE_FILE, '\\', Filepath)\r
35 RecordSet = Db.TblFile.Exec(SqlCommand)\r
36 for Record in RecordSet:\r
c4f52e12
LY
37 DecFullPath = os.path.normpath(mws.join(WorkSpace, Record[0]))\r
38 InfFullPath = os.path.normpath(mws.join(WorkSpace, Record[1]))\r
30fdf114
LG
39 (DecPath, DecName) = os.path.split(DecFullPath)\r
40 (InfPath, InfName) = os.path.split(InfFullPath)\r
e56468c0 41 SqlCommand = """select Value1 from Dec where BelongsToFile =\r
30fdf114
LG
42 (select ID from File where FullPath = '%s') and Model = %s""" \\r
43 % (DecFullPath, MODEL_EFI_INCLUDE)\r
44 NewRecordSet = Db.TblDec.Exec(SqlCommand)\r
45 if InfPath not in IncludeList:\r
46 IncludeList.append(InfPath)\r
47 for NewRecord in NewRecordSet:\r
48 IncludePath = os.path.normpath(os.path.join(DecPath, NewRecord[0]))\r
49 if IncludePath not in IncludeList:\r
50 IncludeList.append(IncludePath)\r
e56468c0 51\r
30fdf114
LG
52 return IncludeList\r
53\r
e56468c0 54## Get the file list\r
55#\r
56# Search table file and find all specific type files\r
57#\r
58def GetFileList(FileModel, Db):\r
59 FileList = []\r
60 SqlCommand = """select FullPath from File where Model = %s""" % str(FileModel)\r
61 RecordSet = Db.TblFile.Exec(SqlCommand)\r
62 for Record in RecordSet:\r
63 FileList.append(Record[0])\r
64\r
65 return FileList\r
66\r
30fdf114
LG
67## Get the table list\r
68#\r
69# Search table file and find all small tables\r
70#\r
71def GetTableList(FileModelList, Table, Db):\r
72 TableList = []\r
73 SqlCommand = """select ID from File where Model in %s""" % str(FileModelList)\r
74 RecordSet = Db.TblFile.Exec(SqlCommand)\r
75 for Record in RecordSet:\r
76 TableName = Table + str(Record[0])\r
77 TableList.append(TableName)\r
e56468c0 78\r
30fdf114
LG
79 return TableList\r
80\r
d0acc87a
LG
81## ParseHeaderCommentSection\r
82#\r
83# Parse Header comment section lines, extract Abstract, Description, Copyright\r
84# , License lines\r
85#\r
86# @param CommentList: List of (Comment, LineNumber)\r
87# @param FileName: FileName of the comment\r
88#\r
89def ParseHeaderCommentSection(CommentList, FileName = None):\r
90 \r
91 Abstract = ''\r
92 Description = ''\r
93 Copyright = ''\r
94 License = ''\r
95 EndOfLine = "\n"\r
96 STR_HEADER_COMMENT_START = "@file"\r
97 \r
98 #\r
99 # used to indicate the state of processing header comment section of dec, \r
100 # inf files\r
101 #\r
102 HEADER_COMMENT_NOT_STARTED = -1\r
103 HEADER_COMMENT_STARTED = 0\r
104 HEADER_COMMENT_FILE = 1\r
105 HEADER_COMMENT_ABSTRACT = 2\r
106 HEADER_COMMENT_DESCRIPTION = 3\r
107 HEADER_COMMENT_COPYRIGHT = 4\r
108 HEADER_COMMENT_LICENSE = 5\r
109 HEADER_COMMENT_END = 6\r
110 #\r
111 # first find the last copyright line\r
112 #\r
113 Last = 0\r
114 HeaderCommentStage = HEADER_COMMENT_NOT_STARTED\r
115 for Index in xrange(len(CommentList)-1, 0, -1):\r
116 Line = CommentList[Index][0]\r
117 if _IsCopyrightLine(Line):\r
118 Last = Index\r
119 break\r
120 \r
121 for Item in CommentList:\r
122 Line = Item[0]\r
123 LineNo = Item[1]\r
124 \r
125 if not Line.startswith('#') and Line:\r
126 SqlStatement = """ select ID from File where FullPath like '%s'""" % FileName\r
127 ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)\r
128 for Result in ResultSet:\r
129 Msg = 'Comment must start with #'\r
130 EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])\r
131 Comment = CleanString2(Line)[1]\r
132 Comment = Comment.strip()\r
133 #\r
134 # if there are blank lines between License or Description, keep them as they would be \r
135 # indication of different block; or in the position that Abstract should be, also keep it\r
136 # as it indicates that no abstract\r
137 #\r
138 if not Comment and HeaderCommentStage not in [HEADER_COMMENT_LICENSE, \\r
139 HEADER_COMMENT_DESCRIPTION, HEADER_COMMENT_ABSTRACT]:\r
140 continue\r
141 \r
142 if HeaderCommentStage == HEADER_COMMENT_NOT_STARTED:\r
143 if Comment.startswith(STR_HEADER_COMMENT_START):\r
144 HeaderCommentStage = HEADER_COMMENT_ABSTRACT\r
145 else:\r
146 License += Comment + EndOfLine\r
147 else:\r
148 if HeaderCommentStage == HEADER_COMMENT_ABSTRACT:\r
149 #\r
150 # in case there is no abstract and description\r
151 #\r
152 if not Comment:\r
153 Abstract = ''\r
154 HeaderCommentStage = HEADER_COMMENT_DESCRIPTION\r
155 elif _IsCopyrightLine(Comment): \r
156 Copyright += Comment + EndOfLine\r
157 HeaderCommentStage = HEADER_COMMENT_COPYRIGHT\r
158 else: \r
159 Abstract += Comment + EndOfLine\r
160 HeaderCommentStage = HEADER_COMMENT_DESCRIPTION\r
161 elif HeaderCommentStage == HEADER_COMMENT_DESCRIPTION:\r
162 #\r
163 # in case there is no description\r
164 # \r
165 if _IsCopyrightLine(Comment): \r
166 Copyright += Comment + EndOfLine\r
167 HeaderCommentStage = HEADER_COMMENT_COPYRIGHT\r
168 else:\r
169 Description += Comment + EndOfLine \r
170 elif HeaderCommentStage == HEADER_COMMENT_COPYRIGHT:\r
171 if _IsCopyrightLine(Comment): \r
172 Copyright += Comment + EndOfLine\r
173 else:\r
174 #\r
175 # Contents after copyright line are license, those non-copyright lines in between\r
176 # copyright line will be discarded \r
177 #\r
178 if LineNo > Last:\r
179 if License:\r
180 License += EndOfLine\r
181 License += Comment + EndOfLine\r
182 HeaderCommentStage = HEADER_COMMENT_LICENSE \r
183 else:\r
184 if not Comment and not License:\r
185 continue\r
186 License += Comment + EndOfLine\r
187 \r
b3d07ff8 188 if not Copyright.strip():\r
d0acc87a
LG
189 SqlStatement = """ select ID from File where FullPath like '%s'""" % FileName\r
190 ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)\r
191 for Result in ResultSet:\r
192 Msg = 'Header comment section must have copyright information'\r
193 EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])\r
194\r
b3d07ff8 195 if not License.strip():\r
d0acc87a
LG
196 SqlStatement = """ select ID from File where FullPath like '%s'""" % FileName\r
197 ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)\r
198 for Result in ResultSet:\r
199 Msg = 'Header comment section must have license information'\r
200 EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])\r
b3d07ff8
HC
201 \r
202 if not Abstract.strip() or Abstract.find('Component description file') > -1:\r
203 SqlStatement = """ select ID from File where FullPath like '%s'""" % FileName\r
204 ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)\r
205 for Result in ResultSet:\r
206 Msg = 'Header comment section must have Abstract information.'\r
207 EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])\r
d0acc87a
LG
208 \r
209 return Abstract.strip(), Description.strip(), Copyright.strip(), License.strip()\r
210\r
211## _IsCopyrightLine\r
212# check whether current line is copyright line, the criteria is whether there is case insensitive keyword "Copyright" \r
213# followed by zero or more white space characters followed by a "(" character \r
214#\r
215# @param LineContent: the line need to be checked\r
216# @return: True if current line is copyright line, False else\r
217#\r
218def _IsCopyrightLine (LineContent):\r
219 LineContent = LineContent.upper()\r
220 Result = False\r
221 \r
222 ReIsCopyrightRe = re.compile(r"""(^|\s)COPYRIGHT *\(""", re.DOTALL)\r
223 if ReIsCopyrightRe.search(LineContent):\r
224 Result = True\r
225 \r
226 return Result\r
227\r
228\r
229## CleanString2\r
230#\r
231# Split comments in a string\r
232# Remove spaces\r
233#\r
234# @param Line: The string to be cleaned\r
235# @param CommentCharacter: Comment char, used to ignore comment content, \r
236# default is DataType.TAB_COMMENT_SPLIT\r
237#\r
238def CleanString2(Line, CommentCharacter='#', AllowCppStyleComment=False):\r
239 #\r
240 # remove whitespace\r
241 #\r
242 Line = Line.strip()\r
243 #\r
244 # Replace EDK1's comment character\r
245 #\r
246 if AllowCppStyleComment:\r
247 Line = Line.replace('//', CommentCharacter)\r
248 #\r
249 # separate comments and statements\r
250 #\r
251 LineParts = Line.split(CommentCharacter, 1)\r
252 #\r
253 # remove whitespace again\r
254 #\r
255 Line = LineParts[0].strip()\r
256 if len(LineParts) > 1:\r
257 Comment = LineParts[1].strip()\r
258 #\r
259 # Remove prefixed and trailing comment characters\r
260 #\r
261 Start = 0\r
262 End = len(Comment)\r
263 while Start < End and Comment.startswith(CommentCharacter, Start, End):\r
264 Start += 1\r
265 while End >= 0 and Comment.endswith(CommentCharacter, Start, End):\r
266 End -= 1\r
267 Comment = Comment[Start:End]\r
268 Comment = Comment.strip()\r
269 else:\r
270 Comment = ''\r
271\r
272 return Line, Comment\r