On Fri, Mar 23, 2018 at 07:45:03PM +0100, Gaetan Rivet wrote:
> Signed-off-by: Gaetan Rivet <gaetan.ri...@6wind.com>
> ---
> 
> Cc: Neil Horman <nhor...@tuxdriver.com>
> 
I'm actually ok with this, but as Keith noted, I'm not sure why you didn't just:

1) Add the ability to create a grouping key, so that key value pairs could
contain a list of comma separated values (something like '{}' to denote that
everything between the characters was the value in a kv pair, regardless of
other tokenizing characters in the value).

2) Add the ability to recursively parse the value into a list of tokens

3) Layer your functionality on top of (1) and (2), as Keith noted

Neil

> I find using rte_parse_kv cleaner.
> The function rte_dev_iterator_init is already ugly enough as it is.
> This is really not helping.
> 
>  lib/librte_eal/common/eal_common_dev.c | 127 
> +++++++++++++++++++++------------
>  lib/librte_eal/linuxapp/eal/Makefile   |   1 +
>  2 files changed, 83 insertions(+), 45 deletions(-)
> 
> diff --git a/lib/librte_eal/common/eal_common_dev.c 
> b/lib/librte_eal/common/eal_common_dev.c
> index 21703b777..9f1a0ebda 100644
> --- a/lib/librte_eal/common/eal_common_dev.c
> +++ b/lib/librte_eal/common/eal_common_dev.c
> @@ -15,6 +15,7 @@
>  #include <rte_devargs.h>
>  #include <rte_debug.h>
>  #include <rte_errno.h>
> +#include <rte_kvargs.h>
>  #include <rte_log.h>
>  
>  #include "eal_private.h"
> @@ -270,12 +271,15 @@ rte_eal_hotplug_remove(const char *busname, const char 
> *devname)
>  }
>  
>  int __rte_experimental
> -rte_dev_iterator_init(struct rte_dev_iterator *it, const char *str)
> +rte_dev_iterator_init(struct rte_dev_iterator *it,
> +                   const char *devstr)
>  {
> -     struct rte_bus *bus = NULL;
> +     struct rte_kvargs *kvlist = NULL;
>       struct rte_class *cls = NULL;
> -     struct rte_kvarg kv;
> -     char *slash;
> +     struct rte_bus *bus = NULL;
> +     struct rte_kvargs_pair *kv;
> +     char *slash = NULL;
> +     char *str = NULL;
>  
>       /* Having both busstr and clsstr NULL is illegal,
>        * marking this iterator as invalid unless
> @@ -283,98 +287,131 @@ rte_dev_iterator_init(struct rte_dev_iterator *it, 
> const char *str)
>        */
>       it->busstr = NULL;
>       it->clsstr = NULL;
> +     str = strdup(devstr);
> +     if (str == NULL) {
> +             rte_errno = ENOMEM;
> +             goto get_out;
> +     }
> +     slash = strchr(str, '/');
> +     if (slash != NULL) {
> +             slash[0] = '\0';
> +             slash = strchr(devstr, '/') + 1;
> +     }
>       /* Safety checks and prep-work */
> -     if (rte_parse_kv(str, &kv)) {
> +     kvlist = rte_kvargs_parse(str, NULL);
> +     if (kvlist == NULL) {
>               RTE_LOG(ERR, EAL, "Could not parse: %s\n", str);
>               rte_errno = EINVAL;
> -             return -rte_errno;
> +             goto get_out;
>       }
>       it->device = NULL;
>       it->class_device = NULL;
> -     if (strcmp(kv.key, "bus") == 0) {
> -             bus = rte_bus_find_by_name(kv.value);
> +     kv = &kvlist->pairs[0];
> +     if (strcmp(kv->key, "bus") == 0) {
> +             bus = rte_bus_find_by_name(kv->value);
>               if (bus == NULL) {
>                       RTE_LOG(ERR, EAL, "Could not find bus \"%s\"\n",
> -                             kv.value);
> +                             kv->value);
>                       rte_errno = EFAULT;
> -                     return -rte_errno;
> +                     goto get_out;
>               }
> -             slash = strchr(str, '/');
>               if (slash != NULL) {
> -                     if (rte_parse_kv(slash + 1, &kv)) {
> +                     rte_kvargs_free(kvlist);
> +                     kvlist = rte_kvargs_parse(slash, NULL);
> +                     if (kvlist == NULL) {
>                               RTE_LOG(ERR, EAL, "Could not parse: %s\n",
> -                                     slash + 1);
> +                                     slash);
>                               rte_errno = EINVAL;
> -                             return -rte_errno;
> +                             goto get_out;
>                       }
> -                     cls = rte_class_find_by_name(kv.value);
> +                     kv = &kvlist->pairs[0];
> +                     if (strcmp(kv->key, "class")) {
> +                             RTE_LOG(ERR, EAL, "Additional layer must be a 
> class\n");
> +                             rte_errno = EINVAL;
> +                             goto get_out;
> +                     }
> +                     cls = rte_class_find_by_name(kv->value);
>                       if (cls == NULL) {
>                               RTE_LOG(ERR, EAL, "Could not find class 
> \"%s\"\n",
> -                                     kv.value);
> +                                     kv->value);
>                               rte_errno = EFAULT;
> -                             return -rte_errno;
> +                             goto get_out;
>                       }
>               }
> -     } else if (strcmp(kv.key, "class") == 0) {
> -             cls = rte_class_find_by_name(kv.value);
> +     } else if (strcmp(kv->key, "class") == 0) {
> +             cls = rte_class_find_by_name(kv->value);
>               if (cls == NULL) {
>                       RTE_LOG(ERR, EAL, "Could not find class \"%s\"\n",
> -                             kv.value);
> +                             kv->value);
>                       rte_errno = EFAULT;
> -                     return -rte_errno;
> +                     goto get_out;
>               }
>       } else {
>               rte_errno = EINVAL;
> -             return -rte_errno;
> +             goto get_out;
>       }
>       /* The string should have at least
>        * one layer specified.
>        */
>       if (bus == NULL && cls == NULL) {
>               rte_errno = EINVAL;
> -             return -rte_errno;
> +             goto get_out;
>       }
>       if ((bus != NULL && bus->dev_iterate == NULL) ||
>           (cls != NULL && cls->dev_iterate == NULL)) {
>               rte_errno = ENOTSUP;
> -             return -rte_errno;
> +             goto get_out;
>       }
>       if (bus != NULL) {
> -             it->busstr = str;
> +             it->busstr = devstr;
>               if (cls != NULL)
> -                     it->clsstr = slash + 1;
> +                     it->clsstr = slash;
>       } else if (cls != NULL) {
> -             it->clsstr = str;
> +             it->clsstr = devstr;
>       }
> -     it->devstr = str;
> +     it->devstr = devstr;
>       it->bus = bus;
>       it->cls = cls;
> -     return 0;
> +get_out:
> +     rte_kvargs_free(kvlist);
> +     free(str);
> +     return -rte_errno;
> +}
> +
> +/* '\0' forbidden in sym */
> +static const char *
> +strfirstof(const char *str,
> +        const char *sym)
> +{
> +     const char *s;
> +
> +     for (s = str; s[0] != '\0'; s++) {
> +             const char *c;
> +
> +             for (c = sym; c[0] != '\0'; c++) {
> +                     if (c[0] == s[0])
> +                             return s;
> +             }
> +     }
> +     return NULL;
>  }
>  
>  static char *
>  dev_str_sane_cpy(const char *str)
>  {
> -     struct rte_kvarg kv;
> -     char *end;
> +     const char *end;
>       char *cpy;
>  
> -     if (rte_parse_kv(str, &kv)) {
> -             rte_errno = EINVAL;
> -             return NULL;
> -     }
> -     /* copying '\0' is valid. */
> -     if (kv.next != NULL)
> -             cpy = strdup(kv.next);
> -     else
> +     end = strfirstof(str, ",/");
> +     if (end != NULL &&
> +         end[0] == ',') {
> +             cpy = strdup(end + 1);
> +     } else {
> +             /* '/' or '\0' */
>               cpy = strdup("");
> -     if (cpy == NULL) {
> -             rte_errno = ENOMEM;
> -             return NULL;
>       }
> -     end = strchr(cpy, '/');
> -     if (end != NULL)
> -             end[0] = '\0';
> +     if (cpy == NULL)
> +             rte_errno = ENOMEM;
>       return cpy;
>  }
>  
> diff --git a/lib/librte_eal/linuxapp/eal/Makefile 
> b/lib/librte_eal/linuxapp/eal/Makefile
> index a3edbbe76..87caa23a1 100644
> --- a/lib/librte_eal/linuxapp/eal/Makefile
> +++ b/lib/librte_eal/linuxapp/eal/Makefile
> @@ -27,6 +27,7 @@ LDLIBS += -lrt
>  ifeq ($(CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES),y)
>  LDLIBS += -lnuma
>  endif
> +LDLIBS += -lrte_kvargs
>  
>  # specific to linuxapp exec-env
>  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) := eal.c
> -- 
> 2.11.0
> 
> 

Reply via email to