All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Gibson <david-xT8FGy+AXnRB3Ne2BGzF6laj5H9X9Tb+@public.gmane.org>
To: Thierry Reding <thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: Jon Loeliger <jdl-CYoMK+44s/E@public.gmane.org>,
	devicetree-compiler-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>,
	Masahiro Yamada
	<yamada.masahiro-uWyLwvC0a2jby3iVrkZq2A@public.gmane.org>
Subject: Re: [PATCH v2 2/3] fdt: Add a function to get the index of a string
Date: Tue, 29 Sep 2015 15:54:46 +1000	[thread overview]
Message-ID: <20150929055446.GQ19428@voom.redhat.com> (raw)
In-Reply-To: <1437045021-4549-3-git-send-email-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 6370 bytes --]

On Thu, Jul 16, 2015 at 01:10:20PM +0200, Thierry Reding wrote:
> From: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> 
> Given a device tree node and a property name, the new fdt_find_string()
> function will look up a given string in the string list contained in the
> property's value and return its index.
> 
> Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

This also looks good, except for the name.  I'd prefer
'fdt_stringlist_search()' again to match the existing
'fdt_stringlist_contains()'.

Speaking of which, fdt_stringlist_contains() could be reimplemented in
terms of this function.

> ---
> Changes in v2:
> - handle non-NUL-terminated properties more gracefully
> - improve documentation
> 
>  libfdt/fdt_ro.c | 30 ++++++++++++++++++++++++++++++
>  libfdt/libfdt.h | 22 ++++++++++++++++++++++
>  tests/strings.c | 40 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 92 insertions(+)
> 
> diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c
> index cf55c71df79c..39b84b1cea60 100644
> --- a/libfdt/fdt_ro.c
> +++ b/libfdt/fdt_ro.c
> @@ -563,6 +563,36 @@ int fdt_count_strings(const void *fdt, int nodeoffset, const char *property)
>  	return count;
>  }
>  
> +int fdt_find_string(const void *fdt, int nodeoffset, const char *property,
> +		    const char *string)
> +{
> +	int length, len, index = 0;
> +	const char *list, *end;
> +
> +	list = fdt_getprop(fdt, nodeoffset, property, &length);
> +	if (!list)
> +		return -length;
> +
> +	len = strlen(string) + 1;
> +	end = list + length;
> +
> +	while (list < end) {
> +		length = strnlen(list, end - list) + 1;
> +
> +		/* Abort if the last string isn't properly NUL-terminated. */
> +		if (list + length > end)
> +			return -FDT_ERR_BADVALUE;
> +
> +		if (length == len && memcmp(list, string, length) == 0)
> +			return index;
> +
> +		list += length;
> +		index++;
> +	}
> +
> +	return -FDT_ERR_NOTFOUND;
> +}
> +
>  int fdt_node_check_compatible(const void *fdt, int nodeoffset,
>  			      const char *compatible)
>  {
> diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h
> index bf60c1593e4e..e64680dd741c 100644
> --- a/libfdt/libfdt.h
> +++ b/libfdt/libfdt.h
> @@ -885,6 +885,28 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
>   */
>  int fdt_count_strings(const void *fdt, int nodeoffset, const char *property);
>  
> +/**
> + * fdt_find_string - find a string in a string list and return its index
> + * @fdt: pointer to the device tree blob
> + * @nodeoffset: offset of a tree node
> + * @property: name of the property containing the string list
> + * @string: string to look up in the string list
> + *
> + * Note that it is possible for this function to succeed on property values
> + * that are not NUL-terminated. That's because the function will stop after
> + * finding the first occurrence of @string. This can for example happen with
> + * small-valued cell properties, such as #address-cells, when searching for
> + * the empty string.
> + *
> + * @return:
> + *   the index of the string in the list of strings
> + *   -FDT_ERR_BADVALUE if the property value is not NUL-terminated
> + *   -FDT_ERR_NOTFOUND if the property does not exist or does not contain
> + *                     the given string
> + */
> +int fdt_find_string(const void *fdt, int nodeoffset, const char *property,
> +		    const char *string);
> +
>  /**********************************************************************/
>  /* Read-only functions (addressing related)                           */
>  /**********************************************************************/
> diff --git a/tests/strings.c b/tests/strings.c
> index e10d9ece5a3e..29c49bfcc78c 100644
> --- a/tests/strings.c
> +++ b/tests/strings.c
> @@ -40,6 +40,24 @@ static void check_expected_failure(const void *fdt, const char *path,
>  	err = fdt_count_strings(fdt, offset, "#address-cells");
>  	if (err != -FDT_ERR_BADVALUE)
>  		FAIL("unexpectedly succeeded in parsing #address-cells\n");
> +
> +	err = fdt_find_string(fdt, offset, "#address-cells", "foo");
> +	if (err != -FDT_ERR_BADVALUE)
> +		FAIL("found string in #address-cells: %d\n", err);
> +
> +	/*
> +	 * Note that the #address-cells property contains a small 32-bit
> +	 * unsigned integer, hence some bytes will be zero, and searching for
> +	 * the empty string will succeed.
> +	 *
> +	 * The reason for this oddity is that the function will exit when the
> +	 * first occurrence of the string is found, but in order to determine
> +	 * that the property does not contain a valid string list it would
> +	 * need to process the whole value.
> +	 */
> +	err = fdt_find_string(fdt, offset, "#address-cells", "");
> +	if (err != 0)
> +		FAIL("empty string not found in #address-cells: %d\n", err);
>  }
>  
>  static void check_string_count(const void *fdt, const char *path,
> @@ -61,6 +79,23 @@ static void check_string_count(const void *fdt, const char *path,
>  		     path, property, err, count);
>  }
>  
> +static void check_string_index(const void *fdt, const char *path,
> +			       const char *property, const char *string,
> +			       int index)
> +{
> +	int offset, err;
> +
> +	offset = fdt_path_offset(fdt, path);
> +	if (offset < 0)
> +		FAIL("Couldn't find path %s", path);
> +
> +	err = fdt_find_string(fdt, offset, property, string);
> +
> +	if (err != index)
> +		FAIL("Index of %s in property %s of node %s is %d, expected %d\n",
> +		     string, property, path, err, index);
> +}
> +
>  int main(int argc, char *argv[])
>  {
>  	void *fdt;
> @@ -78,5 +113,10 @@ int main(int argc, char *argv[])
>  	check_string_count(fdt, "/device", "compatible", 2);
>  	check_string_count(fdt, "/device", "big-endian", 0);
>  
> +	check_string_index(fdt, "/", "compatible", "test-strings", 0);
> +	check_string_index(fdt, "/device", "compatible", "foo", 0);
> +	check_string_index(fdt, "/device", "compatible", "bar", 1);
> +	check_string_index(fdt, "/device", "big-endian", "baz", -1);
> +
>  	PASS();
>  }

-- 
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 #2: Type: application/pgp-signature, Size: 819 bytes --]

  parent reply	other threads:[~2015-09-29  5:54 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-16 11:10 [PATCH v2 0/3] Add a couple of string-related functions Thierry Reding
     [not found] ` <1437045021-4549-1-git-send-email-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-07-16 11:10   ` [PATCH v2 1/3] fdt: Add a function to count strings Thierry Reding
     [not found]     ` <1437045021-4549-2-git-send-email-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-09-29  5:53       ` David Gibson
     [not found]         ` <20150929055313.GP19428-1s0os16eZneny3qCrzbmXA@public.gmane.org>
2015-09-29  8:32           ` Thierry Reding
2015-07-16 11:10   ` [PATCH v2 2/3] fdt: Add a function to get the index of a string Thierry Reding
     [not found]     ` <1437045021-4549-3-git-send-email-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-09-29  5:54       ` David Gibson [this message]
     [not found]         ` <20150929055446.GQ19428-1s0os16eZneny3qCrzbmXA@public.gmane.org>
2015-09-29  8:32           ` Thierry Reding
2015-07-16 11:10   ` [PATCH v2 3/3] fdt: Add functions to retrieve strings Thierry Reding
     [not found]     ` <1437045021-4549-4-git-send-email-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-09-29  6:00       ` David Gibson
     [not found]         ` <20150929060041.GR19428-1s0os16eZneny3qCrzbmXA@public.gmane.org>
2015-09-29  9:10           ` Thierry Reding
2015-09-29  5:50   ` [PATCH v2 0/3] Add a couple of string-related functions David Gibson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150929055446.GQ19428@voom.redhat.com \
    --to=david-xt8fgy+axnrb3ne2bgzf6laj5h9x9tb+@public.gmane.org \
    --cc=devicetree-compiler-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=jdl-CYoMK+44s/E@public.gmane.org \
    --cc=sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org \
    --cc=thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=yamada.masahiro-uWyLwvC0a2jby3iVrkZq2A@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.