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