[dpdk-dev] [PATCH 04/33] app/testeventdev: add string parsing helpers

Van Haaren, Harry harry.van.haaren at intel.com
Fri Jun 23 14:30:04 CEST 2017


> From: Jerin Jacob [mailto:jerin.jacob at caviumnetworks.com]
> Sent: Sunday, May 28, 2017 8:58 PM
> To: dev at dpdk.org
> Cc: Richardson, Bruce <bruce.richardson at intel.com>; Van Haaren, Harry
> <harry.van.haaren at intel.com>; hemant.agrawal at nxp.com; Eads, Gage <gage.eads at intel.com>;
> nipun.gupta at nxp.com; Vangati, Narender <narender.vangati at intel.com>; Rao, Nikhil
> <nikhil.rao at intel.com>; gprathyusha at caviumnetworks.com
> Subject: [dpdk-dev] [PATCH 04/33] app/testeventdev: add string parsing helpers
> 
> From: Guduri Prathyusha <gprathyusha at caviumnetworks.com>
> 
> Add a couple of help functions that will allow parsing many types of
> input parameters, i.e.: bool, 16, 32, 64 bits, hex and list of cores etc.
> 
> Derived from examples/ip_pipeline/parser.h
> 
> Signed-off-by: Guduri Prathyusha <gprathyusha at caviumnetworks.com>

I'm not sure about the licenses, but here's an Ack for the code:

Acked-by: Harry van Haaren <harry.van.haaren at intel.com>


> ---
>  app/test-eventdev/Makefile |   1 +
>  app/test-eventdev/parser.c | 432 +++++++++++++++++++++++++++++++++++++++++++++
>  app/test-eventdev/parser.h |  79 +++++++++
>  3 files changed, 512 insertions(+)
>  create mode 100644 app/test-eventdev/parser.c
>  create mode 100644 app/test-eventdev/parser.h
> 
> diff --git a/app/test-eventdev/Makefile b/app/test-eventdev/Makefile
> index 8f4fc5f45..2e552a084 100644
> --- a/app/test-eventdev/Makefile
> +++ b/app/test-eventdev/Makefile
> @@ -40,5 +40,6 @@ CFLAGS += $(WERROR_FLAGS)
>  #
>  SRCS-y := evt_main.c
>  SRCS-y += evt_test.c
> +SRCS-y += parser.c
> 
>  include $(RTE_SDK)/mk/rte.app.mk
> diff --git a/app/test-eventdev/parser.c b/app/test-eventdev/parser.c
> new file mode 100644
> index 000000000..d267447a2
> --- /dev/null
> +++ b/app/test-eventdev/parser.c
> @@ -0,0 +1,432 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2016 Intel Corporation. All rights reserved.
> + *   All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of Intel Corporation nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +/*
> + * For my_ether_aton() function:
> + *
> + * Copyright (c) 2009, Olivier MATZ <zer0 at droids-corp.org>
> + * All rights reserved.
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in the
> + *       documentation and/or other materials provided with the distribution.
> + *     * Neither the name of the University of California, Berkeley nor the
> + *       names of its contributors may be used to endorse or promote products
> + *       derived from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
> + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
> + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +/*
> + * For inet_pton4() and inet_pton6() functions:
> + *
> + * Copyright (c) 1996 by Internet Software Consortium.
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
> + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
> + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
> + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
> + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
> + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
> + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
> + * SOFTWARE.
> + */
> +
> +#include <stdint.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <ctype.h>
> +#include <getopt.h>
> +#include <errno.h>
> +#include <stdarg.h>
> +#include <string.h>
> +#include <libgen.h>
> +#include <unistd.h>
> +#include <sys/wait.h>
> +#include <stdbool.h>
> +
> +#include <rte_errno.h>
> +#include <rte_string_fns.h>
> +
> +#include "parser.h"
> +
> +static uint32_t
> +get_hex_val(char c)
> +{
> +	switch (c) {
> +	case '0': case '1': case '2': case '3': case '4': case '5':
> +	case '6': case '7': case '8': case '9':
> +		return c - '0';
> +	case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
> +		return c - 'A' + 10;
> +	case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
> +		return c - 'a' + 10;
> +	default:
> +		return 0;
> +	}
> +}
> +
> +int
> +parser_read_arg_bool(const char *p)
> +{
> +	p = skip_white_spaces(p);
> +	int result = -EINVAL;
> +
> +	if (((p[0] == 'y') && (p[1] == 'e') && (p[2] == 's')) ||
> +		((p[0] == 'Y') && (p[1] == 'E') && (p[2] == 'S'))) {
> +		p += 3;
> +		result = 1;
> +	}
> +
> +	if (((p[0] == 'o') && (p[1] == 'n')) ||
> +		((p[0] == 'O') && (p[1] == 'N'))) {
> +		p += 2;
> +		result = 1;
> +	}
> +
> +	if (((p[0] == 'n') && (p[1] == 'o')) ||
> +		((p[0] == 'N') && (p[1] == 'O'))) {
> +		p += 2;
> +		result = 0;
> +	}
> +
> +	if (((p[0] == 'o') && (p[1] == 'f') && (p[2] == 'f')) ||
> +		((p[0] == 'O') && (p[1] == 'F') && (p[2] == 'F'))) {
> +		p += 3;
> +		result = 0;
> +	}
> +
> +	p = skip_white_spaces(p);
> +
> +	if (p[0] != '\0')
> +		return -EINVAL;
> +
> +	return result;
> +}
> +
> +int
> +parser_read_uint64(uint64_t *value, const char *p)
> +{
> +	char *next;
> +	uint64_t val;
> +
> +	p = skip_white_spaces(p);
> +	if (!isdigit(*p))
> +		return -EINVAL;
> +
> +	val = strtoul(p, &next, 10);
> +	if (p == next)
> +		return -EINVAL;
> +
> +	p = next;
> +	switch (*p) {
> +	case 'T':
> +		val *= 1024ULL;
> +		/* fall through */
> +	case 'G':
> +		val *= 1024ULL;
> +		/* fall through */
> +	case 'M':
> +		val *= 1024ULL;
> +		/* fall through */
> +	case 'k':
> +	case 'K':
> +		val *= 1024ULL;
> +		p++;
> +		break;
> +	}
> +
> +	p = skip_white_spaces(p);
> +	if (*p != '\0')
> +		return -EINVAL;
> +
> +	*value = val;
> +	return 0;
> +}
> +
> +int
> +parser_read_int32(int32_t *value, const char *p)
> +{
> +	char *next;
> +	int32_t val;
> +
> +	p = skip_white_spaces(p);
> +	if (!isdigit(*p))
> +		return -EINVAL;
> +
> +	val = strtol(p, &next, 10);
> +	if (p == next)
> +		return -EINVAL;
> +
> +	*value = val;
> +	return 0;
> +}
> +
> +int
> +parser_read_uint64_hex(uint64_t *value, const char *p)
> +{
> +	char *next;
> +	uint64_t val;
> +
> +	p = skip_white_spaces(p);
> +
> +	val = strtoul(p, &next, 16);
> +	if (p == next)
> +		return -EINVAL;
> +
> +	p = skip_white_spaces(next);
> +	if (*p != '\0')
> +		return -EINVAL;
> +
> +	*value = val;
> +	return 0;
> +}
> +
> +int
> +parser_read_uint32(uint32_t *value, const char *p)
> +{
> +	uint64_t val = 0;
> +	int ret = parser_read_uint64(&val, p);
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	if (val > UINT32_MAX)
> +		return -ERANGE;
> +
> +	*value = val;
> +	return 0;
> +}
> +
> +int
> +parser_read_uint32_hex(uint32_t *value, const char *p)
> +{
> +	uint64_t val = 0;
> +	int ret = parser_read_uint64_hex(&val, p);
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	if (val > UINT32_MAX)
> +		return -ERANGE;
> +
> +	*value = val;
> +	return 0;
> +}
> +
> +int
> +parser_read_uint16(uint16_t *value, const char *p)
> +{
> +	uint64_t val = 0;
> +	int ret = parser_read_uint64(&val, p);
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	if (val > UINT16_MAX)
> +		return -ERANGE;
> +
> +	*value = val;
> +	return 0;
> +}
> +
> +int
> +parser_read_uint16_hex(uint16_t *value, const char *p)
> +{
> +	uint64_t val = 0;
> +	int ret = parser_read_uint64_hex(&val, p);
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	if (val > UINT16_MAX)
> +		return -ERANGE;
> +
> +	*value = val;
> +	return 0;
> +}
> +
> +int
> +parser_read_uint8(uint8_t *value, const char *p)
> +{
> +	uint64_t val = 0;
> +	int ret = parser_read_uint64(&val, p);
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	if (val > UINT8_MAX)
> +		return -ERANGE;
> +
> +	*value = val;
> +	return 0;
> +}
> +
> +int
> +parser_read_uint8_hex(uint8_t *value, const char *p)
> +{
> +	uint64_t val = 0;
> +	int ret = parser_read_uint64_hex(&val, p);
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	if (val > UINT8_MAX)
> +		return -ERANGE;
> +
> +	*value = val;
> +	return 0;
> +}
> +
> +int
> +parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
> +{
> +	uint32_t i;
> +
> +	if ((string == NULL) ||
> +		(tokens == NULL) ||
> +		(*n_tokens < 1))
> +		return -EINVAL;
> +
> +	for (i = 0; i < *n_tokens; i++) {
> +		tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
> +		if (tokens[i] == NULL)
> +			break;
> +	}
> +
> +	if ((i == *n_tokens) &&
> +		(strtok_r(string, PARSE_DELIMITER, &string) != NULL))
> +		return -E2BIG;
> +
> +	*n_tokens = i;
> +	return 0;
> +}
> +
> +int
> +parse_hex_string(char *src, uint8_t *dst, uint32_t *size)
> +{
> +	char *c;
> +	uint32_t len, i;
> +
> +	/* Check input parameters */
> +	if ((src == NULL) ||
> +		(dst == NULL) ||
> +		(size == NULL) ||
> +		(*size == 0))
> +		return -1;
> +
> +	len = strlen(src);
> +	if (((len & 3) != 0) ||
> +		(len > (*size) * 2))
> +		return -1;
> +	*size = len / 2;
> +
> +	for (c = src; *c != 0; c++) {
> +		if ((((*c) >= '0') && ((*c) <= '9')) ||
> +			(((*c) >= 'A') && ((*c) <= 'F')) ||
> +			(((*c) >= 'a') && ((*c) <= 'f')))
> +			continue;
> +
> +		return -1;
> +	}
> +
> +	/* Convert chars to bytes */
> +	for (i = 0; i < *size; i++)
> +		dst[i] = get_hex_val(src[2 * i]) * 16 +
> +			get_hex_val(src[2 * i + 1]);
> +
> +	return 0;
> +}
> +
> +int
> +parse_lcores_list(bool lcores[], const char *corelist)
> +{
> +	int i, idx = 0;
> +	int min, max;
> +	char *end = NULL;
> +
> +	if (corelist == NULL)
> +		return -1;
> +	while (isblank(*corelist))
> +		corelist++;
> +	i = strlen(corelist);
> +	while ((i > 0) && isblank(corelist[i - 1]))
> +		i--;
> +
> +	/* Get list of lcores */
> +	min = RTE_MAX_LCORE;
> +	do {
> +		while (isblank(*corelist))
> +			corelist++;
> +		if (*corelist == '\0')
> +			return -1;
> +		idx = strtoul(corelist, &end, 10);
> +
> +		if (end == NULL)
> +			return -1;
> +		while (isblank(*end))
> +			end++;
> +		if (*end == '-') {
> +			min = idx;
> +		} else if ((*end == ',') || (*end == '\0')) {
> +			max = idx;
> +			if (min == RTE_MAX_LCORE)
> +				min = idx;
> +			for (idx = min; idx <= max; idx++)
> +				lcores[idx] = 1;
> +
> +			min = RTE_MAX_LCORE;
> +		} else
> +			return -1;
> +		corelist = end + 1;
> +	} while (*end != '\0');
> +
> +	return 0;
> +}
> diff --git a/app/test-eventdev/parser.h b/app/test-eventdev/parser.h
> new file mode 100644
> index 000000000..75a5a3b45
> --- /dev/null
> +++ b/app/test-eventdev/parser.h
> @@ -0,0 +1,79 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
> + *   All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of Intel Corporation nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef __INCLUDE_PARSER_H__
> +#define __INCLUDE_PARSER_H__
> +
> +#include <stdint.h>
> +
> +#define PARSE_DELIMITER				" \f\n\r\t\v"
> +
> +#define skip_white_spaces(pos)			\
> +({						\
> +	__typeof__(pos) _p = (pos);		\
> +	for ( ; isspace(*_p); _p++)		\
> +		;				\
> +	_p;					\
> +})
> +
> +static inline size_t
> +skip_digits(const char *src)
> +{
> +	size_t i;
> +
> +	for (i = 0; isdigit(src[i]); i++)
> +		;
> +
> +	return i;
> +}
> +
> +int parser_read_arg_bool(const char *p);
> +
> +int parser_read_uint64(uint64_t *value, const char *p);
> +int parser_read_uint32(uint32_t *value, const char *p);
> +int parser_read_uint16(uint16_t *value, const char *p);
> +int parser_read_uint8(uint8_t *value, const char *p);
> +
> +int parser_read_uint64_hex(uint64_t *value, const char *p);
> +int parser_read_uint32_hex(uint32_t *value, const char *p);
> +int parser_read_uint16_hex(uint16_t *value, const char *p);
> +int parser_read_uint8_hex(uint8_t *value, const char *p);
> +
> +int parser_read_int32(int32_t *value, const char *p);
> +
> +int parse_hex_string(char *src, uint8_t *dst, uint32_t *size);
> +
> +int parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens);
> +
> +int parse_lcores_list(bool lcores[], const char *corelist);
> +#endif
> --
> 2.13.0



More information about the dev mailing list