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