]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Workspace/MetaFileTable.py
BaseTools: Correct report the line number in INF file issue
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / MetaFileTable.py
CommitLineData
30fdf114
LG
1## @file\r
2# This file is used to create/update/query/erase a meta file table\r
3#\r
55c84777 4# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r
2e351cbe 5# SPDX-License-Identifier: BSD-2-Clause-Patent\r
30fdf114
LG
6#\r
7\r
8##\r
9# Import Modules\r
10#\r
1ccc4d89 11from __future__ import absolute_import\r
0d2711a6
LG
12import uuid\r
13\r
30fdf114 14import Common.EdkLogger as EdkLogger\r
901fd822 15from Common.BuildToolError import FORMAT_INVALID\r
0d2711a6 16\r
0d2711a6
LG
17from CommonDataClass.DataClass import MODEL_FILE_DSC, MODEL_FILE_DEC, MODEL_FILE_INF, \\r
18 MODEL_FILE_OTHERS\r
8518bf0b 19from Common.DataType import *\r
30fdf114 20\r
2f818ed0 21class MetaFileTable():\r
30fdf114 22 # TRICK: use file ID as the part before '.'\r
643556fc
FB
23 _ID_STEP_ = 1\r
24 _ID_MAX_ = 99999999\r
0d2711a6
LG
25\r
26 ## Constructor\r
2f818ed0 27 def __init__(self, DB, MetaFile, FileType, Temporary, FromItem=None):\r
0d2711a6 28 self.MetaFile = MetaFile\r
2f818ed0
B
29 self.TableName = ""\r
30 self.DB = DB\r
31 self._NumpyTab = None\r
643556fc 32\r
2f818ed0
B
33 self.CurrentContent = []\r
34 DB.TblFile.append([MetaFile.Name,\r
35 MetaFile.Ext,\r
36 MetaFile.Dir,\r
37 MetaFile.Path,\r
38 FileType,\r
39 MetaFile.TimeStamp,\r
40 FromItem])\r
643556fc
FB
41 self.FileId = len(DB.TblFile)\r
42 self.ID = self.FileId * 10**8\r
0d2711a6 43 if Temporary:\r
2f818ed0 44 self.TableName = "_%s_%s_%s" % (FileType, len(DB.TblFile), uuid.uuid4().hex)\r
0d2711a6 45 else:\r
2f818ed0 46 self.TableName = "_%s_%s" % (FileType, len(DB.TblFile))\r
0d2711a6
LG
47\r
48 def IsIntegrity(self):\r
b3ee616e 49 Result = False\r
0d2711a6 50 try:\r
64b2609f 51 TimeStamp = self.MetaFile.TimeStamp\r
643556fc
FB
52 if not self.CurrentContent:\r
53 Result = False\r
54 else:\r
55 Result = self.CurrentContent[-1][0] < 0\r
5b0671c1 56 except Exception as Exc:\r
0d2711a6
LG
57 EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc))\r
58 return False\r
b3ee616e 59 return Result\r
0d2711a6 60\r
2f818ed0
B
61 def SetEndFlag(self):\r
62 self.CurrentContent.append(self._DUMMY_)\r
63\r
64 def GetAll(self):\r
5bc96263 65 return [item for item in self.CurrentContent if item[0] >= 0 and item[-1]>=0]\r
2f818ed0 66\r
0d2711a6
LG
67## Python class representation of table storing module data\r
68class ModuleTable(MetaFileTable):\r
30fdf114
LG
69 _COLUMN_ = '''\r
70 ID REAL PRIMARY KEY,\r
71 Model INTEGER NOT NULL,\r
72 Value1 TEXT NOT NULL,\r
73 Value2 TEXT,\r
74 Value3 TEXT,\r
75 Scope1 TEXT,\r
76 Scope2 TEXT,\r
77 BelongsToItem REAL NOT NULL,\r
78 StartLine INTEGER NOT NULL,\r
79 StartColumn INTEGER NOT NULL,\r
80 EndLine INTEGER NOT NULL,\r
81 EndColumn INTEGER NOT NULL,\r
82 Enabled INTEGER DEFAULT 0\r
83 '''\r
84 # used as table end flag, in case the changes to database is not committed to db file\r
2f818ed0 85 _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]\r
30fdf114
LG
86\r
87 ## Constructor\r
2f818ed0
B
88 def __init__(self, Db, MetaFile, Temporary):\r
89 MetaFileTable.__init__(self, Db, MetaFile, MODEL_FILE_INF, Temporary)\r
30fdf114
LG
90\r
91 ## Insert a record into table Inf\r
92 #\r
93 # @param Model: Model of a Inf item\r
94 # @param Value1: Value1 of a Inf item\r
95 # @param Value2: Value2 of a Inf item\r
96 # @param Value3: Value3 of a Inf item\r
97 # @param Scope1: Arch of a Inf item\r
98 # @param Scope2 Platform os a Inf item\r
99 # @param BelongsToItem: The item belongs to which another item\r
100 # @param StartLine: StartLine of a Inf item\r
101 # @param StartColumn: StartColumn of a Inf item\r
102 # @param EndLine: EndLine of a Inf item\r
103 # @param EndColumn: EndColumn of a Inf item\r
104 # @param Enabled: If this item enabled\r
105 #\r
55c84777 106 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,\r
30fdf114 107 BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):\r
2f818ed0
B
108\r
109 (Value1, Value2, Value3, Scope1, Scope2) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip())\r
110 self.ID = self.ID + self._ID_STEP_\r
111 if self.ID >= (MODEL_FILE_INF + self._ID_MAX_):\r
112 self.ID = MODEL_FILE_INF + self._ID_STEP_\r
113\r
114 row = [ self.ID,\r
115 Model,\r
116 Value1,\r
117 Value2,\r
118 Value3,\r
119 Scope1,\r
120 Scope2,\r
121 BelongsToItem,\r
122 StartLine,\r
123 StartColumn,\r
124 EndLine,\r
125 EndColumn,\r
126 Enabled\r
127 ]\r
128 self.CurrentContent.append(row)\r
129 return self.ID\r
130\r
30fdf114
LG
131 ## Query table\r
132 #\r
f7496d71
LG
133 # @param Model: The Model of Record\r
134 # @param Arch: The Arch attribute of Record\r
135 # @param Platform The Platform attribute of Record\r
30fdf114 136 #\r
f7496d71 137 # @retval: A recordSet of all found records\r
30fdf114 138 #\r
e8a47801 139 def Query(self, Model, Arch=None, Platform=None, BelongsToItem=None):\r
2f818ed0
B
140\r
141 QueryTab = self.CurrentContent\r
142 result = [item for item in QueryTab if item[1] == Model and item[-1]>=0 ]\r
30fdf114 143\r
55c84777 144 if Arch is not None and Arch != TAB_ARCH_COMMON:\r
2f818ed0
B
145 ArchList = set(['COMMON'])\r
146 ArchList.add(Arch)\r
147 result = [item for item in result if item[5] in ArchList]\r
148\r
55c84777 149 if Platform is not None and Platform != TAB_COMMON:\r
2f818ed0
B
150 Platformlist = set( ['COMMON','DEFAULT'])\r
151 Platformlist.add(Platform)\r
152 result = [item for item in result if item[6] in Platformlist]\r
153\r
4231a819 154 if BelongsToItem is not None:\r
2f818ed0 155 result = [item for item in result if item[7] == BelongsToItem]\r
30fdf114 156\r
b6e36087 157 result = [ [r[2],r[3],r[4],r[5],r[6],r[0],r[8]] for r in result ]\r
2f818ed0 158 return result\r
30fdf114
LG
159\r
160## Python class representation of table storing package data\r
0d2711a6 161class PackageTable(MetaFileTable):\r
30fdf114
LG
162 _COLUMN_ = '''\r
163 ID REAL PRIMARY KEY,\r
164 Model INTEGER NOT NULL,\r
165 Value1 TEXT NOT NULL,\r
166 Value2 TEXT,\r
167 Value3 TEXT,\r
168 Scope1 TEXT,\r
169 Scope2 TEXT,\r
170 BelongsToItem REAL NOT NULL,\r
171 StartLine INTEGER NOT NULL,\r
172 StartColumn INTEGER NOT NULL,\r
173 EndLine INTEGER NOT NULL,\r
174 EndColumn INTEGER NOT NULL,\r
175 Enabled INTEGER DEFAULT 0\r
176 '''\r
177 # used as table end flag, in case the changes to database is not committed to db file\r
2f818ed0 178 _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]\r
30fdf114
LG
179\r
180 ## Constructor\r
0d2711a6
LG
181 def __init__(self, Cursor, MetaFile, Temporary):\r
182 MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DEC, Temporary)\r
30fdf114
LG
183\r
184 ## Insert table\r
185 #\r
186 # Insert a record into table Dec\r
187 #\r
188 # @param Model: Model of a Dec item\r
189 # @param Value1: Value1 of a Dec item\r
190 # @param Value2: Value2 of a Dec item\r
191 # @param Value3: Value3 of a Dec item\r
192 # @param Scope1: Arch of a Dec item\r
193 # @param Scope2: Module type of a Dec item\r
194 # @param BelongsToItem: The item belongs to which another item\r
195 # @param StartLine: StartLine of a Dec item\r
196 # @param StartColumn: StartColumn of a Dec item\r
197 # @param EndLine: EndLine of a Dec item\r
198 # @param EndColumn: EndColumn of a Dec item\r
199 # @param Enabled: If this item enabled\r
200 #\r
55c84777 201 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,\r
30fdf114 202 BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):\r
2f818ed0
B
203 (Value1, Value2, Value3, Scope1, Scope2) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip())\r
204 self.ID = self.ID + self._ID_STEP_\r
2f818ed0
B
205\r
206 row = [ self.ID,\r
207 Model,\r
208 Value1,\r
209 Value2,\r
210 Value3,\r
211 Scope1,\r
212 Scope2,\r
213 BelongsToItem,\r
214 StartLine,\r
215 StartColumn,\r
216 EndLine,\r
217 EndColumn,\r
218 Enabled\r
219 ]\r
220 self.CurrentContent.append(row)\r
221 return self.ID\r
30fdf114
LG
222\r
223 ## Query table\r
224 #\r
f7496d71
LG
225 # @param Model: The Model of Record\r
226 # @param Arch: The Arch attribute of Record\r
30fdf114 227 #\r
f7496d71 228 # @retval: A recordSet of all found records\r
30fdf114
LG
229 #\r
230 def Query(self, Model, Arch=None):\r
2f818ed0
B
231\r
232 QueryTab = self.CurrentContent\r
233 result = [item for item in QueryTab if item[1] == Model and item[-1]>=0 ]\r
30fdf114 234\r
55c84777 235 if Arch is not None and Arch != TAB_ARCH_COMMON:\r
2f818ed0
B
236 ArchList = set(['COMMON'])\r
237 ArchList.add(Arch)\r
238 result = [item for item in result if item[5] in ArchList]\r
30fdf114 239\r
2f818ed0 240 return [[r[2], r[3], r[4], r[5], r[6], r[0], r[8]] for r in result]\r
30fdf114 241\r
82a6a960 242 def GetValidExpression(self, TokenSpaceGuid, PcdCName):\r
2f818ed0
B
243\r
244 QueryTab = self.CurrentContent\r
245 result = [[item[2], item[8]] for item in QueryTab if item[3] == TokenSpaceGuid and item[4] == PcdCName]\r
82a6a960
BF
246 validateranges = []\r
247 validlists = []\r
248 expressions = []\r
901fd822 249 try:\r
2f818ed0 250 for row in result:\r
901fd822 251 comment = row[0]\r
f7496d71 252\r
901fd822
BF
253 LineNum = row[1]\r
254 comment = comment.strip("#")\r
255 comment = comment.strip()\r
256 oricomment = comment\r
257 if comment.startswith("@ValidRange"):\r
258 comment = comment.replace("@ValidRange", "", 1)\r
259 validateranges.append(comment.split("|")[1].strip())\r
260 if comment.startswith("@ValidList"):\r
261 comment = comment.replace("@ValidList", "", 1)\r
262 validlists.append(comment.split("|")[1].strip())\r
263 if comment.startswith("@Expression"):\r
264 comment = comment.replace("@Expression", "", 1)\r
265 expressions.append(comment.split("|")[1].strip())\r
5b0671c1 266 except Exception as Exc:\r
901fd822
BF
267 ValidType = ""\r
268 if oricomment.startswith("@ValidRange"):\r
269 ValidType = "@ValidRange"\r
270 if oricomment.startswith("@ValidList"):\r
271 ValidType = "@ValidList"\r
272 if oricomment.startswith("@Expression"):\r
273 ValidType = "@Expression"\r
ccaa7754
GL
274 EdkLogger.error('Parser', FORMAT_INVALID, "The syntax for %s of PCD %s.%s is incorrect" % (ValidType, TokenSpaceGuid, PcdCName),\r
275 ExtraData=oricomment, File=self.MetaFile, Line=LineNum)\r
901fd822 276 return set(), set(), set()\r
82a6a960 277 return set(validateranges), set(validlists), set(expressions)\r
643556fc 278\r
30fdf114 279## Python class representation of table storing platform data\r
0d2711a6 280class PlatformTable(MetaFileTable):\r
30fdf114
LG
281 _COLUMN_ = '''\r
282 ID REAL PRIMARY KEY,\r
283 Model INTEGER NOT NULL,\r
284 Value1 TEXT NOT NULL,\r
285 Value2 TEXT,\r
286 Value3 TEXT,\r
287 Scope1 TEXT,\r
288 Scope2 TEXT,\r
8518bf0b 289 Scope3 TEXT,\r
30fdf114
LG
290 BelongsToItem REAL NOT NULL,\r
291 FromItem REAL NOT NULL,\r
292 StartLine INTEGER NOT NULL,\r
293 StartColumn INTEGER NOT NULL,\r
294 EndLine INTEGER NOT NULL,\r
295 EndColumn INTEGER NOT NULL,\r
296 Enabled INTEGER DEFAULT 0\r
297 '''\r
298 # used as table end flag, in case the changes to database is not committed to db file\r
2f818ed0 299 _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====','====', -1, -1, -1, -1, -1, -1, -1]\r
30fdf114
LG
300\r
301 ## Constructor\r
395f3336
YF
302 def __init__(self, Cursor, MetaFile, Temporary, FromItem=0):\r
303 MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DSC, Temporary, FromItem)\r
30fdf114
LG
304\r
305 ## Insert table\r
306 #\r
307 # Insert a record into table Dsc\r
308 #\r
309 # @param Model: Model of a Dsc item\r
310 # @param Value1: Value1 of a Dsc item\r
311 # @param Value2: Value2 of a Dsc item\r
312 # @param Value3: Value3 of a Dsc item\r
313 # @param Scope1: Arch of a Dsc item\r
314 # @param Scope2: Module type of a Dsc item\r
315 # @param BelongsToItem: The item belongs to which another item\r
316 # @param FromItem: The item belongs to which dsc file\r
317 # @param StartLine: StartLine of a Dsc item\r
318 # @param StartColumn: StartColumn of a Dsc item\r
319 # @param EndLine: EndLine of a Dsc item\r
320 # @param EndColumn: EndColumn of a Dsc item\r
321 # @param Enabled: If this item enabled\r
322 #\r
55c84777 323 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON, Scope3=TAB_DEFAULT_STORES_DEFAULT,BelongsToItem=-1,\r
30fdf114 324 FromItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=1):\r
2f818ed0
B
325 (Value1, Value2, Value3, Scope1, Scope2, Scope3) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip(), Scope3.strip())\r
326 self.ID = self.ID + self._ID_STEP_\r
2f818ed0
B
327\r
328 row = [ self.ID,\r
329 Model,\r
330 Value1,\r
331 Value2,\r
332 Value3,\r
333 Scope1,\r
334 Scope2,\r
335 Scope3,\r
336 BelongsToItem,\r
337 FromItem,\r
338 StartLine,\r
339 StartColumn,\r
340 EndLine,\r
341 EndColumn,\r
342 Enabled\r
343 ]\r
344 self.CurrentContent.append(row)\r
345 return self.ID\r
346\r
30fdf114
LG
347\r
348 ## Query table\r
349 #\r
f7496d71 350 # @param Model: The Model of Record\r
30fdf114
LG
351 # @param Scope1: Arch of a Dsc item\r
352 # @param Scope2: Module type of a Dsc item\r
353 # @param BelongsToItem: The item belongs to which another item\r
354 # @param FromItem: The item belongs to which dsc file\r
355 #\r
f7496d71 356 # @retval: A recordSet of all found records\r
30fdf114
LG
357 #\r
358 def Query(self, Model, Scope1=None, Scope2=None, BelongsToItem=None, FromItem=None):\r
2f818ed0
B
359\r
360 QueryTab = self.CurrentContent\r
361 result = [item for item in QueryTab if item[1] == Model and item[-1]>0 ]\r
55c84777 362 if Scope1 is not None and Scope1 != TAB_ARCH_COMMON:\r
2f818ed0
B
363 Sc1 = set(['COMMON'])\r
364 Sc1.add(Scope1)\r
365 result = [item for item in result if item[5] in Sc1]\r
366 Sc2 = set( ['COMMON','DEFAULT'])\r
367 if Scope2 and Scope2 != TAB_COMMON:\r
35dc964b
YZ
368 if '.' in Scope2:\r
369 Index = Scope2.index('.')\r
55c84777 370 NewScope = TAB_COMMON + Scope2[Index:]\r
2f818ed0
B
371 Sc2.add(NewScope)\r
372 Sc2.add(Scope2)\r
373 result = [item for item in result if item[6] in Sc2]\r
30fdf114 374\r
4231a819 375 if BelongsToItem is not None:\r
2f818ed0 376 result = [item for item in result if item[8] == BelongsToItem]\r
30fdf114 377 else:\r
2f818ed0 378 result = [item for item in result if item[8] < 0]\r
4231a819 379 if FromItem is not None:\r
2f818ed0
B
380 result = [item for item in result if item[9] == FromItem]\r
381\r
4a6b179f 382 result = [ [r[2],r[3],r[4],r[5],r[6],r[7],r[0],r[10]] for r in result ]\r
2f818ed0 383 return result\r
30fdf114 384\r
5bc96263
FB
385 def DisableComponent(self,comp_id):\r
386 for item in self.CurrentContent:\r
387 if item[0] == comp_id or item[8] == comp_id:\r
388 item[-1] = -1\r
30fdf114 389\r
0d2711a6
LG
390## Factory class to produce different storage for different type of meta-file\r
391class MetaFileStorage(object):\r
392 _FILE_TABLE_ = {\r
393 MODEL_FILE_INF : ModuleTable,\r
394 MODEL_FILE_DEC : PackageTable,\r
395 MODEL_FILE_DSC : PlatformTable,\r
396 MODEL_FILE_OTHERS : MetaFileTable,\r
397 }\r
398\r
399 _FILE_TYPE_ = {\r
400 ".inf" : MODEL_FILE_INF,\r
401 ".dec" : MODEL_FILE_DEC,\r
402 ".dsc" : MODEL_FILE_DSC,\r
403 }\r
643556fc 404 _ObjectCache = {}\r
0d2711a6 405 ## Constructor\r
395f3336 406 def __new__(Class, Cursor, MetaFile, FileType=None, Temporary=False, FromItem=None):\r
0d2711a6 407 # no type given, try to find one\r
643556fc
FB
408 key = (MetaFile.Path, FileType,Temporary,FromItem)\r
409 if key in Class._ObjectCache:\r
410 return Class._ObjectCache[key]\r
0d2711a6
LG
411 if not FileType:\r
412 if MetaFile.Type in self._FILE_TYPE_:\r
413 FileType = Class._FILE_TYPE_[MetaFile.Type]\r
414 else:\r
415 FileType = MODEL_FILE_OTHERS\r
416\r
417 # don't pass the type around if it's well known\r
418 if FileType == MODEL_FILE_OTHERS:\r
419 Args = (Cursor, MetaFile, FileType, Temporary)\r
420 else:\r
421 Args = (Cursor, MetaFile, Temporary)\r
395f3336
YF
422 if FromItem:\r
423 Args = Args + (FromItem,)\r
0d2711a6
LG
424\r
425 # create the storage object and return it to caller\r
643556fc
FB
426 reval = Class._FILE_TABLE_[FileType](*Args)\r
427 if not Temporary:\r
428 Class._ObjectCache[key] = reval\r
429 return reval\r
0d2711a6 430\r