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