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