xref: /dpdk/examples/vm_power_manager/guest_cli/parse.c (revision 72b452c5f2599f970f47fd17d3e8e5d60bfebe7a)
159287933SDavid Hunt /* SPDX-License-Identifier: BSD-3-Clause
259287933SDavid Hunt  * Copyright(c) 2010-2014 Intel Corporation.
359287933SDavid Hunt  * Copyright(c) 2014 6WIND S.A.
459287933SDavid Hunt  */
559287933SDavid Hunt 
6*72b452c5SDmitry Kozlyuk #include <ctype.h>
7*72b452c5SDmitry Kozlyuk #include <errno.h>
859287933SDavid Hunt #include <stdlib.h>
959287933SDavid Hunt #include <string.h>
10*72b452c5SDmitry Kozlyuk 
1159287933SDavid Hunt #include <rte_log.h>
12*72b452c5SDmitry Kozlyuk 
1359287933SDavid Hunt #include "parse.h"
1459287933SDavid Hunt 
1559287933SDavid Hunt /*
1659287933SDavid Hunt  * Parse elem, the elem could be single number/range or group
1759287933SDavid Hunt  * 1) A single number elem, it's just a simple digit. e.g. 9
1859287933SDavid Hunt  * 2) A single range elem, two digits with a '-' between. e.g. 2-6
1959287933SDavid Hunt  * 3) A group elem, combines multiple 1) or 2) e.g 0,2-4,6
2059287933SDavid Hunt  *    Within group, '-' used for a range separator;
2159287933SDavid Hunt  *                       ',' used for a single number.
2259287933SDavid Hunt  */
2359287933SDavid Hunt int
parse_set(const char * input,uint16_t set[],unsigned int num)2459287933SDavid Hunt parse_set(const char *input, uint16_t set[], unsigned int num)
2559287933SDavid Hunt {
2659287933SDavid Hunt 	unsigned int idx;
2759287933SDavid Hunt 	const char *str = input;
2859287933SDavid Hunt 	char *end = NULL;
2959287933SDavid Hunt 	unsigned int min, max;
3059287933SDavid Hunt 
3159287933SDavid Hunt 	memset(set, 0, num * sizeof(uint16_t));
3259287933SDavid Hunt 
3359287933SDavid Hunt 	while (isblank(*str))
3459287933SDavid Hunt 		str++;
3559287933SDavid Hunt 
3659287933SDavid Hunt 	/* only digit or left bracket is qualify for start point */
3759287933SDavid Hunt 	if (!isdigit(*str) || *str == '\0')
3859287933SDavid Hunt 		return -1;
3959287933SDavid Hunt 
4059287933SDavid Hunt 	while (isblank(*str))
4159287933SDavid Hunt 		str++;
4259287933SDavid Hunt 	if (*str == '\0')
4359287933SDavid Hunt 		return -1;
4459287933SDavid Hunt 
4559287933SDavid Hunt 	min = num;
4659287933SDavid Hunt 	do {
4759287933SDavid Hunt 
4859287933SDavid Hunt 		/* go ahead to the first digit */
4959287933SDavid Hunt 		while (isblank(*str))
5059287933SDavid Hunt 			str++;
5159287933SDavid Hunt 		if (!isdigit(*str))
5259287933SDavid Hunt 			return -1;
5359287933SDavid Hunt 
5459287933SDavid Hunt 		/* get the digit value */
5559287933SDavid Hunt 		errno = 0;
5659287933SDavid Hunt 		idx = strtoul(str, &end, 10);
5759287933SDavid Hunt 		if (errno || end == NULL || idx >= num)
5859287933SDavid Hunt 			return -1;
5959287933SDavid Hunt 
6059287933SDavid Hunt 		/* go ahead to separator '-' and ',' */
6159287933SDavid Hunt 		while (isblank(*end))
6259287933SDavid Hunt 			end++;
6359287933SDavid Hunt 		if (*end == '-') {
6459287933SDavid Hunt 			if (min == num)
6559287933SDavid Hunt 				min = idx;
6659287933SDavid Hunt 			else /* avoid continuous '-' */
6759287933SDavid Hunt 				return -1;
6859287933SDavid Hunt 		} else if ((*end == ',') || (*end == '\0')) {
6959287933SDavid Hunt 			max = idx;
7059287933SDavid Hunt 
7159287933SDavid Hunt 			if (min == num)
7259287933SDavid Hunt 				min = idx;
7359287933SDavid Hunt 
7459287933SDavid Hunt 			for (idx = RTE_MIN(min, max);
7559287933SDavid Hunt 					idx <= RTE_MAX(min, max); idx++) {
7659287933SDavid Hunt 				set[idx] = 1;
7759287933SDavid Hunt 			}
7859287933SDavid Hunt 			min = num;
7959287933SDavid Hunt 		} else
8059287933SDavid Hunt 			return -1;
8159287933SDavid Hunt 
8259287933SDavid Hunt 		str = end + 1;
8359287933SDavid Hunt 	} while (*end != '\0');
8459287933SDavid Hunt 
8559287933SDavid Hunt 	return str - input;
8659287933SDavid Hunt }
87