From 726c501c2c9a1ef103fab7846e2d1a34506715d8 Mon Sep 17 00:00:00 2001 From: Yonghong Zhu Date: Tue, 26 Dec 2017 16:17:13 +0800 Subject: 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 Signed-off-by: Yonghong Zhu Reviewed-by: Liming Gao --- BaseTools/Source/Python/Common/Misc.py | 203 ++++++++++++++++++--------------- 1 file changed, 112 insertions(+), 91 deletions(-) (limited to 'BaseTools/Source/Python/Common/Misc.py') diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py index f44000829a..59d1ba2639 100644 --- a/BaseTools/Source/Python/Common/Misc.py +++ b/BaseTools/Source/Python/Common/Misc.py @@ -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 # -- cgit v1.2.3