xref: /f-stack/dpdk/app/test-eventdev/parser.c (revision 4418919f)
1*4418919fSjohnjiang /* SPDX-License-Identifier: BSD-3-Clause
2*4418919fSjohnjiang  * Copyright(c) 2016 Intel Corporation.
3*4418919fSjohnjiang  * Copyright(c) 2017 Cavium, Inc.
42bfe3f2eSlogwang  */
52bfe3f2eSlogwang 
62bfe3f2eSlogwang #include <stdint.h>
72bfe3f2eSlogwang #include <stdlib.h>
82bfe3f2eSlogwang #include <stdio.h>
92bfe3f2eSlogwang #include <ctype.h>
102bfe3f2eSlogwang #include <getopt.h>
112bfe3f2eSlogwang #include <errno.h>
122bfe3f2eSlogwang #include <stdarg.h>
132bfe3f2eSlogwang #include <string.h>
142bfe3f2eSlogwang #include <libgen.h>
152bfe3f2eSlogwang #include <unistd.h>
162bfe3f2eSlogwang #include <sys/wait.h>
172bfe3f2eSlogwang #include <stdbool.h>
182bfe3f2eSlogwang 
192bfe3f2eSlogwang #include <rte_errno.h>
202bfe3f2eSlogwang #include <rte_string_fns.h>
212bfe3f2eSlogwang 
222bfe3f2eSlogwang #include "parser.h"
232bfe3f2eSlogwang 
242bfe3f2eSlogwang static uint32_t
get_hex_val(char c)252bfe3f2eSlogwang get_hex_val(char c)
262bfe3f2eSlogwang {
272bfe3f2eSlogwang 	switch (c) {
282bfe3f2eSlogwang 	case '0': case '1': case '2': case '3': case '4': case '5':
292bfe3f2eSlogwang 	case '6': case '7': case '8': case '9':
302bfe3f2eSlogwang 		return c - '0';
312bfe3f2eSlogwang 	case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
322bfe3f2eSlogwang 		return c - 'A' + 10;
332bfe3f2eSlogwang 	case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
342bfe3f2eSlogwang 		return c - 'a' + 10;
352bfe3f2eSlogwang 	default:
362bfe3f2eSlogwang 		return 0;
372bfe3f2eSlogwang 	}
382bfe3f2eSlogwang }
392bfe3f2eSlogwang 
402bfe3f2eSlogwang int
parser_read_arg_bool(const char * p)412bfe3f2eSlogwang parser_read_arg_bool(const char *p)
422bfe3f2eSlogwang {
432bfe3f2eSlogwang 	p = skip_white_spaces(p);
442bfe3f2eSlogwang 	int result = -EINVAL;
452bfe3f2eSlogwang 
462bfe3f2eSlogwang 	if (((p[0] == 'y') && (p[1] == 'e') && (p[2] == 's')) ||
472bfe3f2eSlogwang 		((p[0] == 'Y') && (p[1] == 'E') && (p[2] == 'S'))) {
482bfe3f2eSlogwang 		p += 3;
492bfe3f2eSlogwang 		result = 1;
502bfe3f2eSlogwang 	}
512bfe3f2eSlogwang 
522bfe3f2eSlogwang 	if (((p[0] == 'o') && (p[1] == 'n')) ||
532bfe3f2eSlogwang 		((p[0] == 'O') && (p[1] == 'N'))) {
542bfe3f2eSlogwang 		p += 2;
552bfe3f2eSlogwang 		result = 1;
562bfe3f2eSlogwang 	}
572bfe3f2eSlogwang 
582bfe3f2eSlogwang 	if (((p[0] == 'n') && (p[1] == 'o')) ||
592bfe3f2eSlogwang 		((p[0] == 'N') && (p[1] == 'O'))) {
602bfe3f2eSlogwang 		p += 2;
612bfe3f2eSlogwang 		result = 0;
622bfe3f2eSlogwang 	}
632bfe3f2eSlogwang 
642bfe3f2eSlogwang 	if (((p[0] == 'o') && (p[1] == 'f') && (p[2] == 'f')) ||
652bfe3f2eSlogwang 		((p[0] == 'O') && (p[1] == 'F') && (p[2] == 'F'))) {
662bfe3f2eSlogwang 		p += 3;
672bfe3f2eSlogwang 		result = 0;
682bfe3f2eSlogwang 	}
692bfe3f2eSlogwang 
702bfe3f2eSlogwang 	p = skip_white_spaces(p);
712bfe3f2eSlogwang 
722bfe3f2eSlogwang 	if (p[0] != '\0')
732bfe3f2eSlogwang 		return -EINVAL;
742bfe3f2eSlogwang 
752bfe3f2eSlogwang 	return result;
762bfe3f2eSlogwang }
772bfe3f2eSlogwang 
782bfe3f2eSlogwang int
parser_read_uint64(uint64_t * value,const char * p)792bfe3f2eSlogwang parser_read_uint64(uint64_t *value, const char *p)
802bfe3f2eSlogwang {
812bfe3f2eSlogwang 	char *next;
822bfe3f2eSlogwang 	uint64_t val;
832bfe3f2eSlogwang 
842bfe3f2eSlogwang 	p = skip_white_spaces(p);
852bfe3f2eSlogwang 	if (!isdigit(*p))
862bfe3f2eSlogwang 		return -EINVAL;
872bfe3f2eSlogwang 
882bfe3f2eSlogwang 	val = strtoul(p, &next, 10);
892bfe3f2eSlogwang 	if (p == next)
902bfe3f2eSlogwang 		return -EINVAL;
912bfe3f2eSlogwang 
922bfe3f2eSlogwang 	p = next;
932bfe3f2eSlogwang 	switch (*p) {
942bfe3f2eSlogwang 	case 'T':
952bfe3f2eSlogwang 		val *= 1024ULL;
962bfe3f2eSlogwang 		/* fall through */
972bfe3f2eSlogwang 	case 'G':
982bfe3f2eSlogwang 		val *= 1024ULL;
992bfe3f2eSlogwang 		/* fall through */
1002bfe3f2eSlogwang 	case 'M':
1012bfe3f2eSlogwang 		val *= 1024ULL;
1022bfe3f2eSlogwang 		/* fall through */
1032bfe3f2eSlogwang 	case 'k':
1042bfe3f2eSlogwang 	case 'K':
1052bfe3f2eSlogwang 		val *= 1024ULL;
1062bfe3f2eSlogwang 		p++;
1072bfe3f2eSlogwang 		break;
1082bfe3f2eSlogwang 	}
1092bfe3f2eSlogwang 
1102bfe3f2eSlogwang 	p = skip_white_spaces(p);
1112bfe3f2eSlogwang 	if (*p != '\0')
1122bfe3f2eSlogwang 		return -EINVAL;
1132bfe3f2eSlogwang 
1142bfe3f2eSlogwang 	*value = val;
1152bfe3f2eSlogwang 	return 0;
1162bfe3f2eSlogwang }
1172bfe3f2eSlogwang 
1182bfe3f2eSlogwang int
parser_read_int32(int32_t * value,const char * p)1192bfe3f2eSlogwang parser_read_int32(int32_t *value, const char *p)
1202bfe3f2eSlogwang {
1212bfe3f2eSlogwang 	char *next;
1222bfe3f2eSlogwang 	int32_t val;
1232bfe3f2eSlogwang 
1242bfe3f2eSlogwang 	p = skip_white_spaces(p);
1252bfe3f2eSlogwang 	if (!isdigit(*p))
1262bfe3f2eSlogwang 		return -EINVAL;
1272bfe3f2eSlogwang 
1282bfe3f2eSlogwang 	val = strtol(p, &next, 10);
1292bfe3f2eSlogwang 	if (p == next)
1302bfe3f2eSlogwang 		return -EINVAL;
1312bfe3f2eSlogwang 
1322bfe3f2eSlogwang 	*value = val;
1332bfe3f2eSlogwang 	return 0;
1342bfe3f2eSlogwang }
1352bfe3f2eSlogwang 
1362bfe3f2eSlogwang int
parser_read_uint64_hex(uint64_t * value,const char * p)1372bfe3f2eSlogwang parser_read_uint64_hex(uint64_t *value, const char *p)
1382bfe3f2eSlogwang {
1392bfe3f2eSlogwang 	char *next;
1402bfe3f2eSlogwang 	uint64_t val;
1412bfe3f2eSlogwang 
1422bfe3f2eSlogwang 	p = skip_white_spaces(p);
1432bfe3f2eSlogwang 
1442bfe3f2eSlogwang 	val = strtoul(p, &next, 16);
1452bfe3f2eSlogwang 	if (p == next)
1462bfe3f2eSlogwang 		return -EINVAL;
1472bfe3f2eSlogwang 
1482bfe3f2eSlogwang 	p = skip_white_spaces(next);
1492bfe3f2eSlogwang 	if (*p != '\0')
1502bfe3f2eSlogwang 		return -EINVAL;
1512bfe3f2eSlogwang 
1522bfe3f2eSlogwang 	*value = val;
1532bfe3f2eSlogwang 	return 0;
1542bfe3f2eSlogwang }
1552bfe3f2eSlogwang 
1562bfe3f2eSlogwang int
parser_read_uint32(uint32_t * value,const char * p)1572bfe3f2eSlogwang parser_read_uint32(uint32_t *value, const char *p)
1582bfe3f2eSlogwang {
1592bfe3f2eSlogwang 	uint64_t val = 0;
1602bfe3f2eSlogwang 	int ret = parser_read_uint64(&val, p);
1612bfe3f2eSlogwang 
1622bfe3f2eSlogwang 	if (ret < 0)
1632bfe3f2eSlogwang 		return ret;
1642bfe3f2eSlogwang 
1652bfe3f2eSlogwang 	if (val > UINT32_MAX)
1662bfe3f2eSlogwang 		return -ERANGE;
1672bfe3f2eSlogwang 
1682bfe3f2eSlogwang 	*value = val;
1692bfe3f2eSlogwang 	return 0;
1702bfe3f2eSlogwang }
1712bfe3f2eSlogwang 
1722bfe3f2eSlogwang int
parser_read_uint32_hex(uint32_t * value,const char * p)1732bfe3f2eSlogwang parser_read_uint32_hex(uint32_t *value, const char *p)
1742bfe3f2eSlogwang {
1752bfe3f2eSlogwang 	uint64_t val = 0;
1762bfe3f2eSlogwang 	int ret = parser_read_uint64_hex(&val, p);
1772bfe3f2eSlogwang 
1782bfe3f2eSlogwang 	if (ret < 0)
1792bfe3f2eSlogwang 		return ret;
1802bfe3f2eSlogwang 
1812bfe3f2eSlogwang 	if (val > UINT32_MAX)
1822bfe3f2eSlogwang 		return -ERANGE;
1832bfe3f2eSlogwang 
1842bfe3f2eSlogwang 	*value = val;
1852bfe3f2eSlogwang 	return 0;
1862bfe3f2eSlogwang }
1872bfe3f2eSlogwang 
1882bfe3f2eSlogwang int
parser_read_uint16(uint16_t * value,const char * p)1892bfe3f2eSlogwang parser_read_uint16(uint16_t *value, const char *p)
1902bfe3f2eSlogwang {
1912bfe3f2eSlogwang 	uint64_t val = 0;
1922bfe3f2eSlogwang 	int ret = parser_read_uint64(&val, p);
1932bfe3f2eSlogwang 
1942bfe3f2eSlogwang 	if (ret < 0)
1952bfe3f2eSlogwang 		return ret;
1962bfe3f2eSlogwang 
1972bfe3f2eSlogwang 	if (val > UINT16_MAX)
1982bfe3f2eSlogwang 		return -ERANGE;
1992bfe3f2eSlogwang 
2002bfe3f2eSlogwang 	*value = val;
2012bfe3f2eSlogwang 	return 0;
2022bfe3f2eSlogwang }
2032bfe3f2eSlogwang 
2042bfe3f2eSlogwang int
parser_read_uint16_hex(uint16_t * value,const char * p)2052bfe3f2eSlogwang parser_read_uint16_hex(uint16_t *value, const char *p)
2062bfe3f2eSlogwang {
2072bfe3f2eSlogwang 	uint64_t val = 0;
2082bfe3f2eSlogwang 	int ret = parser_read_uint64_hex(&val, p);
2092bfe3f2eSlogwang 
2102bfe3f2eSlogwang 	if (ret < 0)
2112bfe3f2eSlogwang 		return ret;
2122bfe3f2eSlogwang 
2132bfe3f2eSlogwang 	if (val > UINT16_MAX)
2142bfe3f2eSlogwang 		return -ERANGE;
2152bfe3f2eSlogwang 
2162bfe3f2eSlogwang 	*value = val;
2172bfe3f2eSlogwang 	return 0;
2182bfe3f2eSlogwang }
2192bfe3f2eSlogwang 
2202bfe3f2eSlogwang int
parser_read_uint8(uint8_t * value,const char * p)2212bfe3f2eSlogwang parser_read_uint8(uint8_t *value, const char *p)
2222bfe3f2eSlogwang {
2232bfe3f2eSlogwang 	uint64_t val = 0;
2242bfe3f2eSlogwang 	int ret = parser_read_uint64(&val, p);
2252bfe3f2eSlogwang 
2262bfe3f2eSlogwang 	if (ret < 0)
2272bfe3f2eSlogwang 		return ret;
2282bfe3f2eSlogwang 
2292bfe3f2eSlogwang 	if (val > UINT8_MAX)
2302bfe3f2eSlogwang 		return -ERANGE;
2312bfe3f2eSlogwang 
2322bfe3f2eSlogwang 	*value = val;
2332bfe3f2eSlogwang 	return 0;
2342bfe3f2eSlogwang }
2352bfe3f2eSlogwang 
2362bfe3f2eSlogwang int
parser_read_uint8_hex(uint8_t * value,const char * p)2372bfe3f2eSlogwang parser_read_uint8_hex(uint8_t *value, const char *p)
2382bfe3f2eSlogwang {
2392bfe3f2eSlogwang 	uint64_t val = 0;
2402bfe3f2eSlogwang 	int ret = parser_read_uint64_hex(&val, p);
2412bfe3f2eSlogwang 
2422bfe3f2eSlogwang 	if (ret < 0)
2432bfe3f2eSlogwang 		return ret;
2442bfe3f2eSlogwang 
2452bfe3f2eSlogwang 	if (val > UINT8_MAX)
2462bfe3f2eSlogwang 		return -ERANGE;
2472bfe3f2eSlogwang 
2482bfe3f2eSlogwang 	*value = val;
2492bfe3f2eSlogwang 	return 0;
2502bfe3f2eSlogwang }
2512bfe3f2eSlogwang 
2522bfe3f2eSlogwang int
parse_tokenize_string(char * string,char * tokens[],uint32_t * n_tokens)2532bfe3f2eSlogwang parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
2542bfe3f2eSlogwang {
2552bfe3f2eSlogwang 	uint32_t i;
2562bfe3f2eSlogwang 
2572bfe3f2eSlogwang 	if ((string == NULL) ||
2582bfe3f2eSlogwang 		(tokens == NULL) ||
2592bfe3f2eSlogwang 		(*n_tokens < 1))
2602bfe3f2eSlogwang 		return -EINVAL;
2612bfe3f2eSlogwang 
2622bfe3f2eSlogwang 	for (i = 0; i < *n_tokens; i++) {
2632bfe3f2eSlogwang 		tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
2642bfe3f2eSlogwang 		if (tokens[i] == NULL)
2652bfe3f2eSlogwang 			break;
2662bfe3f2eSlogwang 	}
2672bfe3f2eSlogwang 
2682bfe3f2eSlogwang 	if ((i == *n_tokens) &&
2692bfe3f2eSlogwang 		(strtok_r(string, PARSE_DELIMITER, &string) != NULL))
2702bfe3f2eSlogwang 		return -E2BIG;
2712bfe3f2eSlogwang 
2722bfe3f2eSlogwang 	*n_tokens = i;
2732bfe3f2eSlogwang 	return 0;
2742bfe3f2eSlogwang }
2752bfe3f2eSlogwang 
2762bfe3f2eSlogwang int
parse_hex_string(char * src,uint8_t * dst,uint32_t * size)2772bfe3f2eSlogwang parse_hex_string(char *src, uint8_t *dst, uint32_t *size)
2782bfe3f2eSlogwang {
2792bfe3f2eSlogwang 	char *c;
2802bfe3f2eSlogwang 	uint32_t len, i;
2812bfe3f2eSlogwang 
2822bfe3f2eSlogwang 	/* Check input parameters */
2832bfe3f2eSlogwang 	if ((src == NULL) ||
2842bfe3f2eSlogwang 		(dst == NULL) ||
2852bfe3f2eSlogwang 		(size == NULL) ||
2862bfe3f2eSlogwang 		(*size == 0))
2872bfe3f2eSlogwang 		return -1;
2882bfe3f2eSlogwang 
2892bfe3f2eSlogwang 	len = strlen(src);
2902bfe3f2eSlogwang 	if (((len & 3) != 0) ||
2912bfe3f2eSlogwang 		(len > (*size) * 2))
2922bfe3f2eSlogwang 		return -1;
2932bfe3f2eSlogwang 	*size = len / 2;
2942bfe3f2eSlogwang 
2952bfe3f2eSlogwang 	for (c = src; *c != 0; c++) {
2962bfe3f2eSlogwang 		if ((((*c) >= '0') && ((*c) <= '9')) ||
2972bfe3f2eSlogwang 			(((*c) >= 'A') && ((*c) <= 'F')) ||
2982bfe3f2eSlogwang 			(((*c) >= 'a') && ((*c) <= 'f')))
2992bfe3f2eSlogwang 			continue;
3002bfe3f2eSlogwang 
3012bfe3f2eSlogwang 		return -1;
3022bfe3f2eSlogwang 	}
3032bfe3f2eSlogwang 
3042bfe3f2eSlogwang 	/* Convert chars to bytes */
3052bfe3f2eSlogwang 	for (i = 0; i < *size; i++)
3062bfe3f2eSlogwang 		dst[i] = get_hex_val(src[2 * i]) * 16 +
3072bfe3f2eSlogwang 			get_hex_val(src[2 * i + 1]);
3082bfe3f2eSlogwang 
3092bfe3f2eSlogwang 	return 0;
3102bfe3f2eSlogwang }
3112bfe3f2eSlogwang 
3122bfe3f2eSlogwang int
parse_lcores_list(bool lcores[],const char * corelist)3132bfe3f2eSlogwang parse_lcores_list(bool lcores[], const char *corelist)
3142bfe3f2eSlogwang {
3152bfe3f2eSlogwang 	int i, idx = 0;
3162bfe3f2eSlogwang 	int min, max;
3172bfe3f2eSlogwang 	char *end = NULL;
3182bfe3f2eSlogwang 
3192bfe3f2eSlogwang 	if (corelist == NULL)
3202bfe3f2eSlogwang 		return -1;
3212bfe3f2eSlogwang 	while (isblank(*corelist))
3222bfe3f2eSlogwang 		corelist++;
3232bfe3f2eSlogwang 	i = strlen(corelist);
3242bfe3f2eSlogwang 	while ((i > 0) && isblank(corelist[i - 1]))
3252bfe3f2eSlogwang 		i--;
3262bfe3f2eSlogwang 
3272bfe3f2eSlogwang 	/* Get list of lcores */
3282bfe3f2eSlogwang 	min = RTE_MAX_LCORE;
3292bfe3f2eSlogwang 	do {
3302bfe3f2eSlogwang 		while (isblank(*corelist))
3312bfe3f2eSlogwang 			corelist++;
3322bfe3f2eSlogwang 		if (*corelist == '\0')
3332bfe3f2eSlogwang 			return -1;
3342bfe3f2eSlogwang 		idx = strtoul(corelist, &end, 10);
3352bfe3f2eSlogwang 
3362bfe3f2eSlogwang 		if (end == NULL)
3372bfe3f2eSlogwang 			return -1;
3382bfe3f2eSlogwang 		while (isblank(*end))
3392bfe3f2eSlogwang 			end++;
3402bfe3f2eSlogwang 		if (*end == '-') {
3412bfe3f2eSlogwang 			min = idx;
3422bfe3f2eSlogwang 		} else if ((*end == ',') || (*end == '\0')) {
3432bfe3f2eSlogwang 			max = idx;
3442bfe3f2eSlogwang 			if (min == RTE_MAX_LCORE)
3452bfe3f2eSlogwang 				min = idx;
3462bfe3f2eSlogwang 			for (idx = min; idx <= max; idx++) {
3472bfe3f2eSlogwang 				if (lcores[idx] == 1)
3482bfe3f2eSlogwang 					return -E2BIG;
3492bfe3f2eSlogwang 				lcores[idx] = 1;
3502bfe3f2eSlogwang 			}
3512bfe3f2eSlogwang 
3522bfe3f2eSlogwang 			min = RTE_MAX_LCORE;
3532bfe3f2eSlogwang 		} else
3542bfe3f2eSlogwang 			return -1;
3552bfe3f2eSlogwang 		corelist = end + 1;
3562bfe3f2eSlogwang 	} while (*end != '\0');
3572bfe3f2eSlogwang 
3582bfe3f2eSlogwang 	return 0;
3592bfe3f2eSlogwang }
360