Re: [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]



On Wed, Jun 06, 2018 at 03:37:06PM -0600, Simon Glass wrote:
> 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')

As mentioned elsehwere, I've changed my mind and I think this would be
better as a Property method.

>  
>  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')

Logically, adding the \0 should be done *after* the utf-8 encoding.

> +        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()

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


[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