From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 1D65FA09FF; Mon, 28 Dec 2020 14:21:22 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id AABDEC9C0; Mon, 28 Dec 2020 14:21:19 +0100 (CET) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by dpdk.org (Postfix) with ESMTP id 3D08AC9C0 for ; Mon, 28 Dec 2020 14:21:17 +0100 (CET) Received: from [192.168.38.17] (aros.oktetlabs.ru [192.168.38.17]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by shelob.oktetlabs.ru (Postfix) with ESMTPSA id 9E7857F529; Mon, 28 Dec 2020 16:21:15 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 9E7857F529 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=oktetlabs.ru; s=default; t=1609161675; bh=40UhqmUya3NMogF3EOXOa+U52m8cx6mwSaEjVUZvab0=; h=Subject:To:Cc:References:From:Date:In-Reply-To; b=iyQGSAFHDboci0B5KuOHUbVC4jYpl1DDrWFRIrnnAYWGE5iLCa/Pq3UDuXptkATBB WCOfX1r5H9UpCH//OjcUBGyWU/AtWozT6fKvVZGdmt5/maUdny7AcC6CYo9uASGLJQ 6CafAv8H2MdhIlL1Jti4rvo81iylZBdreM7qbQJY= To: Xueming Li , Viacheslav Ovsiienko , Thomas Monjalon , Ferruh Yigit , Olivier Matz , Matan Azrad Cc: dev@dpdk.org, Asaf Penso References: <1608303356-13089-1-git-send-email-xuemingl@nvidia.com> <1608303356-13089-6-git-send-email-xuemingl@nvidia.com> From: Andrew Rybchenko Organization: OKTET Labs Message-ID: <56c086a9-b611-b276-5a44-d58739cbb414@oktetlabs.ru> Date: Mon, 28 Dec 2020 16:21:15 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.5.1 MIME-Version: 1.0 In-Reply-To: <1608303356-13089-6-git-send-email-xuemingl@nvidia.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Content-Language: en-US Subject: Re: [dpdk-dev] [RFC 5/7] kvargs: update parser for new representor syntax X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" On 12/18/20 5:55 PM, Xueming Li wrote: > This patch updates kvargs parser to allow comma in list value: > k1=a[1,2]b[3-5] > > Signed-off-by: Xueming Li > --- > lib/librte_kvargs/rte_kvargs.c | 82 +++++++++++++++++++++++----------- > 1 file changed, 56 insertions(+), 26 deletions(-) > > diff --git a/lib/librte_kvargs/rte_kvargs.c b/lib/librte_kvargs/rte_kvargs.c > index 285081c86c..6193109a17 100644 > --- a/lib/librte_kvargs/rte_kvargs.c > +++ b/lib/librte_kvargs/rte_kvargs.c > @@ -13,15 +13,19 @@ > /* > * Receive a string with a list of arguments following the pattern > * key=value,key=value,... and insert them into the list. > - * strtok() is used so the params string will be copied to be modified. > + * Params string will be copied to be modified. > + * list "[]" and list element splitter ",", "-" is treated as value. > + * Supported examples: > + * k1=v1,k2=v2 > + * v1 > + * k1=x[0-1]y[1,3-5,9]z > */ > static int > rte_kvargs_tokenize(struct rte_kvargs *kvlist, const char *params) > { > unsigned i; > - char *str; > - char *ctx1 = NULL; > - char *ctx2 = NULL; > + char *str, *start; > + int in_list = 0, end_k = 0, end_v = 0; > > /* Copy the const char *params to a modifiable string > * to pass to rte_strsplit > @@ -32,36 +36,62 @@ rte_kvargs_tokenize(struct rte_kvargs *kvlist, const char *params) > > /* browse each key/value pair and add it in kvlist */ > str = kvlist->str; > - while ((str = strtok_r(str, RTE_KVARGS_PAIRS_DELIM, &ctx1)) != NULL) { > + start = str; /* start of current key or value */ > + while (1) { > + switch (*str) { > + case '=': /* End of key. */ > + end_k = 1; > + break; > + case ',': > + /* End of value, skip comma in middle of range */ > + if (!in_list) > + end_v = 1; > + break; > + case '[': /* Start of list. */ > + in_list++; > + break; > + case ']': /* End of list. */ > + if (in_list) > + in_list--; > + break; > + case 0: /* End of string */ > + end_v = 1; > + break; > + default: > + break; > + } > + > + if (!end_k && !end_v) { DPDK coding style requires to compare integers vs 0 explicitly. Otherwise you can define it as bool and use as bool this way. > + /* Continue if not end of key or value. */ > + str++; > + continue; > + } > > i = kvlist->count; > if (i >= RTE_KVARGS_MAX) > return -1; > > - 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) > - return -1; > - > - /* Detect list [a,b] to skip comma delimiter in list. */ > - str = kvlist->pairs[i].value; > - if (str[0] == '[') { > - /* Find the end of the list. */ > - while (str[strlen(str) - 1] != ']') { > - /* Restore the comma erased by strtok_r(). */ > - if (ctx1 == NULL || ctx1[0] == '\0') > - return -1; /* no closing bracket */ > - str[strlen(str)] = ','; > - /* Parse until next comma. */ > - str = strtok_r(NULL, RTE_KVARGS_PAIRS_DELIM, &ctx1); > - if (str == NULL) > - return -1; /* no closing bracket */ > + if (start == str) /* Empty key or value. */ > + start = NULL; > + > + if (end_k) { same > + /* Key parsed. */ > + kvlist->pairs[i].key = start; > + end_k = 0; > + } else if (end_v) { same > + /* Allow single key or single value. */ > + if (kvlist->pairs[i].key || start) { > + kvlist->pairs[i].value = start; > + kvlist->count++; > } > + end_v = 0; > } > > - kvlist->count++; > - str = NULL; > + if (!*str) /* End of string. */ Compare with '\0'. > + break; > + *str = 0; > + str++; > + start = str; > } > > return 0;