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