It is common to want to set a property to a nul-terminated string in a device tree. Add python methods to handle this. Signed-off-by: Simon Glass <sjg@xxxxxxxxxxxx> --- Changes in v2: - Add support for unicode strings - Check for invalid embedded nul characters in as_str() - Check for nul termination in as_str() - Make the as_str() function a non-member of Property pylibfdt/libfdt.i | 30 ++++++++++++++++++++++++++++++ tests/pylibfdt_tests.py | 27 +++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/pylibfdt/libfdt.i b/pylibfdt/libfdt.i index 0eefc5a..ae63263 100644 --- a/pylibfdt/libfdt.i +++ b/pylibfdt/libfdt.i @@ -170,6 +170,14 @@ def as_uint64(bytes): def as_int64(bytes): return as_cell(bytes, 'q') +def as_str(self): + """Unicode is supposed by decoding from UTF-8""" + if self[-1] != 0: + raise ValueError('Property lacks nul termination') + if 0 in self[:-1]: + raise ValueError('Property contains embedded nul characters') + return self[:-1].decode('utf-8') + class Fdt: """Device tree class, supporting all operations @@ -601,6 +609,28 @@ class Fdt: return check_err(fdt_setprop_u64(self._fdt, nodeoffset, prop_name, val), quiet) + def setprop_str(self, nodeoffset, prop_name, val, quiet=()): + """Set the string value of a property + + The property is set to the string, with a nul terminator added + + Args: + nodeoffset: Node offset containing the property to create/update + prop_name: Name of property + val: Value to write (string without nul terminator). Unicode is + supposed by encoding to UTF-8 + quiet: Errors to ignore (empty to raise on all errors) + + Returns: + Error code, or 0 if OK + + Raises: + FdtException if no parent found or other error occurs + """ + val = (val + '\0').encode('utf-8') + return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name, + val, len(val)), quiet) + def delprop(self, nodeoffset, prop_name): """Delete a property from a node diff --git a/tests/pylibfdt_tests.py b/tests/pylibfdt_tests.py index 2badef2..738210f 100644 --- a/tests/pylibfdt_tests.py +++ b/tests/pylibfdt_tests.py @@ -68,6 +68,8 @@ TEST_VALUE64_1L = 0x01abcdef TEST_VALUE64_1 = (TEST_VALUE64_1H << 32) | TEST_VALUE64_1L TEST_STRING_1 = 'hello world' +TEST_STRING_2 = 'hi world' +TEST_STRING_3 = u'unicode ' + unichr(467) def get_err(err_code): @@ -441,6 +443,31 @@ class PyLibfdtTests(unittest.TestCase): self.assertEquals(struct.pack('>Q', TEST_VALUE64_1), self.fdt.getprop(node, prop)) + def testSetPropStr(self): + """Test that we can set a property to a particular string""" + node = 0 + prop = 'prop-str' + self.assertEquals(TEST_STRING_1, + libfdt.as_str(self.fdt.getprop(node, prop))) + self.fdt.setprop_str(node, prop, TEST_STRING_2) + self.assertEquals(TEST_STRING_2, + libfdt.as_str(self.fdt.getprop(node, prop))) + with self.assertRaises(ValueError) as e: + libfdt.as_str(self.fdt.getprop(node, 'prop-int')) + self.assertIn('lacks nul termination', str(e.exception)) + + node2 = self.fdt.path_offset('/subnode@1/subsubnode') + with self.assertRaises(ValueError) as e: + libfdt.as_str(self.fdt.getprop(node2, 'compatible')) + self.assertIn('embedded nul', str(e.exception)) + + # Expand the device tree so we now have room + self.fdt.resize(self.fdt.totalsize() + 50) + prop = 'prop-unicode' + self.fdt.setprop_str(node, prop, TEST_STRING_3) + self.assertEquals(TEST_STRING_3, + libfdt.as_str(self.fdt.getprop(node, prop))) + if __name__ == "__main__": unittest.main() -- 2.17.1.1185.g55be947832-goog -- To unsubscribe from this list: send the line "unsubscribe devicetree-compiler" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html