[PATCH 1/5] fdt: Use an Enum for the data type
Simon Glass
sjg at chromium.org
Mon Nov 9 04:36:17 CET 2020
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 at chromium.org>
---
tools/binman/fdt_test.py | 14 +++++-----
tools/dtoc/dtb_platdata.py | 26 +++++++++---------
tools/dtoc/fdt.py | 54 +++++++++++++++++++++++++-------------
tools/dtoc/test_dtoc.py | 10 +++----
tools/dtoc/test_fdt.py | 32 +++++++++++-----------
5 files changed, 77 insertions(+), 59 deletions(-)
diff --git a/tools/binman/fdt_test.py b/tools/binman/fdt_test.py
index c491d40e9ee..3e12540f62e 100644
--- a/tools/binman/fdt_test.py
+++ b/tools/binman/fdt_test.py
@@ -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)
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 9b27aecc140..7926fe3a792 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -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
diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py
index 03b86773d5f..cb365ca094a 100644
--- a/tools/dtoc/fdt.py
+++ b/tools/dtoc/fdt.py
@@ -5,6 +5,7 @@
# Written by Simon Glass <sjg at 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):
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
index a5836e04b7a..6dd8a5ca473 100755
--- a/tools/dtoc/test_dtoc.py
+++ b/tools/dtoc/test_dtoc.py
@@ -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"""
diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py
index cfe3e04c7ad..10e7f33a595 100755
--- a/tools/dtoc/test_fdt.py
+++ b/tools/dtoc/test_fdt.py
@@ -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
--
2.29.2.222.g5d2a92d10f8-goog
More information about the U-Boot
mailing list