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
):
51 TimeStamp
= self
.MetaFile
.TimeStamp
52 if not self
.CurrentContent
:
55 Result
= self
.CurrentContent
[-1][0] < 0
56 except Exception as Exc
:
57 EdkLogger
.debug(EdkLogger
.DEBUG_5
, str(Exc
))
62 self
.CurrentContent
.append(self
._DUMMY
_)
65 return [item
for item
in self
.CurrentContent
if item
[0] >= 0 and item
[-1]>=0]
67 ## Python class representation of table storing module data
68 class ModuleTable(MetaFileTable
):
71 Model INTEGER NOT NULL,
77 BelongsToItem REAL NOT NULL,
78 StartLine INTEGER NOT NULL,
79 StartColumn INTEGER NOT NULL,
80 EndLine INTEGER NOT NULL,
81 EndColumn INTEGER NOT NULL,
82 Enabled INTEGER DEFAULT 0
84 # used as table end flag, in case the changes to database is not committed to db file
85 _DUMMY_
= [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]
88 def __init__(self
, Db
, MetaFile
, Temporary
):
89 MetaFileTable
.__init
__(self
, Db
, MetaFile
, MODEL_FILE_INF
, Temporary
)
91 ## Insert a record into table Inf
93 # @param Model: Model of a Inf item
94 # @param Value1: Value1 of a Inf item
95 # @param Value2: Value2 of a Inf item
96 # @param Value3: Value3 of a Inf item
97 # @param Scope1: Arch of a Inf item
98 # @param Scope2 Platform os a Inf item
99 # @param BelongsToItem: The item belongs to which another item
100 # @param StartLine: StartLine of a Inf item
101 # @param StartColumn: StartColumn of a Inf item
102 # @param EndLine: EndLine of a Inf item
103 # @param EndColumn: EndColumn of a Inf item
104 # @param Enabled: If this item enabled
106 def Insert(self
, Model
, Value1
, Value2
, Value3
, Scope1
=TAB_ARCH_COMMON
, Scope2
=TAB_COMMON
,
107 BelongsToItem
=-1, StartLine
=-1, StartColumn
=-1, EndLine
=-1, EndColumn
=-1, Enabled
=0):
109 (Value1
, Value2
, Value3
, Scope1
, Scope2
) = (Value1
.strip(), Value2
.strip(), Value3
.strip(), Scope1
.strip(), Scope2
.strip())
110 self
.ID
= self
.ID
+ self
._ID
_STEP
_
111 if self
.ID
>= (MODEL_FILE_INF
+ self
._ID
_MAX
_):
112 self
.ID
= MODEL_FILE_INF
+ self
._ID
_STEP
_
128 self
.CurrentContent
.append(row
)
133 # @param Model: The Model of Record
134 # @param Arch: The Arch attribute of Record
135 # @param Platform The Platform attribute of Record
137 # @retval: A recordSet of all found records
139 def Query(self
, Model
, Arch
=None, Platform
=None, BelongsToItem
=None):
141 QueryTab
= self
.CurrentContent
142 result
= [item
for item
in QueryTab
if item
[1] == Model
and item
[-1]>=0 ]
144 if Arch
is not None and Arch
!= TAB_ARCH_COMMON
:
145 ArchList
= set(['COMMON'])
147 result
= [item
for item
in result
if item
[5] in ArchList
]
149 if Platform
is not None and Platform
!= TAB_COMMON
:
150 Platformlist
= set( ['COMMON','DEFAULT'])
151 Platformlist
.add(Platform
)
152 result
= [item
for item
in result
if item
[6] in Platformlist
]
154 if BelongsToItem
is not None:
155 result
= [item
for item
in result
if item
[7] == BelongsToItem
]
157 result
= [ [r
[2],r
[3],r
[4],r
[5],r
[6],r
[0],r
[8]] for r
in result
]
160 ## Python class representation of table storing package data
161 class PackageTable(MetaFileTable
):
164 Model INTEGER NOT NULL,
165 Value1 TEXT NOT NULL,
170 BelongsToItem REAL NOT NULL,
171 StartLine INTEGER NOT NULL,
172 StartColumn INTEGER NOT NULL,
173 EndLine INTEGER NOT NULL,
174 EndColumn INTEGER NOT NULL,
175 Enabled INTEGER DEFAULT 0
177 # used as table end flag, in case the changes to database is not committed to db file
178 _DUMMY_
= [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]
181 def __init__(self
, Cursor
, MetaFile
, Temporary
):
182 MetaFileTable
.__init
__(self
, Cursor
, MetaFile
, MODEL_FILE_DEC
, Temporary
)
186 # Insert a record into table Dec
188 # @param Model: Model of a Dec item
189 # @param Value1: Value1 of a Dec item
190 # @param Value2: Value2 of a Dec item
191 # @param Value3: Value3 of a Dec item
192 # @param Scope1: Arch of a Dec item
193 # @param Scope2: Module type of a Dec item
194 # @param BelongsToItem: The item belongs to which another item
195 # @param StartLine: StartLine of a Dec item
196 # @param StartColumn: StartColumn of a Dec item
197 # @param EndLine: EndLine of a Dec item
198 # @param EndColumn: EndColumn of a Dec item
199 # @param Enabled: If this item enabled
201 def Insert(self
, Model
, Value1
, Value2
, Value3
, Scope1
=TAB_ARCH_COMMON
, Scope2
=TAB_COMMON
,
202 BelongsToItem
=-1, StartLine
=-1, StartColumn
=-1, EndLine
=-1, EndColumn
=-1, Enabled
=0):
203 (Value1
, Value2
, Value3
, Scope1
, Scope2
) = (Value1
.strip(), Value2
.strip(), Value3
.strip(), Scope1
.strip(), Scope2
.strip())
204 self
.ID
= self
.ID
+ self
._ID
_STEP
_
220 self
.CurrentContent
.append(row
)
225 # @param Model: The Model of Record
226 # @param Arch: The Arch attribute of Record
228 # @retval: A recordSet of all found records
230 def Query(self
, Model
, Arch
=None):
232 QueryTab
= self
.CurrentContent
233 result
= [item
for item
in QueryTab
if item
[1] == Model
and item
[-1]>=0 ]
235 if Arch
is not None and Arch
!= TAB_ARCH_COMMON
:
236 ArchList
= set(['COMMON'])
238 result
= [item
for item
in result
if item
[5] in ArchList
]
240 return [[r
[2], r
[3], r
[4], r
[5], r
[6], r
[0], r
[8]] for r
in result
]
242 def GetValidExpression(self
, TokenSpaceGuid
, PcdCName
):
244 QueryTab
= self
.CurrentContent
245 result
= [[item
[2], item
[8]] for item
in QueryTab
if item
[3] == TokenSpaceGuid
and item
[4] == PcdCName
]
254 comment
= comment
.strip("#")
255 comment
= comment
.strip()
257 if comment
.startswith("@ValidRange"):
258 comment
= comment
.replace("@ValidRange", "", 1)
259 validateranges
.append(comment
.split("|")[1].strip())
260 if comment
.startswith("@ValidList"):
261 comment
= comment
.replace("@ValidList", "", 1)
262 validlists
.append(comment
.split("|")[1].strip())
263 if comment
.startswith("@Expression"):
264 comment
= comment
.replace("@Expression", "", 1)
265 expressions
.append(comment
.split("|")[1].strip())
266 except Exception as Exc
:
268 if oricomment
.startswith("@ValidRange"):
269 ValidType
= "@ValidRange"
270 if oricomment
.startswith("@ValidList"):
271 ValidType
= "@ValidList"
272 if oricomment
.startswith("@Expression"):
273 ValidType
= "@Expression"
274 EdkLogger
.error('Parser', FORMAT_INVALID
, "The syntax for %s of PCD %s.%s is incorrect" % (ValidType
, TokenSpaceGuid
, PcdCName
),
275 ExtraData
=oricomment
, File
=self
.MetaFile
, Line
=LineNum
)
276 return set(), set(), set()
277 return set(validateranges
), set(validlists
), set(expressions
)
279 ## Python class representation of table storing platform data
280 class PlatformTable(MetaFileTable
):
283 Model INTEGER NOT NULL,
284 Value1 TEXT NOT NULL,
290 BelongsToItem REAL NOT NULL,
291 FromItem REAL NOT NULL,
292 StartLine INTEGER NOT NULL,
293 StartColumn INTEGER NOT NULL,
294 EndLine INTEGER NOT NULL,
295 EndColumn INTEGER NOT NULL,
296 Enabled INTEGER DEFAULT 0
298 # used as table end flag, in case the changes to database is not committed to db file
299 _DUMMY_
= [-1, -1, '====', '====', '====', '====', '====','====', -1, -1, -1, -1, -1, -1, -1]
302 def __init__(self
, Cursor
, MetaFile
, Temporary
, FromItem
=0):
303 MetaFileTable
.__init
__(self
, Cursor
, MetaFile
, MODEL_FILE_DSC
, Temporary
, FromItem
)
307 # Insert a record into table Dsc
309 # @param Model: Model of a Dsc item
310 # @param Value1: Value1 of a Dsc item
311 # @param Value2: Value2 of a Dsc item
312 # @param Value3: Value3 of a Dsc item
313 # @param Scope1: Arch of a Dsc item
314 # @param Scope2: Module type of a Dsc item
315 # @param BelongsToItem: The item belongs to which another item
316 # @param FromItem: The item belongs to which dsc file
317 # @param StartLine: StartLine of a Dsc item
318 # @param StartColumn: StartColumn of a Dsc item
319 # @param EndLine: EndLine of a Dsc item
320 # @param EndColumn: EndColumn of a Dsc item
321 # @param Enabled: If this item enabled
323 def Insert(self
, Model
, Value1
, Value2
, Value3
, Scope1
=TAB_ARCH_COMMON
, Scope2
=TAB_COMMON
, Scope3
=TAB_DEFAULT_STORES_DEFAULT
,BelongsToItem
=-1,
324 FromItem
=-1, StartLine
=-1, StartColumn
=-1, EndLine
=-1, EndColumn
=-1, Enabled
=1):
325 (Value1
, Value2
, Value3
, Scope1
, Scope2
, Scope3
) = (Value1
.strip(), Value2
.strip(), Value3
.strip(), Scope1
.strip(), Scope2
.strip(), Scope3
.strip())
326 self
.ID
= self
.ID
+ self
._ID
_STEP
_
344 self
.CurrentContent
.append(row
)
350 # @param Model: The Model of Record
351 # @param Scope1: Arch of a Dsc item
352 # @param Scope2: Module type of a Dsc item
353 # @param BelongsToItem: The item belongs to which another item
354 # @param FromItem: The item belongs to which dsc file
356 # @retval: A recordSet of all found records
358 def Query(self
, Model
, Scope1
=None, Scope2
=None, BelongsToItem
=None, FromItem
=None):
360 QueryTab
= self
.CurrentContent
361 result
= [item
for item
in QueryTab
if item
[1] == Model
and item
[-1]>0 ]
362 if Scope1
is not None and Scope1
!= TAB_ARCH_COMMON
:
363 Sc1
= set(['COMMON'])
365 result
= [item
for item
in result
if item
[5] in Sc1
]
366 Sc2
= set( ['COMMON','DEFAULT'])
367 if Scope2
and Scope2
!= TAB_COMMON
:
369 Index
= Scope2
.index('.')
370 NewScope
= TAB_COMMON
+ Scope2
[Index
:]
373 result
= [item
for item
in result
if item
[6] in Sc2
]
375 if BelongsToItem
is not None:
376 result
= [item
for item
in result
if item
[8] == BelongsToItem
]
378 result
= [item
for item
in result
if item
[8] < 0]
379 if FromItem
is not None:
380 result
= [item
for item
in result
if item
[9] == FromItem
]
382 result
= [ [r
[2],r
[3],r
[4],r
[5],r
[6],r
[7],r
[0],r
[10]] for r
in result
]
385 def DisableComponent(self
,comp_id
):
386 for item
in self
.CurrentContent
:
387 if item
[0] == comp_id
or item
[8] == comp_id
:
390 ## Factory class to produce different storage for different type of meta-file
391 class MetaFileStorage(object):
393 MODEL_FILE_INF
: ModuleTable
,
394 MODEL_FILE_DEC
: PackageTable
,
395 MODEL_FILE_DSC
: PlatformTable
,
396 MODEL_FILE_OTHERS
: MetaFileTable
,
400 ".inf" : MODEL_FILE_INF
,
401 ".dec" : MODEL_FILE_DEC
,
402 ".dsc" : MODEL_FILE_DSC
,
406 def __new__(Class
, Cursor
, MetaFile
, FileType
=None, Temporary
=False, FromItem
=None):
407 # no type given, try to find one
408 key
= (MetaFile
.Path
, FileType
,Temporary
,FromItem
)
409 if key
in Class
._ObjectCache
:
410 return Class
._ObjectCache
[key
]
412 if MetaFile
.Type
in self
._FILE
_TYPE
_:
413 FileType
= Class
._FILE
_TYPE
_[MetaFile
.Type
]
415 FileType
= MODEL_FILE_OTHERS
417 # don't pass the type around if it's well known
418 if FileType
== MODEL_FILE_OTHERS
:
419 Args
= (Cursor
, MetaFile
, FileType
, Temporary
)
421 Args
= (Cursor
, MetaFile
, Temporary
)
423 Args
= Args
+ (FromItem
,)
425 # create the storage object and return it to caller
426 reval
= Class
._FILE
_TABLE
_[FileType
](*Args
)
428 Class
._ObjectCache
[key
] = reval