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