xref: /dpdk/examples/vm_power_manager/parse.c (revision 99a968fac0cf1229ff6da9e082f3bd119bb1a746)
1*99a968faSDavid Hunt /* SPDX-License-Identifier: BSD-3-Clause
2*99a968faSDavid Hunt  * Copyright(c) 2010-2014 Intel Corporation.
3*99a968faSDavid Hunt  * Copyright(c) 2014 6WIND S.A.
4*99a968faSDavid Hunt  */
5*99a968faSDavid Hunt 
6*99a968faSDavid Hunt #include <string.h>
7*99a968faSDavid Hunt #include <rte_log.h>
8*99a968faSDavid Hunt #include "parse.h"
9*99a968faSDavid Hunt 
10*99a968faSDavid Hunt /*
11*99a968faSDavid Hunt  * Parse elem, the elem could be single number/range or group
12*99a968faSDavid Hunt  * 1) A single number elem, it's just a simple digit. e.g. 9
13*99a968faSDavid Hunt  * 2) A single range elem, two digits with a '-' between. e.g. 2-6
14*99a968faSDavid Hunt  * 3) A group elem, combines multiple 1) or 2) e.g 0,2-4,6
15*99a968faSDavid Hunt  *    Within group, '-' used for a range separator;
16*99a968faSDavid Hunt  *                       ',' used for a single number.
17*99a968faSDavid Hunt  */
18*99a968faSDavid Hunt int
19*99a968faSDavid Hunt parse_set(const char *input, uint16_t set[], unsigned int num)
20*99a968faSDavid Hunt {
21*99a968faSDavid Hunt 	unsigned int idx;
22*99a968faSDavid Hunt 	const char *str = input;
23*99a968faSDavid Hunt 	char *end = NULL;
24*99a968faSDavid Hunt 	unsigned int min, max;
25*99a968faSDavid Hunt 
26*99a968faSDavid Hunt 	memset(set, 0, num * sizeof(uint16_t));
27*99a968faSDavid Hunt 
28*99a968faSDavid Hunt 	while (isblank(*str))
29*99a968faSDavid Hunt 		str++;
30*99a968faSDavid Hunt 
31*99a968faSDavid Hunt 	/* only digit or left bracket is qualify for start point */
32*99a968faSDavid Hunt 	if (!isdigit(*str) || *str == '\0')
33*99a968faSDavid Hunt 		return -1;
34*99a968faSDavid Hunt 
35*99a968faSDavid Hunt 	while (isblank(*str))
36*99a968faSDavid Hunt 		str++;
37*99a968faSDavid Hunt 	if (*str == '\0')
38*99a968faSDavid Hunt 		return -1;
39*99a968faSDavid Hunt 
40*99a968faSDavid Hunt 	min = num;
41*99a968faSDavid Hunt 	do {
42*99a968faSDavid Hunt 
43*99a968faSDavid Hunt 		/* go ahead to the first digit */
44*99a968faSDavid Hunt 		while (isblank(*str))
45*99a968faSDavid Hunt 			str++;
46*99a968faSDavid Hunt 		if (!isdigit(*str))
47*99a968faSDavid Hunt 			return -1;
48*99a968faSDavid Hunt 
49*99a968faSDavid Hunt 		/* get the digit value */
50*99a968faSDavid Hunt 		errno = 0;
51*99a968faSDavid Hunt 		idx = strtoul(str, &end, 10);
52*99a968faSDavid Hunt 		if (errno || end == NULL || idx >= num)
53*99a968faSDavid Hunt 			return -1;
54*99a968faSDavid Hunt 
55*99a968faSDavid Hunt 		/* go ahead to separator '-' and ',' */
56*99a968faSDavid Hunt 		while (isblank(*end))
57*99a968faSDavid Hunt 			end++;
58*99a968faSDavid Hunt 		if (*end == '-') {
59*99a968faSDavid Hunt 			if (min == num)
60*99a968faSDavid Hunt 				min = idx;
61*99a968faSDavid Hunt 			else /* avoid continuous '-' */
62*99a968faSDavid Hunt 				return -1;
63*99a968faSDavid Hunt 		} else if ((*end == ',') || (*end == '\0')) {
64*99a968faSDavid Hunt 			max = idx;
65*99a968faSDavid Hunt 
66*99a968faSDavid Hunt 			if (min == num)
67*99a968faSDavid Hunt 				min = idx;
68*99a968faSDavid Hunt 
69*99a968faSDavid Hunt 			for (idx = RTE_MIN(min, max);
70*99a968faSDavid Hunt 					idx <= RTE_MAX(min, max); idx++) {
71*99a968faSDavid Hunt 				set[idx] = 1;
72*99a968faSDavid Hunt 			}
73*99a968faSDavid Hunt 			min = num;
74*99a968faSDavid Hunt 		} else
75*99a968faSDavid Hunt 			return -1;
76*99a968faSDavid Hunt 
77*99a968faSDavid Hunt 		str = end + 1;
78*99a968faSDavid Hunt 	} while (*end != '\0');
79*99a968faSDavid Hunt 
80*99a968faSDavid Hunt 	return str - input;
81*99a968faSDavid Hunt }
82