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