2 # This file is used to create/update/query/erase a meta file table
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
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.
17 from __future__
import absolute_import
20 import Common
.EdkLogger
as EdkLogger
21 from Common
.BuildToolError
import FORMAT_INVALID
23 from CommonDataClass
.DataClass
import MODEL_FILE_DSC
, MODEL_FILE_DEC
, MODEL_FILE_INF
, \
25 from Common
.DataType
import *
27 class MetaFileTable():
28 # TRICK: use file ID as the part before '.'
29 _ID_STEP_
= 0.00000001
33 def __init__(self
, DB
, MetaFile
, FileType
, Temporary
, FromItem
=None):
34 self
.MetaFile
= MetaFile
38 self
.FileId
= len(DB
.TblFile
)
40 self
.CurrentContent
= []
41 DB
.TblFile
.append([MetaFile
.Name
,
49 self
.TableName
= "_%s_%s_%s" % (FileType
, len(DB
.TblFile
), uuid
.uuid4().hex)
51 self
.TableName
= "_%s_%s" % (FileType
, len(DB
.TblFile
))
53 def IsIntegrity(self
):
55 TimeStamp
= self
.MetaFile
.TimeStamp
56 Result
= int(self
.CurrentContent
[-1][0]) < 0
58 # update the timestamp in database
59 self
.DB
.SetFileTimeStamp(self
.FileId
, TimeStamp
)
62 if TimeStamp
!= self
.DB
.GetFileTimeStamp(self
.FileId
):
63 # update the timestamp in database
64 self
.DB
.SetFileTimeStamp(self
.FileId
, TimeStamp
)
66 except Exception as Exc
:
67 EdkLogger
.debug(EdkLogger
.DEBUG_5
, str(Exc
))
72 self
.CurrentContent
.append(self
._DUMMY
_)
75 return [item
for item
in self
.CurrentContent
if item
[0] > 0 ]
77 ## Python class representation of table storing module data
78 class ModuleTable(MetaFileTable
):
79 _ID_STEP_
= 0.00000001
83 Model INTEGER NOT NULL,
89 BelongsToItem REAL NOT NULL,
90 StartLine INTEGER NOT NULL,
91 StartColumn INTEGER NOT NULL,
92 EndLine INTEGER NOT NULL,
93 EndColumn INTEGER NOT NULL,
94 Enabled INTEGER DEFAULT 0
96 # used as table end flag, in case the changes to database is not committed to db file
97 _DUMMY_
= [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]
100 def __init__(self
, Db
, MetaFile
, Temporary
):
101 MetaFileTable
.__init
__(self
, Db
, MetaFile
, MODEL_FILE_INF
, Temporary
)
103 ## Insert a record into table Inf
105 # @param Model: Model of a Inf item
106 # @param Value1: Value1 of a Inf item
107 # @param Value2: Value2 of a Inf item
108 # @param Value3: Value3 of a Inf item
109 # @param Scope1: Arch of a Inf item
110 # @param Scope2 Platform os a Inf item
111 # @param BelongsToItem: The item belongs to which another item
112 # @param StartLine: StartLine of a Inf item
113 # @param StartColumn: StartColumn of a Inf item
114 # @param EndLine: EndLine of a Inf item
115 # @param EndColumn: EndColumn of a Inf item
116 # @param Enabled: If this item enabled
118 def Insert(self
, Model
, Value1
, Value2
, Value3
, Scope1
=TAB_ARCH_COMMON
, Scope2
=TAB_COMMON
,
119 BelongsToItem
=-1, StartLine
=-1, StartColumn
=-1, EndLine
=-1, EndColumn
=-1, Enabled
=0):
121 (Value1
, Value2
, Value3
, Scope1
, Scope2
) = (Value1
.strip(), Value2
.strip(), Value3
.strip(), Scope1
.strip(), Scope2
.strip())
122 self
.ID
= self
.ID
+ self
._ID
_STEP
_
123 if self
.ID
>= (MODEL_FILE_INF
+ self
._ID
_MAX
_):
124 self
.ID
= MODEL_FILE_INF
+ self
._ID
_STEP
_
140 self
.CurrentContent
.append(row
)
146 # @param Model: The Model of Record
147 # @param Arch: The Arch attribute of Record
148 # @param Platform The Platform attribute of Record
150 # @retval: A recordSet of all found records
152 def Query(self
, Model
, Arch
=None, Platform
=None, BelongsToItem
=None):
154 QueryTab
= self
.CurrentContent
155 result
= [item
for item
in QueryTab
if item
[1] == Model
and item
[-1]>=0 ]
157 if Arch
is not None and Arch
!= TAB_ARCH_COMMON
:
158 ArchList
= set(['COMMON'])
160 result
= [item
for item
in result
if item
[5] in ArchList
]
162 if Platform
is not None and Platform
!= TAB_COMMON
:
163 Platformlist
= set( ['COMMON','DEFAULT'])
164 Platformlist
.add(Platform
)
165 result
= [item
for item
in result
if item
[6] in Platformlist
]
167 if BelongsToItem
is not None:
168 result
= [item
for item
in result
if item
[7] == BelongsToItem
]
170 result
= [ [r
[2],r
[3],r
[4],r
[5],r
[6],r
[0],r
[9]] for r
in result
]
173 ## Python class representation of table storing package data
174 class PackageTable(MetaFileTable
):
177 Model INTEGER NOT NULL,
178 Value1 TEXT NOT NULL,
183 BelongsToItem REAL NOT NULL,
184 StartLine INTEGER NOT NULL,
185 StartColumn INTEGER NOT NULL,
186 EndLine INTEGER NOT NULL,
187 EndColumn INTEGER NOT NULL,
188 Enabled INTEGER DEFAULT 0
190 # used as table end flag, in case the changes to database is not committed to db file
191 _DUMMY_
= [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]
194 def __init__(self
, Cursor
, MetaFile
, Temporary
):
195 MetaFileTable
.__init
__(self
, Cursor
, MetaFile
, MODEL_FILE_DEC
, Temporary
)
199 # Insert a record into table Dec
201 # @param Model: Model of a Dec item
202 # @param Value1: Value1 of a Dec item
203 # @param Value2: Value2 of a Dec item
204 # @param Value3: Value3 of a Dec item
205 # @param Scope1: Arch of a Dec item
206 # @param Scope2: Module type of a Dec item
207 # @param BelongsToItem: The item belongs to which another item
208 # @param StartLine: StartLine of a Dec item
209 # @param StartColumn: StartColumn of a Dec item
210 # @param EndLine: EndLine of a Dec item
211 # @param EndColumn: EndColumn of a Dec item
212 # @param Enabled: If this item enabled
214 def Insert(self
, Model
, Value1
, Value2
, Value3
, Scope1
=TAB_ARCH_COMMON
, Scope2
=TAB_COMMON
,
215 BelongsToItem
=-1, StartLine
=-1, StartColumn
=-1, EndLine
=-1, EndColumn
=-1, Enabled
=0):
216 (Value1
, Value2
, Value3
, Scope1
, Scope2
) = (Value1
.strip(), Value2
.strip(), Value3
.strip(), Scope1
.strip(), Scope2
.strip())
217 self
.ID
= self
.ID
+ self
._ID
_STEP
_
218 if self
.ID
>= (MODEL_FILE_INF
+ self
._ID
_MAX
_):
219 self
.ID
= MODEL_FILE_INF
+ self
._ID
_STEP
_
235 self
.CurrentContent
.append(row
)
240 # @param Model: The Model of Record
241 # @param Arch: The Arch attribute of Record
243 # @retval: A recordSet of all found records
245 def Query(self
, Model
, Arch
=None):
247 QueryTab
= self
.CurrentContent
248 result
= [item
for item
in QueryTab
if item
[1] == Model
and item
[-1]>=0 ]
250 if Arch
is not None and Arch
!= TAB_ARCH_COMMON
:
251 ArchList
= set(['COMMON'])
253 result
= [item
for item
in result
if item
[5] in ArchList
]
255 return [[r
[2], r
[3], r
[4], r
[5], r
[6], r
[0], r
[8]] for r
in result
]
257 def GetValidExpression(self
, TokenSpaceGuid
, PcdCName
):
259 QueryTab
= self
.CurrentContent
260 result
= [[item
[2], item
[8]] for item
in QueryTab
if item
[3] == TokenSpaceGuid
and item
[4] == PcdCName
]
269 comment
= comment
.strip("#")
270 comment
= comment
.strip()
272 if comment
.startswith("@ValidRange"):
273 comment
= comment
.replace("@ValidRange", "", 1)
274 validateranges
.append(comment
.split("|")[1].strip())
275 if comment
.startswith("@ValidList"):
276 comment
= comment
.replace("@ValidList", "", 1)
277 validlists
.append(comment
.split("|")[1].strip())
278 if comment
.startswith("@Expression"):
279 comment
= comment
.replace("@Expression", "", 1)
280 expressions
.append(comment
.split("|")[1].strip())
281 except Exception as Exc
:
283 if oricomment
.startswith("@ValidRange"):
284 ValidType
= "@ValidRange"
285 if oricomment
.startswith("@ValidList"):
286 ValidType
= "@ValidList"
287 if oricomment
.startswith("@Expression"):
288 ValidType
= "@Expression"
289 EdkLogger
.error('Parser', FORMAT_INVALID
, "The syntax for %s of PCD %s.%s is incorrect" % (ValidType
, TokenSpaceGuid
, PcdCName
),
290 ExtraData
=oricomment
, File
=self
.MetaFile
, Line
=LineNum
)
291 return set(), set(), set()
292 return set(validateranges
), set(validlists
), set(expressions
)
293 ## Python class representation of table storing platform data
294 class PlatformTable(MetaFileTable
):
297 Model INTEGER NOT NULL,
298 Value1 TEXT NOT NULL,
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
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]
316 def __init__(self
, Cursor
, MetaFile
, Temporary
, FromItem
=0):
317 MetaFileTable
.__init
__(self
, Cursor
, MetaFile
, MODEL_FILE_DSC
, Temporary
, FromItem
)
321 # Insert a record into table Dsc
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
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 if self
.ID
>= (MODEL_FILE_INF
+ self
._ID
_MAX
_):
342 self
.ID
= MODEL_FILE_INF
+ self
._ID
_STEP
_
360 self
.CurrentContent
.append(row
)
366 # @param Model: The Model of Record
367 # @param Scope1: Arch of a Dsc item
368 # @param Scope2: Module type of a Dsc item
369 # @param BelongsToItem: The item belongs to which another item
370 # @param FromItem: The item belongs to which dsc file
372 # @retval: A recordSet of all found records
374 def Query(self
, Model
, Scope1
=None, Scope2
=None, BelongsToItem
=None, FromItem
=None):
376 QueryTab
= self
.CurrentContent
377 result
= [item
for item
in QueryTab
if item
[1] == Model
and item
[-1]>0 ]
379 if Scope1
is not None and Scope1
!= TAB_ARCH_COMMON
:
380 Sc1
= set(['COMMON'])
382 result
= [item
for item
in result
if item
[5] in Sc1
]
383 Sc2
= set( ['COMMON','DEFAULT'])
384 if Scope2
and Scope2
!= TAB_COMMON
:
386 Index
= Scope2
.index('.')
387 NewScope
= TAB_COMMON
+ Scope2
[Index
:]
390 result
= [item
for item
in result
if item
[6] in Sc2
]
392 if BelongsToItem
is not None:
393 result
= [item
for item
in result
if item
[8] == BelongsToItem
]
395 result
= [item
for item
in result
if item
[8] < 0]
396 if FromItem
is not None:
397 result
= [item
for item
in result
if item
[9] == FromItem
]
399 result
= [ [r
[2],r
[3],r
[4],r
[5],r
[6],r
[7],r
[0],r
[9]] for r
in result
]
403 ## Factory class to produce different storage for different type of meta-file
404 class MetaFileStorage(object):
406 MODEL_FILE_INF
: ModuleTable
,
407 MODEL_FILE_DEC
: PackageTable
,
408 MODEL_FILE_DSC
: PlatformTable
,
409 MODEL_FILE_OTHERS
: MetaFileTable
,
413 ".inf" : MODEL_FILE_INF
,
414 ".dec" : MODEL_FILE_DEC
,
415 ".dsc" : MODEL_FILE_DSC
,
419 def __new__(Class
, Cursor
, MetaFile
, FileType
=None, Temporary
=False, FromItem
=None):
420 # no type given, try to find one
422 if MetaFile
.Type
in self
._FILE
_TYPE
_:
423 FileType
= Class
._FILE
_TYPE
_[MetaFile
.Type
]
425 FileType
= MODEL_FILE_OTHERS
427 # don't pass the type around if it's well known
428 if FileType
== MODEL_FILE_OTHERS
:
429 Args
= (Cursor
, MetaFile
, FileType
, Temporary
)
431 Args
= (Cursor
, MetaFile
, Temporary
)
433 Args
= Args
+ (FromItem
,)
435 # create the storage object and return it to caller
436 return Class
._FILE
_TABLE
_[FileType
](*Args
)