From: Olivier Matz Date: Tue, 28 Jan 2014 16:06:39 +0000 (+0100) Subject: kvargs: simpler parsing and allow duplicated keys X-Git-Tag: spdx-start~10966 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=ac15c813157156b8651cfa5eb75c9122c6a15bbe;p=dpdk.git kvargs: simpler parsing and allow duplicated keys Remove the rte_kvargs_add_pair() function whose only role was to check if a key is duplicated. Having duplicated keys is now allowed by kvargs API. Also replace rte_strsplit() by more a standard function strtok_r() that is easier to understand for people already knowing the libc. It also avoids useless calls to strnlen(). The delimiters macros become strings instead of chars due to the strtok_r() API. Signed-off-by: Olivier Matz Acked-by: Bruce Richardson --- diff --git a/lib/librte_kvargs/rte_kvargs.c b/lib/librte_kvargs/rte_kvargs.c index f3689564d8..12910841a0 100644 --- a/lib/librte_kvargs/rte_kvargs.c +++ b/lib/librte_kvargs/rte_kvargs.c @@ -32,8 +32,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include -#include -#include #include #include @@ -41,38 +39,6 @@ #include "rte_kvargs.h" -/* - * Add a key-value pair at the end of a given key/value list. - * Return an error if the list is full or if the key is duplicated. - */ -static int -rte_kvargs_add_pair(struct rte_kvargs *kvlist, char *key, char *val) -{ - unsigned i; - struct rte_kvargs_pair* entry; - - /* is the list full? */ - if (kvlist->count >= RTE_KVARGS_MAX) { - RTE_LOG(ERR, PMD, "Couldn't add %s, key/value list is full\n", key); - return -1; - } - - /* Check if the key is duplicated */ - for (i = 0; i < kvlist->count; i++) { - entry = &kvlist->pairs[i]; - if (strcmp(entry->key, key) == 0) { - RTE_LOG(ERR, PMD, "Couldn't add %s, duplicated key\n", key); - return -1; - } - } - - entry = &kvlist->pairs[kvlist->count]; - entry->key = key; - entry->value = val; - kvlist->count++; - return 0; -} - /* * Receive a string with a list of arguments following the pattern * key=value;key=value;... and insert them into the list. @@ -81,15 +47,8 @@ rte_kvargs_add_pair(struct rte_kvargs *kvlist, char *key, char *val) static int rte_kvargs_tokenize(struct rte_kvargs *kvlist, const char *params) { - unsigned i, count; - char *pairs[RTE_KVARGS_MAX]; - char *pair[2]; - - /* If params are empty, nothing to do */ - if (params == NULL || params[0] == 0) { - RTE_LOG(ERR, PMD, "Cannot parse empty arguments\n"); - return -1; - } + unsigned i; + char *str, *ctx1, *ctx2; /* Copy the const char *params to a modifiable string * to pass to rte_strsplit @@ -100,27 +59,29 @@ rte_kvargs_tokenize(struct rte_kvargs *kvlist, const char *params) return -1; } - count = rte_strsplit(kvlist->str, strnlen(kvlist->str, MAX_ARG_STRLEN), pairs, - RTE_KVARGS_MAX, RTE_KVARGS_PAIRS_DELIM); - - for (i = 0; i < count; i++) { - pair[0] = NULL; - pair[1] = NULL; + /* browse each key/value pair and add it in kvlist */ + str = kvlist->str; + while ((str = strtok_r(str, RTE_KVARGS_PAIRS_DELIM, &ctx1)) != NULL) { - rte_strsplit(pairs[i], strnlen(pairs[i], MAX_ARG_STRLEN), pair, 2, - RTE_KVARGS_KV_DELIM); + i = kvlist->count; + if (i >= RTE_KVARGS_MAX) { + RTE_LOG(ERR, PMD, "Cannot parse arguments: list full\n"); + return -1; + } - if (pair[0] == NULL || pair[1] == NULL || pair[0][0] == 0 - || pair[1][0] == 0) { + kvlist->pairs[i].key = strtok_r(str, RTE_KVARGS_KV_DELIM, &ctx2); + kvlist->pairs[i].value = strtok_r(NULL, RTE_KVARGS_KV_DELIM, &ctx2); + if (kvlist->pairs[i].key == NULL || kvlist->pairs[i].value == NULL) { RTE_LOG(ERR, PMD, "Cannot parse arguments: wrong key or value\n" "params=<%s>\n", params); return -1; } - if (rte_kvargs_add_pair(kvlist, pair[0], pair[1]) < 0) - return -1; + kvlist->count++; + str = NULL; } + return 0; } diff --git a/lib/librte_kvargs/rte_kvargs.h b/lib/librte_kvargs/rte_kvargs.h index 25e086f01d..d09dab860b 100644 --- a/lib/librte_kvargs/rte_kvargs.h +++ b/lib/librte_kvargs/rte_kvargs.h @@ -42,6 +42,10 @@ * This module can be used to parse arguments whose format is * key1=value1;key2=value2;key3=value3;... * + * The same key can appear several times with the same or a different + * value. Indeed, the arguments are stored as a list of key/values + * associations and not as a dictionary. + * * This file provides some helpers that are especially used by virtual * ethernet devices at initialization for arguments parsing. */ @@ -54,10 +58,10 @@ extern "C" { #define RTE_KVARGS_MAX 32 /** separator character used between each pair */ -#define RTE_KVARGS_PAIRS_DELIM ';' +#define RTE_KVARGS_PAIRS_DELIM ";" /** separator character used between key and value */ -#define RTE_KVARGS_KV_DELIM '=' +#define RTE_KVARGS_KV_DELIM "=" /** Type of callback function used by rte_kvargs_process() */ typedef int (*arg_handler_t)(char *value, void *opaque);