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