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