]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Workspace/MetaFileTable.py
BaseTools: Enable CODE format in DEC file
[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
40d841f6 5# This program and the accompanying materials\r
30fdf114
LG
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
1ccc4d89 17from __future__ import absolute_import\r
0d2711a6
LG
18import uuid\r
19\r
30fdf114 20import Common.EdkLogger as EdkLogger\r
901fd822 21from Common.BuildToolError import FORMAT_INVALID\r
0d2711a6 22\r
0d2711a6
LG
23from CommonDataClass.DataClass import MODEL_FILE_DSC, MODEL_FILE_DEC, MODEL_FILE_INF, \\r
24 MODEL_FILE_OTHERS\r
8518bf0b 25from Common.DataType import *\r
30fdf114 26\r
2f818ed0 27class MetaFileTable():\r
30fdf114 28 # TRICK: use file ID as the part before '.'\r
643556fc
FB
29 _ID_STEP_ = 1\r
30 _ID_MAX_ = 99999999\r
0d2711a6
LG
31\r
32 ## Constructor\r
2f818ed0 33 def __init__(self, DB, MetaFile, FileType, Temporary, FromItem=None):\r
0d2711a6 34 self.MetaFile = MetaFile\r
2f818ed0
B
35 self.TableName = ""\r
36 self.DB = DB\r
37 self._NumpyTab = None\r
643556fc 38\r
2f818ed0
B
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
643556fc
FB
47 self.FileId = len(DB.TblFile)\r
48 self.ID = self.FileId * 10**8\r
0d2711a6 49 if Temporary:\r
2f818ed0 50 self.TableName = "_%s_%s_%s" % (FileType, len(DB.TblFile), uuid.uuid4().hex)\r
0d2711a6 51 else:\r
2f818ed0 52 self.TableName = "_%s_%s" % (FileType, len(DB.TblFile))\r
0d2711a6
LG
53\r
54 def IsIntegrity(self):\r
55 try:\r
64b2609f 56 TimeStamp = self.MetaFile.TimeStamp\r
643556fc
FB
57 if not self.CurrentContent:\r
58 Result = False\r
59 else:\r
60 Result = self.CurrentContent[-1][0] < 0\r
0d2711a6 61 if not Result:\r
64b2609f 62 # update the timestamp in database\r
2f818ed0 63 self.DB.SetFileTimeStamp(self.FileId, TimeStamp)\r
0d2711a6
LG
64 return False\r
65\r
2f818ed0 66 if TimeStamp != self.DB.GetFileTimeStamp(self.FileId):\r
0d2711a6 67 # update the timestamp in database\r
2f818ed0 68 self.DB.SetFileTimeStamp(self.FileId, TimeStamp)\r
0d2711a6 69 return False\r
5b0671c1 70 except Exception as Exc:\r
0d2711a6
LG
71 EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc))\r
72 return False\r
73 return True\r
74\r
2f818ed0
B
75 def SetEndFlag(self):\r
76 self.CurrentContent.append(self._DUMMY_)\r
77\r
78 def GetAll(self):\r
5bc96263 79 return [item for item in self.CurrentContent if item[0] >= 0 and item[-1]>=0]\r
2f818ed0 80\r
0d2711a6
LG
81## Python class representation of table storing module data\r
82class ModuleTable(MetaFileTable):\r
30fdf114
LG
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
2f818ed0 99 _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]\r
30fdf114
LG
100\r
101 ## Constructor\r
2f818ed0
B
102 def __init__(self, Db, MetaFile, Temporary):\r
103 MetaFileTable.__init__(self, Db, MetaFile, MODEL_FILE_INF, Temporary)\r
30fdf114
LG
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
55c84777 120 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,\r
30fdf114 121 BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):\r
2f818ed0
B
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
30fdf114
LG
145 ## Query table\r
146 #\r
f7496d71
LG
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
30fdf114 150 #\r
f7496d71 151 # @retval: A recordSet of all found records\r
30fdf114 152 #\r
e8a47801 153 def Query(self, Model, Arch=None, Platform=None, BelongsToItem=None):\r
2f818ed0
B
154\r
155 QueryTab = self.CurrentContent\r
156 result = [item for item in QueryTab if item[1] == Model and item[-1]>=0 ]\r
30fdf114 157\r
55c84777 158 if Arch is not None and Arch != TAB_ARCH_COMMON:\r
2f818ed0
B
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
55c84777 163 if Platform is not None and Platform != TAB_COMMON:\r
2f818ed0
B
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
4231a819 168 if BelongsToItem is not None:\r
2f818ed0 169 result = [item for item in result if item[7] == BelongsToItem]\r
30fdf114 170\r
2f818ed0
B
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
30fdf114
LG
173\r
174## Python class representation of table storing package data\r
0d2711a6 175class PackageTable(MetaFileTable):\r
30fdf114
LG
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
2f818ed0 192 _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]\r
30fdf114
LG
193\r
194 ## Constructor\r
0d2711a6
LG
195 def __init__(self, Cursor, MetaFile, Temporary):\r
196 MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DEC, Temporary)\r
30fdf114
LG
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
55c84777 215 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,\r
30fdf114 216 BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):\r
2f818ed0
B
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
2f818ed0
B
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
30fdf114
LG
236\r
237 ## Query table\r
238 #\r
f7496d71
LG
239 # @param Model: The Model of Record\r
240 # @param Arch: The Arch attribute of Record\r
30fdf114 241 #\r
f7496d71 242 # @retval: A recordSet of all found records\r
30fdf114
LG
243 #\r
244 def Query(self, Model, Arch=None):\r
2f818ed0
B
245\r
246 QueryTab = self.CurrentContent\r
247 result = [item for item in QueryTab if item[1] == Model and item[-1]>=0 ]\r
30fdf114 248\r
55c84777 249 if Arch is not None and Arch != TAB_ARCH_COMMON:\r
2f818ed0
B
250 ArchList = set(['COMMON'])\r
251 ArchList.add(Arch)\r
252 result = [item for item in result if item[5] in ArchList]\r
30fdf114 253\r
2f818ed0 254 return [[r[2], r[3], r[4], r[5], r[6], r[0], r[8]] for r in result]\r
30fdf114 255\r
82a6a960 256 def GetValidExpression(self, TokenSpaceGuid, PcdCName):\r
2f818ed0
B
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
82a6a960
BF
260 validateranges = []\r
261 validlists = []\r
262 expressions = []\r
901fd822 263 try:\r
2f818ed0 264 for row in result:\r
901fd822 265 comment = row[0]\r
f7496d71 266\r
901fd822
BF
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
5b0671c1 280 except Exception as Exc:\r
901fd822
BF
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
ccaa7754
GL
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
901fd822 290 return set(), set(), set()\r
82a6a960 291 return set(validateranges), set(validlists), set(expressions)\r
643556fc 292\r
30fdf114 293## Python class representation of table storing platform data\r
0d2711a6 294class PlatformTable(MetaFileTable):\r
30fdf114
LG
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
8518bf0b 303 Scope3 TEXT,\r
30fdf114
LG
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
2f818ed0 313 _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====','====', -1, -1, -1, -1, -1, -1, -1]\r
30fdf114
LG
314\r
315 ## Constructor\r
395f3336
YF
316 def __init__(self, Cursor, MetaFile, Temporary, FromItem=0):\r
317 MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DSC, Temporary, FromItem)\r
30fdf114
LG
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
55c84777 337 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON, Scope3=TAB_DEFAULT_STORES_DEFAULT,BelongsToItem=-1,\r
30fdf114 338 FromItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=1):\r
2f818ed0
B
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
2f818ed0
B
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
30fdf114
LG
361\r
362 ## Query table\r
363 #\r
f7496d71 364 # @param Model: The Model of Record\r
30fdf114
LG
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
f7496d71 370 # @retval: A recordSet of all found records\r
30fdf114
LG
371 #\r
372 def Query(self, Model, Scope1=None, Scope2=None, BelongsToItem=None, FromItem=None):\r
2f818ed0
B
373\r
374 QueryTab = self.CurrentContent\r
375 result = [item for item in QueryTab if item[1] == Model and item[-1]>0 ]\r
55c84777 376 if Scope1 is not None and Scope1 != TAB_ARCH_COMMON:\r
2f818ed0
B
377 Sc1 = set(['COMMON'])\r
378 Sc1.add(Scope1)\r
379 result = [item for item in result if item[5] in Sc1]\r
380 Sc2 = set( ['COMMON','DEFAULT'])\r
381 if Scope2 and Scope2 != TAB_COMMON:\r
35dc964b
YZ
382 if '.' in Scope2:\r
383 Index = Scope2.index('.')\r
55c84777 384 NewScope = TAB_COMMON + Scope2[Index:]\r
2f818ed0
B
385 Sc2.add(NewScope)\r
386 Sc2.add(Scope2)\r
387 result = [item for item in result if item[6] in Sc2]\r
30fdf114 388\r
4231a819 389 if BelongsToItem is not None:\r
2f818ed0 390 result = [item for item in result if item[8] == BelongsToItem]\r
30fdf114 391 else:\r
2f818ed0 392 result = [item for item in result if item[8] < 0]\r
4231a819 393 if FromItem is not None:\r
2f818ed0
B
394 result = [item for item in result if item[9] == FromItem]\r
395\r
396 result = [ [r[2],r[3],r[4],r[5],r[6],r[7],r[0],r[9]] for r in result ]\r
397 return result\r
30fdf114 398\r
5bc96263
FB
399 def DisableComponent(self,comp_id):\r
400 for item in self.CurrentContent:\r
401 if item[0] == comp_id or item[8] == comp_id:\r
402 item[-1] = -1\r
30fdf114 403\r
0d2711a6
LG
404## Factory class to produce different storage for different type of meta-file\r
405class MetaFileStorage(object):\r
406 _FILE_TABLE_ = {\r
407 MODEL_FILE_INF : ModuleTable,\r
408 MODEL_FILE_DEC : PackageTable,\r
409 MODEL_FILE_DSC : PlatformTable,\r
410 MODEL_FILE_OTHERS : MetaFileTable,\r
411 }\r
412\r
413 _FILE_TYPE_ = {\r
414 ".inf" : MODEL_FILE_INF,\r
415 ".dec" : MODEL_FILE_DEC,\r
416 ".dsc" : MODEL_FILE_DSC,\r
417 }\r
643556fc 418 _ObjectCache = {}\r
0d2711a6 419 ## Constructor\r
395f3336 420 def __new__(Class, Cursor, MetaFile, FileType=None, Temporary=False, FromItem=None):\r
0d2711a6 421 # no type given, try to find one\r
643556fc
FB
422 key = (MetaFile.Path, FileType,Temporary,FromItem)\r
423 if key in Class._ObjectCache:\r
424 return Class._ObjectCache[key]\r
0d2711a6
LG
425 if not FileType:\r
426 if MetaFile.Type in self._FILE_TYPE_:\r
427 FileType = Class._FILE_TYPE_[MetaFile.Type]\r
428 else:\r
429 FileType = MODEL_FILE_OTHERS\r
430\r
431 # don't pass the type around if it's well known\r
432 if FileType == MODEL_FILE_OTHERS:\r
433 Args = (Cursor, MetaFile, FileType, Temporary)\r
434 else:\r
435 Args = (Cursor, MetaFile, Temporary)\r
395f3336
YF
436 if FromItem:\r
437 Args = Args + (FromItem,)\r
0d2711a6
LG
438\r
439 # create the storage object and return it to caller\r
643556fc
FB
440 reval = Class._FILE_TABLE_[FileType](*Args)\r
441 if not Temporary:\r
442 Class._ObjectCache[key] = reval\r
443 return reval\r
0d2711a6 444\r