#include #include #include #include #define NEGATIVE (-1) #define CH_RANGE '-' #define CH_NOT '!' #define CH_SEPARATOR ',' // VERY SIMILAR TO atoi(), BUT RETURNS A POINTER TO THE NEXT NON-DIGIT CHAR char *parse1int(char *str, int *n) { *n = 0; while(isdigit(*str)) { *n = (*n)*10 + (*str-'0'); ++str; } return str; } int *parse_intlist(char *str, int *listlen) { int *intlist = NULL; int max = NEGATIVE; // SCAN THE PROVIDED STRING, LOOKING FOR THE MAXIMUM INTEGER if(str) { char *s = str; int value; while(*s) { if(isdigit(*s)) { s = parse1int(s, &value); // POSSIBLY UPDATE THE NEW MAXIMUM if(max < value) { max = value; } } else { ++s; } } } // IF WE FOUND A MAXIMUM, ALLOCATE A VECTOR OF INTEGERS if(max >= 0) { intlist = calloc(max+1, sizeof(intlist[0])); } // IF NO LIST ALLOCATED, RETURN FAILURE TO THE CALLER if(intlist == NULL) { if(listlen != NULL) { *listlen = 0; } return NULL; } if(listlen != NULL) { *listlen = max; } // OK, ATTEMPT TO PARSE A 'VALID' LIST while(*str) { int int1 = NEGATIVE, int2 = NEGATIVE; bool set = true; // NEGATE THE EXISTENCE OF FOLLOWING VALUES while(*str == CH_NOT) { set = !set; ++str; } // PARSE THE FIRST VALUE if(isdigit(*str)) { str = parse1int(str, &int1); // PERMIT A RANGE OF VALUES if(*str == CH_RANGE) { while(*str == CH_RANGE) { ++str; } // LOOK FOR A SECOND VALUE, int1..int2 str = parse1int(str, &int2); for(int i=int1 ; i<=int2 ; ++i) { intlist[i] = set; } } else { intlist[int1] = set; } while(*str == CH_SEPARATOR) { ++str; } } else { break; } } // RETURN THE ALLOCATED LIST (AND ITS LENGTH) return intlist; } int main(int argc, char *argv[]) { for(int a=1 ; a