[PATCH v2 07/10] pylibfdt: Add functions to set and get properties as strings

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



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



[Index of Archives]     [Device Tree]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux