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