1d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2d30ea906Sjfb8856606  * Copyright(c) 2010-2014 Intel Corporation.
3d30ea906Sjfb8856606  * Copyright(c) 2014 6WIND S.A.
4d30ea906Sjfb8856606  */
5d30ea906Sjfb8856606 
6d30ea906Sjfb8856606 #include <string.h>
7d30ea906Sjfb8856606 #include <rte_log.h>
8d30ea906Sjfb8856606 #include "parse.h"
9d30ea906Sjfb8856606 
10d30ea906Sjfb8856606 /*
11d30ea906Sjfb8856606  * Parse elem, the elem could be single number/range or group
12d30ea906Sjfb8856606  * 1) A single number elem, it's just a simple digit. e.g. 9
13d30ea906Sjfb8856606  * 2) A single range elem, two digits with a '-' between. e.g. 2-6
14d30ea906Sjfb8856606  * 3) A group elem, combines multiple 1) or 2) e.g 0,2-4,6
15d30ea906Sjfb8856606  *    Within group, '-' used for a range separator;
16d30ea906Sjfb8856606  *                       ',' used for a single number.
17d30ea906Sjfb8856606  */
18d30ea906Sjfb8856606 int
parse_set(const char * input,uint16_t set[],unsigned int num)19d30ea906Sjfb8856606 parse_set(const char *input, uint16_t set[], unsigned int num)
20d30ea906Sjfb8856606 {
21d30ea906Sjfb8856606 	unsigned int idx;
22d30ea906Sjfb8856606 	const char *str = input;
23d30ea906Sjfb8856606 	char *end = NULL;
24d30ea906Sjfb8856606 	unsigned int min, max;
25d30ea906Sjfb8856606 
26d30ea906Sjfb8856606 	memset(set, 0, num * sizeof(uint16_t));
27d30ea906Sjfb8856606 
28d30ea906Sjfb8856606 	while (isblank(*str))
29d30ea906Sjfb8856606 		str++;
30d30ea906Sjfb8856606 
31d30ea906Sjfb8856606 	/* only digit or left bracket is qualify for start point */
32d30ea906Sjfb8856606 	if (!isdigit(*str) || *str == '\0')
33d30ea906Sjfb8856606 		return -1;
34d30ea906Sjfb8856606 
35d30ea906Sjfb8856606 	while (isblank(*str))
36d30ea906Sjfb8856606 		str++;
37d30ea906Sjfb8856606 	if (*str == '\0')
38d30ea906Sjfb8856606 		return -1;
39d30ea906Sjfb8856606 
40d30ea906Sjfb8856606 	min = num;
41d30ea906Sjfb8856606 	do {
42d30ea906Sjfb8856606 
43d30ea906Sjfb8856606 		/* go ahead to the first digit */
44d30ea906Sjfb8856606 		while (isblank(*str))
45d30ea906Sjfb8856606 			str++;
46d30ea906Sjfb8856606 		if (!isdigit(*str))
47d30ea906Sjfb8856606 			return -1;
48d30ea906Sjfb8856606 
49d30ea906Sjfb8856606 		/* get the digit value */
50d30ea906Sjfb8856606 		errno = 0;
51d30ea906Sjfb8856606 		idx = strtoul(str, &end, 10);
52d30ea906Sjfb8856606 		if (errno || end == NULL || idx >= num)
53d30ea906Sjfb8856606 			return -1;
54d30ea906Sjfb8856606 
55d30ea906Sjfb8856606 		/* go ahead to separator '-' and ',' */
56d30ea906Sjfb8856606 		while (isblank(*end))
57d30ea906Sjfb8856606 			end++;
58d30ea906Sjfb8856606 		if (*end == '-') {
59d30ea906Sjfb8856606 			if (min == num)
60d30ea906Sjfb8856606 				min = idx;
61d30ea906Sjfb8856606 			else /* avoid continuous '-' */
62d30ea906Sjfb8856606 				return -1;
63*2d9fd380Sjfb8856606 		} else if ((*end == ',') || (*end == ':') || (*end == '\0')) {
64d30ea906Sjfb8856606 			max = idx;
65d30ea906Sjfb8856606 
66d30ea906Sjfb8856606 			if (min == num)
67d30ea906Sjfb8856606 				min = idx;
68d30ea906Sjfb8856606 
69d30ea906Sjfb8856606 			for (idx = RTE_MIN(min, max);
70d30ea906Sjfb8856606 					idx <= RTE_MAX(min, max); idx++) {
71d30ea906Sjfb8856606 				set[idx] = 1;
72d30ea906Sjfb8856606 			}
73d30ea906Sjfb8856606 			min = num;
74d30ea906Sjfb8856606 		} else
75d30ea906Sjfb8856606 			return -1;
76d30ea906Sjfb8856606 
77d30ea906Sjfb8856606 		str = end + 1;
78*2d9fd380Sjfb8856606 	} while ((*end != '\0') && (*end != ':'));
79*2d9fd380Sjfb8856606 
80*2d9fd380Sjfb8856606 	return str - input;
81*2d9fd380Sjfb8856606 }
82*2d9fd380Sjfb8856606 
83*2d9fd380Sjfb8856606 int
parse_branch_ratio(const char * input,float * branch_ratio)84*2d9fd380Sjfb8856606 parse_branch_ratio(const char *input, float *branch_ratio)
85*2d9fd380Sjfb8856606 {
86*2d9fd380Sjfb8856606 	const char *str = input;
87*2d9fd380Sjfb8856606 	char *end = NULL;
88*2d9fd380Sjfb8856606 
89*2d9fd380Sjfb8856606 	while (isblank(*str))
90*2d9fd380Sjfb8856606 		str++;
91*2d9fd380Sjfb8856606 
92*2d9fd380Sjfb8856606 	if (*str == '\0')
93*2d9fd380Sjfb8856606 		return -1;
94*2d9fd380Sjfb8856606 
95*2d9fd380Sjfb8856606 	/* Go straight to the ':' separator if present */
96*2d9fd380Sjfb8856606 	while ((*str != '\0') && (*str != ':'))
97*2d9fd380Sjfb8856606 		str++;
98*2d9fd380Sjfb8856606 
99*2d9fd380Sjfb8856606 	/* Branch ratio not specified in args so leave it at default setting */
100*2d9fd380Sjfb8856606 	if (*str == '\0')
101*2d9fd380Sjfb8856606 		return 0;
102*2d9fd380Sjfb8856606 
103*2d9fd380Sjfb8856606 	/* Confirm ':' separator present */
104*2d9fd380Sjfb8856606 	if (*str != ':')
105*2d9fd380Sjfb8856606 		return -1;
106*2d9fd380Sjfb8856606 
107*2d9fd380Sjfb8856606 	str++;
108*2d9fd380Sjfb8856606 	errno = 0;
109*2d9fd380Sjfb8856606 	*branch_ratio = strtof(str, &end);
110*2d9fd380Sjfb8856606 	if (errno || end == NULL)
111*2d9fd380Sjfb8856606 		return -1;
112*2d9fd380Sjfb8856606 
113*2d9fd380Sjfb8856606 	if (*end != '\0')
114*2d9fd380Sjfb8856606 		return -1;
115*2d9fd380Sjfb8856606 
116*2d9fd380Sjfb8856606 	str = end + 1;
117d30ea906Sjfb8856606 
118d30ea906Sjfb8856606 	return str - input;
119d30ea906Sjfb8856606 }
120