BaseTools: Support PCD flexible values format
https://bugzilla.tianocore.org/show_bug.cgi?id=541 Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com> Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
@ -37,6 +37,7 @@ from Parsing import GetSplitValueList
|
||||
from Common.LongFilePathSupport import OpenLongFilePath as open
|
||||
from Common.MultipleWorkspace import MultipleWorkspace as mws
|
||||
import uuid
|
||||
from CommonDataClass.Exceptions import BadExpression
|
||||
|
||||
## Regular expression used to find out place holders in string template
|
||||
gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE | re.UNICODE)
|
||||
@ -1472,99 +1473,119 @@ def AnalyzePcdExpression(Setting):
|
||||
|
||||
return FieldList
|
||||
|
||||
def ParseDevPathValue (Value):
|
||||
pass
|
||||
|
||||
def ParseFieldValue (Value):
|
||||
if type(Value) == type(0):
|
||||
return Value, (Value.bit_length() + 7) / 8
|
||||
if type(Value) <> type(''):
|
||||
raise ValueError
|
||||
Value = Value.strip()
|
||||
if Value.startswith('UINT8') and Value.endswith(')'):
|
||||
Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
|
||||
if Size > 1:
|
||||
raise ValueError
|
||||
if type(Value) == type(0):
|
||||
return Value, (Value.bit_length() + 7) / 8
|
||||
if type(Value) <> type(''):
|
||||
raise BadExpression('Type %s is %s' %(Value, type(Value)))
|
||||
Value = Value.strip()
|
||||
if Value.startswith('UINT8') and Value.endswith(')'):
|
||||
Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
|
||||
if Size > 1:
|
||||
raise BadExpression('Value (%s) Size larger than %d' %(Value, Size))
|
||||
return Value, 1
|
||||
if Value.startswith('UINT16') and Value.endswith(')'):
|
||||
Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
|
||||
if Size > 2:
|
||||
raise BadExpression('Value (%s) Size larger than %d' %(Value, Size))
|
||||
return Value, 2
|
||||
if Value.startswith('UINT32') and Value.endswith(')'):
|
||||
Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
|
||||
if Size > 4:
|
||||
raise BadExpression('Value (%s) Size larger than %d' %(Value, Size))
|
||||
return Value, 4
|
||||
if Value.startswith('UINT64') and Value.endswith(')'):
|
||||
Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
|
||||
if Size > 8:
|
||||
raise BadExpression('Value (%s) Size larger than %d' % (Value, Size))
|
||||
return Value, 8
|
||||
if Value.startswith('GUID') and Value.endswith(')'):
|
||||
Value = Value.split('(', 1)[1][:-1].strip()
|
||||
if Value[0] == '{' and Value[-1] == '}':
|
||||
Value = Value[1:-1].strip()
|
||||
Value = Value.split('{', 1)
|
||||
Value = ['%02x' % int(Item, 16) for Item in (Value[0] + Value[1][:-1]).split(',')]
|
||||
if len(Value[0]) != 8:
|
||||
Value[0] = '%08X' % int(Value[0], 16)
|
||||
if len(Value[1]) != 4:
|
||||
Value[1] = '%04X' % int(Value[1], 16)
|
||||
if len(Value[2]) != 4:
|
||||
Value[2] = '%04X' % int(Value[2], 16)
|
||||
Value = '-'.join(Value[0:3]) + '-' + ''.join(Value[3:5]) + '-' + ''.join(Value[5:11])
|
||||
if Value[0] == '"' and Value[-1] == '"':
|
||||
Value = Value[1:-1]
|
||||
try:
|
||||
Value = "'" + uuid.UUID(Value).get_bytes_le() + "'"
|
||||
except ValueError, Message:
|
||||
raise BadExpression('%s' % Message)
|
||||
Value, Size = ParseFieldValue(Value)
|
||||
return Value, 16
|
||||
if Value.startswith('L"') and Value.endswith('"'):
|
||||
# Unicode String
|
||||
List = list(Value[2:-1])
|
||||
List.reverse()
|
||||
Value = 0
|
||||
for Char in List:
|
||||
Value = (Value << 16) | ord(Char)
|
||||
return Value, (len(List) + 1) * 2
|
||||
if Value.startswith('"') and Value.endswith('"'):
|
||||
# ASCII String
|
||||
List = list(Value[1:-1])
|
||||
List.reverse()
|
||||
Value = 0
|
||||
for Char in List:
|
||||
Value = (Value << 8) | ord(Char)
|
||||
return Value, len(List) + 1
|
||||
if Value.startswith("L'") and Value.endswith("'"):
|
||||
# Unicode Character Constant
|
||||
List = list(Value[2:-1])
|
||||
List.reverse()
|
||||
Value = 0
|
||||
for Char in List:
|
||||
Value = (Value << 16) | ord(Char)
|
||||
return Value, len(List) * 2
|
||||
if Value.startswith("'") and Value.endswith("'"):
|
||||
# Character constant
|
||||
List = list(Value[1:-1])
|
||||
List.reverse()
|
||||
Value = 0
|
||||
for Char in List:
|
||||
Value = (Value << 8) | ord(Char)
|
||||
return Value, len(List)
|
||||
if Value.startswith('{') and Value.endswith('}'):
|
||||
# Byte array
|
||||
Value = Value[1:-1]
|
||||
List = [Item.strip() for Item in Value.split(',')]
|
||||
List.reverse()
|
||||
Value = 0
|
||||
RetSize = 0
|
||||
for Item in List:
|
||||
ItemValue, Size = ParseFieldValue(Item)
|
||||
RetSize += Size
|
||||
for I in range(Size):
|
||||
Value = (Value << 8) | ((ItemValue >> 8 * I) & 0xff)
|
||||
return Value, RetSize
|
||||
if Value.startswith('DEVICE_PATH(') and Value.endswith(')'):
|
||||
Value = Value.split('"')[1]
|
||||
return ParseDevPathValue(Value)
|
||||
if Value.lower().startswith('0x'):
|
||||
Value = int(Value, 16)
|
||||
if Value == 0:
|
||||
return 0, 1
|
||||
return Value, (Value.bit_length() + 7) / 8
|
||||
if Value[0].isdigit():
|
||||
Value = int(Value, 10)
|
||||
if Value == 0:
|
||||
return 0, 1
|
||||
return Value, (Value.bit_length() + 7) / 8
|
||||
if Value.lower() == 'true':
|
||||
return 1, 1
|
||||
if Value.lower() == 'false':
|
||||
return 0, 1
|
||||
return Value, 1
|
||||
if Value.startswith('UINT16') and Value.endswith(')'):
|
||||
Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
|
||||
if Size > 2:
|
||||
raise ValueError
|
||||
return Value, 2
|
||||
if Value.startswith('UINT32') and Value.endswith(')'):
|
||||
Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
|
||||
if Size > 4:
|
||||
raise ValueError
|
||||
return Value, 4
|
||||
if Value.startswith('UINT64') and Value.endswith(')'):
|
||||
Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
|
||||
if Size > 8:
|
||||
raise ValueError
|
||||
return Value, 8
|
||||
if Value.startswith('GUID') and Value.endswith(')'):
|
||||
Value = Value.split('(', 1)[1][:-1].strip()
|
||||
if Value[0] == '{' and Value[-1] == '}':
|
||||
Value = Value[1:-1].strip()
|
||||
Value = Value.split('{', 1)
|
||||
Value = [Item.strip()[2:] for Item in (Value[0] + Value[1][:-1]).split(',')]
|
||||
Value = '-'.join(Value[0:3]) + '-' + ''.join(Value[3:5]) + '-' + ''.join(Value[5:11])
|
||||
if Value[0] == '"' and Value[-1] == '"':
|
||||
Value = Value[1:-1]
|
||||
Value = "'" + uuid.UUID(Value).get_bytes_le() + "'"
|
||||
Value, Size = ParseFieldValue(Value)
|
||||
return Value, 16
|
||||
if Value.startswith('L"') and Value.endswith('"'):
|
||||
# Unicode String
|
||||
List = list(Value[2:-1])
|
||||
List.reverse()
|
||||
Value = 0
|
||||
for Char in List:
|
||||
Value = (Value << 16) | ord(Char)
|
||||
return Value, (len(List) + 1) * 2
|
||||
if Value.startswith('"') and Value.endswith('"'):
|
||||
# ASCII String
|
||||
List = list(Value[1:-1])
|
||||
List.reverse()
|
||||
Value = 0
|
||||
for Char in List:
|
||||
Value = (Value << 8) | ord(Char)
|
||||
return Value, len(List) + 1
|
||||
if Value.startswith("L'") and Value.endswith("'"):
|
||||
# Unicode Character Constant
|
||||
List = list(Value[2:-1])
|
||||
List.reverse()
|
||||
Value = 0
|
||||
for Char in List:
|
||||
Value = (Value << 16) | ord(Char)
|
||||
return Value, len(List) * 2
|
||||
if Value.startswith("'") and Value.endswith("'"):
|
||||
# Character constant
|
||||
List = list(Value[1:-1])
|
||||
List.reverse()
|
||||
Value = 0
|
||||
for Char in List:
|
||||
Value = (Value << 8) | ord(Char)
|
||||
return Value, len(List)
|
||||
if Value.startswith('{') and Value.endswith('}'):
|
||||
# Byte array
|
||||
Value = Value[1:-1]
|
||||
List = [Item.strip() for Item in Value.split(',')]
|
||||
List.reverse()
|
||||
Value = 0
|
||||
for Item in List:
|
||||
ItemValue, Size = ParseFieldValue(Item)
|
||||
if Size > 1:
|
||||
raise ValueError
|
||||
Value = (Value << 8) | ItemValue
|
||||
return Value, len(List)
|
||||
if Value.lower().startswith('0x'):
|
||||
Value = int(Value, 16)
|
||||
return Value, (Value.bit_length() + 7) / 8
|
||||
if Value[0].isdigit():
|
||||
Value = int(Value, 10)
|
||||
return Value, (Value.bit_length() + 7) / 8
|
||||
if Value.lower() == 'true':
|
||||
return 1, 1
|
||||
if Value.lower() == 'false':
|
||||
return 0, 1
|
||||
return Value, 1
|
||||
|
||||
## AnalyzeDscPcd
|
||||
#
|
||||
|
Reference in New Issue
Block a user