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 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