fdt: Use an Enum for the data type
Use an Enum instead of the current ad-hoc constants, so that there is a data type associated with each 'type' value. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
ddaa949785
commit
5ea9dccf02
@ -50,37 +50,37 @@ class TestFdt(unittest.TestCase):
|
||||
self.assertEquals('me.bin', val)
|
||||
|
||||
prop = node.props['intval']
|
||||
self.assertEquals(fdt.TYPE_INT, prop.type)
|
||||
self.assertEquals(fdt.Type.INT, prop.type)
|
||||
self.assertEquals(3, fdt_util.GetInt(node, 'intval'))
|
||||
|
||||
prop = node.props['intarray']
|
||||
self.assertEquals(fdt.TYPE_INT, prop.type)
|
||||
self.assertEquals(fdt.Type.INT, prop.type)
|
||||
self.assertEquals(list, type(prop.value))
|
||||
self.assertEquals(2, len(prop.value))
|
||||
self.assertEquals([5, 6],
|
||||
[fdt_util.fdt32_to_cpu(val) for val in prop.value])
|
||||
|
||||
prop = node.props['byteval']
|
||||
self.assertEquals(fdt.TYPE_BYTE, prop.type)
|
||||
self.assertEquals(fdt.Type.BYTE, prop.type)
|
||||
self.assertEquals(chr(8), prop.value)
|
||||
|
||||
prop = node.props['bytearray']
|
||||
self.assertEquals(fdt.TYPE_BYTE, prop.type)
|
||||
self.assertEquals(fdt.Type.BYTE, prop.type)
|
||||
self.assertEquals(list, type(prop.value))
|
||||
self.assertEquals(str, type(prop.value[0]))
|
||||
self.assertEquals(3, len(prop.value))
|
||||
self.assertEquals([chr(1), '#', '4'], prop.value)
|
||||
|
||||
prop = node.props['longbytearray']
|
||||
self.assertEquals(fdt.TYPE_INT, prop.type)
|
||||
self.assertEquals(fdt.Type.INT, prop.type)
|
||||
self.assertEquals(0x090a0b0c, fdt_util.GetInt(node, 'longbytearray'))
|
||||
|
||||
prop = node.props['stringval']
|
||||
self.assertEquals(fdt.TYPE_STRING, prop.type)
|
||||
self.assertEquals(fdt.Type.STRING, prop.type)
|
||||
self.assertEquals('message2', fdt_util.GetString(node, 'stringval'))
|
||||
|
||||
prop = node.props['stringarray']
|
||||
self.assertEquals(fdt.TYPE_STRING, prop.type)
|
||||
self.assertEquals(fdt.Type.STRING, prop.type)
|
||||
self.assertEquals(list, type(prop.value))
|
||||
self.assertEquals(3, len(prop.value))
|
||||
self.assertEquals(['another', 'multi-word', 'message'], prop.value)
|
||||
|
@ -35,13 +35,13 @@ PROP_IGNORE_LIST = [
|
||||
'u-boot,dm-spl',
|
||||
]
|
||||
|
||||
# C type declarations for the tyues we support
|
||||
# C type declarations for the types we support
|
||||
TYPE_NAMES = {
|
||||
fdt.TYPE_INT: 'fdt32_t',
|
||||
fdt.TYPE_BYTE: 'unsigned char',
|
||||
fdt.TYPE_STRING: 'const char *',
|
||||
fdt.TYPE_BOOL: 'bool',
|
||||
fdt.TYPE_INT64: 'fdt64_t',
|
||||
fdt.Type.INT: 'fdt32_t',
|
||||
fdt.Type.BYTE: 'unsigned char',
|
||||
fdt.Type.STRING: 'const char *',
|
||||
fdt.Type.BOOL: 'bool',
|
||||
fdt.Type.INT64: 'fdt64_t',
|
||||
}
|
||||
|
||||
STRUCT_PREFIX = 'dtd_'
|
||||
@ -106,17 +106,17 @@ def get_value(ftype, value):
|
||||
type: Data type (fdt_util)
|
||||
value: Data value, as a string of bytes
|
||||
"""
|
||||
if ftype == fdt.TYPE_INT:
|
||||
if ftype == fdt.Type.INT:
|
||||
return '%#x' % fdt_util.fdt32_to_cpu(value)
|
||||
elif ftype == fdt.TYPE_BYTE:
|
||||
elif ftype == fdt.Type.BYTE:
|
||||
return '%#x' % tools.ToByte(value[0])
|
||||
elif ftype == fdt.TYPE_STRING:
|
||||
elif ftype == fdt.Type.STRING:
|
||||
# Handle evil ACPI backslashes by adding another backslash before them.
|
||||
# So "\\_SB.GPO0" in the device tree effectively stays like that in C
|
||||
return '"%s"' % value.replace('\\', '\\\\')
|
||||
elif ftype == fdt.TYPE_BOOL:
|
||||
elif ftype == fdt.Type.BOOL:
|
||||
return 'true'
|
||||
elif ftype == fdt.TYPE_INT64:
|
||||
elif ftype == fdt.Type.INT64:
|
||||
return '%#x' % value
|
||||
|
||||
def get_compat_name(node):
|
||||
@ -435,7 +435,7 @@ class DtbPlatdata(object):
|
||||
na, ns = self.get_num_cells(node)
|
||||
total = na + ns
|
||||
|
||||
if reg.type != fdt.TYPE_INT:
|
||||
if reg.type != fdt.Type.INT:
|
||||
raise ValueError("Node '%s' reg property is not an int" %
|
||||
node.name)
|
||||
if len(reg.value) % total:
|
||||
@ -445,7 +445,7 @@ class DtbPlatdata(object):
|
||||
reg.na = na
|
||||
reg.ns = ns
|
||||
if na != 1 or ns != 1:
|
||||
reg.type = fdt.TYPE_INT64
|
||||
reg.type = fdt.Type.INT64
|
||||
i = 0
|
||||
new_value = []
|
||||
val = reg.value
|
||||
|
@ -5,6 +5,7 @@
|
||||
# Written by Simon Glass <sjg@chromium.org>
|
||||
#
|
||||
|
||||
from enum import IntEnum
|
||||
import struct
|
||||
import sys
|
||||
|
||||
@ -22,7 +23,25 @@ from patman import tools
|
||||
# so it is fairly efficient.
|
||||
|
||||
# A list of types we support
|
||||
(TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL, TYPE_INT64) = range(5)
|
||||
class Type(IntEnum):
|
||||
(BYTE, INT, STRING, BOOL, INT64) = range(5)
|
||||
|
||||
def is_wider_than(self, other):
|
||||
"""Check if another type is 'wider' than this one
|
||||
|
||||
A wider type is one that holds more information than an earlier one,
|
||||
similar to the concept of type-widening in C.
|
||||
|
||||
This uses a simple arithmetic comparison, since type values are in order
|
||||
from narrowest (BYTE) to widest (INT64).
|
||||
|
||||
Args:
|
||||
other: Other type to compare against
|
||||
|
||||
Return:
|
||||
True if the other type is wider
|
||||
"""
|
||||
return self.value > other.value
|
||||
|
||||
def CheckErr(errnum, msg):
|
||||
if errnum:
|
||||
@ -41,9 +60,9 @@ def BytesToValue(data):
|
||||
Type of data
|
||||
Data, either a single element or a list of elements. Each element
|
||||
is one of:
|
||||
TYPE_STRING: str/bytes value from the property
|
||||
TYPE_INT: a byte-swapped integer stored as a 4-byte str/bytes
|
||||
TYPE_BYTE: a byte stored as a single-byte str/bytes
|
||||
Type.STRING: str/bytes value from the property
|
||||
Type.INT: a byte-swapped integer stored as a 4-byte str/bytes
|
||||
Type.BYTE: a byte stored as a single-byte str/bytes
|
||||
"""
|
||||
data = bytes(data)
|
||||
size = len(data)
|
||||
@ -63,21 +82,21 @@ def BytesToValue(data):
|
||||
is_string = False
|
||||
if is_string:
|
||||
if count == 1:
|
||||
return TYPE_STRING, strings[0].decode()
|
||||
return Type.STRING, strings[0].decode()
|
||||
else:
|
||||
return TYPE_STRING, [s.decode() for s in strings[:-1]]
|
||||
return Type.STRING, [s.decode() for s in strings[:-1]]
|
||||
if size % 4:
|
||||
if size == 1:
|
||||
return TYPE_BYTE, tools.ToChar(data[0])
|
||||
return Type.BYTE, tools.ToChar(data[0])
|
||||
else:
|
||||
return TYPE_BYTE, [tools.ToChar(ch) for ch in list(data)]
|
||||
return Type.BYTE, [tools.ToChar(ch) for ch in list(data)]
|
||||
val = []
|
||||
for i in range(0, size, 4):
|
||||
val.append(data[i:i + 4])
|
||||
if size == 4:
|
||||
return TYPE_INT, val[0]
|
||||
return Type.INT, val[0]
|
||||
else:
|
||||
return TYPE_INT, val
|
||||
return Type.INT, val
|
||||
|
||||
|
||||
class Prop:
|
||||
@ -97,7 +116,7 @@ class Prop:
|
||||
self.bytes = bytes(data)
|
||||
self.dirty = False
|
||||
if not data:
|
||||
self.type = TYPE_BOOL
|
||||
self.type = Type.BOOL
|
||||
self.value = True
|
||||
return
|
||||
self.type, self.value = BytesToValue(bytes(data))
|
||||
@ -128,9 +147,8 @@ class Prop:
|
||||
update the current property to be like the second, since it is less
|
||||
specific.
|
||||
"""
|
||||
if newprop.type < self.type:
|
||||
# Special handling to convert an int into bytes
|
||||
if self.type == TYPE_INT and newprop.type == TYPE_BYTE:
|
||||
if self.type.is_wider_than(newprop.type):
|
||||
if self.type == Type.INT and newprop.type == Type.BYTE:
|
||||
if type(self.value) == list:
|
||||
new_value = []
|
||||
for val in self.value:
|
||||
@ -155,11 +173,11 @@ class Prop:
|
||||
Returns:
|
||||
A single value of the given type
|
||||
"""
|
||||
if type == TYPE_BYTE:
|
||||
if type == Type.BYTE:
|
||||
return chr(0)
|
||||
elif type == TYPE_INT:
|
||||
elif type == Type.INT:
|
||||
return struct.pack('>I', 0);
|
||||
elif type == TYPE_STRING:
|
||||
elif type == Type.STRING:
|
||||
return ''
|
||||
else:
|
||||
return True
|
||||
@ -184,7 +202,7 @@ class Prop:
|
||||
"""
|
||||
self.bytes = struct.pack('>I', val);
|
||||
self.value = self.bytes
|
||||
self.type = TYPE_INT
|
||||
self.type = Type.INT
|
||||
self.dirty = True
|
||||
|
||||
def SetData(self, bytes):
|
||||
|
@ -134,13 +134,13 @@ class TestDtoc(unittest.TestCase):
|
||||
def test_get_value(self):
|
||||
"""Test operation of get_value() function"""
|
||||
self.assertEqual('0x45',
|
||||
get_value(fdt.TYPE_INT, struct.pack('>I', 0x45)))
|
||||
get_value(fdt.Type.INT, struct.pack('>I', 0x45)))
|
||||
self.assertEqual('0x45',
|
||||
get_value(fdt.TYPE_BYTE, struct.pack('<I', 0x45)))
|
||||
get_value(fdt.Type.BYTE, struct.pack('<I', 0x45)))
|
||||
self.assertEqual('0x0',
|
||||
get_value(fdt.TYPE_BYTE, struct.pack('>I', 0x45)))
|
||||
self.assertEqual('"test"', get_value(fdt.TYPE_STRING, 'test'))
|
||||
self.assertEqual('true', get_value(fdt.TYPE_BOOL, None))
|
||||
get_value(fdt.Type.BYTE, struct.pack('>I', 0x45)))
|
||||
self.assertEqual('"test"', get_value(fdt.Type.STRING, 'test'))
|
||||
self.assertEqual('true', get_value(fdt.Type.BOOL, None))
|
||||
|
||||
def test_get_compat_name(self):
|
||||
"""Test operation of get_compat_name() function"""
|
||||
|
@ -19,7 +19,7 @@ sys.path.insert(1, os.path.join(our_path, '..'))
|
||||
from dtoc import fdt
|
||||
from dtoc import fdt_util
|
||||
from dtoc.fdt_util import fdt32_to_cpu
|
||||
from fdt import TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL, BytesToValue
|
||||
from fdt import Type, BytesToValue
|
||||
import libfdt
|
||||
from patman import command
|
||||
from patman import test_util
|
||||
@ -127,7 +127,7 @@ class TestFdt(unittest.TestCase):
|
||||
|
||||
def testBytesToValue(self):
|
||||
self.assertEqual(BytesToValue(b'this\0is\0'),
|
||||
(TYPE_STRING, ['this', 'is']))
|
||||
(Type.STRING, ['this', 'is']))
|
||||
|
||||
class TestNode(unittest.TestCase):
|
||||
"""Test operation of the Node class"""
|
||||
@ -249,46 +249,46 @@ class TestProp(unittest.TestCase):
|
||||
def testMakeProp(self):
|
||||
"""Test we can convert all the the types that are supported"""
|
||||
prop = self._ConvertProp('boolval')
|
||||
self.assertEqual(fdt.TYPE_BOOL, prop.type)
|
||||
self.assertEqual(Type.BOOL, prop.type)
|
||||
self.assertEqual(True, prop.value)
|
||||
|
||||
prop = self._ConvertProp('intval')
|
||||
self.assertEqual(fdt.TYPE_INT, prop.type)
|
||||
self.assertEqual(Type.INT, prop.type)
|
||||
self.assertEqual(1, fdt32_to_cpu(prop.value))
|
||||
|
||||
prop = self._ConvertProp('intarray')
|
||||
self.assertEqual(fdt.TYPE_INT, prop.type)
|
||||
self.assertEqual(Type.INT, prop.type)
|
||||
val = [fdt32_to_cpu(val) for val in prop.value]
|
||||
self.assertEqual([2, 3, 4], val)
|
||||
|
||||
prop = self._ConvertProp('byteval')
|
||||
self.assertEqual(fdt.TYPE_BYTE, prop.type)
|
||||
self.assertEqual(Type.BYTE, prop.type)
|
||||
self.assertEqual(5, ord(prop.value))
|
||||
|
||||
prop = self._ConvertProp('longbytearray')
|
||||
self.assertEqual(fdt.TYPE_BYTE, prop.type)
|
||||
self.assertEqual(Type.BYTE, prop.type)
|
||||
val = [ord(val) for val in prop.value]
|
||||
self.assertEqual([9, 10, 11, 12, 13, 14, 15, 16, 17], val)
|
||||
|
||||
prop = self._ConvertProp('stringval')
|
||||
self.assertEqual(fdt.TYPE_STRING, prop.type)
|
||||
self.assertEqual(Type.STRING, prop.type)
|
||||
self.assertEqual('message', prop.value)
|
||||
|
||||
prop = self._ConvertProp('stringarray')
|
||||
self.assertEqual(fdt.TYPE_STRING, prop.type)
|
||||
self.assertEqual(Type.STRING, prop.type)
|
||||
self.assertEqual(['multi-word', 'message'], prop.value)
|
||||
|
||||
prop = self._ConvertProp('notstring')
|
||||
self.assertEqual(fdt.TYPE_BYTE, prop.type)
|
||||
self.assertEqual(Type.BYTE, prop.type)
|
||||
val = [ord(val) for val in prop.value]
|
||||
self.assertEqual([0x20, 0x21, 0x22, 0x10, 0], val)
|
||||
|
||||
def testGetEmpty(self):
|
||||
"""Tests the GetEmpty() function for the various supported types"""
|
||||
self.assertEqual(True, fdt.Prop.GetEmpty(fdt.TYPE_BOOL))
|
||||
self.assertEqual(chr(0), fdt.Prop.GetEmpty(fdt.TYPE_BYTE))
|
||||
self.assertEqual(tools.GetBytes(0, 4), fdt.Prop.GetEmpty(fdt.TYPE_INT))
|
||||
self.assertEqual('', fdt.Prop.GetEmpty(fdt.TYPE_STRING))
|
||||
self.assertEqual(True, fdt.Prop.GetEmpty(Type.BOOL))
|
||||
self.assertEqual(chr(0), fdt.Prop.GetEmpty(Type.BYTE))
|
||||
self.assertEqual(tools.GetBytes(0, 4), fdt.Prop.GetEmpty(Type.INT))
|
||||
self.assertEqual('', fdt.Prop.GetEmpty(Type.STRING))
|
||||
|
||||
def testGetOffset(self):
|
||||
"""Test we can get the offset of a property"""
|
||||
@ -304,13 +304,13 @@ class TestProp(unittest.TestCase):
|
||||
# No action
|
||||
prop2 = node2.props['intval']
|
||||
prop.Widen(prop2)
|
||||
self.assertEqual(fdt.TYPE_INT, prop.type)
|
||||
self.assertEqual(Type.INT, prop.type)
|
||||
self.assertEqual(1, fdt32_to_cpu(prop.value))
|
||||
|
||||
# Convert singla value to array
|
||||
prop2 = self.node.props['intarray']
|
||||
prop.Widen(prop2)
|
||||
self.assertEqual(fdt.TYPE_INT, prop.type)
|
||||
self.assertEqual(Type.INT, prop.type)
|
||||
self.assertTrue(isinstance(prop.value, list))
|
||||
|
||||
# A 4-byte array looks like a single integer. When widened by a longer
|
||||
|
Loading…
Reference in New Issue
Block a user