]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/Python/Workspace/MetaFileTable.py
BaseTools: Remove the file timestamp checking during parsing
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / MetaFileTable.py
... / ...
CommitLineData
1## @file\r
2# This file is used to create/update/query/erase a meta file table\r
3#\r
4# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r
5# SPDX-License-Identifier: BSD-2-Clause-Patent\r
6#\r
7\r
8##\r
9# Import Modules\r
10#\r
11from __future__ import absolute_import\r
12import uuid\r
13\r
14import Common.EdkLogger as EdkLogger\r
15from Common.BuildToolError import FORMAT_INVALID\r
16\r
17from CommonDataClass.DataClass import MODEL_FILE_DSC, MODEL_FILE_DEC, MODEL_FILE_INF, \\r
18 MODEL_FILE_OTHERS\r
19from Common.DataType import *\r
20\r
21class MetaFileTable():\r
22 # TRICK: use file ID as the part before '.'\r
23 _ID_STEP_ = 1\r
24 _ID_MAX_ = 99999999\r
25\r
26 ## Constructor\r
27 def __init__(self, DB, MetaFile, FileType, Temporary, FromItem=None):\r
28 self.MetaFile = MetaFile\r
29 self.TableName = ""\r
30 self.DB = DB\r
31 self._NumpyTab = None\r
32\r
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
41 self.FileId = len(DB.TblFile)\r
42 self.ID = self.FileId * 10**8\r
43 if Temporary:\r
44 self.TableName = "_%s_%s_%s" % (FileType, len(DB.TblFile), uuid.uuid4().hex)\r
45 else:\r
46 self.TableName = "_%s_%s" % (FileType, len(DB.TblFile))\r
47\r
48 def IsIntegrity(self):\r
49 Result = False\r
50 try:\r
51 TimeStamp = self.MetaFile.TimeStamp\r
52 if not self.CurrentContent:\r
53 Result = False\r
54 else:\r
55 Result = self.CurrentContent[-1][0] < 0\r
56 except Exception as Exc:\r
57 EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc))\r
58 return False\r
59 return Result\r
60\r
61 def SetEndFlag(self):\r
62 self.CurrentContent.append(self._DUMMY_)\r
63\r
64 def GetAll(self):\r
65 return [item for item in self.CurrentContent if item[0] >= 0 and item[-1]>=0]\r
66\r
67## Python class representation of table storing module data\r
68class ModuleTable(MetaFileTable):\r
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
85 _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]\r
86\r
87 ## Constructor\r
88 def __init__(self, Db, MetaFile, Temporary):\r
89 MetaFileTable.__init__(self, Db, MetaFile, MODEL_FILE_INF, Temporary)\r
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
106 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,\r
107 BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):\r
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
131 ## Query table\r
132 #\r
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
136 #\r
137 # @retval: A recordSet of all found records\r
138 #\r
139 def Query(self, Model, Arch=None, Platform=None, BelongsToItem=None):\r
140\r
141 QueryTab = self.CurrentContent\r
142 result = [item for item in QueryTab if item[1] == Model and item[-1]>=0 ]\r
143\r
144 if Arch is not None and Arch != TAB_ARCH_COMMON:\r
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
149 if Platform is not None and Platform != TAB_COMMON:\r
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
154 if BelongsToItem is not None:\r
155 result = [item for item in result if item[7] == BelongsToItem]\r
156\r
157 result = [ [r[2],r[3],r[4],r[5],r[6],r[0],r[9]] for r in result ]\r
158 return result\r
159\r
160## Python class representation of table storing package data\r
161class PackageTable(MetaFileTable):\r
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
178 _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]\r
179\r
180 ## Constructor\r
181 def __init__(self, Cursor, MetaFile, Temporary):\r
182 MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DEC, Temporary)\r
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
201 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,\r
202 BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):\r
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
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
222\r
223 ## Query table\r
224 #\r
225 # @param Model: The Model of Record\r
226 # @param Arch: The Arch attribute of Record\r
227 #\r
228 # @retval: A recordSet of all found records\r
229 #\r
230 def Query(self, Model, Arch=None):\r
231\r
232 QueryTab = self.CurrentContent\r
233 result = [item for item in QueryTab if item[1] == Model and item[-1]>=0 ]\r
234\r
235 if Arch is not None and Arch != TAB_ARCH_COMMON:\r
236 ArchList = set(['COMMON'])\r
237 ArchList.add(Arch)\r
238 result = [item for item in result if item[5] in ArchList]\r
239\r
240 return [[r[2], r[3], r[4], r[5], r[6], r[0], r[8]] for r in result]\r
241\r
242 def GetValidExpression(self, TokenSpaceGuid, PcdCName):\r
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
246 validateranges = []\r
247 validlists = []\r
248 expressions = []\r
249 try:\r
250 for row in result:\r
251 comment = row[0]\r
252\r
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
266 except Exception as Exc:\r
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
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
276 return set(), set(), set()\r
277 return set(validateranges), set(validlists), set(expressions)\r
278\r
279## Python class representation of table storing platform data\r
280class PlatformTable(MetaFileTable):\r
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
289 Scope3 TEXT,\r
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
299 _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====','====', -1, -1, -1, -1, -1, -1, -1]\r
300\r
301 ## Constructor\r
302 def __init__(self, Cursor, MetaFile, Temporary, FromItem=0):\r
303 MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DSC, Temporary, FromItem)\r
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
323 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON, Scope3=TAB_DEFAULT_STORES_DEFAULT,BelongsToItem=-1,\r
324 FromItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=1):\r
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
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
347\r
348 ## Query table\r
349 #\r
350 # @param Model: The Model of Record\r
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
356 # @retval: A recordSet of all found records\r
357 #\r
358 def Query(self, Model, Scope1=None, Scope2=None, BelongsToItem=None, FromItem=None):\r
359\r
360 QueryTab = self.CurrentContent\r
361 result = [item for item in QueryTab if item[1] == Model and item[-1]>0 ]\r
362 if Scope1 is not None and Scope1 != TAB_ARCH_COMMON:\r
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
368 if '.' in Scope2:\r
369 Index = Scope2.index('.')\r
370 NewScope = TAB_COMMON + Scope2[Index:]\r
371 Sc2.add(NewScope)\r
372 Sc2.add(Scope2)\r
373 result = [item for item in result if item[6] in Sc2]\r
374\r
375 if BelongsToItem is not None:\r
376 result = [item for item in result if item[8] == BelongsToItem]\r
377 else:\r
378 result = [item for item in result if item[8] < 0]\r
379 if FromItem is not None:\r
380 result = [item for item in result if item[9] == FromItem]\r
381\r
382 result = [ [r[2],r[3],r[4],r[5],r[6],r[7],r[0],r[10]] for r in result ]\r
383 return result\r
384\r
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
389\r
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
404 _ObjectCache = {}\r
405 ## Constructor\r
406 def __new__(Class, Cursor, MetaFile, FileType=None, Temporary=False, FromItem=None):\r
407 # no type given, try to find one\r
408 key = (MetaFile.Path, FileType,Temporary,FromItem)\r
409 if key in Class._ObjectCache:\r
410 return Class._ObjectCache[key]\r
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
422 if FromItem:\r
423 Args = Args + (FromItem,)\r
424\r
425 # create the storage object and return it to caller\r
426 reval = Class._FILE_TABLE_[FileType](*Args)\r
427 if not Temporary:\r
428 Class._ObjectCache[key] = reval\r
429 return reval\r
430\r