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 # SPDX-License-Identifier: BSD-2-Clause-Patent
11 from __future__
import absolute_import
14 import Common
.EdkLogger
as EdkLogger
15 from Common
.BuildToolError
import FORMAT_INVALID
17 from CommonDataClass
.DataClass
import MODEL_FILE_DSC
, MODEL_FILE_DEC
, MODEL_FILE_INF
, \
19 from Common
.DataType
import *
21 class MetaFileTable():
22 # TRICK: use file ID as the part before '.'
27 def __init__(self
, DB
, MetaFile
, FileType
, Temporary
, FromItem
=None):
28 self
.MetaFile
= MetaFile
33 self
.CurrentContent
= []
34 DB
.TblFile
.append([MetaFile
.Name
,
41 self
.FileId
= len(DB
.TblFile
)
42 self
.ID
= self
.FileId
* 10**8
44 self
.TableName
= "_%s_%s_%s" % (FileType
, len(DB
.TblFile
), uuid
.uuid4().hex)
46 self
.TableName
= "_%s_%s" % (FileType
, len(DB
.TblFile
))
48 def IsIntegrity(self
):
50 TimeStamp
= self
.MetaFile
.TimeStamp
51 if not self
.CurrentContent
:
54 Result
= self
.CurrentContent
[-1][0] < 0
56 # update the timestamp in database
57 self
.DB
.SetFileTimeStamp(self
.FileId
, TimeStamp
)
60 if TimeStamp
!= self
.DB
.GetFileTimeStamp(self
.FileId
):
61 # update the timestamp in database
62 self
.DB
.SetFileTimeStamp(self
.FileId
, TimeStamp
)
64 except Exception as Exc
:
65 EdkLogger
.debug(EdkLogger
.DEBUG_5
, str(Exc
))
70 self
.CurrentContent
.append(self
._DUMMY
_)
73 return [item
for item
in self
.CurrentContent
if item
[0] >= 0 and item
[-1]>=0]
75 ## Python class representation of table storing module data
76 class ModuleTable(MetaFileTable
):
79 Model INTEGER NOT NULL,
85 BelongsToItem REAL NOT NULL,
86 StartLine INTEGER NOT NULL,
87 StartColumn INTEGER NOT NULL,
88 EndLine INTEGER NOT NULL,
89 EndColumn INTEGER NOT NULL,
90 Enabled INTEGER DEFAULT 0
92 # used as table end flag, in case the changes to database is not committed to db file
93 _DUMMY_
= [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]
96 def __init__(self
, Db
, MetaFile
, Temporary
):
97 MetaFileTable
.__init
__(self
, Db
, MetaFile
, MODEL_FILE_INF
, Temporary
)
99 ## Insert a record into table Inf
101 # @param Model: Model of a Inf item
102 # @param Value1: Value1 of a Inf item
103 # @param Value2: Value2 of a Inf item
104 # @param Value3: Value3 of a Inf item
105 # @param Scope1: Arch of a Inf item
106 # @param Scope2 Platform os a Inf item
107 # @param BelongsToItem: The item belongs to which another item
108 # @param StartLine: StartLine of a Inf item
109 # @param StartColumn: StartColumn of a Inf item
110 # @param EndLine: EndLine of a Inf item
111 # @param EndColumn: EndColumn of a Inf item
112 # @param Enabled: If this item enabled
114 def Insert(self
, Model
, Value1
, Value2
, Value3
, Scope1
=TAB_ARCH_COMMON
, Scope2
=TAB_COMMON
,
115 BelongsToItem
=-1, StartLine
=-1, StartColumn
=-1, EndLine
=-1, EndColumn
=-1, Enabled
=0):
117 (Value1
, Value2
, Value3
, Scope1
, Scope2
) = (Value1
.strip(), Value2
.strip(), Value3
.strip(), Scope1
.strip(), Scope2
.strip())
118 self
.ID
= self
.ID
+ self
._ID
_STEP
_
119 if self
.ID
>= (MODEL_FILE_INF
+ self
._ID
_MAX
_):
120 self
.ID
= MODEL_FILE_INF
+ self
._ID
_STEP
_
136 self
.CurrentContent
.append(row
)
141 # @param Model: The Model of Record
142 # @param Arch: The Arch attribute of Record
143 # @param Platform The Platform attribute of Record
145 # @retval: A recordSet of all found records
147 def Query(self
, Model
, Arch
=None, Platform
=None, BelongsToItem
=None):
149 QueryTab
= self
.CurrentContent
150 result
= [item
for item
in QueryTab
if item
[1] == Model
and item
[-1]>=0 ]
152 if Arch
is not None and Arch
!= TAB_ARCH_COMMON
:
153 ArchList
= set(['COMMON'])
155 result
= [item
for item
in result
if item
[5] in ArchList
]
157 if Platform
is not None and Platform
!= TAB_COMMON
:
158 Platformlist
= set( ['COMMON','DEFAULT'])
159 Platformlist
.add(Platform
)
160 result
= [item
for item
in result
if item
[6] in Platformlist
]
162 if BelongsToItem
is not None:
163 result
= [item
for item
in result
if item
[7] == BelongsToItem
]
165 result
= [ [r
[2],r
[3],r
[4],r
[5],r
[6],r
[0],r
[9]] for r
in result
]
168 ## Python class representation of table storing package data
169 class PackageTable(MetaFileTable
):
172 Model INTEGER NOT NULL,
173 Value1 TEXT NOT NULL,
178 BelongsToItem REAL NOT NULL,
179 StartLine INTEGER NOT NULL,
180 StartColumn INTEGER NOT NULL,
181 EndLine INTEGER NOT NULL,
182 EndColumn INTEGER NOT NULL,
183 Enabled INTEGER DEFAULT 0
185 # used as table end flag, in case the changes to database is not committed to db file
186 _DUMMY_
= [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]
189 def __init__(self
, Cursor
, MetaFile
, Temporary
):
190 MetaFileTable
.__init
__(self
, Cursor
, MetaFile
, MODEL_FILE_DEC
, Temporary
)
194 # Insert a record into table Dec
196 # @param Model: Model of a Dec item
197 # @param Value1: Value1 of a Dec item
198 # @param Value2: Value2 of a Dec item
199 # @param Value3: Value3 of a Dec item
200 # @param Scope1: Arch of a Dec item
201 # @param Scope2: Module type of a Dec item
202 # @param BelongsToItem: The item belongs to which another item
203 # @param StartLine: StartLine of a Dec item
204 # @param StartColumn: StartColumn of a Dec item
205 # @param EndLine: EndLine of a Dec item
206 # @param EndColumn: EndColumn of a Dec item
207 # @param Enabled: If this item enabled
209 def Insert(self
, Model
, Value1
, Value2
, Value3
, Scope1
=TAB_ARCH_COMMON
, Scope2
=TAB_COMMON
,
210 BelongsToItem
=-1, StartLine
=-1, StartColumn
=-1, EndLine
=-1, EndColumn
=-1, Enabled
=0):
211 (Value1
, Value2
, Value3
, Scope1
, Scope2
) = (Value1
.strip(), Value2
.strip(), Value3
.strip(), Scope1
.strip(), Scope2
.strip())
212 self
.ID
= self
.ID
+ self
._ID
_STEP
_
228 self
.CurrentContent
.append(row
)
233 # @param Model: The Model of Record
234 # @param Arch: The Arch attribute of Record
236 # @retval: A recordSet of all found records
238 def Query(self
, Model
, Arch
=None):
240 QueryTab
= self
.CurrentContent
241 result
= [item
for item
in QueryTab
if item
[1] == Model
and item
[-1]>=0 ]
243 if Arch
is not None and Arch
!= TAB_ARCH_COMMON
:
244 ArchList
= set(['COMMON'])
246 result
= [item
for item
in result
if item
[5] in ArchList
]
248 return [[r
[2], r
[3], r
[4], r
[5], r
[6], r
[0], r
[8]] for r
in result
]
250 def GetValidExpression(self
, TokenSpaceGuid
, PcdCName
):
252 QueryTab
= self
.CurrentContent
253 result
= [[item
[2], item
[8]] for item
in QueryTab
if item
[3] == TokenSpaceGuid
and item
[4] == PcdCName
]
262 comment
= comment
.strip("#")
263 comment
= comment
.strip()
265 if comment
.startswith("@ValidRange"):
266 comment
= comment
.replace("@ValidRange", "", 1)
267 validateranges
.append(comment
.split("|")[1].strip())
268 if comment
.startswith("@ValidList"):
269 comment
= comment
.replace("@ValidList", "", 1)
270 validlists
.append(comment
.split("|")[1].strip())
271 if comment
.startswith("@Expression"):
272 comment
= comment
.replace("@Expression", "", 1)
273 expressions
.append(comment
.split("|")[1].strip())
274 except Exception as Exc
:
276 if oricomment
.startswith("@ValidRange"):
277 ValidType
= "@ValidRange"
278 if oricomment
.startswith("@ValidList"):
279 ValidType
= "@ValidList"
280 if oricomment
.startswith("@Expression"):
281 ValidType
= "@Expression"
282 EdkLogger
.error('Parser', FORMAT_INVALID
, "The syntax for %s of PCD %s.%s is incorrect" % (ValidType
, TokenSpaceGuid
, PcdCName
),
283 ExtraData
=oricomment
, File
=self
.MetaFile
, Line
=LineNum
)
284 return set(), set(), set()
285 return set(validateranges
), set(validlists
), set(expressions
)
287 ## Python class representation of table storing platform data
288 class PlatformTable(MetaFileTable
):
291 Model INTEGER NOT NULL,
292 Value1 TEXT NOT NULL,
298 BelongsToItem REAL NOT NULL,
299 FromItem REAL NOT NULL,
300 StartLine INTEGER NOT NULL,
301 StartColumn INTEGER NOT NULL,
302 EndLine INTEGER NOT NULL,
303 EndColumn INTEGER NOT NULL,
304 Enabled INTEGER DEFAULT 0
306 # used as table end flag, in case the changes to database is not committed to db file
307 _DUMMY_
= [-1, -1, '====', '====', '====', '====', '====','====', -1, -1, -1, -1, -1, -1, -1]
310 def __init__(self
, Cursor
, MetaFile
, Temporary
, FromItem
=0):
311 MetaFileTable
.__init
__(self
, Cursor
, MetaFile
, MODEL_FILE_DSC
, Temporary
, FromItem
)
315 # Insert a record into table Dsc
317 # @param Model: Model of a Dsc item
318 # @param Value1: Value1 of a Dsc item
319 # @param Value2: Value2 of a Dsc item
320 # @param Value3: Value3 of a Dsc item
321 # @param Scope1: Arch of a Dsc item
322 # @param Scope2: Module type of a Dsc item
323 # @param BelongsToItem: The item belongs to which another item
324 # @param FromItem: The item belongs to which dsc file
325 # @param StartLine: StartLine of a Dsc item
326 # @param StartColumn: StartColumn of a Dsc item
327 # @param EndLine: EndLine of a Dsc item
328 # @param EndColumn: EndColumn of a Dsc item
329 # @param Enabled: If this item enabled
331 def Insert(self
, Model
, Value1
, Value2
, Value3
, Scope1
=TAB_ARCH_COMMON
, Scope2
=TAB_COMMON
, Scope3
=TAB_DEFAULT_STORES_DEFAULT
,BelongsToItem
=-1,
332 FromItem
=-1, StartLine
=-1, StartColumn
=-1, EndLine
=-1, EndColumn
=-1, Enabled
=1):
333 (Value1
, Value2
, Value3
, Scope1
, Scope2
, Scope3
) = (Value1
.strip(), Value2
.strip(), Value3
.strip(), Scope1
.strip(), Scope2
.strip(), Scope3
.strip())
334 self
.ID
= self
.ID
+ self
._ID
_STEP
_
352 self
.CurrentContent
.append(row
)
358 # @param Model: The Model of Record
359 # @param Scope1: Arch of a Dsc item
360 # @param Scope2: Module type of a Dsc item
361 # @param BelongsToItem: The item belongs to which another item
362 # @param FromItem: The item belongs to which dsc file
364 # @retval: A recordSet of all found records
366 def Query(self
, Model
, Scope1
=None, Scope2
=None, BelongsToItem
=None, FromItem
=None):
368 QueryTab
= self
.CurrentContent
369 result
= [item
for item
in QueryTab
if item
[1] == Model
and item
[-1]>0 ]
370 if Scope1
is not None and Scope1
!= TAB_ARCH_COMMON
:
371 Sc1
= set(['COMMON'])
373 result
= [item
for item
in result
if item
[5] in Sc1
]
374 Sc2
= set( ['COMMON','DEFAULT'])
375 if Scope2
and Scope2
!= TAB_COMMON
:
377 Index
= Scope2
.index('.')
378 NewScope
= TAB_COMMON
+ Scope2
[Index
:]
381 result
= [item
for item
in result
if item
[6] in Sc2
]
383 if BelongsToItem
is not None:
384 result
= [item
for item
in result
if item
[8] == BelongsToItem
]
386 result
= [item
for item
in result
if item
[8] < 0]
387 if FromItem
is not None:
388 result
= [item
for item
in result
if item
[9] == FromItem
]
390 result
= [ [r
[2],r
[3],r
[4],r
[5],r
[6],r
[7],r
[0],r
[10]] for r
in result
]
393 def DisableComponent(self
,comp_id
):
394 for item
in self
.CurrentContent
:
395 if item
[0] == comp_id
or item
[8] == comp_id
:
398 ## Factory class to produce different storage for different type of meta-file
399 class MetaFileStorage(object):
401 MODEL_FILE_INF
: ModuleTable
,
402 MODEL_FILE_DEC
: PackageTable
,
403 MODEL_FILE_DSC
: PlatformTable
,
404 MODEL_FILE_OTHERS
: MetaFileTable
,
408 ".inf" : MODEL_FILE_INF
,
409 ".dec" : MODEL_FILE_DEC
,
410 ".dsc" : MODEL_FILE_DSC
,
414 def __new__(Class
, Cursor
, MetaFile
, FileType
=None, Temporary
=False, FromItem
=None):
415 # no type given, try to find one
416 key
= (MetaFile
.Path
, FileType
,Temporary
,FromItem
)
417 if key
in Class
._ObjectCache
:
418 return Class
._ObjectCache
[key
]
420 if MetaFile
.Type
in self
._FILE
_TYPE
_:
421 FileType
= Class
._FILE
_TYPE
_[MetaFile
.Type
]
423 FileType
= MODEL_FILE_OTHERS
425 # don't pass the type around if it's well known
426 if FileType
== MODEL_FILE_OTHERS
:
427 Args
= (Cursor
, MetaFile
, FileType
, Temporary
)
429 Args
= (Cursor
, MetaFile
, Temporary
)
431 Args
= Args
+ (FromItem
,)
433 # create the storage object and return it to caller
434 reval
= Class
._FILE
_TABLE
_[FileType
](*Args
)
436 Class
._ObjectCache
[key
] = reval