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